Successfully reported this slideshow.
Your SlideShare is downloading. ×

高速フーリエ変換

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad

Check these out next

1 of 30 Ad
Advertisement

More Related Content

Slideshows for you (20)

More from AtCoder Inc. (20)

Advertisement

Recently uploaded (20)

高速フーリエ変換

  1. 1. AtCoder Typical Contest 001 C 高速フーリエ変換 AtCoder 株式会社
  2. 2. 問題概要 AtCoder 食堂では, 円の主菜が 種類 円の副菜が 種類 i Ai j Bj ある. ちょうど 円になる, 主菜と副菜一つずつの組合せがい くつあるかを出力せよ. k
  3. 3. 畳込み ちょうど 円になる組合せの数を とすると, 主菜で 円の物を選んだ時, 副菜として 円の物を選べばよ く, となる. 但し, とおく. k Ck i k − i =Ck ∑ i=0 k Ai Bk−i = = 0A0 B0 このような を, と の畳込み (convolution) という.C A B
  4. 4. 畳込みから多項式乗算へ ここで, , を係数とする多項式 を考えると, その積は で定まる. A B g(x) = , ∑ i=0 N Ai x i h(x) = ∑ j=0 N Bj x j (g ∗ h)(x) = g(x) ∗ h(x) = ∑ i=0 N ∑ j=0 N Ai Bj x i+j
  5. 5. 畳込みから多項式乗算へ ここで, とおいて を書きなおすと, i + j = k (g ∗ h)(x) = ∑ i=0 N ∑ j=0 N Ai Bj x i+j (g ∗ h)(x) = ( ) ∑ k=0 2N ∑ i=0 k Ai Bk−i x k = ∑ k=0 2N Ck x k となるから, この が計算出来ればよい.(g ∗ h)(x)
  6. 6. 多項式乗算 を高速に求めたい.(g ∗ h)(x) 普通に書くと, こんな感じで .O (deg(g) ∗ deg(h)) def multiply(g, h):   f = [ 0 for _ in range(len(g) + len(h) ­ 1) ]   for i in range(len(g)):     for j in range(len(h)):       f[i+j] += g[i] * h[j]   return f
  7. 7. 多項式の性質 は, 次の多項式.g(x) ∗ h(x) deg(g) + deg(h) よって, 個の点 での値 が 求まっていれば, これを通る は一意. deg(g) + deg(h) + 1 xi f ( )xi h 例えば, 二点を決めると, それを同時に通る直線は一つ. 三点を決めると, それを同時に通る放物線は一つ.
  8. 8. 高速多項式乗算の戦略 1. とし, 個の点 を, 計算しやすいようにうまく選ぶ. 2. と, を計算する. 3. を使って, を計算する. 4. うまいこと何かして, から を復元する. n > deg(g) + deg(h) n , …,x0 xn−1 g( ), …, g( )x0 xn−1 h( ), …, h( )x0 xn−1 (g ∗ h)(x) = g(x) ∗ h(x) (g ∗ h)( ), …, (g ∗ h)( )x0 xn−1 (g ∗ h)( ), …, (g ∗ h)( )x0 xn−1 (g ∗ h)(x) 2 のように, 点での値を求めることを "評価" (evaluation), 4 のように, 点での値から元の多項式を復元することを "補間" (interpolation) と呼ぶ.
  9. 9. 点の選び方 実際には, が の冪乗になるようにし, と しては の 乗根全体を選ぶ. n 2 , …,x0 xn−1 1 n つまり, として, とする.= exp(2π /n)ζn −1‾‾‾√ =xi ζi n
  10. 10. の性質ζn には, 次の性質がある.= exp(2π /n)ζn −1‾‾‾√ . "直交性" が成り立つ. すなわち, (最後の は, 等比級数の和の公式から.) = ⇔ i = j mod nζi n ζj n = ∑ i=0 n−1 ( )ζj n i ( ) ζk n ⎯ ⎯⎯⎯⎯⎯ i ∑ i=0 n−1 ζi(j−k) n = { n, if j = k mod n, 0, otherwise. = 0 を で置き換えても, これらの性質は変わらない.ζn ζ−1 n
  11. 11. 離散フーリエ変換 前述の通り, として, 評価と補間をする. こうする と, 何がよいのかを見ていこう. =xi ζi n 多項式 に対し, を で定める. つまり, 評価した各点での値を係数に持つ多項 式である. f (x) (t)fˆ (t) = f ( )fˆ ∑ i=0 n−1 ζi n t i これを, の離散フーリエ変換 (Discrete Fourier Transformation, DFT) と呼ぶ. f
  12. 12. 離散フーリエ変換 とすると,f (x) = ∑n−1 j=0 cj x j (t)fˆ = f ( ) ∑ i=0 n−1 ζi n t i = ( ( ) ∑ i=0 n−1 ∑ j=0 n−1 cj ζi n ) j t i = ( t ∑ j=0 n−1 cj ∑ i=0 n−1 ζj n ) i
  13. 13. 離散フーリエ逆変換 を求めてみると, だが, だったから, ( )fˆ ζ−k n ( )fˆ ζ−k n = ( ∑ j=0 n−1 cj ∑ i=0 n−1 ζj n ζ−k n ) i = {∑ i=0 n−1 ζi(j−k) n n, if j = k mod n, 0, otherwise ( )fˆ ζ−k n = n .ck
  14. 14. 離散フーリエ逆変換 よって, の DFT から, と, を で置き換えた DFT で を復元出来る. こ れを, 離散フーリエ逆変換と呼ぶ. f (t) = f ( )fˆ ∑ i=0 n−1 ζi n t i f (x) = ( ) 1 n ∑ i=0 n−1 fˆ ζ−i n x i ζn ζ−1 n f (x)
  15. 15. 積の離散フーリエ変換 (DFT) さて, "多項式を評価した値" を係数としたのだから当然 ではあるが, は, と, と の係数毎の積で求められる. (t)g ∗ hˆ (t)g ∗ hˆ = (g ∗ h)( ) ∑ i=0 n−1 ζi n t i = g( )h( ) ∑ i=0 n−1 ζi n ζi n t i gˆ hˆ
  16. 16. 離散フーリエ変換を使った乗算 結局, 多項式の積を求めるには, 1. となる の冪乗を選ぶ. 2. 上の に DFT をして を計算する. 3. と を係数毎に掛け, を求める. 4. に inverse DFT をして を復元する. n > deg(g) + deg(h) 2 g, h (t), (t)gˆ hˆ (t)gˆ (t)hˆ (t)g ∗ hˆ (t)g ∗ hˆ (g ∗ h)(x) とすればよい.
  17. 17. 離散フーリエ変換を使った乗算 擬似コードで書くと, def multiply(g, h):   n = pow_2_at_least(deg(g) + deg(h) + 1)   # g, h は n­1 次になるように 0 を詰めておく.   gg = dft(g, n)   hh = dft(h, n)   ff = [ gg[i] * hh[i] for i in range(n) ]   return inverse_dft(ff, n)
  18. 18. 高速フーリエ変換 あとは, DFT, inverse DFT を高速に求められればよい. 高速に DFT を求めるアルゴリズムを "高速フーリエ変換" (Fast Fourier Transformation, FFT) と呼ぶ. inverse DFT は, DFT で出てくる を全て で置き換 え, 最後に で割ればよいだけなので, 以下では DFT につ いてのみ解説する. ζn ζ−1 n n
  19. 19. 高速フーリエ変換 の冪乗 と 次以下の多項式 に対し, とすると, で, , はそれぞれ 次以下の多項式. 2 n n − 1 f (x) = ∑n−1 i=0 ci x i (x)f0 (x)f1 = = + + + …, ∑ i=0 n/2−1 c2i x i c0 x 0 c2 x 1 c4 x 2 = = + + + …∑ i=0 n/2−1 c2i+1 x i c1 x 0 c3 x 1 c5 x 2 f (x) = ( ) + x ( )f0 x 2 f1 x 2 f0 f1 n/2 − 1
  20. 20. 高速フーリエ変換 を求めるには,fˆ f ( ), f ( ), …, f ( )ζ0 n ζ1 n ζn−1 n を求められればよかったが, だ から, f (x) = ( ) + x ( )f0 x 2 f1 x 2 ( ), ( ), …, ( ),f0 ζ0 n f0 ζ2 n f0 ζ2(n−1) n ( ), ( ), …, ( )f1 ζ0 n f1 ζ2 n f1 ζ2(n−1) n を求めればよい.
  21. 21. 高速フーリエ変換 だから, = exp (2 ∗ 2π /n) = exp (2π /(n/2)) =ζ2 n −1‾‾‾√ −1‾‾‾√ ζn/2 ( ), ( ), …, ( ),f0 ζ0 n f0 ζ2 n f0 ζ2(n−1) n ( ), ( ), …, ( )f1 ζ0 n f1 ζ2 n f1 ζ2(n−1) n は, ( ), ( ), …, ( ),f0 ζ0 n/2 f0 ζ1 n/2 f0 ζn−1 n/2 ( ), ( ), …, ( )f1 ζ0 n/2 f1 ζ1 n/2 f1 ζn−1 n/2 と同じ.
  22. 22. 高速フーリエ変換 は 乗すると だから, . よって,ζn/2 n/2 1 =ζi+n/2 n/2 ζi n/2 ( ), ( ), …, ( ),f0 ζ0 n/2 f0 ζ1 n/2 f0 ζn−1 n/2 ( ), ( ), …, ( )f1 ζ0 n/2 f1 ζ1 n/2 f1 ζn−1 n/2 は, それぞれ前半と後半が同じで, 前半だけの ( ), ( ), …, ( ),f0 ζ0 n/2 f0 ζ1 n/2 f0 ζn/2−1 n/2 ( ), ( ), …, ( )f1 ζ0 n/2 f1 ζ1 n/2 f1 ζn/2−1 n/2 を求めればよい.
  23. 23. 高速フーリエ変換 よって, 次以下の多項式 に対してn − 1 f f ( ), f ( ), …, f ( )ζ0 n ζ1 n ζn−1 n を求めるには, 二つの 次以下の多項式 に対 して n/2 − 1 ,f0 f1 ( ), ( ), …, ( ),f0 ζ0 n/2 f0 ζ1 n/2 f0 ζn/2−1 n/2 ( ), ( ), …, ( )f1 ζ0 n/2 f1 ζ1 n/2 f1 ζn/2−1 n/2 を求めればよいことになった. これは, サイズが半分になった同じ問題を二つ解けばよ いということ!!
  24. 24. 高速フーリエ変換 再帰的に行うと, 必要になる計算回数 は,T (n) T (n) = { O(1), 2T (n/2) + O(n), if n = 1, otherwise で, これを解くと になる.T (n) = O(n log n)
  25. 25. 高速フーリエ変換 以上のアルゴリズムを擬似コードで書くと, def dft(f, n):   if n == 1:     return f   f0 = [ f[2*i + 0] for i in range(n / 2) ]   f1 = [ f[2*i + 1] for i in range(n / 2) ]   f0 = dft(f0, n/2)   f1 = dft(f1, n/2)   zeta = complex(cos(2 * pi / n), sin(2 * pi / n))   pow_zeta = 1   for i in range(n)     # この時点で, pow_zeta = pow(zeta, i)     f[i] = f0[i % (n/2)] + pow_zeta * f1[i % (n/2)]     pow_zeta *= zeta   return f
  26. 26. 発展的な話題
  27. 27. 複素数以外の "環" での FFT 上の FFT は, 複素数だけでなく, の原始 乗根(ちょうど 乗すると になるような要素)が存在する "可換環" で 出来る. 1 n n 1 これから, 例えば で割ると 余る素数を法とする FFT が出来る事がわかる. n 1
  28. 28. 発展的な FFT アルゴリズム 今まで紹介した再帰的な FFT が基本だが, 他にも様々な FFT アルゴリズムがある. Cooley-Tukey FFT, Gentleman-Sande FFT 再帰的 FFT を非再帰, in-place(入力の領域を使い回 し, 余分な領域をあまり使わない)にしたもの. 競技プ ログラミングではよく用いられている. Stockham FFT 上の二つと異なり, "ビット反転" が不要で, メモリア クセスがシーケンシャル. その代わり, in-place でない.
  29. 29. 発展的な FFT アルゴリズム 分割基底 FFT と のように二つに分割するのではなく, より多 くの個数に分割する. つに分割する, -基底 FFT がよく用いられる. four-step FFT, six-step FFT 約 個に分割し, 組み合わせる時にも FFT を用い る. 並列化する時によいらしい. nine-step FFT 約 ずつ, 三次元的に分割する. f0 f1 4 4 n‾√ n 1/3
  30. 30. 参考文献 1. R. Crandall, C. Pomerance, 和田秀男 監訳, "素数全書: 計算からのアプローチ", 朝倉書店, 2010, ISBN 978-4-254-11128-6. 2. R. Sedgewick, 野下 浩平, 星 守, 佐藤 創, 田口 東 共訳, "アルゴリズムC <第3巻> グラフ・数理・トピックス", 近代科学社, 1996, ISBN 978-4-764-90257-2

×