バックナンバーはこちら。
https://www.simulationroom999.com/blog/stock-predict-matlabpython-backnumber/
はじめに
FFT、IFFTの入出力って実は良く分かってないようなので、
自明且つシンプルな波形を入れて評価してみることに。
自明且つシンプルな波形はsin波とかそれらの合成波。
これらをこれから試していく。
登場人物
博識フクロウのフクさん
イラスト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
sin波でFFT、IFFT
とりあえず今回からFFT、IFFTに対して
「自明且つシンプルな波形を入れて評価」
ってのをやるんだよね?
その通り。
まずは基本中の基本であるsin波を入れてみよう。
とりあえず実験的にこさえたMATLABコードが以下だ。
N=1024;
L=pi;
x=linspace(-L,L,N);
k=0:N-1;
ft=sin(x);
subplot(4,1,1);
plot(x,ft);
title('f(t)');
Fw=fft(ft);
subplot(4,1,2);
plot(k,abs(Fw));
title('F(\omega)');
subplot(4,1,3);
plot(k(1:10),abs(Fw(1:10)));
title('F(\omega) expansion');
fx=ifft(Fw);
subplot(4,1,4);
plot(x,fx);
title('f(x)');
実験コードの結果
じゃ、とりあえず実行して結果を見てみよう。
1番上がFFTに入力するsin波で
2番目がそのFFTからの戻りになるのかな?
3番目がFFTの戻りを拡大してる。
1周期のsin波だから1[Hz]が取り出せてることを示していると思う。
4番目がIFFTで元のsin波に戻してる。
ってところかな。
まぁ正解だな。
ちょっと気になったのは2番目のFFTの戻りって、1のところも起ってるようだけど、
1000を超えた、たぶん1023のところもなんか立ってるよね?
これってなんだっけ?
複素共役
複素共役だな。
FFTに限らず複素フーリエ係数由来のものすべてに当てはまるのだけど、
複素指数関数の虚数部を相殺するための係数がセットで出てくるんだよ。
試しに、FFTの出力であるFwを先頭10個、末尾9個を取り出してみよう。
>> Fw(1:10)'
ans =
1.0e+02 *
0.0000
-0.0157 - 5.1175i
0.0000 + 0.0067i
0.0000 + 0.0038i
0.0000 + 0.0027i
0.0000 + 0.0021i
0.0000 + 0.0017i
0.0000 + 0.0015i
0.0000 + 0.0013i
0.0000 + 0.0011i
>> Fw(end:-1:end-8)'
ans =
1.0e+02 *
-0.0157 + 5.1175i
0.0000 - 0.0067i
0.0000 - 0.0038i
0.0000 - 0.0027i
0.0000 - 0.0021i
0.0000 - 0.0017i
0.0000 - 0.0015i
0.0000 - 0.0013i
0.0000 - 0.0011i
んー、実数部は一緒だけど、虚数部が真逆になってる?
これにより、逆変換後に実数のみになるようになってる。
さっきも言ったけど、これは複素フーリエ係数由来の仕様だ。
人間がパワースペクトルで見る場合は、
FFTの出力データの前半分を絶対値として見ることで周波数の分布を見ることになるね。
後半の複素共役はIFFTで元の波形に戻す時に必要な情報ってところだ。
つまり、特定の周波数だけを取り出したい場合は、この複素共役の部分も一緒に取り出してあげないと、IFFT後に減衰したり、位相がズレたりしちゃうね。
うーん、言ってることはよくわからんが、
周波数分布を見る際は不要だけど、
IFFTを行うときに必要だから気を付けろってことかな?
まずはその認識でOKだろう。
まとめ
まとめだよ。
- sin波でFFT、IFFTを実施。
- パッと見ちゃんと元に戻ってるのは確認。
- FFTの出力である周波数の分布は前半と後半で意味が異なる。
- 後半が前半の複素共役に当たり、IFFT時に虚数部を相殺する役割を追っている。
- 特定周波数を取り出す場合は複素共役部分も一緒に取り出す必要がある。
バックナンバーはこちら。
コメント