Subsections
4 高速Fourier変換を利用した乗算法
先の章で述べたことを行列を用いて整理してみよう。多項式
 |
(4.40) |
に
個の値
を代入すれば、
個の値
が得られる。行列を用いて表現すれば
 |
(4.41) |
となる。
が分かっているならば、上の式に(もし存在するならば)逆行列を掛けることで
が求まる(補間)。逆行列が存在するように
を選びさえすれば、
の代わりに
を使って多項式を表すことができるのである。問題の行列はVandermonde行列(Vandermonde Matrix)と呼ばれているもので、
 |
(4.42) |
と表され、行列式は
 |
(4.43) |
で与えられるので、
が全て異なれば逆行列が存在する。
多項式の乗算
を行列を用いて大雑把に述べると、
の係数を並べた列ベクトルをそれぞれ
として、
-
を
に掛け、
を得る。
-
を要素ごとに掛け、
を得る。
-
を
に掛け、
を得る。
となる。大雑把というのは必要な次元を考慮していないからである。上で述べたままだと、
が
次、つまり
の上位の係数合わせて
個が
でないと上手くいかない。これは
の次数が
の次数よりも高くなるからで、Toom-Cook法で連立方程式を立てる際に、
が2次なら
は4次となり、従って
に5個の異なる値を代入しなければならなかったのと同じである。
Toom-Cook法は2.の要素ごとの乗算を再帰的に行うアルゴリズムである。従って1.や3.における
の乗算をいかに速く行うかが問題となるが、
の分割数を大きくするとこの部分が複雑になり、位数も余り下がらなくなるので、大した効果は期待できなくなる。ここで発想を変えて、1.や3.で再帰を行うのが次に述べる高速Fourier変換である。
Vandermonde行列の要素を
 |
(4.44) |
としたときに得られる
を
の離散Fourier変換(Discrete Fourier Transform, DFT)と呼び、
で表す。特に
を2の冪に限った場合、高速Fourier変換(Fast Fourier Transform, FFT)というアルゴリズムによって
の時間で
が求まるのである。
FFTの基本的な考え方は簡単である。
 |
(4.45) |
とおくと、
を得るためには
を評価しなければならないが、もし
ならば
を
の偶奇で分けた2つの
次多項式
を用いることによって
のように計算することができる。
ここで
について
の値を求めることを考えると、
は
個の値をとるのに対して、
は
個の値しかとらず、しかもそれは複素
乗根であることが分かる。つまり
を得る問題は
を得る問題に帰着されるのである。具体的に
の場合を考えると、
のように計算でき、計算量がほぼ半分に減るのである。当然
にも同じ方法を適用できれば計算量を減らすことができるので、
が2の冪であれば最も効率が良いが、これは
を係数として加えるだけで実現できる。結局このアルゴリズムで実際に乗算が行われる部分は
のみとなり、
を得るのに必要な時間
は
となる。このアルゴリズムを再帰的FFT(Recursive FFT)という。
後は逆変換(Inverse DFT,
)が高速に実行できれば良いが、
 |
(4.50) |
であるあから、FFTを少し変更するだけで逆変換が行え、従って必要な時間も
となる。
以上のことを考えると、多項式の乗算は次のようになる。下準備として、
の次数より小さくない最小の2の冪を
とし、
の次数が
となるように
を高次の係数として加えておく。そうすると、
- FFTを用いて
を求める。必要な時間は
。
-
の要素同士を掛けて
を求める。必要な時間は
。
- FFTを用いて
を求める。必要な時間は
。
という計算を行うことによって乗算が
の時間で実行できることになる。
再帰を行わず、繰り返しのみでFFTが実行できれば速度が向上するはずである。そこで
がどのように振り分けられるのかを考える。例えば
の場合、添字だけを書けば
となる。少し考えると、
の2進表記の上位と下位を入れ替えた値が
の位置となることが分かる。このようにして
を予め並べ替えておけば、繰り返しだけで簡単にFFTが実行できる。この方法をCooley-Tukeyのアルゴリズム(Cooley-Tukey Algorithm)という。
Kenichi Kondo
平成16年3月18日