前回に引き続き、今回は離散フーリエ変換と、具体的な高速フーリエ変換の実装方法についてまとめてみます。
離散フーリエ変換は、一定のサンプリングレートで取られた離散データに対してフーリエ変換を行う方法です。
高速フーリエ変換はこれを高速で処理できるように実装したものです。
離散フーリエ変換
前回導出したフーリエ変換の定義式は次のものでした。
F(ω)=2π1∫−∞∞f(x)e−iωxdx
これは、ある周波数に対しての波形を為す関数を得る式でした。
離散フーリエ変換の場合、関数が連続ではないため、データ数が限られてしまいます。
そこで、これを次のように和の形で表してあげます。データの数列fn、データ数Nとして、
F(t)=n=0∑N−1fneN−2nπit(0≤t≤N)
N2nπとxが置き換わっています。フーリエ変換は非周期関数を無限大の周期を持つ関数としてフーリエ級数展開を行う処理でしたね。
これを限られたデータ数Nにおいて実現するためにこのような処理をしています。
高速フーリエ変換の実装
これをそのまま実装した場合、すべてのt∈Nについて、N回の足し算を行うことになるので、計算量はO(N2)となります。
私の場合Web AudioのAudio Workletを用いた処理にFFTを使いたいと考えているのですが、Audio Workletでは一度に128個の信号を取得できます。この時、計算量は1282=16384となります。
この計算量を抑える工夫をしてみるのが、高速フーリエ変換です。今回はWikipediaにデカデカと載っているクーリー・テューキー型FFTアルゴリズムを取り上げます。
複素数を用いることで、1のn乗根を求めることができます。
ϵnk=eN−2ikπ=cos(n2kπ)+isin(n2kπ)
この一つWN=eN−2iπ用いると、離散フーリエ変換の式は次のように表せます。
F(t)=n=0∑N−1fnWNtn
ここで、N=4として、フーリエ級数を行列を用いて表してみます。
⎝⎛X0X1X2X3⎠⎞=⎝⎛W0W0W0W0W0W1W2W3W0W2W4W6W0W3W6W9⎠⎞⎝⎛f0f1f2f3⎠⎞
行を添え字の偶奇によって分け、
=⎝⎛W0W0W0W0W0W2W4W6W0W1W2W3W0W3W6W9⎠⎞⎝⎛f0f2f1f3⎠⎞
こうすると、N=2の結果を用いて演算できます。
⎝⎛X0X1X2X3⎠⎞=⎝⎛10100101W00W200W10W3⎠⎞⎝⎛W20W2000W20W210000W20W2000W20W20⎠⎞⎝⎛f0f2f1f3⎠⎞
これを繰り返し行います。計算量はN個のデータに対してlog(N)回繰り返すので、O(Nlog(N))となります。
このアルゴリズムは他のアルゴリズムと組み合わせることもできます。
まとめ
フーリエ変換を離散データに対して行う離散フーリエ変換と、その具体的な実装方法である高速フーリエ変換についてまとめました。
3回に渡って高速フーリエ変換を理解するための理屈や知識をまとめてみました。書いていてとても勉強になったので、こういう記事はこれからも書いていきたいです。
参考