Onde posso obter uma implementação de código aberto do algoritmo de design de filtro FIR ideal Parks-McClellan?

20

Antecedentes: Muitas vezes, estou realizando algum tipo de tarefa de processamento de sinal que requer um filtro exclusivo. Normalmente, neste ponto, vou ao MATLAB e giro um novo filtro exclusivo usando firpm() . A firpm()função MATLAB implementa esse algoritmo Parks-McClellan. Agora eu tenho um filtro e coloco o filtro em uma matriz codificada. Mas aqui está o problema: agora tenho um filtro codificado que funciona apenas para um cenário.

O problema: agora posso resolver meu problema de processamento de sinal du-jour ... mas apenas para uma taxa de amostra única muito ESPECÍFICA ou um cenário ESPECÍFICO.

O objetivo: quero poder chamar firpm() do código C ou de algum outro idioma e tornar meu código de processamento de sinal mais genérico. Não consigo encontrar uma implementação de código aberto do firpm()!

Onde posso obter uma implementação de código aberto do algoritmo ideal de design de filtro FIR de Parks-McClellan (também conhecido como firpm() no MATLAB)?

  • PS Estou ciente de que posso projetar filtros de maneira diferente usando janelas ou algo mais ... fique à vontade para mencionar os que estão nos comentários. Mas o objetivo desta pergunta não é perguntar "quais são as outras técnicas de design de filtro?" o objetivo é encontrar uma implementação de código aberto do MUITO MUITO Útil firpm() ... ou algo semelhante.

  • PPS Um dos objetivos desta pergunta é aprender como o algoritmo Parks-McClellan funciona, examinando primeiro o código e depois planejo ler alguma teoria de fundo.

Trevor Boyd Smith
fonte
É importante que a solução seja gratuita? Você já investigou a API C do Matlab?
2
A prioridade mais alta é que eu quero ver o código-fonte (de preferência não fortran, para que não precise desviar os olhos). Não colocarei a restrição de que deve ser livre (talvez haja algum tipo de código-fonte aberto, mas não-livre).
Trevor Boyd Smith
3
Estou ciente de que você pode compilar o Matlab usando o compilador Matlab e depois distribuí-lo usando o Matlab Runtime ... para que tecnicamente seu cliente não precise pagar pela licença do Matlab. Também estou ciente do Matlab Engine (também conhecido como C to Matlab API). Ambos são irrelevantes porque eu normalmente corro em uma plataforma incorporada onde nenhum deles está disponível.
Trevor Boyd Smith
1
@TrevorBoydSmith Como você só quer ver o código-fonte, já tentou type firpm.mno MATLAB? Isso mostrará a implementação da função do MATLAB.
Lorem Ipsum
1
O design do filtro FIR é muito útil para o processamento de sinais e o Parks-McClelan é um assunto não trivial. E, no entanto, estou sendo votado repetidamente por perguntar sobre um assunto que a IMO se encaixa diretamente no estatuto dsp.stackexchange. Por favor, explique seus votos negativos.
Trevor Boyd Smith

Respostas:

5

Aqui está uma versão LGPL do algoritmo de troca Remez. O código de oitava parece derivar dele. Ele foi vinculado a partir da página da wikipedia Parks McClellan .
O código original do Janovetz pode ser mais facilmente utilizável em seu projeto, pois não possui chamadas de oitava, mas seria sensato procurar no changelog do octave-forge svn para obter mais informações sobre correções de bugs ou acelerações no arquivo remez.cc .

Mark Borgerding
fonte
Concordo que o uso do código Janovetz em um projeto seria mais fácil porque é direto C. Concordo definitivamente que verificar o log de alterações da implementação da oitava seria muito inteligente.
Trevor Boyd Smith
O código Janovetz IMO é provavelmente um primeiro ou segundo rascunho ... mas não foi muito usado como o código Octave.
Trevor Boyd Smith
NOTA MUITO IMPORTANTE: O código Janovetz é LGPL, para que você possa usá-lo em um ambiente comercial.
Trevor Boyd Smith
O primeiro link da resposta está quebrado, então aqui está um link para uma biblioteca onde a mesma implementação é usada.
Machta
11

Existe uma implementação de código aberto do Parks-McClellan (também conhecido como algoritmo de troca Remez) no GNU Octave, uma implementação de software livre de um ambiente semelhante ao MATLAB. A função, chamada "remez", está contida no pacote "signal" , hospedado no Octave-Forge . Se você baixar o pacote, encontrará "remez.cc", uma implementação em C ++ do algoritmo.

Uma coisa legal do Octave é que ele é quase compatível com o MATLAB, então você pode facilmente portar o código para usá-lo se quiser. É uma boa maneira de espiar as implementações de algoritmos fornecidos no formato MEX no MATLAB.

Jason R
fonte
"O algoritmo Parks-McClellan é uma variação do algoritmo Remez ou do algoritmo de troca Remez, com a alteração que foi especificamente projetada para filtros FIR e se tornou um método padrão para o design de filtros FIR". Também em SciPy: docs.scipy.org/doc/scipy/reference/generated/...
endolith
2

Aqui está outra fonte para o algoritmo Parks McClellan em C. Esse código é diferente do código SciPy mencionado acima, pois possui 61 das 69 instruções goto originais removidas (o código SciPy ainda possui cerca de 37 goto's). Ele também corrige o código em 3 locais onde a divisão por zero pode ocorrer e possui algum código adicional que verifica os valores da borda da banda.

http://www.iowahills.com/A7ExampleCodePage.html

user5108_Dan
fonte
1

Talvez você já saiba disso, mas se tiver o matlab, poderá usar o codificador matlab e criar uma função simples que use o recurso que você deseja examinar. Em seguida, execute-o e veja o código C criado. Eu tentei com o FFT e com a decomposição do QR e, embora seja um pouco bagunçado, pode ser entendido perfeitamente.

osso
fonte
1

Aqui está um artigo que faz uma versão real do Matlab do algoritmo remez "core". “Um programa de design de filtros FIR de várias bandas ideal, baseado no MATLAB, seguindo a idéia original do algoritmo de troca múltipla Remez” -2011 Simpósio Internacional de Circuitos e Sistemas IEEE de 2011 (ISCAS) - Autores (Ahsan, Saramaki)

Este artigo faz um bom trabalho ao explicar o algoritmo básico. O objetivo do artigo era evitar o uso do código Fortran original - o que não explica muito bem o algoritmo e geralmente é traduzido diretamente para vários outros idiomas.

Uma coisa que vou comentar. Uma das idéias centrais do algoritmo é ajustar uma curva e, em seguida, encontrar os pontos extremos. Geralmente, uma interpolação de Lagrange é usada para explicar essa idéia, mas a interpolação de Lagrange tem propriedades numéricas ruins. No algoritmo original, use a Implementação Baricêntrica da Interpolação de Lagrange - que evita muitas das armadilhas associadas à interpolação Lagrangiana. Portanto, se você estiver tentando entender completamente o código, convém consultar a Interpolação baricêntrica.

David
fonte
Olhando para o jornal - é uma versão modificada do código Parks-McClellan. Ele ainda é baseado no algoritmo de troca Remez, mas tende a ter melhor desempenho e permite projetar filtros muito mais longos do que aqueles obtidos no algoritmo PM (ou na implementação do Matlab).
David
1

Cuidado com as diferenças entre a firma do Matlab e a remez do Scipy.signal. Por exemplo, essas duas instruções são equivalentes:

% Matlab
firpm(10,[.2 .8],[1 1],'Hilbert')
# Python
from scipy.signal import remez

remez(11, [0.1, 0.4], [1], type='hilbert')
Zhanwen Chen
fonte