FFT(Fast Fourier Transformation)是离散傅氏变换(DFT)的快速算法。即为快速傅氏变换。它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。
Fast Fourier Transform
多项式乘法
假如我们有两个多项式:
我们想求得:
使用朴素的做法肯定需要 O(n2) 的复杂度。
我们将上述的 A(x) 的系数表示为向量 A ,则称这种表示法为系数表示法。
现在来考虑另一种表示法,即点值表示法。
设向量 A=(A(p1),A(p2),A(p3),...,A(pn)) ,则 A 称作 A(x) 的点值表示。
点值表示有什么优点?首先,n维点值表示与n维系数表示一一对应(证明似乎有点麻烦……),其次,点值表示下的多项式运算得到了化简。
以乘法为例:
这样便转换为了点值表示的两个式子。而且我们可以发现,完成点值表示下的乘法复杂度是O(n) 的。
那么加速多项式乘法的过程,变为了:
系数表示 → 点值表示 → 乘法 → 点值表示 → 系数表示
而快速傅里叶变换,就是从系数表示转换到点值表示的桥梁。
我们观察到,点值表示下所取的点 p1,p2,...,pn 是可以任取的,那么我们利用一些特殊值,是否能加速运算?
快速傅里叶变换
此处我们引入单位根的概念。即满足:
的复数,记为 ωn。它可以看做是复平面上x轴正方向绕逆时针方向旋转 2πn 的复数。
单位根有一些很好的性质,这些性质都可以利用复平面上的向量比较直观地感受。
假如我们取单位根的幂进行转换,会有什么效果?设 A0(x) 是 A(x) 的偶次项的和, A1(x) 是奇次项的和。那么:
即我们只要有了 A0(x),A1(x) 的点值表示,就能在 O(n) 时间内算出 A(x) 的点值表示。
每一层对于一个确定的 m,我们用对应的两个值来更新出当前的值,称这个操作为“蝴蝶变换”。
分析一下复杂度,A(x) 的规模为 T(n) ,而他的奇、偶次项分别的和的规模都为 T(n2) ,而合并的时间为 O(n) ,即 T(n)=2T(n2)+O(n) ,根据主定理,这个问题的复杂度为O(nlogn).
逆离散傅里叶变换
现在我们已经可以快速从系数表示转换到点值表示了。接下来的问题就是如何从点值表示转换到系数表示。
我们转移到点值表示的过程可以看做是一个矩阵乘法: