高速フーリエ変換(FFT)の原理
離散フーリエ変換の素朴な O(n^2) を O(n log n) へ落とすFFTの中身を、Cooley-Tukey分割・回転因子・バタフライ演算から原理で腹落ちさせる。多項式乗算や信号処理で効く理由まで一気通貫で説明する。
- 1.DFTは定義どおり計算すると O(n^2)。FFTはCooley-Tukey分割で偶奇に分け、回転因子の周期性を使って O(n log n) に落とす。
- 2.基数2FFTの核は、対称性 W_n^(k+n/2) = −W_n^k を使うバタフライ演算。2つの値を1回の乗算と加減算で更新する。
- 3.高速な巡回畳み込み(多項式乗算・大整数乗算・FIRフィルタ・相関)を支える基盤で、点値表現への往復で積を O(n log n) にする。
DFTという「重い行列積」をどう軽くするか
離散フーリエ変換(DFT)は、長さ n の数列 x[0..n-1] を、同じ長さの周波数成分 X[0..n-1] に写す変換です。定義はこうです。
X[k] = Σ_{j=0}^{n-1} x[j] · W_n^{jk} (k = 0..n-1)
W_n = exp(-2πi / n) ← n 乗根、これを回転因子と呼ぶ
W_n(twiddle factor、回転因子)は複素平面の単位円を n 等分する点で、W_n^{jk} は角度 -2π·jk/n の回転を表します。定義どおりに計算すると、各 X[k] が n 項の和、それを n 個求めるので乗算回数は n^2。これは n×n の行列 (W_n^{jk}) とベクトル x の積そのもので、素朴には O(n^2) です。n が数万を超える信号や多項式では、この二乗が致命的になります。
FFTはこの行列積を、回転因子が持つ周期性と対称性を突いて O(n log n) に落とすアルゴリズムです。値が変わるわけではなく、同じ X[k] を冗長な計算を畳み込んで求め直す――その意味で完全に正確な変換です。
Cooley-Tukey分割: 偶奇に割ると再帰になる
最も基本的な基数2のCooley-Tukey法は、n が2の冪のとき、入力を偶数インデックスと奇数インデックスに二分します。和を偶奇で分けて書き直すのが出発点です。
X[k] = Σ_{j even} x[j] W_n^{jk} + Σ_{j odd} x[j] W_n^{jk}
= Σ_{m=0}^{n/2-1} x[2m] W_n^{2mk}
+ Σ_{m=0}^{n/2-1} x[2m+1] W_n^{(2m+1)k}
ここで鍵になる恒等式が W_n^2 = W_{n/2} です。exp(-2πi·2/n) = exp(-2πi/(n/2)) だから、W_n^{2mk} = W_{n/2}^{mk}。これを使うと、偶数項の和はサイズ n/2 のDFT(これを E[k] とする)、奇数項の和は同じく n/2 のDFT(O[k])に W_n^k を掛けたものに変形できます。
X[k] = E[k] + W_n^k · O[k]
E[k] = 長さ n/2 DFT(偶数位置の入力)
O[k] = 長さ n/2 DFT(奇数位置の入力)
つまり長さ n のDFTが、長さ n/2 のDFT2つに帰着しました。これは典型的な分割統治で、漸化式は T(n) = 2·T(n/2) + O(n)。結合の O(n) は回転因子の掛け算と加算ぶんです。マスター定理のケース2にあたり、計算量は O(n log n)。この対数倍の削減が、信号処理から大整数乗算までを一変させました。
E[k] と O[k] の周期は n/2 なので、k が 0..n/2-1 の範囲を定義します。しかし X[k] は 0..n-1 の n 個必要です。差を埋めるのが次節の対称性で、E と O をそれぞれ1回だけ計算すれば、上半分(k と k+n/2)の両方を導けます。だから部分問題が2つで済むのです。
バタフライ演算: 対称性で計算を半分にする
X[k] = E[k] + W_n^k·O[k] だけでは k = 0..n/2-1 しか埋まりません。残る上半分 X[k+n/2] を、回転因子の半周期対称性で導きます。W_n^{n/2} = exp(-πi) = -1 なので次が成り立ちます。
W_n^{k+n/2} = W_n^k · W_n^{n/2} = -W_n^k
E[k]・O[k] の周期が n/2 であることと合わせると、下半分と上半分が同じ2つの値から作れます。
X[k] = E[k] + W_n^k · O[k]
X[k+n/2] = E[k] - W_n^k · O[k] (k = 0..n/2-1)
この一対の更新がバタフライ演算です。t = W_n^k·O[k] を1回だけ計算し、E[k] との和と差で2つの出力を同時に得ます。データフロー図が蝶の羽のように交差するのが名の由来です。1回のバタフライは複素乗算1回・複素加減算2回で、1段に n/2 個、段数は log_2 n 段。掛け算の総数が (n/2)·log_2 n に収まることが、O(n log n) の正体です。
偶奇分割を再帰的に続けると、葉に並ぶ入力の順序は元のインデックスを2進でビット反転した順になります(例: n=8 で 1=001 → 100=4)。最初に配列をビット反転並べ替えしておけば、以降はバタフライを所定の位置で重ねるだけで済み、追加配列なしのin-placeかつ反復的な実装になります。再帰の関数呼び出しを消せるので、実用FFTはほぼこの形です。
逆変換と数値的な注意点
逆DFT(IDFT)は回転因子の符号を反転し、最後に 1/n で割るだけで、同じバタフライ構造をそのまま使えます。
| 項目 | 順方向 DFT | 逆方向 IDFT |
|---|---|---|
| 回転因子 | W_n = exp(-2πi/n) | W_n^{-1} = exp(+2πi/n) |
| スケール | なし | 1/n を最後に乗じる |
| 計算量 | O(n log n) | O(n log n) |
| 用途 | 時間→周波数 | 周波数→時間(畳み込みの復元) |
実装では sin・cos を再計算せず、回転因子テーブルを事前計算して参照します。複素演算はIEEE 754の浮動小数点で行うため丸め誤差が乗りますが、FFTの誤差成長は段数に対しておおむね O(log n) 程度に抑えられ、定義どおりの O(n) 蓄積よりむしろ良いのが利点です。整数の厳密計算が要る場面では、浮動小数点の代わりに有限体上で同型のアルゴリズムを走らせる数論変換(NTT)を使い、丸め誤差をゼロにします。
基数2FFTは n が2の冪である前提です。実データの長さが中途半端なときは、(1) 末尾をゼロで埋めて2の冪に伸ばす、(2) 任意長を扱えるBluesteinのアルゴリズム(チャープZ変換でDFTを畳み込みに変換)や、素因数を使う混合基数FFTを使う、のいずれかをとります。なおゼロ詰めは周波数軸のサンプリング(ビン)を細かくする補間であって、真の周波数分解能(観測長で決まる)が上がるわけではない点には注意が必要です。
なぜ効くのか: 畳み込みという主戦場
FFTが広く使われる最大の理由は、巡回畳み込みを高速化することにあります。畳み込み定理は「時間領域の畳み込みは周波数領域の要素ごとの積に等しい」と述べます。
a ⊛ b = IDFT( DFT(a) ⊙ DFT(b) ) ⊙ は要素ごとの積
素朴な畳み込みは O(n^2) ですが、両者をFFTで周波数領域に移し(O(n log n))、要素積をとり(O(n))、逆変換で戻す(O(n log n))と、全体が O(n log n) に下がります。これが効く代表例を挙げます。
- 多項式乗算: 多項式は係数列。係数の畳み込みが積に対応するので、2つの多項式を点値表現(DFT)に移して点ごとに掛け、補間(IDFT)で係数へ戻すと
O(n log n)で積が求まります。 - 大整数乗算: 桁列を係数とみなせば多項式乗算に帰着。Schönhage–Strassen 法はこの発想を整数環
Z/(2^k+1)Z上のFFTで丸め誤差なく実現したもので、巨大数ライブラリの根幹です(素数体上のNTTを使う実装も広く用いられます)。 - 信号処理: FIRフィルタ適用、相関・自己相関、スペクトル解析、画像の周波数フィルタリングはすべて畳み込みかDFTそのものです。
(1) DFTは O(n^2)、FFTは O(n log n)、削減の根拠は回転因子の周期性と対称性 W_n^{k+n/2} = -W_n^k。(2) Cooley-Tukey は偶奇分割で T(n)=2T(n/2)+O(n)、バタフライ1回が乗算1・加減算2。(3) 畳み込み定理により多項式・大整数乗算が O(n log n)。この3点を式とともに即答できるかが分かれ目。
文字列照合でも、ワイルドカード照合やパターンの相互相関をFFTで O(n log n) に落とす技法があり、文字列照合アルゴリズムで扱うRabin-Karp系の畳み込み解釈と地続きです。
まとめ: 周期性が二乗を対数倍に変える
FFTの本質は、DFTという O(n^2) の行列積を、回転因子 W_n が持つ周期性 W_n^2 = W_{n/2} と対称性 W_n^{k+n/2} = -W_n^k の2本で畳み込み、分割統治の O(n log n) に圧縮することです。核となるバタフライ演算は、2つの値を1回の乗算と加減算で同時に更新する最小単位。そして畳み込み定理を通じて、多項式乗算・大整数乗算・信号処理という広大な応用へつながります。「二乗を対数倍に変える対称性」を見抜く視点が、FFTを理解し使いこなす鍵です。
プログラミング Article
高速フーリエ変換(FFT)の原理を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
アルゴリズム
比較で見る軸
難易度: advanced / カテゴリ: プログラミング / タグ数: 6
導入後に効く点
基数2FFTの核は、対称性 W_n^(k+n/2) = −W_n^k を使うバタフライ演算。2つの値を1回の乗算と加減算で更新する。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- プログラミング
- タグ数
- 6
判断チェックリスト
- 自社の用途が「アルゴリズム / FFT」に近いか確認する。
- 強みである「DFTは定義どおり計算すると O(n^2)。FFTはCooley-Tukey分割で偶奇に分け、回転因子の周期性を使って O(n log n) に落とす。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。