私は肉まんの白い部分が好きです.ほのかに甘い,あの白い部分だけ食べたいです.
ということで,今回は最近のFFTのお話
chaos-kiyono.hatenablog.com
の続きです.
FFTの説明で,バタフライ演算ってのが登場します.バタフライ演算は下の図のようなバタフライダイアグラムで表すことができます.

「バタフライ」ってのは,FFTの計算を図で表すと蝶蝶の羽のように見えることに由来していると思います (知らんけど).今回はバタフライダイアグラムが表す計算過程を説明します.
右上がりは足し,右下がりは引く
時系列の長さが4の時系列
を考えます.前回はRでの実装を想定して,時系列の順番について1から番号をふりましたが,今回は0からです.ビット反転を説明するために,一般的な表現を使います.
のとき,バタフライダイアグラムに補足の記号 (プラスマイナスと回転因子)を加えると下図のようになります.

上の図では,左から右へ計算が進んでいきます.赤 (右上がり線)と青 (右下がり線)で描いた線は,それぞれ,「足し算」と「引き算」を表します.
前回,長さが2の倍数であれば,時系列
の離散フーリエ変換
は,偶数番目の周波数の離散フーリエ変換
と,奇数番目の周波数の離散フーリエ変換
に分けられることを説明しました (詳しくは説明してないけど).ここで,です.
バタフライダイアグラムの上半分は偶数番目の周波数の離散フーリエ変換,下半分は奇数番目の周波数の離散フーリエ変換に対応します.
ダイアグラムの見方を理解するために,以下ではバタフライダイアグラムのパーツに注目してみます.
右上がりの線 (足し算)
下の図のように,右上がりの線 (赤)は,●でつないだ2本の線に対応する値を足すことを表しています.

これは,偶数番目の周波数の離散フーリエ変換
に登場する
の計算を表しています.
ビット反転でフーリエ変換の結果を並び替え
以上の説明で,バタフライダイアグラムが表している計算アルゴリズムを理解できたでしょうか.例えば,下の図のような,のバタフライダイアグラムが表す計算式をイメージできますか.

とりあえず,バタフライダイアグラムの読み方は分かったとしても,右端に書いた離散フーリエ変換の結果の順番がめちゃくちゃです.この順番は,どうやって決められるのでしょうか.そこで,登場するのがビット反転 (ビットリバース)です.
ビット反転の計算
ビット反転では,10進数を2進数に変換して,2進数の並びを反転してから10進数に戻します.ただし,時系列の長さがのときは,
桁の2進数で表し,上位の桁がないときは,0を詰めます (わかった?).
例えば,のとき,
桁の2進数を考えます.
のとき,1をビット反転してみます.10進数の
は,2進数で表しても
ですが,3桁にしたいので,0を詰めて,
とします.数字の順番を逆にならべると,
になります.これを10進数にすると,
になります.確かに,上の図では,の右端に,
が書いてあります.
なぜ,ビット反転でうまくいくの?
ビット反転で対応する周波数の順番が決まる理由を考えてみます.の例を表した下の図を見てください.この図を使って考えてみます.

まず,バタフライダイアグラムの最初の段 (一番左)で,上半分にあれば,それは偶数番目の周波数です.だって,
の計算をしているからです.の例では,周波数の番号は
のどれかです.逆に,下半分は奇数で,
のどれかです.
偶数ってことは,2進数で表したとき1の位は0です.奇数ってことは,2進数で表したとき,1の位は1です.この桁は,左端のの順番
を2進数で表したときの,100の位に一致します.
後は計算式を追ってやればビット反転との対応が見えてきます.
例えば,では,
は偶数なので,最初は偶数のフーリエ変換の式
を使います.これで,2進数で表したときの1桁目は,0に確定です.この式では,周波数がのフーリエ変換が,半分の
でのフーリエ変換に書き換わっています.
ということは,の
を2で割って,
のフーリエ変換の式を次の段階で使うことになります.
は偶数なので,バタフライダイアグラムの真ん中の段は,上半分のパスを通ります.なので,2進数で表したときの10の位は,0になります.
最後は,の
を2で割って,
のフーリエ変換の式を使うことになります.1は奇数なので,バタフライダイアグラムの一番右側の段は,下半分のパスを通ります.なので,2進数で表したときの100の位は,1になります.
順番を整理すると,0→0→1です.これは,4を2進数に変換したを逆に並べたものと同じです.
エビフライダイアグラムの左側のの順番
は,上の図に書いた0と1を左から右へ並べた2進数になってます.一方,右側の
の順番
(フーリエ変換結果)では,左が1の位に対応するので,上の図に書いた0と1を右から左へ並べた2進数になってます.
こんな説明で,理解できますでしょうか.
まとめ
Rのコマンドとか,パッケージを使って,それっぽい結果出すだけでなく,使う道具にも興味や疑問をもって基礎知識を身につけてください.