博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【文文殿下】快速傅里叶变换(FFT)学习笔记
阅读量:5991 次
发布时间:2019-06-20

本文共 5917 字,大约阅读时间需要 19 分钟。

多项式

定义

形如\(A(x)=\sum_{i=0}^{n-1} a_i x^i\)的式子称为多项式。

我们把\(n\)称为该多项式的次数界。
显然,一个\(n-1\)次多项式的次数界为\(n\)

运算法则

\(A(x)\)\(B(x)\)为多项式,且次数界分别为\(n\),\(m\)。则有:

\(A(x)=\sum_{i=0}^{n-1}a_i x^i\)
\(B(x)=\sum_{i=0}^{m-1}b_i x^i\)

他们遵循下面的常用运算法则:

\(A(x)+B(x)=\sum_{i=0}^{max(n-1,m-1)} (a_i+b_i)x^i\)

\(A(x)-B(x)=\sum_{i=0}^{max(n-1,m-1)} (a_i-b_i)x^i\)
\(A(x)B(x)=\sum_{k=0}^{n+m-2}\sum_{i=0}^{k}a_i b_{k-i} x^k\)

两个多项式的乘积称为他们的卷积。卷积也是一个多项式。

易证次数界分别为\(n\),\(m\)的多项式的卷积是一个次数界为\(n+m-1\)的多项式。
用定义计算卷积的复杂度为\(O(n^2)\)
使用快速傅里叶变换,可以使复杂度降为\(O(nlogn)\)

复数

代数形式

形如\(a+bi\)形式的数称为复数。其中\(i\)\(\sqrt{-1}\)

我们可以使用平面上的点\((a,b)\)来描述一个复数。
复数的运算法则和向量相似。

三角形式

除了上文提到的代数形式,也有一种三角形式来表示复数。

如图所示。
12.bmp

我们知道复数\(a+bi\)对应着平面上的点\((a,b)\),也对应着复平面上的一个向量。

这个向量的长度叫做复数\(a+bi\)的模,记作\(|a+bi|\),通常用小写字母\(r\)表示。
这个向量与\(x\)正半轴有一个夹角,称为辐角,我们用希腊字母\(\theta\)表示。

显然有\(a=r\cos\theta\),\(b=r\sin\theta\)

把上式带入到代数表达式,可以得到\(a+bi=r\cos\theta+ir\sin\theta=r(\cos\theta+i\sin\theta)\)

定理:两复数相乘,模长相乘,辐角相加。

证明:
\(z_1=r_1(\cos x+i\sin x)\),\(z_2=r_2(\cos y+i\sin y)\).
\(z_1 z_2=r_1 r_2 [\cos x\cos y-\sin x\sin y+i(\cos x\sin y+\cos y\sin x)]=r_1 r_2[\cos(x+y)+i\sin(x+y)]\)

指数形式

欧拉公式:\(e^{i\theta}=\cos\theta+i\sin\theta\)

证明:
\(e^x\)\(\sin x\)\(\cos x\)按照泰勒展开得到他们的泰勒级数:
\(e^x=1+\frac{x}{1!}+\frac{x^2}{2!}+\frac{x^3}{3!}+…\)
\(\cos x=1-\frac{x^2}{2!}+\frac{x^4}{4!}-\frac{x^6}{6!}+…\)
\(\sin x=x-\frac{x^3}{3!}+\frac{x^5}{5!}-\frac{x^7}{7!}\)
\(x=i\theta\)带入得:
\(e^{i\theta}=1+\theta i-\frac{\theta^2}{2!}-\frac{\theta^3}{3!}i+\frac{\theta^4}{4!}+\frac{\theta^5}{5!}i-\frac{\theta^6}{6!}-\frac{\theta^7}{7!}i+…\)
\(e^{i\theta}=(1-\frac{\theta^2}{2!}+\frac{\theta^4}{4!}-\frac{\theta^6}{6!}+…)+i(\theta-\frac{\theta^3}{3!}+\frac{\theta^5}{5!}-\frac{\theta^7}{7!}+…)\)
\(e^{i\theta}=\cos\theta+i\sin\theta\)
将欧拉公式带入到三角形式的表达式中就能得到复数的指数形式表达式:\(z=r(\cos\theta+i\sin\theta)=re^{i\theta}\)

单位复数根

在复数域内,有且仅有\(n\)个数,使得这个数的\(n\)次方等于1,我们把这样的数称为单位复数根,记作\(\omega_{n}^{i} (i\epsilon [0,n-1])\)

\(\theta=2\pi\)带入欧拉公式,得\(e^{2\pi i}=1\)
所以\(\omega_{n}^{k}=(e^{\frac{2\pi i}{n}})^k\)
消去引理:\(\omega_{dn}^{dk}=\omega_{n}^{k}\)
证明:\(\omega_{dn}^{dk}=(e^{\frac{2\pi i}{dn}})^{dk}=(e^{\frac{2\pi i}{n}})^k=\omega_{n}^{k}\)

折半引理:\((\omega_{n}^{k})^2=\omega_{n/2}^{k}\)

证明:将\(d=\frac {1}{2}\)带入消去引理

求和引理:\(\sum_{i=0}^{n-1} (\omega_{n}^{k})^i=0\) (\(k\)不是\(n\)的倍数)

证明:利用等比数列求和公式,原式等于\(\frac{(\omega_{n}^{k})^n-1}{\omega_{n}^{k}-1}=\frac{0}{\omega_{n}^{k}-1}\)
因为分母不能为0,所以\(\omega_{n}^{k}\)不等于\(1\),所以\(k\)不是\(n\)的倍数.

循环性质:\((\omega_{n}^{k})^p=\omega_{n}^{pk}=\omega_{n}^{(pk\mod{n})}\)

证明:\(\omega_{n}^{kp}=\omega_{n}^{(kp\mod n+\left \lfloor \frac{kp}{n} \right \rfloor n)}=\omega_{n}^{(kp \mod n)}\)

对称性质:\(w_{n}^{k+\frac{n}{2}}=-w_{n}^{k}\)

证明:\(w_{n}^{k+\frac{n}{2}}=e^{\frac{2\pi ki}{n}+\pi i}=w_{n}^{k} e^{\pi i}=-w_{n}^{k}\)

离散傅里叶变换

多项式的两种表示方法

开头提到的多项式,都是用系数表达法来表示的。

也就是将次数界为\(n\)的多项式的系数\(a_0,a_1,…,a_{n-1}\)看成\(n\)维向量\(\vec{a}=(a_0,a_1,…,a_{n-1})\),\(\vec{a}\)称作多项式\(A(x)\)的系数表示。
事实上,除了系数表示\(A(x)=\sum_{i=0}^{n-1}a_i x^i\)还有一种表示方法:点值表示法。
一个次数界为\(n\)的多项式,就是\(n\)的点值对组成的集合。\((x_0,y_0),(x_1,y_1),…,(x_{n-1},y_{n-1})\) .对于\(0<=k<=n-1\),所有的\(x_k\)各不相同,记作\(y_k=A(x_k)\)
而离散傅里叶变换就是要快速求出多项式在这\(n\)的点的值

Cooley-Tukey算法

Cooley-Tukey算法是一种基于分治的算法

们取\(n\)\(n\)次单位根 \(w_{n}^{0},w_{n}^{1},…,w_{n}^{n-1}\) 进行求值:\(A(w_{n}^{k})=\sum_{i=0}^{n-1}a_i w_{n}^{ki}\)
向量\(\vec{y}=(A(w_{n}^{0}),…,A(w_{n}^{n-1}))\)称作\(\vec{a}=(a_0,…,a_n-1)\)的离散傅里叶变换
接下来我们按照奇偶分开来算:
\(A(w_{n}^{k})=\sum_{i=0}^{n-1}a_i w_{n}^{ki}\)
\(=\sum_{i=0}^{\frac{n}{2}-1}a_{2i}w_{n}^{2ki}+w_{n}^{k}\sum_{i=0}^{\frac{n}{2}-1}a_{2i+1}w_{n}^{2ki}\)
\(=\sum_{i=0}^{\frac{n}{2}-1}a_{2i}w_{\frac{n}{2}}^{ki}+w_{n}^{k}\sum_{i=0}^{\frac{n}{2}-1}a_{2i+1}w_{\frac{n}{2}}^{ki}\) (折半引理)
\(A(w_{n}^{k+\frac{n}{2}})=\sum_{i=0}^{\frac{n}{2}-1}a_{2i}w_{\frac{n}{2}}^{ki}-w_{n}^{k}\sum_{i=0}^{\frac{n}{2}-1}a_{2i+1}w_{\frac{n}{2}}^{ki}\)(对称性质)
这样问题就变成了求\(\frac{n}{2}\)个单位根的点值,问题的规模缩小了一半,所以是\(O(nlogn)\)的。

快速傅里叶变换的逆变换

求值与插值

对于一个多项式,如果知道它的系数表达式,我们很容易求出它的点值表达式,这一过程成为求值

如果知道它的点值表达式,让你求它的系数表达式,这一过程称为插值
定理:当插值多项式的次数界等于已知点值对的数目时,插值才是明确的
证明:\(y_k=A(x_k)\)等价于
11.bmp
其中,左边的矩阵称为范德蒙矩阵,其行列式\(Det=\prod_{0\leq j<k\leq n-1}(x_k-x_j)\)
如果所有\(x_k\)均不相等,那么其行列式不为\(0\),该矩阵可逆。
因此给定点值表达,能够唯一确定系数表达
所以如果我们知道了一个多项式的点值表示,就可以通过矩阵求逆的方法来算出系数向量
现在我们得到了点值表达式,那么如何求系数表达式呢?
矩阵求逆的复杂度是\(O(n^3)\)的,范德蒙矩阵求逆可以优化至\(O(n^2)\),但是复杂度依旧很高.
我们考虑构造一个现成的能算的东西进行优化

构造逆矩阵

我们现在已经得到了这样的方程:

14.bmp
记系数矩阵为\(V\),记下面的矩阵\(d_{ij}=w_{n}^{-ij}\)
15.bmp
它们相乘的结果\(E=DV\)满足\(e_{ij}=\sum_{k=0}^{n-1}w_{n}^{k(j-i)}\)
\(i=j\)时,\(e_{ij}=n\)
\(i\neq j\)时,\(e_{ij}=\sum_{k=0}^{n-1}(w_{n}^{(j-i)})^k=0\)(求和引理)
所以\(\frac{1}{n}D\)就是我们要求的逆矩阵,如下图:
16.bmp
这就相当于我们把单位复数根\(w^{k}_{n}\)换成\(w^{-k}_{n}\)再做一遍离散傅里叶变换结果除以\(n\)就行了

模板代码

#include
#include
#include
#include
const int maxn = 1200000;const double pi = acos(-1.0);struct Complex { double r,i; Complex(double r,double i):r(r),i(i){} Complex(){};};Complex operator + (Complex a,Complex b) { return Complex(a.r+b.r,a.i+b.i);}Complex operator - (Complex a,Complex b) { return Complex(a.r-b.r,a.i-b.i);}Complex operator * (Complex a,Complex b) { return Complex(a.r*b.r-a.i*b.i,a.r*b.i+b.r*a.i);}int n,m,L[maxn],R[maxn];Complex A[maxn<<1],B[maxn<<1];inline void read(int &x) { char ch=getchar();x=0; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}}inline void read(double &x) { char ch=getchar();x=0; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9') {x=10*x+ch-'0';ch=getchar();}}void fft(Complex *a,int n,int inv) { for(register int i=1,j=n/2;i
>1; while(j>=k) { j-=k;k>>=1; } j+=k; } for(register int j=2;j<=n;j<<=1) { Complex wn(cos(2*pi/j*inv),sin(2*pi/j*inv)); for(register int i=0;i
>1);k++) { Complex u=a[k],t=a[k+(j>>1)]*w; a[k]=u+t;a[k+(j>>1)]=u-t; w=w*wn; } } } if(inv==-1) for(register int i=0;i

转载于:https://www.cnblogs.com/Syameimaru/p/9950322.html

你可能感兴趣的文章
Linux常用命令——cut
查看>>
【2018版】Spring4.3入门视频课程——笔记(一)
查看>>
ls对文件进行按大小排序和按时间排序
查看>>
网页设计基础
查看>>
centos7下yum安装mysql
查看>>
简易系统的快速开发
查看>>
Yii2.0中rules验证的调试
查看>>
CPU 硬盘性能到底相差多少
查看>>
linux笔记(26)grep
查看>>
linux日常维护(iostat,free,ps,netstat,tcp三次握手,tcpdump)
查看>>
IPv6技术系列②——IPv6地址配置
查看>>
网络判断
查看>>
spring aop 注解通配符
查看>>
swap空间、lvm、磁盘故障案例
查看>>
ckeditor编辑的使用方法
查看>>
大数讯智能电销机器人,让电销从此变得轻松!
查看>>
JVM知识
查看>>
iBatis简单入门教程
查看>>
连载07:软件体系设计新方向:数学抽象、设计模式、系统架构与方案设计(简化版)(袁晓河著)...
查看>>
校园人脸识别门禁的实施方案有效隔离闲杂人员
查看>>