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

Posted UQI-LIUWJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数学笔记:FFT(快速傅里叶变换)相关的知识,希望对你有一定的参考价值。

0 前言

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

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

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

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

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

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

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

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

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

0.2 多项式的数值表示法

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

        即对于一个p阶多项式

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

 证明如下:

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

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

 

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

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

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

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

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

 0.3 多项式乘法的框架

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

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

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

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

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

1 求值 evaluation

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

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

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

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

 

 

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

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

 

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

 那么,对于,这两个又是两个求值问题

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

 2.1 FFT总结?

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

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

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

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

 

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

 

 2.2 引入复数的概念

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

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

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

 2.2.1 欧拉公式

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

所以我们找的值就是1,ω,...

 2.3 FFT总结!

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

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

 与此同时,我们知道,于是再做修改

 同时,我们又有

于是进一步,可以写成

 

 2.4 FFT伪代码

3 interpolation 差值

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

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

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

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

 

 

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

以上是关于数学笔记:FFT(快速傅里叶变换)的主要内容,如果未能解决你的问题,请参考以下文章

快速傅里叶变换(FFT)详解

scipy笔记:FFT

快速傅里叶变换fft

笔记篇(理论向)快速傅里叶变换(FFT)学习笔记w

快速傅里叶变化(FFT)含模板

快速傅里叶变换(FFT)