Eu tenho este trecho de código que aplica um filtro Bessel:
Versão única:
import scipy.signal
fc_bessel = 0.14 # [Hz]
ordre_bessel = 3
b,a = scipy.signal.bessel(ordre_bessel, fc_bessel, 'low', analog=False, output='ba', fs=300)
filter_once = scipy.signal.lfilter(b, a, input_data)
Como no final receberei meus dados em tempo real, preciso adaptar esse código para pegar cada um input_data
na hora, então preciso manter o estado do filtro em uma zi
variável. Então eu escrevi:
Versão iterativa:
import scipy.signal
fc_bessel = 0.14 # [Hz]
ordre_bessel = 3
b,a = scipy.signal.bessel(ordre_bessel, fc_bessel, 'low', analog=False, output='ba', fs=300)
z = scipy.signal.lfilter_zi(b, a)
filter_iter = []
for input_value in input_data:
filtered_value, z = scipy.signal.lfilter(b, a, [input_value], zi=z)
filter_iter.append(filtered_value[0])
No entanto, as saídas são completamente diferentes (se o primeiro valor for 0, filter_once[0]
é 0
0,999 filter_iter[0]
...)
Não tenho certeza se isso está certo; esta é a primeira vez que trabalho nesta área do SciPy, mas acho que não está funcionando devido às diferentes condições iniciais de
lfilter()
vslfilter_zi()
.Os documentos para
lfilter_zi()
dizeristo é, suponha que um grande passo na entrada acabou de ocorrer.
Os documentos para
lfilter()
dizerLendo a documentação do
lfiltic()
, você pode construir um estado de filtro que assume o repouso inicial da seguinte forma:Este
z
valor faz com que sua solução iterativa corresponda exatamente à sua solução completa.Inspecionando
z
, são apenas zeros, então você pode simplificar isso para:Não posso comentar se você deve usar um estado inicial de resposta ao degrau ou um estado inicial de repouso, mas isso faz com que as duas soluções forneçam a mesma saída.