離散フーリエ変換を O(n log n) で行うアルゴリズム
離散フーリエ変換とは,長さ の数列 から長さ の数列 への変換で,各 について次のように定義されます.
今回はこれを任意の について で計算するアルゴリズムを考えます.
Cooley-Tukey のアルゴリズム
Cooley-Tukey のアルゴリズムは離散フーリエ変換を行う最も有名なアルゴリズムで, が合成数のときに限って使えます.例として, のときを考えます. の離散フーリエ変換 は,定義によれば次のようになります.
今度は, , としてみましょう.同様の変形により
以上より,長さ の数列の離散フーリエ変換は,長さ の数列の離散フーリエ変換を 回行ったあとに,長さ の数列の離散フーリエ変換を 回行うことでできることが分かりました.これを繰り返していくことで, が小さな素数の積で構成されているときに で離散フーリエ変換を行うのが,Cooley-Tukey のアルゴリズムです. の最小の素因数を としてこれを繰り返すやり方を DIF (周波数間引き), の最小の素因数を としてこれを繰り返すやり方を DIT (時間間引き)といいます.
特に が のべき乗のときの DIT が広く知られています.
フーリエ変換の性質
さて,次に が素数のときを考えるのですが,その前に離散フーリエ変換の重要な性質について見てみます.それは「畳み込み定理」と呼ばれるものです.
長さが であるような 2 つの数列 と について,その畳み込み を次のように定義します.
2020/10/25 追記:熨斗さんからより分かりやすい証明をいただきました.
多項式同士の mod を次のように定義します.
原始根
さて,突然ですが数論の話をします. を素数とし, を 以上 未満の自然数とします.このとき, を満たす最小の自然数 を, を法とした の「位数」といい, と書きます. の位数 は常に の約数です.なぜなら,フェルマーの小定理より であり,もし でないと仮定すると を で割った余り は を満たすので, ではなく が の位数となるはずだからです.
「 が の原始根である」とは, であることをいいます.
が の原始根であるとき, を で割った余りは を並べ替えたものになります.なぜなら任意の について より だからです.
が の原始根かどうかは,で判定できます.もし が原始根でない,すなわち ならば, は全て と合同になるはずです.ということは,逆に の各素因数 について を調べ上げれば,その中に必ず と合同なものが含まれるはずです.もし含まれなければ, は の原始根です.
任意の奇素数 に少なくとも 1 つ原始根が存在します.証明は難しいので省略しますが,整数 が の原始根でなければ, のいずれとも合同でない数 をとってくることで, の位数が の位数よりも大きくなります.これを繰り返すと,いつか位数が であるような数が見つかります(ただし,実際に原始根を求めるコードを書くときは, 以上 未満の自然数について順に原始根かどうか確かめていくだけで十分高速に動作します).
Rader のアルゴリズム
離散フーリエ変換の話に戻ります.Rader のアルゴリズムは, が 以上の素数のときに使えるアルゴリズムです. は合成数なので,長さ の数列の離散フーリエ変換を長さ の数列の離散フーリエ変換で表し, Cooley-Tukey のアルゴリズムを適用します.
例として, の場合を考えます.
よって,Cooley-Turkey のアルゴリズムと Rader のアルゴリズムを組み合わせて使うことで,任意の自然数 に対して で離散フーリエ変換を計算することができます.
最後まで読んでくださってありがとうございましたm(_ _)m