快速傅里叶变换——FFT学习小记
其他
2018-08-14 18:58:29
阅读次数: 0
问题
- 给定两个一元多项式,快速求解它们的笛卡尔积。可以简单理解为多项式乘法。
- 叙述算法前,先允许我介绍一下多项式。(
不是你小学学的那种简单的)
多项式
- 对于多项式
A(x)=2x3−5x2+x−4
,其次数界为4(最高次项的指数+1)。
- 一个次数界为N的多项式可以记作:
A(x)=∑n−1j=0ajxj
- 其中a为系数。
- 回到多项式乘法。
- 记多项式A(x)与B(x)的乘积为:C(x)=A(x)B(x),则C的次数界为A与B的次数界的和-1。
- C(x)系数计算方法:
ci=∑ij=0ajbi−j
- 朴素方法时间复杂度为
O(n2)
。
点值
- 对于一个多项式A(x),将x代入具体数值并求解出多项式的值y,则数对(x,y)为该多项式的点值对。
- 一个次数界为n的多项式的点值表达就是由n个点值对组成的集合:
{(x0,y0),(x1,y1),...,(xn−1,yn−1)}
- 其中x互不相同。
插值
- 插值运算即点值运算的逆运算。
- 假设我们得到了一个有n个点值对的点值表达,那我们可以确定唯一的一个次数界为n的多项式。
多项式乘法
- 考虑使用点值与插值来完成多项式乘法。
- 可以确定一组x,求得A与B的点值表达:
A:{(x0,y0),(x1,y1),...,(xn−1,yn−1)}
B:{(x0,y′0),(x1,y′1),...,(xn−1,y′n−1)}
- 我们可以得到C的点值表达:
C:{(x0,y0∗y′0),(x1,y1∗y′1),...,(xn−1,yn−1∗y′n−1)}
- 注意:若A和B的次数界均为n,则C的次数界为2n-1。所以我们要找出2n-1个x来求点值表达,否则无法插值。
算法流程
- 点值运算:分别构造A和B长度为2n-1的点值表达。
- 逐点相乘:计算出C的点值表达。
- 插值运算:通过C的点值表达求C每一项的系数。
- 显然,若随便选2n-1个数,按照上述方法进行点值运算、插值运算,时间复杂度依然是
O(n2)
。而FFT的关键就在于优化点值运算、插值运算的时间。
复数
- 复数应该妇孺皆知吧。复数z=a+bi的模长
l=a2+b2−−−−−−√
,记作|z|。
- 如图,当Z不是原点时,其与x轴正方向的夹角称为复数Z的辐角,记作ArgZ。
- Z可以表示成:
Z=|Z|(cos(ϕ)+isin(ϕ)),phi=ArgZ
。
- 上述表示负数的形式我们称为复数的三角表示。
- 由上图可得两个复数相乘的法则:模长相乘,辐角相加。
N次单位复数根
DFT——离散傅里叶变换
- 将A(x)中的x代入N次单位复数根(共N个),并定义结果y:
yk=A(ωkn)=∑n−1j=0ajωkjn
- y即为a的离散傅里叶变换(DFT)。记
y=DFTn(a)
。
分治策略
转载自blog.csdn.net/qq_36551189/article/details/81544620