fft算法
前言
由于本人学习FFT时第一份代码并不是从普通的FFT学起的,而是直接从一个经过优化的版本开始学。
这是一个利用到共轭复数性质的优化,出自myy的论文,但在网上缺乏关于这个优化的文章,有写的都是大神,没有很细致的讲解。因此我决定自己总结一下。
本文是在默认读者了解并掌握了FFT算法的情况下写的。没有学过FFT的同学可以先去学一下。
FFT的基本运算
记 ωN 表示 eN2πi 。
对于给定的多项式函数
f(x)=i=0∑naixi
记 X 为 f 的 DFT ,则有
Xi=j=0∑N−1ajωNij,ai=N1j=0∑N−1XjωN−ij
以及我们知道的卷积定理
DFT(f⋅g)=DFT(f)⋅DFT(g)DFT(f+g)=DFT(f)+DFT(g)
还有各种各样的复数运算法则,都是本文的前置技能。
其中复数运算法则中有一条性质:
z1z2=zˉ1⋅zˉ2
其中 aˉ 表示 a 的共轭复数。
这是我们优化FFT算法需要用到的重要性质。
如何优化?
考虑到 DFT 的对称性,我们来比较一下 Xi 以及 XN−i :
Xi=j=0∑N−1ajωNijXN−i=j=0∑N−1ajωN(N−i)j=j=0∑N−1ajωN−ij=Xi
咦??求出 Xi 就知道 XN−i 了?那用 N 的长度做岂不是很浪费??
为什么 Xn−i=Xi 呢?实际上这是由于我们的多项式函数的系数并没有虚部造成的。我们换一个系数有虚部的函数看看。
设
f(x)=i=0∑n(ai+ibi)xi
这里可能变量名重了= =,考虑到惯用的表达方式,我们约定此文以下部分中上下标的 i 表示变量,其余位置表示虚数单位。
Xi=j=0∑N−1(aj+ibj)ωNijXN−i=j=0∑N−1(aj+ibj)ωN(N−i)j=j=0∑N−1(aj+ibj)ωN−ij=Xi
这时候上面的等号就不成立了。但我们依然可以使用共轭复数的性质对比 XN−i 和 Xi :
XN−i=j=0∑N−1(aj+ibj)ωNij=j=0∑N−1(aj−ibj)ωNij
这个结果相当美妙。我们将 Xi 与 XN−i 相加减,可以得到:
Xi+XN−i=2j=0∑N−1ajωNijXi−XN−i=2ij=0∑N−1bjωNij
也就是说,我们只要对 f 做了 DFT ,就可以在 O(n) 时间内得到其实部和虚部分别做 DFT 的结果。
因此对于任意一个系数为实数的多项式
f(x)=i=0∑naixi
我们可以将其改写为
f(x)=i=0∑⌊2n⌋(a2i+ia2i+1)xi
以提高我们的时空效率。
当然也可以不按这种方法拆开,但这种拆分方式有利于之后的多项式乘法优化。
在多项式乘法上的应用
FFT 最大的应用是解决多项式乘法的问题,我们将这个优化回归应用到多项式乘法上。
普通的多项式乘法
对于两个函数
f(x)=i=0∑naixi,g(x)=i=0∑mbixi
我们当然可以用上面的方式把 f 和 g 的奇偶项的 DFT 分别乘起来再分别做 IDFT 得到 f⋅g ,但这样我们的优化就失去了实用价值。我们考虑怎样使用更少的 IDFT 次数得到原函数。
我们已经将 f,g 改写成了以下形式:
f(x)=i=0∑⌊2n⌋(a2i+ia2i+1)xi,g(x)=i=0∑⌊2m⌋(b2i+ib2i+1)xi
我们的目标函数为
h(x)=i=0∑⌊2n+m⌋j=0∑i(a2jb2(i−j)+a2j+1b2(i−j)−1+i(a2jb2(i−j)+1+a2j+1b2(i−j)))xi
记 X,Y,Z 为 f,g,h 的 DFT 。
Xi=j=0∑N−1(a2j+ia2j+1)ωNij,Yi=j=0∑N−1(b2j+ib2j+1)ωNijZi=j=0∑N−1k=0∑j(a2kb2(j−k)+a2k+1b2(j−k)−1+i(a2kb2(j−k)+1+a2k+1b2(j−k)))ωNijXiYi=j=0∑N−1k=0∑j(a2kb2(j−k)−a2k+1b2(j−k)+1+i(a2kb2(j−k)+1+a2k+1b2(j−k)))ωNij
对比括号里的四项我们发现只有一项不同,我们将两式相减:
Zi−XiYi=j=0∑N−1k=0∑j(a2k+1b2(j−k)−1+a2k+1b2(j−k)+1)ωNij=j=0∑N−1k=0∑ja2k+1b2(j−k)−1ωNij+j=0∑N−1k=0∑ja2k+1b2(j−k)+1ωNij=j=0∑N−1k=0∑ja2k+1b2(j−k)+1ωNi(j+1)+j=0∑N−1k=0∑ja2k+1b2(j−k)+1ωNij=(1+ωNi)j=0∑N−1k=0∑ja2k+1b2(j−k)+1ωNij=−4(1+ωNi)(Xi−XN−i)(Yi−YN−i)
这里利用到了上面的结论
Xi−XN−i=2ij=0∑N−1a2j+1ωNij
因此
Zi=44XiYi−(1+ωNi)(Xi−XN−i)(Yi−YN−i)
这样我们做多项式乘法就可以把时空效率都提高一倍了,从原先的3次FFT优化到1.5次FFT,并且该做法的精度上优于普通的FFT。
对任意模多项式乘法的优化
我们知道任意模多项式乘法有8次和7次 DFT 的做法,直接套上上面的做法就可以优化到4次或3.5次。此外还有一种更好写的4次做法:
将 a 拆成 A1,A2 , b 拆成 B1,B2 ,并构造
f(x)=i=0∑n(A1,i+iA2,i)xi,g(x)=i=0∑m(B1,i+iB2,i)xi
分别做 DFT 之后算出 A1B1,A1B2,A2B1,A2B2 的DFT 分别存进两个数组的虚部和实部最后合并。
作为黑科技还是很值得一用的。
(第一次写blog,写得不好,可能还有写挂的地方,求轻喷)
相关阅读
MMR算法学习
MMRMMR的全称为Maximal Marginal Relevance ,中文名字为最大边界相关法或者最大边缘相关。在MMR的公式是这样的,截图来自http://www
判断素数最有效的算法
目录
定义
1 常规方法判断
2 最有效方法判断
3 测试
定义
约数只有1和本身的整数称为质数,或称素数。
1 常规方法判断
根据定义
遗传算法原理及算法实例
遗传算法原理解析
遗传算法(GA)是一种元启发式自然选择的过程,属于进化算法(EA)大类。遗传算法通常是利用生物启发算子,如变异、交叉和
实时系统动态内存算法分析dsa(二)——TLSF代码分析
上一篇我们看了dsa的分类和简单的内存管理算法实现,这篇文档我们来看TLSF的实现,一种更加高级的内存管理算法;一、实现原理
基本的Se
AI产品经理必懂算法:支持向量机SVM
作为AI产品经理必懂算法的第二篇,来了解一下支持向量机SVM算法,英文全称是“Support Vector Machine”。在机器学习中,SVM是监督学习