快速傅里叶变换初步
来源:互联网 发布:java android开发 编辑:程序博客网 时间:2024/05/17 21:54
快速傅里叶变换。。一个曾经遥不可及的东西。。
昨天晚上心血来潮看了一个小时,今天早上正好又没有联考。。把这道题实现了一下
首先普及一下快速傅里叶变换的知识。。看了以后,这道题真的是好裸的模板题啊。。
首先,对于一个多项式A(x),我们带入一个x0,得到一个A(x0)=y0,那么(x0,y0)就是一个点值。
由算导上的证明:一个次数为n的多项式系数可以被对应的n个点值表达式确定。
点值表示有一个优势,其乘法效率为线性!!
系数表达式转点值表达式,也就是传说中的DFT。如果随便取值并计算,连变换都要N^2的效率,谈何优越。
根据这n个点值只要彼此不同就可以。我们不妨找到某种特殊的带入值,让我们可以从A(x)得出的值推出其他和A(x)有关的点值。
这时候单位复数根wn派上用场了。我们设wn=cos(2π/n)+sin(sπ/n) i,它是一个复数。且wn^n=1
它有一个美妙的性质。|wn^(k+n/2)|=|wn^k|,证明也不难,(wn^(k+n/2))^2=wn^(2k+n)=wn^2k*wn^n=wn^2k=(wn^k)^2
这个引理称为折半引理。事实上这个引理是n^2到nlogn的一个关键。
wn^(k+n/2)既然有这么美妙的性质,A(wn^(k+n/2))和A(wn^k)是不是也存在某种关系呢?
答案是肯定的。
对于
A(x)=a0+a1x+a2x^2+a3x^3...+an-1x^(n-1)
我们把其分成两个部分
A[0](x)=a0+a2x+a4x^2+...+an-2x(n/2 -1)
A[1](x)=a1+a3x+a5x^2+...+an-1x(n/2 -1)
于是有
A(x)=A[0](x^2)+xA[1](x^2)
于是我们的问题变成了求A[0]和A[1]在
(wn^0)^2 (wn^1)^2 ... (wn^(n-1))^2
的取值
于是折半引理派上用场了。
A[0]((wn^(k+n/2))^2)=A[0]((wn^k)^2)
A[1]((wn^(k+n/2))^2)=A[1]((wn^k)^2)
事实上由复平面的性质,我们发现wn^(k+n/2)=-wn^k;
那么
A(wn^(k+n/2))=A[0]((wn^k)^2)-wn^kA[1]((wn^k)^2)
A(wn^k)=A[0]((wn^k)^2)+wn^kA[1]((wn^k)^2)
假设我们对于这一层暴力计算,那么O(N)之后
我们好像一下子得到了A(wn^(k+n/2))和A(wn^k)两个值。
但是我们显然不会暴力计算,对于A[0]和A[1]存在和A一样的形式,继续递归!
每一次求值都可以将问题折半化,那么n变成logn也就不是梦了
点值形式的解求好了,要变换回去的呀,于是逆DFT登场。
不难发现这不过就是矩阵求逆的问题。详见算导P535矩阵图。
aj=1/n Sigma(yk*wn^(-kj))
再看看我们做DFT时的式子
A(wn^k)=Sigma(aj*wn^kj)
我们完全可以把上下两式当做同一类型的变换!
所以事实上只要对函数稍作修改,就可以实现DFT和逆DFT两种操作了。
讲到这里。其实递归版已经可以实现了,但是慢!怎么办?
在之后的zjoi2014的力作为例题会详细讲解。
- 快速傅里叶变换初步
- 快速傅里叶变换-快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 初步理解傅里叶变换
- 快速傅里叶变换(FFT)(ZZ)
- 实序列快速傅里叶变换
- FFT快速傅里叶变换;
- 快速傅里叶变换(FFT)
- 国庆期间遇到两个诈骗团伙
- uboot编译全程
- Android打开各种类型的文件方法总结
- 一个由数组越界引发的。。。
- 禅道 linux用一键安装包
- 快速傅里叶变换初步
- Java表达式、流控制、数组、字符串和类、对象、包、接口——Java学习笔记(三)
- MyReport报表引擎2.7.6.7新功能
- block 存储循环
- dalvik虚拟机寄存器
- shared_ptr智能指针源码剖析
- [动态规划]PKU Bridging signals
- mongoDB启动项的配置详细步骤(图文配置讲解——一目了然)
- POJ2181