最近做一个东西,要用到快速傅里叶变换,抱着蛋疼的心态,自己尝试写了一下,遇到一些问题。
首先看一下什么叫做快速傅里叶变换(FFT)(来自Wiki):
快速傅里叶变换(英语:Fast Fourier Transform, FFT),是离散傅里叶变换的快速算法,也可用于计算离散傅里叶变换的逆变换。快速傅里叶变换有广泛的应用,如数字信号处理、计算大整数乘法、求解偏微分方程等等。
离散傅里叶变换公式:
y j = ∑ k = 0 n − 1 e − 2 π i n j k x k , j = 0 , 1 , . . . , n − 1 y_j=\sum_{k=0}^{n-1}e^{-\frac{2\pi i}{n}j^k}x_k,j=0,1,...,n-1 yj=k=0∑n−1e−n2πijkxk,j=0,1,...,n−1
直接变换的计算复杂度是 O ( n 2 ) O(n^2) O(n2).快速傅里叶变换可以计算出与直接计算相同的结果,但只需要 O ( n log n ) O(n\log n) O(nlogn)的计算复杂度。
首先,看一个概念叫做N次单位复根:复数 W N n = 1 WN^n = 1 WNn=1。N次单位复根一共有N个,分别为: W ( k , N ) = c i s ( 2 ∗ P I ∗ k / N ) , k = 0 , 1 , . . . , n − 1 W(k,N) = cis(2*PI*k/N),k=0,1,...,n-1 W(k,N)=cis(2∗PI∗k/N),k=0,1,...,n−1
其中 c i s ( u ) = e i ∗ u = cos ( u ) + i sin ( u ) cis(u) = e^i*u = \cos(u) + i\sin(u) cis(u)=ei∗u=cos(u)+isin(u)(欧拉公式)
N次单位复根有如下性质:
- W ( k + N , N ) = W ( k , N ) W(k+N,N) = W(k,N) W(k+N,N)=W(k,N)
- W ( k + N / 2 , N ) = − W ( k , N ) W(k+N/2,N) = -W(k,N) W(k+N/2,N)=−W(k,N)
- W ( d k , d N ) = W ( k , N ) ( d > 0 ) W(dk,dN) = W(k,N) (d>0) W(dk,dN)=W(k,N)(d>0)
库利-图基算法:
将长度为N的序列分成两个N/2的子序列N1和N2,其中N1是原来序列的奇数项,N2为偶数项。
将离散傅里叶变换写成:
N ( x ) = ∑ j = 0 n − 1 a j x j x = W ( k , N ) N(x)=\sum_{j=0}^{n-1}a_jx_jx=W(k,N) N(x)=j=0∑n−1ajxjx=W