数学笔记:FFT(快速傅里叶变换)

0 前言

FFT是一个很厉害的算法,几乎任何和信号处理有关的算法都依赖于FFT

0.1 引入:多项式的系数表示法

我们从一个简单的问题中引入FFT:

给定两个多项式,我们希望去计算二者的乘积

中学的时候我们学过,展开相乘就可以了

但是在计算机里面,一个很重要的问题是,如何存储一个多项式?

显然,最自然的方法就是存储多项式的系数,我们把系数映射到一个列表中,这样列表中第k个数字正好对应第k阶系数——>这种表示方法,即是多项式的系数表示法

         一般来说,给定两个d阶的多项式,二者的乘积应该是2d阶的多项式,所以如果用naive的乘法分配律来计算,时间复杂度应该是\large O(d^2)【多项式A中的每一项都会跟多项式B中的所有项分别相乘】

那么问题来了,这个算法可以更快一点吗?

0.2 多项式的数值表示法

我们知道,任意的d阶多项式,可以由d+1个点唯一确定

        即对于一个p阶多项式

p+1个点确定了之后,多项式的系数可以唯一确定

 证明如下:

        我们将这d+1个点带入多项式中,得到d+1个方程

 将其转化为矩阵&向量的形式 

 

         我们可以发现,只要这d+1个x不一样,那么矩阵始终可逆(该矩阵对应的行列式为范德蒙行列式)

 于是我们得到了多项式的两种表示方法:

 利用值表示法,多项式乘法就变得很简单:

我们知道了乘法之后的阶数为4维,于是我们分别在A(x)和B(x)上取5个点,然后将对应每个点的两个值相乘,得到C在每个点的函数值 。然后根据前面的证明,我们知道,这五个点唯一决定了这个乘积多项式的系数

于是我们不难发现,使用值表示法之后,计算多项式乘法的时间,从原来的\large O(d^2)缩短至O(d)

 0.3 多项式乘法的框架

于是我们就可以得到多项式乘法的新框架了:

给定两个d阶多项式,我们已经知道了值表示法计算多项式乘法计算多项式乘法更快,所以我们可以先计算两个多项式在2d+1个点上的值

然后将函数值一对一对乘起来,从而得到乘出来的多项式的值表示

然后,最后一步需要做的是,把值表示转换回系数表示

 但问题在于,我们如何把系数形式转换成值表示形式?与此同时,如何把值表示形式转化为系数表示形式?这个就是FFT考虑的内容了

1 求值 evaluation

我们先关注从系数表示到值表示的方向

给定d阶多项式和n个点(n≥d+1),我们想计算多项式在这n个点上的值,最简单粗暴的方法就是随便挑选n个点,一个一个地计算函数值

但是这样的问题在于,每一个点的计算都是O(d)的时间复杂度,加起来的时间复杂度还是\large O(nd)\ge O(d^2)——>这样的话,相当于啥都没做

对于奇函数和偶函数,我们可以取一对一对的相反数,这样可以减少一半的采样点

 

对于一般的函数,我们可以将其分成奇函数+偶函数的形式

然后我们将奇函数的x提出来,得到两个偶函数的形式 

 我们将两部分都看成\large x^2的函数,于是可以发现Pe和Po的阶数都降到了原先的一半

 那么,对于\large P_e(x^2)\large P_o(x^2),这两个又是两个求值问题

而我们一开始取的是一对一对的相反数,所以这里只剩下一半的点了(n/2)

 2.1 FFT总结?

 我们可以看出来,这是一个递归的思想

总结一下就是,我们想计算多项式P在n个点上的值,这n个点是一对一对的相反数

 我们将多项式分成两个部分(两个阶为n/2-1的多项式),每个多项式只需要求n/2个点的值

我们只需要递归地求解这两个分多项式的值,就可以得到原多项式的n个值

 

如果这一切可行,那么我们的时间复杂度是O(nlogn)【每一层对应点的值相乘还是n,只不过现在从上到下,每一层阶数减半,故只有logn层】

 2.2 引入复数的概念

 但是至此为止,还是有一个小问题,就是从第一次迭代开始,\large P_e(x^2)\large P_o(x^2)只能取正值,但我们希望新的求指点也可以是相反数

于是我们在这里引入了复数的概念

 1的n次方根,用图像表示,可以解释为在复平面上沿着单位元等距排布的一系列点,其中任意两点之间的夹角为\large \frac{2\pi}{n} 

 2.2.1 欧拉公式

 用欧拉公式,可以很简单地表达这些点:

所以我们找的值就是1,ω,...\large \omega^{n-1}

 2.3 FFT总结!

  • FFT算法的输入是多项式的n个系数\large p_0,\dots,p_{n-1},其中n是2的幂(也可以不是,只不过复杂一些)
  • 我们取\large \omega=e^{\frac{2\pi i}{n}} 为1的n次方根 (最底层的递归情况是P(1))
  • 递归的主要命令,就是把多项式拆分成奇函数和偶函数的部分,两部分分别调用函数。此时两个子多项式函数都是n/2阶的,所以对应的求值点是1的n/2次方根
  • 我们假设得到的两部分结果为ye和yo,那么我们可以把这两部分函数值结合一下,计算出原多项式函数在对应点的函数值

  • 结合的核心思想是利用正负对,不过这里我们是n次方根,所以稍作修改

 与此同时,我们知道\large -\omega^j=\omega^{j+\frac{n}{2}},于是再做修改

 同时,我们又有

于是进一步,可以写成

 

 2.4 FFT伪代码

2.5 用公式表达FFT和iFFT

已知一个序列(x_0,\cdots,x_{N-1}) ,我们可以用\lfloor N/2 \rfloor +1个傅里叶系数表示,其中第k项为

3 interpolation 差值

 实际上差值和求值是紧密联系的,我们之间将求值问题表示为矩阵-向量 乘积

因为FFT中的x是1的n次方根,所以可以改写为

 这个矩阵被称为离散傅里叶变换矩阵DFT

而我们的差值,即取逆即可

 

 

参考资料:The Fast Fourier Transform (FFT): Most Ingenious Algorithm Ever? - YouTube 

  • 21
    点赞
  • 126
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UQI-LIUWJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值