バックナンバーはこちら。
https://www.simulationroom999.com/blog/stock-predict-matlabpython-backnumber/
はじめに
前回までで、MATLAB、Python(Numpy)によるFFT出力の周波数分布をローテーションをできることが確認できた状態。
今回から実際に超簡易バンドパスフィルタを実施していく。
登場人物
博識フクロウのフクさん
イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん
イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
MATLABで超簡易バンドパスフィルタ
じゃ、ついにバンドパスフィルタをやるところだね。
そうそう。
前回までで、FFTと周波数分布のローテーションは終わってるから、
特定周波数の抽出とIFFTをやるだけだ。
まるで簡単なような言い方してるけど、あまり簡単だった試しが無いんだよなぁ。
そんなことは無いよ。
少なくともIFFTはすでにやってるものだし、
太郎くんから見て不明点は「特定周波数の抽出」の部分だけだと思うよ。
そうそう!そこそこ!
まぁこれもコードで見れば一行で終わるやつだから。
ということは、チョロいってことで良さそうか。
ちょっと通常の書き方とは違うかもいしれないけど。
(やっぱり罠がありそう・・・。)
MATALBコード
じゃ、作って来たコードだ。
N=1024;
L=pi;
x=linspace(-L,L,N)';
k=-N/2:N/2-1;
ft=sin(x)+sin(3*x)+sin(7*x);
% 変換前波形
subplot(4,1,1)
plot(x,ft)
title('f(t)');
grid();
% FFT後にローテーション
Fw=fft(ft);
Fw_tmp=circshift(Fw,N/2);
subplot(4,1,2);
mask = (-10<=k & k<=10);
plot(k(mask),abs(Fw_tmp(mask)));
title('F(\omega)');
grid();
% 特定周波数のみ抽出
Fw_Filter=Fw_tmp;
Hz = 3;
Low = Hz-0.1;
High = Hz+0.1;
Fw_Filter( k< -High | (-Low < k & k <= 0) | (0 <= k & k < Low) | High < k)=0;
subplot(4,1,3);
mask = (-10<=k & k<=10);
plot(k(mask),abs(Fw_Filter(mask)));
title('F(\omega) Filter');
grid();
% IFFT前にローテーション
Fx = (ifft(circshift(Fw_Filter,N/2)));
subplot(4,1,4);
plot(x,real(Fx));
title('f(x)');
grid();
結果
そして、結果だ。
おー!
ちゃんと3Hzだけ取り出せてる!
というわけで、
無事、バンドパスフィルタができたというわけだ。
コードを見てると?
ちょっと疑問に思ったのだけど、
おそらく周波数分布で3[Hz]と-3[Hz]以外を0にしてる部分のコードが妙なことになってるように見える・・・。
Fw_Filter( k< -High | (-Low < k & k <= 0) | (0 <= k & k < Low) | High < k)=0;
あー、そこね。
論理インデックス検索って書き方だな。
なんだそれは?
やはりそこで引っかかったか。
じゃ、次回はそこは少し掘り下げよう。
(こうなることを知っててやりやがったな・・・。)
まとめ
まとめだよ。
- MATLABで超簡易バンドパスフィルタ実施。
- コード開示&結果確認。
- 想定通り、3Hzだけ抽出で来た。
- 3[Hz]と-3[Hz]以外を0にしてる部分のコードが妙。
- 論理インデックス検索という手法を使っている。
バックナンバーはこちら。
コメント