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伪代码

2.5 用公式表达FFT和iFFT

已知一个序列 ,我们可以用个傅里叶系数表示,其中第k项为

3 interpolation 差值

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

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

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

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

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

数学笔记:FFT(快速傅里叶变换)相关推荐

  1. FFT快速傅里叶变换 超详细的入门学习总结

    FFT快速傅里叶变换 说明 本文创作的目的是为自己巩固该算法,加深印象并深入理解,同时也为FFT入门学者提供一份可鉴的学习总结. 原文链接:https://blog.csdn.net/qq_39565 ...

  2. [MATLAB学习笔记]采用快速傅里叶变换求时间序列的周期项

    [MATLAB学习笔记]采用快速傅里叶变换求时间序列的周期项 1. 背景 现有长度为11年的5个时间序列,为某拟研究对象的5个参数.现计划先通过快速傅里叶变换求每个系数序列的显著周期项,再分别按照傅里 ...

  3. FFT快速傅里叶变换的应用——画单边频谱图matlab

    FFT快速傅里叶变换的应用--画单边频谱图matlab 快速傅里叶变换在数字信号处理里用的十分广泛,在matlab仿真中,处理信号的时频域变换十分有效,这里结合两个做过的仿真,来说一说fft的应用:画 ...

  4. 【经典算法实现 44】理解二维FFT快速傅里叶变换 及 IFFT快速傅里叶逆变换(迭代法 和 递归法)

    [经典算法实现 44]理解二维FFT快速傅里叶变换 及 IFFT快速傅里叶逆变换(迭代法 和 递归法) 一.二维FFTFFTFFT快速傅里叶变换 公式推导 二.二维FFTFFTFFT 及 IFFTIF ...

  5. FFT快速傅里叶变换C语言实现信号处理 对振动信号进行实现时域到频域的转换

    FFT快速傅里叶变换C语言实现信号处理 对振动信号进行实现时域到频域的转换,可实现FFT8192个点或改成其他FFT1024.4096等等,可以直接运行,运行结果与matlab运行的一致,写好了注释, ...

  6. c语言fft乘法步骤,C语言实现FFT(快速傅里叶变换).doc

    C语言实现FFT(快速傅里叶变换) 择蚁牙幸帆揣邓淌港烬粹甩滋整维含兔忿茂慨渔下餐随扼哇房坏鹅穆礼围引介害芝共茨恿把喜恤寇杖除冕嗓停揍猫调锚遭傀个碱晓频斌硕宾撕坪莱哩腊养掘蹄轴国繁蔬虞靡砖焙倍勾呸怀怒 ...

  7. 快速傅里叶变换c语言函数,C语言实现FFT(快速傅里叶变换)

    while(1); } #include #include /********************************************************************* ...

  8. 如何 FFT(快速傅里叶变换) 求幅度、频率(超详细 含推导过程)

    目录 如何 FFT(快速傅里叶变换) 求幅度.频率(超详细 含推导过程) 一. 打颗栗子 二. 求幅度 1. 快速傅里叶变换 2. 求出复数的绝对值 3. 归一化 小结 三. 求频率 1. 频率公式 ...

  9. FFT 快速傅里叶变换 初探

    一直认为很高深的东西其实也并不很难. 以下内容部分来自qy大神的ppt,同时结合了自己的理解.但理解还不是很深,需要继续研究. 开头 首先什么是傅里叶变换:傅立叶变换能将满足一定条件的某个函数表示成三 ...

  10. 【算法竞赛学习笔记】快速傅里叶变换FFT-数学提高计划

    tilte : 快速傅里叶变换FFT学习笔记 tags : ACM,数论 date : 2021-7-18 简介 FFT(Fast Fourier Transformation),中文名快速傅里叶变换 ...

最新文章

  1. zookeeper(一):功能和原理
  2. Python 骚操作:如何给你爱的读者每天发早报?
  3. Step by step通过online方式做product archiving
  4. Swoole入门指南:PHP7安装Swoole详细教程(一)
  5. ※※Java调用Runtime.exec()要注意的问题
  6. 内存超频时序怎么调_电脑内存条专业科普,内存选购、内存品牌、内存安装、内存时序体质、内存超频频率详细讲解...
  7. 使用ASP.NET Core,JavaScript,PostegreSql和ChartJs的动态仪表板Web应用程序
  8. 生成n*n蛇形矩阵的算法
  9. 联想i微型计算机怎么拆,联想t410i如何拆机?联想t410i拆机方法【图文】
  10. Fedora 9安装vmware tools解决方案
  11. 基于 Roslyn 实现代码动态编译
  12. 【贵州大学计算机考研1】三本学生考研上岸贵州大学软件工程专硕(附带真题与答案)
  13. 读书笔记—产品型社群:互联网思维的本质
  14. 如何修改背景色?证件照背景颜色怎样换成白色?
  15. 卡贴机变无锁教程_如何让“有锁”iPhone变“无锁”?“有锁”iPhone变“无锁”设置教程...
  16. PT项目-SAP库存账龄分析报表
  17. 从事Web前端相关的工作应该掌握哪些职业技能?
  18. ewebeditor文件上传漏洞2.8.0版本(漏洞复现)
  19. 程序员求职之道(《程序员面试笔试宝典》)之走进微软
  20. 图论复习之强连通分量以及缩点—Tarjan算法

热门文章

  1. 统一依赖管理Composing builds
  2. 【博学谷学习记录】超强总结,用心分享|产品经理需求分析方法简析
  3. 业务消息中心系统设计与实现(一)
  4. SQL基础培训13-索引和优化
  5. Golang: glog 的使用
  6. 7.3 习而学与CDIO,来自工程教育思想的启示——《逆袭大学》连载
  7. 靠一碗面一年三轮融资受资本热捧,张拉拉真的高枕无忧?
  8. 【论文发表】认识SCI、EI、ISTP、IEEE等和算法论文
  9. SSD固态硬盘优化方案,让新买的SSD速度不再慢
  10. 【9505】部落卫队