快速傅里叶变换 (fast Fourier transform),即利用计算机计算离散傅里叶变换(DFT)的高效、快速计算方法的统称,简称FFT。快速傅里叶变换是1965年由J.W.库利和T.W.图基提出的。采用这种算法能使计算机计算离散傅里叶变换所需要的乘法次数大为减少,特别是被变换的抽样点数N越多,FFT算法计算量的节省就越显著。
FFT(Fast Fourier Transformation) 是离散傅氏变换(DFT)的快速算法。即为快速傅氏变换。它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。
——百度百科
快速傅里叶变换可以干什么
简短来说快速傅里叶变换就是为了加速多项式的乘法运算,多项式的乘法也叫卷积。
形如:
y n = ∑ i x i h n − i = x n ∗ h n {y_{n} = \sum_{i}x_{i}h_{n-i}} = x_{n}*h_{n} yn=∑ixihn−i=xn∗hn
y n y_{n} yn就是 x n x_{n} xn和 h n h_{n} hn的卷积
朴素的多项式乘法为各系数相乘,时间复杂度是 O ( n 2 ) O(n^2) O(n2),通过快速傅里叶变换可以降为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)。
快速傅里叶变化的算法步骤
明确概念:
多项式的系数表示法和点值表示法
-
系数表达法就是我们常用的方式
A ( x ) = a 0 x 0 + a 1 x 2 + a 3 x 3 + . . . a n − 1 x n − 1 {A(x)} = a_{0}x^{0} +a_{1}x^{2} +a_{3}x^{3} +...a_{n-1}x^{n-1} A(x)=a0x0+a1x2+a3x3+...an−1xn−1
-
点值表达法则是:
等于使用一个含有n个固定方程的方程组来表示多项式。
- 多项式的系数表示和点值表示可以互相转换
快速傅里叶主要分为三步:
1.将多项式从系数表达法变为点值表达法。
2.使用点值表达法进行多项式相乘。
3.再将乘出来的结果从点值表达转换为系数表达的多项式。
快速傅里叶变换的算法原理
说明原理前先明确一些需要的概念。
1.复数
z = a + b i ( a , b ∈ R ) {z = a + bi}(a,b∈R) z=a+bi(a,b∈R),Z就是复数
其中a 称为实部,b 称为虚部,i称为虚数单位
2.复数相乘
将复数放到直接坐标系里,满足复数相乘就是 模长相乘,极角相加的规律。
( a 1 , θ 1 ) ∗ ( a 1 , θ 2 ) = ( a 1 a 2 , θ 1 + θ 2 ) {(a_{1},θ_{1})*(a_{1},θ_{2}) = (a_{1} a_{2},θ_{1}+θ_{2})} (a1,θ1)∗(a1,θ2)=(a1a2,θ1+θ2)
DFT(离散傅里叶变换)
- 一定注意从这里开始所有的n 都默认为2的整数次幂,如果原来的n不是2的整数次幂,通过添加系数为 0 的高阶系数,可以使得 n 是 2 的幂。
对于任意系数多项式转点值,当然可以随便取任意n 个x值代入计算,但是暴力计算x0k,x1k,…,xn−1k(k∈[0,n])需要O(n^2)的时间。其实可以代入一组特定的 x 来优化这个时间。
很容易想到,如果有一个x,他的所有次方都是1,即 x 0 , x 1 , x 2 . . . x n − 1 {x_{0},x_{1},x_{2}...x_{n-1}} x0,x1,x2...xn−1都是1。那么我们就可以很快地将系多项式转换为点值的形式。
那现在就是需要找到一个x,满足x的0…n次方都是1,这样我们就不用做全部的次方运算了
±1是可以的,考虑虚数的话±i也可以,但只有这四个数远远不够
下面就开始构造这个x:
在刚才的二维复数坐标系上取一个单位圆
可以知道单位圆上所有的点都可以经过若干次次方得到1,将它给n等分了,比如此时n=8。将其分成8份,并将每个点标好记号。从(1,0)开始,逆时针从0开始标号。
我们可以找到 e 2 π i k n {e^{\frac{2 π i k}{n}}} en2πik(k = 0,1,… n-1,由欧拉公式得出: e i u = c o s u + i s i n u {e^{iu} = cosu +isinu} eiu=cosu+isinu)。为了方便表示,称 w n k {w^{k}_{n}} wnk表示为标记为k的n次单位根,即:
w n k {w^{k}_{n}} wnk = e 2 π i k n {e^{\frac{2πik}{n}}} en2πik
w n 1 {w^{1}_{n}} wn1成为主n次单位根,其他n次单位根都是它的次幂。
由模长相乘,极角相加可知
w n k {w^{k}_{n}} wnk = c o s k n 2 π + i s i n k n 2 π {cos\frac{k}{n}2π +isin\frac{k}{n}2π} cosnk2π+isinnk2π
下图也可以解释这条式子
推导FFT中需要n次单位根的一些性质
(原本是需要消去,折半,求和三个引例,因为不好理解所以采用博客:@路人黑的纸巾,中的一些性质)。
w n k {w^{k}_{n}} wnk = w 2 n 2 k {w^{2k}_{2n}} w2n2