ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-03-03 11:02:34  阅读:398  来源: 互联网

标签:系数 个点 多项式 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伪代码

3 interpolation 差值

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

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

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

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

 

 

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

标签:系数,个点,多项式,FFT,笔记,傅里叶,我们,乘法
来源: https://blog.csdn.net/qq_40206371/article/details/123243309

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有