FFT
離散フーリエ変換 は
O(n2)かかってしまって遅いので
O(nlogn)で解けるアルゴリズム用いてフーリエ変換しよう
いくつか種類がある
クーリー–テューキー
任意の基数で分割されたグループで DFT を解いてそれらを合成することで最終結果を得るという
分割統治法的な考え方
なのでデータ長は基数の累乗である必要がある、基数2なら2の累乗
データ長が素数の場合に有効
基数2のクーリー–テューキー型 FFT をやるぞ
まずこれは DFT です、
WN を回転因子呼んだりする
F(k)=∑n=0N−1f(n)WNkn,WN=e−2πiN1
基数2で分けるということは偶数と奇数で分けることになるのでこうなる
F(k)=∑n=0N/2−1f(2n)WNk(2n)+∑n=0N/2−1f(2n+1)WNk(2n+1)
さらに変形してこうなる
F(k)=∑n=0N/2−1f(2n)WN2kn+WNk∑n=0N/2−1f(2n+1)WN2kn
回転因子をこんな感じで変形すると
WN2kn=e−2πiN12kn=e−4πiknN1=e−2πiknN/21=WN/2kn
元のデータ長の半分の偶数、奇数 dft で求まることが分かる
F(k)=∑n=0N/2−1f(2n)WN/2kn+WNk∑n=0N/2−1f(2n+1)WN/2kn
Ek=∑n=0N/2−1f(2n)WN/2kn,Ok=∑n=0N/2−1f(2n+1)WN/2kn とすると
F(k)=Ek+WNkOkとなり、
Ek,Okは長さ
N/2 の DFT なので周期も
N/2なので
Ek=Ek+N/2,Ok=Ok+N/2 で同じだが、
回転因子は
WNk+N/2=WNkWNN/2=WNke−πi WNN/2=e−2πiN12N=e−2πi21=e−πi
WNke−πi は
WNkくるっと半周だけ回すので対称性により
WNk+N/2=−WNk
なので
F(k)=Ek+WNkOk F(k+N/2)=Ek−WNkOk k=(0,1...,N/2−1) ということが言える(バタフライ演算と言うらしい)
つまり
データ長
NのDFTの前半
k番目はそのデータの偶数だけ集めたDFTの
k番目とそのデータの奇数だけを集めたDFTの
k番目を
WNkだけ回したものを足したものと一致し、
データ長
NのDFTの後半
k番目はそのデータの偶数だけ集めたDFTの
k番目とそのデータの奇数だけを集めたDFTの
k番目を
WNkだけ回したものを引いたものと一致
この分割の操作をデータ長が1になるまで分割して出来たDFTを合成していく感じ
データ長8ならまずx[0], x[2], x[4], x[6]とx[1], x[3], x[5], x[7]に分ける
それをさらに分けてx[0], x[4] , x[2], x[6] , x[1], x[5] , x[3] x[7]
それをさらに分けてx[0] , x[4] , x[2] , x[6] , x[1] , x[5] , x[3] , x[7]
この分割の操作はビット反転で上手いこと出来るらしいです
それを愚直にコードで解くとこうなる
それを for とかで関数にパッケージしたものがこれ (Gemini 製)
逆FFT
DFTにバタフライ演算を逆回転でして出来たデータ配列の要素をデータ長で割るだけ
逆DFTと一緒でゲースー
Gemini 曰く基数4のクーリー–テューキーが実践向けでよく実装されてるらしいがほんとかな?
まあ基数4のバタフライ演算の導出はいつかやりますよ
ToDo