高速フーリエ変換
(fast Fourier transform)
1
• 高速フーリエ変換とは?
– 簡単に言うとフーリエ変換を効率よく計算する
方法
– アルゴリズムの設計技法は分割統治法に基
づいている
• 今回の目的は?
– 多項式の積を求める問題を取り上げ、高速
フーリエ変換のアルゴリズムを用いた解法を
導いて、計算時間を驚くほど短縮できることを
示す
2
多項式の積の計算の例1
• 以下のような2次多項式のp(x)とq(x)をかける
p( x ) 1 x x 2
q( x ) 2 x x 2
p( x )q( x ) (1 x x 2 )(2 x x 2 )
2 x x 2 2x x 2 x 3 2x 2 x 3 x 4
2 x 2x 2 x 4
この場合2次式のため簡単に出来たが、一般的
にN-1次多項式の時は、このような方法では大変
時間 N2回の乗算 がかかる.どうすればよいのか?
3
多項式の積の計算を高速化するに
は?
• N-1次の多項式はN個の異なる点における
関数値で完全に決まるという事実を利用
する(N-1次式の項の数は定数も含むから
N個)
⇒2つのN-1次多項式同士の積は2N-1個の点
でその多項式の値が分かっていれば、その積
を完全に決定できる
4
2つのN-1次多項式の積を求める
基本的な手順
• 評価:入力された多項式の値を2N-1個の
異なる点で計算する
• 乗算:各点でえられた値を掛ける
• 補間:上で求めた2N-1個の値を補間する
– 補間とは、多項式のN個の異なる点における
値が与えられた時、その多項式の係数を求め
ること
5
2つのN-1次多項式
P(x)
Q(x)
評
価
乗算
N2の計算時間
フーリエ変換
分割統治法を用いて
効率よくしたのが高速フーリエ変換
p(a1 ),, pa 2 N1
q(a1 ),, qa 2 N1
乗算
2N-1次の多項式
R(x)=P(x)Q(x)
補
間
逆フーリエ変換
r ( x ) p ( x )q ( x )
r (a1 ),, r (a 2 N1 )
6
• 例2)
p( x ) 1 x x 2
q( x ) 2 x x 2
r x p( x )q( x )を求めたい
x 2,1,0,1,2においてpx , qx を計算すると
p(2), p(1), p(0), p(1),p(2) 3,1,1,3,7
q(2), q(1), q(0), q(1),q(2) 8,4,2,2,4
となる.すると
r ( x )は
r(2), r(1), r(0), r(1),r(2) 24,4,2,6,28
7
ラグランジュの公式を用いると
x 1 x 0 x 1 x 2
r ( x ) 24
2 1 2 0 2 1 2 2
x 2 x 0 x 1 x 2
4
1 2 1 0 11 1 2
x 2 x 1 x 1 x 2
2
0 2 0 1 0 1 0 2
x 2 x 1 x 1 x 2
6
1 2 11 1 0 1 2
x 2 x 1 x 0 x 1
28
2 2 2 1 2 0 2 1
2 x 2x 2 x 4
となる.
8
ラグランジュの公式
N 1次多項式 P (x)のN個の点 x1 , x 2 ,, x Nと
そこでの値y1 , y 2 ,, y Nが与えられた時、
P( x1 ) y1 , P( x 2 ) y 2 , , P( x N ) y N
を満たす唯一の N 1次多項式を求めたい.(補間する)
この時の古典的な解は ラグランジュの補間公式を用いること
x xi
P( x ) y j
1 j N 1i N x j x i
(ラグランジュの補間
公式)
i j
9
2
N
• 例2の場合、評価と補間それぞれで の計
算時間がかかってしまう
• しかし、多項式の値を計算する2N-1個の
点はどこの点を選んでもよいことに注目す
ると、多項式の積の計算を簡単にする点
集合を選べば、効率のよく計算時間を短縮
できるのでは?
10
1の複素累乗根
• 多項式の積の計算をする点として、1の複
素累乗根を用いると計算を高速化できる
2つの複素数の積は
(a bi )(c di ) (ac bd ) (ad bc )i
となる.次の例のよう
に乗算の結果、実数部 や虚数部が0になることもある.
(1 i)(1 i) 2i
(1 i)8 16
8
上の式を16 2 で割ると
8
i
1
1
2
2
をえる.
11
一般に、その数を累乗して1となる複素数は
たくさんあり、
1の累乗根とよばれる.
実際、自然数Nに対して、
Z N 1となる複素数ZがN個ある.
これらの中の1つは「
1の原始N乗根」とよばれ、
それをWNと表わすと、
全ての根は k 0,1,2, , N 1に対して、
WN をk乗してえられる.
例)1の8乗根
W80 , W81 , W82 , W83 , W84 , W85 , W86 , W87
W80 1で、W81が原始8乗根である .
Nが偶数の時は WN 2は 1であるから、
W84 1となる.
N
12
N-1次多項式の値を
1のN乗根において計算する
• 1のN乗根における値をそのまま計算した
のではあまり意味がない
• 分割統治法を用いる
– 低次の項から順に交互にとって2つに分ける
– N-1次多項式の値をN個の点で計算するため
に、まずN/2個の係数の2つの多項式に分割
する。そしてそれぞれの多項式の値をN/2個
の点で計算して全体のN点における値を求め
ればよい
13
• なぜ分割統治法がいいのか?
– 根を2乗すると別の根が得られる
– 特にNが偶数の時は、
1のN乗根を2乗すると、1のN/2乗根が得ら
れる
例) ( W 1 ) 2 W 1
8
4
( W41 ) 2 W21
実際にN=8で考えてみる
14
例3)N 8の時
p( x ) p 0 p1x p 2 x 2 p 3 x 3 p 4 x 4 p 5 x 5 p 6 x 6 p 7 x 7
(p 0 p 2 x 2 p 4 x 4 p 6 x 6 ) x (p1x p 3 x 2 p 5 x 4 p 7 x 6 )
p e ( x 2 ) xpo ( x 2 )
上のように2つに分割する.ここで、7次多
項式 p( x )を1の8乗根で計算する
W8 : w 80 , w 18 , w 82 , w 83 , w 84 , w 85 , w 86 , w 87
まず、w 84 1だから
W8 : w 80 , w 18 , w 82 , w 83 , w 80 , w 18 , w 82 , w 83
となる.次に各項を2
乗すると
W82 : w 04 , w14 , w 24 , w 34 , w 04 , w 14 , w 24 , w 34
になる.
15
p( x ) p e ( x 2 ) xpo ( x 2 )
に注目すると以下のような次式が導かれる.
p( w 80 ) p e ( w 04 ) w 80 p o ( w 04 ),
p( w 18 ) p e ( w 14 ) w 18 p o ( w 14 ),
p( w 82 ) p e ( w 24 ) w 82 p o ( w 24 ),
p( w 83 ) p e ( w 34 ) w 83 p o ( w 34 ),
p( w 84 ) p e ( w 04 ) w 80 p o ( w 04 ),
p( w 85 ) p e ( w 14 ) w 18 p o ( w 14 ),
p( w 86 ) p e ( w 24 ) w 82 p o ( w 24 ),
p( w 87 ) p e ( w 34 ) w 83 p o ( w 34 ),
16
実際に、p( w18 ) p e ( w14 ) w 18 p o ( w14 )を計算してみる.
p( w18 ) p e ( w14 ) w18 p o ( w14 )
(p 0 p 2 w14 p 4 w 24 p 6 w 34 ) w18 (p1 p 3 w14 p 5 w 24 p 7 w 34 )
(p 0 p 4 w 24 ) w14 (p 2 p 6 w 24 ) w18{( p1 p 5 w 24 ) w14 (p 3 p 7 w 24 )}
(p 0 p 4 w12 ) w14 (p 2 p 6 w12 ) w18{( p1 p 5 w12 ) w14 (p 3 p 7 w12 )}
ここで、
w12 1だから
(p 0 p 4 ) w14 (p 2 p 6 ) w18{( p1 p 5 ) w14 (p 3 p 7 )}
またw ( w )
1
w (w )
1
1
4
1
8
1
2
1
4
2
2
(1)
(i)
1
2
1
2
i,
i だから
(p 0 p 4 ) i(p 2 p 6 ) i{( p1 p 5 ) i(p 3 p 7 )}
17
一般的に、1のN乗根におけるp( x )の計算をする
p e x とp o x とを1のN / 2乗根において再帰的に 計算する.
このような乗算を
N回繰り返す.
(ただし、再帰的な計
算でN / 2, N / 4,となるので、
Nは2のベキ乗であると仮定する.)
再帰は w 2xのようにN 2の時に打ち切る.
このときxはw12 1, ( w12 ) 2 1 のどちらかだから
p 0 p1xはp 0 p1かp 0 p1を得る.
あとは1つずつ上にあげて計算 し、全体のp( x )を求める.
18
性質41.1
約N lg N回の乗算によって、N 1次多項式の値を1のN乗根において計算できる
証明)第6章漸化式4
を参照
乗算の回数を M ( N)とする.分割統治法の再帰式は
M ( N ) 2 M ( N / 2) N
これを解くと、
N 2 n とおく
M (2 n ) 2M (2 n 1 ) 2 n
M (2 n ) M (2 n 1 )
1
n
n 1
2
2
M(2 n 2 )
11
n 2
2
M ( 2 n 3 )
111
n 3
2
n
よって ( N 2 n よりn lg N)
M ( N ) M (2 n ) n 2 n N lg N
19
1の累乗根の関数値の補間
• 1の累乗根を用いて高速で多項式の値が得られた
⇒その値を高速で補間すれば、高速で多項式の積が
求まったことになる.
補間する点集合が1の累乗根ならば、
関数値を計算する手順で補間多項式も求まる!
なぜなら
フーリエ変換とその逆変換を使っているから!!
20
前と同じN 8の例で、補間は、多項式
r ( x ) r0 r1x r2 x 2 r3 x 3 r4 x 4 r5 x 5 r6 x 6 r7 x 7
が1の8乗根において次の値をとるように係
数ri (0 i 8)を求めることである.
r ( w 80 ) s 0, r ( w 18 ) s1, r ( w 82 ) s 2, r ( w 83 ) s 3,
r ( w 84 ) s 4, r ( w 85 ) s 5, r ( w 86 ) s 6, r ( w 87 ) s 7 .
各点における値を係数 とする多項式を
s( x ) s 0 s1x s 2 x 2 s 3 x 3 s 4 x 4 s 5 x 5 s 6 x 6 s 7 x 7
とする.多項式s( x )の値を1の累乗根の逆 数
W81 : w 80 , w 81 , w 8 2 , w 83 , w 8 4 , w 85 , w 86 , w 87 .
において計算すると、r ( x )の係数
r0 , r1 , r2 , r3 , r4 , r5 , r6 , r7 .
が求まる.(
r ( w 18 ) s1だからs( w 81 ) 8r1)
ここで、数列
W81は1の8乗根をW8の逆順にしただけ
W81 : w 80 , w 87 , w 86 , w 85 , w 84 , w 83 , w 82 , w 18 .
つまり値の計算すべき点を並び替えるだけで
関数値の計算の手順が そのまま補間の計算に 使える.
21
1のN乗根の t番目の値の逆数におけ るs( x )の値を計算すると、
s( w Nt )
0 j N
r(w
0 j N
t j
s
(
w
j N)
j
N
)(w Nt ) j
j i
t j
r
(
w
)
(
w
i N N)
j i t
r
w
i N
ri
j i t
w
N Nrt
0 j N 0i N
0 j N 0i N
0i N 0 j N
となる.
i tの時、 ri rt ,
0i N
w
0 j N
j it
N
N
i t N
w
1
i tの時、 w Nji t Ni t
0
w N 1
0 j N
22
1の8乗根の1番目の値の逆数におけ るs( x )の値を計算すると、
s( w 81 )
1 j
s
(
w
j 8)
0 j8
s 0 s1w 81 s 2 ( w 81 ) 2 s 7 ( w 81 ) 7
j
1 j
r
(
w
)(
w
8 8)
0 j8
w rw w
r w r w
0
8
1
8
1
8
j i
1 j
r
(
w
)
(
w
i 8 8)
0 j8 0i 8
2
8
2 2
8
w
r w
7
8
7 7
8
r0 r1w 80 r7 ( w 80 ) 7 r0 r1w 18 r7 ( w 18 ) 7 w 81
r0 r1w 87 r7 ( w 87 ) 7 ( w 81 ) 7
ji 1
r
w
i 8
0 j8 0i 8
r w
i
0 j8 0i 8
j i 1
8
8r1
23
• 性質41.2
1のN乗根における値が与えられたN-1次多項式の係数
を、約NlgN回の乗算で求めることが出来る.
これは補間の計算は多項式の値の計算の逆であるから
性質41.1より乗算は約NlgN回となる.
多項式の値の計算と補間の計算の乗算の回数は
NlgN回であるが、あくまで1のN乗根に対してだけ
あてはまる
24
eval(p, outN, 0);
eval(q, outN, 0);
for (i = 0; i <= outN; i++) r[i] = p[i]*q[i];
eval(r, outN, 0);
for (i = 1; i <= N; i++)
{ t = r[i]; r[i] = r[outN+1-i]; r[outN+1-i] = t; }
for (i = 0; i <= outN; i++) r[i] = r[i]/(outN+1);
・大域変数outNに2N-1が与えられている.
・p,q,rは添字の範囲が0から2N-1の複素数の配列
と仮定されている.
・多項式p,qはN-1次であり、N次より上位の係数は0に
初期化されている.
25
手続きeval
• 1番目の引き数
– 多項式の係数を、1の累乗根における多項式
の値に書き換える
• 2番目の引き数
– 多項式の次数(係数の数、1の根の数より1少
ない)
手続きevalの目的
N+1個の係数が連続して入っている配列を入力と
して、同じ配列にN+1個の関数値を入れて返すこと
26
• しかし、再帰呼出しでは連続していない偶数番目
と奇数番目の係数の配列を入れかえなければな
らない.
⇒ここで用いられるのが、完全シャッフル
• 完全シャッフルをすることにより
配列の前半に連続して偶数番目の係数を入れ、
後半に奇数番目の係数を入れることが出来る.
27
完全シャッフル
P[0] P[1] P[2] P[3] P[4] P[5] P[6] P[7]
P[0] P[2] P[4] P[6] P[1] P[3] P[5] P[7]
28
高速フーリエ変換のプログラム
• 実際計算する時の1のN乗根の値は、
2j
2j
w cos
i sin
N 1
N 1
j
N
• 配列wに1の(outN+1)乗根が入っている
上のことも考慮すると
次のような高速フーリエ変換のプログラム
となる.
29
eval(struct complex p[], int N,
int k)
{ int i, j;
if (N == 1)
{
p0 = p[k]; p1 = p[k+1];
p[k] = p0+p1; p[k+1] =
p0-p1;
}
else
{
for (i = 0; i <= N/2; i++)
{
j = k+2*i;
t[i] = p[j]; t[i+1+N/2]
= p[j+1];
}
for (i = 0; i <= N; i++) p[k+i]
= t[i];
eval(p, N/2, k);
eval(q, N/2, (k+1+N)/2);
j = (outN+1)/(N+1);
for (i = 0; i <= N/2; i++)
{
p0 =
w[i*j]*p[k+(N/2)+1+i];
t[i] = p[k+i]+p0;
t[i+(N/2)+1] =
p[k+i]-p0;
}
for (i = 0; i <= N; i++)
p[k+i] = t[i];
}
30
}
• 性質41.3
2つのN-1次多項式の積は2NlgN+O(N)回
の複素数の計算によって求められる.
性質41.1と性質41.2より、N-1次多項
式を1のN乗根の値への変換と補間の乗
算の回数はそれぞれNlgN回である.また1
のN乗根に変換した値を掛け合わせるの
にO(N)の乗算が必要だから、積の回数は
2NlgN+O(N)回となる.
31
まとめ
◎2つのN 1次多項式の積を求める 時、
普通に掛けると、乗算の回数は N 2回
高速フーリエ変換を使うと、
2 N lg N ON 回
◎高速フーリエ変換の手順
①:
2つのN 1次多項式を 2 N 1個の異なる点で計算す る.
(このとき
1のN乗根を使う)
②:変換した値を掛け合わせる.
③:①と同じ計算手順により補間する
32
© Copyright 2026 ExpyDoc