Filtro de fase zero: Determinando condições iniciais para filtragem reversa direta

7

Alguém está familiarizado com o algoritmo de Gustafson para minimizar os transientes na filtragem reversa para frente [1]? Estou tentando implementá-lo e meu primeiro palpite foi verificar o filtfilt.m do Matlab, já que eles estão fazendo referência ao artigo. Na função Matlab também é resolvido um sistema de equações lineares para encontrar condições iniciais zi que minimizem os transientes de inicialização, mas a relação entre referência e código não é óbvia para mim. As únicas linhas de código relacionadas à minimização são (nfilt é o comprimento dos vetores do coeficiente):

zi = ( eye(nfilt-1) - [-a(2:nfilt), [eye(nfilt-2); zeros(1,nfilt-2)]] ) \...
 ( b(2:nfilt) - b(1)*a(2:nfilt) );

Alguém pode me indicar a direção certa de como essas linhas se relacionam com o algoritmo descrito no artigo de Gustafson?

[1] Gustafsson, F. "Determinando os estados iniciais na filtragem para frente e para trás". Transações IEEE® no processamento de sinais. Vol. 44, abril de 1996, pp. 988–992.

user967493
fonte
os estados iniciais de qualquer filtro IIR devem ser zero no início do passo de filtragem direta e zero no início do passo de filtragem reversa. em ambas as passagens, o arquivo de sinal (ou buffer) sendo filtrado aumentará pelo comprimento aparente do IIR (quanto tempo leva para a saída decair perto o suficiente para zero, para que você possa optar por interromper o restante da decadência) .
22617 Robert Bristow-Johnson
No artigo, o autor afirma que os filtros para frente e para trás são diferentes em sua representação do espaço de estados. Você pode explicar o porquê?
Maxtron 14/05/19
bem, como eu entendo o uso de filtfilt()não consigo ver o porquê. eu não li o artigo de Gustafson (eu não sou o IEEE e não posso obtê-lo de graça, qualquer pessoa que tenha uma cópia pode enviar e-mail com um arquivo .pdf). ao usar o conceito de filtfilt, pode-se fazer isso com um arquivo inteiro de amostras (para mim seria um arquivo de áudio ou som, como um .wav) primeiro filtrar o som para a frente, filtrando o som com o preenchimento zero no final, desde que você espera que a resposta de impulso do filtro direto seja. isso aumenta o arquivo, mas a saída fica praticamente zero. depois, execute o arquivo resultante pelo filtro para trás.
robert bristow-johnson
existe outro uso, baseado em um artigo de Powell e Chau que faz filtfiltem tempo real dividindo a entrada em blocos de amostras, preenchendo com zero cada bloco, filtrando os blocos para trás, mas mantendo as "caudas" voltando-as para a direção para frente e sobreposição de adição. Powell-Chau não fez isso, mas acho que essa é uma boa aplicação dos filtros IIR truncados, para que você saiba quando a saída do bloco decadente termina.
robert bristow-johnson
11
@ robertbristow-johnson: Encontrei esta cópia do artigo de Gustafsson .
djvg

Respostas:

5

Para quem estiver interessado, encontrei por acaso um documento descrevendo o método implementado no filtfilt.m do matlab. Um link para o artigo está anexado. Pelo menos para meu entendimento, o filtfilt.m do matlab não implementa o algoritmo Gustafson.

Sadovsky, P .; Bartusek, K: Otimização da resposta transitória de um filtro digital, Radioengineering vol. 9, n. 2, 2000

user967493
fonte
Consulte também a scipy documentação de lfilter_zi, que é o padrão scipy.signal.filtfiltpara determinar as condições iniciais, como você pode ver na fonte . Nesse caso, o preenchimento 'ímpar' é usado por padrão, mas pode usar o método de Gustafsson como uma opção (veja a definição _filtfilt_gustna fonte).
djvg
0

A zi = (...)\(...)linha na pergunta do OP determina o estado inicial do filtro. Eu acredito que exatamente a mesma abordagem é usada pelo Python scipy. De acordo com os documentos scipy :

Um filtro linear com a ordem m tem uma representação do espaço de estados (A, B, C, D), para a qual a saída y do filtro pode ser expressa como:

z (n + 1) = A z (n) + B x (n)

y (n) = C z (n) + D x (n)

onde z (n) é um vetor de comprimento m, A tem forma (m, m), B tem forma (m, 1), C tem forma (1, m) e D tem forma (1, 1) (assumindo x (n) é um escalar). lfilter_zi resolve:

zi = A * zi + B

Em outras palavras, ele encontra a condição inicial para a qual a resposta a uma entrada de todas é uma constante .

(minha ênfase)

Observe que filtfiltcalcula o estado inicial zi, dimensiona-o pelo primeiro valor de amostra e passa para o filterque realmente o aplica ( docs ).

Um exemplo básico de como esse estado inicial zipode ser aplicado em um filtro, usando a representação do espaço de estado, é fornecido aqui .

djvg
fonte