快速傅里叶变换初步

来源:互联网 发布: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的力作为例题会详细讲解。

0 0
原创粉丝点击