Pythonバンドパスフィルタ - 特異行列エラー

私はscipyを使ってバンドパスフィルターを設計しようとしていましたが、LinAlg Singular Matrixエラーが出ています。私は、特異行列は可逆ではない行列だと読んでいますが、その誤差がどのように現れているのか、それを修正するために何ができるのかよくわかりません

The code takes in an EEG signal (which, in the code below, I have just replaced with an int array for testing) and filters out frequencies < 8Hz and > 12Hz (alpha band)

特異行列エラーがどこから来ているのか誰にでもわかることができますか?あるいは、このような信号をフィルタリングするより良い方法が分かっていれば、他のオプションもテストしたいと思います

from scipy import signal
from scipy.signal import filter_design as fd
import matplotlib.pylab as plt

#bandpass
Wp = [8, 12]   # Cutoff frequency
Ws = [7.5, 12.5]   # Stop frequency
Rp = 1             # passband maximum loss (gpass)
As = 100              # stoppand min attenuation (gstop)

b,a = fd.iirdesign(Wp,Ws,Rp,As,ftype='butter')
w,H = signal.freqz(b,a)  # filter response
plt.plot(w,H)

t = np.linspace(1,256,256)
x = np.arange(256)
plt.plot(t,x)

y = signal.filtfilt(b,a,x)
plt.plot(t,y)
0

1 答え

あなたのパラメータの選択肢をもう一度確認することをお勧めします

b,a = fd.iirdesign(Wp,Ws,Rp,As,ftype='butter')

結果のフィルタ係数を見ると、DCでポール/ゼロキャンセル、すなわち$ z = 1 $が得られます。

0
追加された
iirdesignはWpとWsの両方を正規化する必要があることがわかります。それで私の問題は解決しました。しかし、私は信号処理に非常に新しいです - あなたはDCでのポールキャンセルの意味を説明できますか?
追加された 著者 PyRulez,
うーん、私はキャンセルが悪いことだと思うのは正しいですか?私はこれを読もうとしましたが、私の理解のレベルをはるかに超えています。極と零の両方が1の場合を防ぐことを試みていますか?
追加された 著者 PyRulez,
あなたのコードによって生成されたインパルス応答の$ z $変換は$$ H(z)= K \ frac {(1-az ^ { - 1})(1-bz ^ { - 1})}} { (1-a ^ { - 1})(1-c ^ { - 1})} $$ここで$ K $はシステム利得です。分子のパラメータは、ゼロと呼ばれる。 $ z = b $に対して$ H(z)= 0 $。同様に、分母のパラメータは、$ H(z)$が爆発する、すなわち$ H(c)= \ infty $となるので、極と呼ばれる。したがって、$ a $が極とゼロの両方であるとすれば、等価な$ H(z)$は$$ Hなので、数値的にしか問題にならない$ H(a)= \ frac {0} {0}この問題がないとすると、(1-bz ^ { - 1})} {(1-cz ^ { - 1})} $$となる。
追加された 著者 Pedro Lauridsen Ribeiro,
それは、実装の詳細に依存します。基本的にIO(入力出力)の安定性と内部安定性の違いになります。 $ x = 0 $に対して$ \ frac {x ^ 2} {x} $を計算することについてThnk。片方の手には、\ frac {0} {0} $というものがあります。一方、答えは$ \ frac {x ^ 2} {x} = x $から$ 0 $であることがわかります。したがって、素朴な実装は、分子を計算し、分母を計算してから除算し、誤差を生じることになります。キャンセルを確認すると、まずこの問題が解消され、正しい答えが得られます。
追加された 著者 Pedro Lauridsen Ribeiro,