私はSOスレッドで、のfiltfilt
代わりに後方/前方フィルタリングを実行するための提案を使用しましたlfilter
。
他の手法に対して1つを使用する動機は何ですか?
filtfilt
は同じフィルターを反対方向にlfilter
2回行うため、1方向に2回行うよりも遅くなりません。これは同じ周波数応答を得る方法です。
私はSOスレッドで、のfiltfilt
代わりに後方/前方フィルタリングを実行するための提案を使用しましたlfilter
。
他の手法に対して1つを使用する動機は何ですか?
filtfilt
は同じフィルターを反対方向にlfilter
2回行うため、1方向に2回行うよりも遅くなりません。これは同じ周波数応答を得る方法です。
回答:
filtfilt
ゼロ位相フィルタリングであり、フィルタリング時に信号をシフトしません。位相はすべての周波数でゼロであるため、線形位相でもあります。時間をさかのぼってフィルタリングするには、将来を予測する必要があるため、「オンライン」の実際のアプリケーションでは使用できず、信号の記録のオフライン処理にのみ使用できます。
lfilter
は、実際の電子フィルターに似た、因果的な前方フィルタリングのみです。ゼロフェーズにすることはできません。線形位相(対称FIR)にできますが、通常はそうではありません。通常、異なる周波数で異なる量の遅延を追加します。
例と画像はそれを明らかにするはずです。フィルターの周波数応答の大きさは同じですが(左上と右上)、ゼロ位相ローパスは元の信号と並んでおり、高周波成分はまったくありませんが、最小位相フィルタリングは信号を因果的に遅延させます:
from __future__ import division, print_function
import numpy as np
from numpy.random import randn
from numpy.fft import rfft
from scipy import signal
import matplotlib.pyplot as plt
b, a = signal.butter(4, 0.03, analog=False)
# Show that frequency response is the same
impulse = np.zeros(1000)
impulse[500] = 1
# Applies filter forward and backward in time
imp_ff = signal.filtfilt(b, a, impulse)
# Applies filter forward in time twice (for same frequency response)
imp_lf = signal.lfilter(b, a, signal.lfilter(b, a, impulse))
plt.subplot(2, 2, 1)
plt.semilogx(20*np.log10(np.abs(rfft(imp_lf))))
plt.ylim(-100, 20)
plt.grid(True, which='both')
plt.title('lfilter')
plt.subplot(2, 2, 2)
plt.semilogx(20*np.log10(np.abs(rfft(imp_ff))))
plt.ylim(-100, 20)
plt.grid(True, which='both')
plt.title('filtfilt')
sig = np.cumsum(randn(800)) # Brownian noise
sig_ff = signal.filtfilt(b, a, sig)
sig_lf = signal.lfilter(b, a, signal.lfilter(b, a, sig))
plt.subplot(2, 1, 2)
plt.plot(sig, color='silver', label='Original')
plt.plot(sig_ff, color='#3465a4', label='filtfilt')
plt.plot(sig_lf, color='#cc0000', label='lfilter')
plt.grid(True, which='both')
plt.legend(loc="best")
lfilter
は必ずしも最小位相ではなく、フィルター係数に応じて何でもかまいませんが、いずれにせよ因果関係があり、そうでfiltfilt
はありません。したがって、filtfilt
遅延がゼロで、lfilter
常に何らかの遅延が追加される比較の結果は、filtfilt
そもそも非因果的であるため、正確には真ではありません。実際に重要なのは、filtfilt
位相歪みを引き起こさないのに対し、それlfilter
が線形位相FIRフィルターとして使用されない限り、つまり分母= 1の場合です。
filtfilt
フィルタリングは、(2N-1)次のフィルタリングに対応することに注意してくださいlfilter
。
lfilter
またはでフィルタリングできますfiltfilt
。示したように彼らは、異なる動作を
@endolithによる回答は完全かつ正確です!最初に彼の投稿を読んでから、それに加えてこれを読んでください。評判が悪いため、コメントに返信できませんでした @ Thomas Arildsenと@endolithが次の方法で得られたフィルターの効果的な順序について議論返信たfiltfilt
。
lfilter
与えられたフィルターを適用し、フーリエ空間でこれはフィルター伝達関数を一度適用するようなものです。
filtfilt
同じフィルターを2回適用すると、効果はフィルター伝達関数SQUAREDを適用するようなものになります。バタワースフィルターの場合(scipy.signal.butter
)の、伝達関数
有効なゲインは
そして、これはとして解釈することはできません次のバタワースフィルター