快速傅里叶变换学习记录——Fast Fourier Transformation

序言

掌声鼓励,本蒟蒻终于学会FFT啦!快速傅里叶变换学习记录——Fast Fourier Transformation_第1张图片
死磕了接近5天的FFT,中途断断续续,请教了所谓的“数论讲师”葛某
他居然告诉我:
他不会!!!
他不会!!!
他不会!!!
他不会!!!
他不会!!!
他不会!!!
快速傅里叶变换学习记录——Fast Fourier Transformation_第2张图片

前排膜拜dalao

如果觉得本人蒟蒻的,勿喷,可以看这两位dalao的Blog:
Mikcoo
Picks

前排预警:这篇Blog有很多公式!!!

预备知识

数论dalao可以直接跳过了……

多项式

形如 A(x)=a0+a1x+a2x2++anxn A ( x ) = a 0 + a 1 x + a 2 x 2 + ⋯ + a n x n 的称为多项式
a0,a1,,an a 0 , a 1 , ⋯ , a n 称为多项式的系数
x x 为不定元,不表达任何确定值。
不定元 x x 在多项式中最大的次数称为多项式的次数

多项式的系数表达法

多项式的系数表示为 n+1 n + 1 维向量 a⃗ =(a0,a1,,an) a → = ( a 0 , a 1 , ⋯ , a n )
简单理解为一个数组就好……数学家总是喜欢搞些奇奇怪怪的东西。

多项式的点值表示法

已知对于一元 n n 次方程可以用 n+1 n + 1 个点的坐标表示。(理由自证)
多项式的点值表示为 {(xi,A(xi)):0in} { ( x i , A ( x i ) ) : 0 ≤ i ≤ n }
还可用点值向量 y⃗ =(A(x0),A(x1),,A(xn)) y → = ( A ( x 0 ) , A ( x 1 ) , ⋯ , A ( x n ) )

复数

形如 a+bi a + b i 的数称为复数,其中 a,b a , b 为实数, i i 为虚数单位,满足 i2=1 i 2 = − 1

单位根

n n 次单位根 ωn ω n 为满足 ωnn=1 ω n n = 1 的复数,共有 n n 个,均匀的分布在复平面的单位圆上,将单位圆 n n 等分。
所以 n n 次单位根的算术表示为 ωn=e2πin ω n = e 2 π i n

多项式乘法

给定两个多项式 A(x),B(x) A ( x ) , B ( x ) ,求 C(x)=A(x)B(x) C ( x ) = A ( x ) B ( x )

系数表示法下的运算

C(x)=i=12ncixi ∵ C ( x ) = ∑ i = 1 2 n c i x i
C(x)=j+k=i,0j,knajbkxi ∴ C ( x ) = ∑ j + k = i , 0 ≤ j , k ≤ n a j b k x i
易证时间复杂度为 O(n2) O ( n 2 )

点值表示法下的运算

C(x)=A(x)B(x) ∵ C ( x ) = A ( x ) B ( x )
C(xi)=A(xi)B(xi) ∴ C ( x i ) = A ( x i ) B ( x i )
C(x) ∴ C ( x ) 的点值表示为 {(xi,A(xi)B(xi)):1in} { ( x i , A ( x i ) B ( x i ) ) : 1 ≤ i ≤ n }
易证时间复杂度为 O(n) O ( n )

Fast Fourier Transformation

FFT在竞赛中一般用于加速多项式乘法运算。
现在引入FFT(Fast Fourier Transformation)
我们观察到对于以上两种运算,点值表示法下的运算明显优于系数表示法下的运算,考虑将运算过程转移到点值表示法下。
使用暴力强行将系数表示法转换为点值表示法的时间复杂度是 O(n2) O ( n 2 ) ,这里不再做讨论。

FFT算法流程

快速傅里叶变换学习记录——Fast Fourier Transformation_第3张图片
英文看的辛不辛苦啊,我就不翻译。(手动滑稽)

Discrete Fourier Transform

DFT的目的是将系数向量 a⃗  a → 转换为点值向量 y⃗  y →
n n 个相异实数 x0,x1,,xn1 x 0 , x 1 , ⋯ , x n − 1 代入多项式。
A(xk)=i=0n1aixik,(0kn1) ∴ A ( x k ) = ∑ i = 0 n − 1 a i x k i , ( 0 ≤ k ≤ n − 1 )
A(x) ∴ A ( x ) 的点值表示为 {(xk,A(xk)):0kn1} { ( x k , A ( x k ) ) : 0 ≤ k ≤ n − 1 }
点值向量 y⃗ =(A(x0),A(x1),,A(xn1)) y → = ( A ( x 0 ) , A ( x 1 ) , ⋯ , A ( x n − 1 ) )
点值向量 y⃗  y → 称为系数向量 a⃗  a → 离散傅里叶变换(Discrete Fourier Transform),记作 y⃗ =DFTn(a⃗ ) y → = D F T n ( a → )
易证上述做法时间复杂度为 O(n2) O ( n 2 )

Cooley-Tukey算法(蝶形算法)

以下摘自Wiki:

库利-图基快速傅里叶变换算法(Cooley-Tukey算法)[1]是最常见的快速傅里叶变换算法。这一方法以分治法为策略递归地将长度为N = N1N2的DFT分解为长度分别为N1和N2的两个较短序列的DFT,以及与旋转因子的复数乘法。这种方法以及FFT的基本思路在1965年J. W. Cooley和J. W. Tukey合作发表An algorithm for the machine calculation of complex Fourier series之后开始为人所知。但后来发现,实际上这两位作者只是重新发明了高斯在1805年就已经提出的算法(此算法在历史上数次以各种形式被再次提出)。
库利-图基算法最有名的应用,是将序列长为N的DFT分割为两个长为N/2的子序列的DFT,因此这一应用只适用于序列长度为2的幂的DFT计算,即基2-FFT。实际上,如同高斯和库利与图基都指出的那样,库利-图基算法也可以用于序列长度N为任意因数分解形式的DFT,即混合基FFT,而且还可以应用于其他诸如分裂基FFT等变种。尽管库利-图基算法的基本思路是采用递归的方法进行计算,大多数传统的算法实现都将显示的递归算法改写为非递归的形式。另外,因为库利-图基算法是将DFT分解为较小长度的多个DFT,因此它可以同任一种其他的DFT算法联合使用。

从中我们注意到一句话:“……因此这一应用只适用于序列长度为 2 2 的幂的DFT计算……”。
所以,为了计算的方便,我们将 n1 n − 1 位多项式 A(x)=i=0naixi A ( x ) = ∑ i = 0 n a i x i 补位至2的幂。( n=2n,mZ n = 2 n , m ∈ Z ,高位补为 0 0
n n 个单位根 ω0n,ω1n,,ωn1n ω n 0 , ω n 1 , ⋯ , ω n n − 1 代入多项式。
A(ωkn)=i=0n1ai(ωkn)i,(0kn1) ∴ A ( ω n k ) = ∑ i = 0 n − 1 a i ( ω n k ) i , ( 0 ≤ k ≤ n − 1 )
A(x) ∴ A ( x ) 的点值表示为 {(ωkn,A(ωkn)):0kn1} { ( ω n k , A ( ω n k ) ) : 0 ≤ k ≤ n − 1 }
点值向量 y⃗ =(A(ω0n),A(ω1n),,A(ωn1n)) y → = ( A ( ω n 0 ) , A ( ω n 1 ) , ⋯ , A ( ω n n − 1 ) )
现在Cooley-Tukey算法将每一项系数按指数奇偶分类,以此将系数减半:
A(ωkn)=i=0n1aiωkin=i=1n21a2iω2kin+ωkni=1n21a2i+1ω2kin A ( ω n k ) = ∑ i = 0 n − 1 a i ω n k i = ∑ i = 1 n 2 − 1 a 2 i ω n 2 k i + ω n k ∑ i = 1 n 2 − 1 a 2 i + 1 ω n 2 k i
现在我们考虑如何将代入的值也减半:
因为:
ω2n=(e2πin)2=e4πin=e2πin/2=ωn2 ω n 2 = ( e 2 π i n ) 2 = e 4 π i n = e 2 π i n / 2 = ω n 2
且当 k<n2 k < n 2
ωk+n2n=ωn2nωkn=1ωkn=ωkn ω n k + n 2 = ω n n 2 ⋅ ω n k = − 1 ⋅ ω n k = − ω n k
所以:
k<n2 k < n 2
A(ωkn)A(ωn2+kn)=i=1n21a2iω2kin+ωkni=1n21a2i+1ω2kin=i=1n21a2iωkin2+ωkni=1n21a2i+1ωkin2=i=1n21a2iωkin2+ωn2+kni=1n21a2i+1ωkin2=i=1n21a2iωkin2ωkni=1n21a2i+1ωkin2 A ( ω n k ) = ∑ i = 1 n 2 − 1 a 2 i ω n 2 k i + ω n k ∑ i = 1 n 2 − 1 a 2 i + 1 ω n 2 k i = ∑ i = 1 n 2 − 1 a 2 i ω n 2 k i + ω n k ∑ i = 1 n 2 − 1 a 2 i + 1 ω n 2 k i A ( ω n n 2 + k ) = ∑ i = 1 n 2 − 1 a 2 i ω n 2 k i + ω n n 2 + k ∑ i = 1 n 2 − 1 a 2 i + 1 ω n 2 k i = ∑ i = 1 n 2 − 1 a 2 i ω n 2 k i − ω n k ∑ i = 1 n 2 − 1 a 2 i + 1 ω n 2 k i
需要代入的值有 ω0n2,ω1n2,,ωn21n2 ω n 2 0 , ω n 2 1 , ⋯ , ω n 2 n 2 − 1 ,问题转换为两个折半的子问题,可通过递归或迭代实现。
易证时间复杂度为 O(nlogn) O ( n log ⁡ n )
至此,通过Cooley-Tukey算法,我们将DFT的时间复杂度降为 O(nlogn) O ( n log ⁡ n )

Inverse Discrete Fourier Transform

IDFT的目的是将点值向量 y⃗  y → 转换为系数向量 a⃗  a →
IDFT就相当于把DFT过程中的 ωkn ω n k 换成 ωkn ω n − k ,然后做一次DFT,之后结果除以 n n 就可以了。
这里只给出结论,用兴趣的同学可以自行研究。(你就是懒得写)

总结

对于多项式的运算(高精度预算),使用FFT可以实现十分好的时空复杂度优化。

你可能感兴趣的:(FFT,基础学习,数论)