快速傅里叶变换(FFT)算法学习

这篇具有很好参考价值的文章主要介绍了快速傅里叶变换(FFT)算法学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

人生如逆旅,我亦是行人。


一、介绍

快速傅里叶变换(FFT)算法学习

算法的世界多么广大,我们可以将算法大致分为两类:

  • 第一类是较为有用的算法:比如一些经典的图算法,像 DFS 和 BFS(深度 / 广度优先算法),这些算法应用在很多方面,他们非常高效,
    快速傅里叶变换(FFT)算法学习

  • 第二类算法是那些极具美感的算法:例如当我们第一次看到汉诺塔的递归实现算法时的状态,你肯定会觉得这个算法贼牛逼,甚至会被它的美感所震撼到,但这些算法或许并没有那么有用或者高效,不过我们还是会研究它,就像没事干了我们还是会看小说;
    快速傅里叶变换(FFT)算法学习

这些伟大而精妙的算法会激发我们的灵感,促使我们发散性思考,下面介绍一种同时属于以上两类的算法:快速傅里叶变换(FFT)。

FFT 算法毫无疑问是上个世纪发明的最伟大的算法之一。很多我们现代生活所依赖的科技,比如无线通讯和 GPS ,以至于任何和信号处理有关的算法,都依赖于 FFT 的深刻洞见。

人们常常不能感知 FFT 的美感,因为它常常有很长很长的前置知识要求, 比如离散傅里叶变换、时域/频域转换、甚至更多。

yysy(有一说一),想要真正搞清 FFT 的应用,你也不得不把这些前置要求都学好。

快速傅里叶变换 ( fast Fourier transform ), 即利用计算机计算离散傅里叶变换(DFT)的高效、快速计算方法的统称,简称 FFT


二、学习

  • 简单的问题:给定两个多项式,计算二者的乘积。
  • 我们的任务就是设计高效的算法解决这个问题。
    快速傅里叶变换(FFT)算法学习
  1. 数学上,这个问题可以直接通过重复使用乘法分配律解决。
    快速傅里叶变换(FFT)算法学习
    但是在计算机中,首先需要解决的问题是,如何存储一个多项式?
  • 显然,最自然的做法就是储存多项式的系数。我们只需要把系数映射到一个数组中。

系数应该按如下图所示的顺序储存。

因为这样一来数组的第 k 个数字正好对应多项式的 k 阶项系数。

这种表示方法为多项式的系数表示方法。

快速傅里叶变换(FFT)算法学习

一般情况下,给定两个 d 阶多项式,二者乘积应为 2d 阶多项式。

并且这一算法,如果用 naive 的乘法分配律来算,时间复杂度为 O(d ^ 2) 。因为多项式 A 的每一项都会跟多项式 B 的每一项相乘。

如何改进这个算法?

快速傅里叶变换(FFT)算法学习


例子

我们以最简单的多项式,即一阶多项式/线性函数为例。

快速傅里叶变换(FFT)算法学习

我们可以用两个系数来表示线性函数,即截距(0阶系数)和斜率(1阶系数)(注:一对系数一对一决定了唯一的一条直线),还有没有别的直线的表示也可以唯一确定一个直线呢?

表示其实很多,我们这里使用直线的两点表示。

  • 美丽的几何学告诉我们:两点确定一条直线。

  • 事实上:高阶多项式也有类似的性质。 (即:任意 d 阶多项式都由 d+1 个点唯一确定的

快速傅里叶变换(FFT)算法学习

例如下图中的三个点确定了左边这个二次函数:

快速傅里叶变换(FFT)算法学习
如果图中有四个点,那么我们就能确定左边这个唯一的三次函数:

快速傅里叶变换(FFT)算法学习
接下来证明一下这个结论:

  • 假设我们有 p(x) 这个 d 阶多项式,通过了给定的 d+1 个点,我们需要证明:系数是唯一
  • 因此,我们将这 d+1 个点带入多项式的方程,得到 d+1 个方程。线性方程组当然可以写作 矩阵-向量 表示。
    快速傅里叶变换(FFT)算法学习
  • 矩阵 M 可逆,只要这些 点 x_0、… 、x_d 不重复(即两两都不同(下面为 范德蒙德矩阵)),只需证明 M 的行列式不为零(范德蒙德行列式
    快速傅里叶变换(FFT)算法学习
    从而我们知道系数p_0、… 、p_d 是被 d+1 个点唯一确定的,从而多项式也是唯一的。

我们现在有两种表示多项式的方法:

  • 第一种是系数表示法;
  • 第二种是 d+1 个点表示法,称为值表示法;(利用值表示法,多项式乘法变得不能再简单了)

快速傅里叶变换(FFT)算法学习


回到之前的问题

快速傅里叶变换(FFT)算法学习
乘出来的多项式 C(x)必然为 4 阶,所以需要 5 个点表示。我们现在只需要挑出五个点并计算已有的两个多项式的值,然后把对应每个点的两个值相乘,得到 C 在每个点的函数值。

快速傅里叶变换(FFT)算法学习

根据我们前面的学习,五个点可以确定唯一的多项式,

快速傅里叶变换(FFT)算法学习

这个多项式的系数表示我们也算出来了,利用值表示法,我们计算多项式乘法的时间一下子从 O(d^2)缩短到了 O(d)。

接下来开始快速的多项式乘法算法了。


问:

  • 给定两个系数表示的 d 阶多项式,我们已经知道了值表示法计算多项式乘法更快,所以我们可以先计算两个多项式在 2d + 1 个点上的值,然后将函数值一对对地乘起来,从而得到乘出来的多项式的值表示,最后,将值表示转换回系数表示。

快速傅里叶变换(FFT)算法学习

  • 主要的方法我们大致已经清楚,现在的问题在于还有些步骤我们没搞清楚,
  • 事实上我们缺的就是:如何将系数转换成值表示,以及反过来,如何将值表示转换成系数?
  • 这一过程,实际上就是 FFT 重要之处。

四、求值(evaluation)

让我们先关注一个方向:从系数表示到值表示。这个问题称为求值(evaluation)。

给定 d 阶多项式和 n 个点,我们想计算多项式在这 n 个点上的值(n >= d+1)

  • 我们可以采取粗暴的方式:直接在 x 轴上挑取 n 个点,一个一个计算函数值,但是如果这样计算的话,将会变得十分麻烦。 即每个点的计算都是 O(d),加起来还是 O(nd) >= O(d^2)。这样问题又变得像最初那样复杂,现在的问题是能不能整点更快的?

快速傅里叶变换(FFT)算法学习

  • 将问题简化一下:考虑一个简单的多项式,比如:P(x) = x ^ 2,在 n=8 个点进行求值。
  • 那么问题又来了,我们选那八个点更具有代表性呢?
  • 有没有这样的一对点:当你知道一个点的函数值时,另一个点的也可以立刻知道?
  • 答案是:互为相反数的数对。(前提是:函数 P 是一个偶函数)

快速傅里叶变换(FFT)算法学习

  • 如果是 P(x) = x^3 咋办,?
  • 事实上这个技巧依旧是对的,不过我们要在 -x 的函数值前面加个负号,

快速傅里叶变换(FFT)算法学习

  • 所以在这两个偶/奇函数的情形中,我们只需要计算一半数量的点就好了,因为剩下一半从奇偶性中就可以的得到了。

再来看看奇偶这个点子对一般的多项式还适不适用,将多项式分成奇/偶函数两个部分,把奇函数部分的 x 提出来一个,那么两个括号里都是两个偶多项式函数。

快速傅里叶变换(FFT)算法学习

这样的分解使得我们对于一对相反数计算函数值时,只需要计算其中一个,同时我们可以把两部分都看作 x^2 的函数,你可以看到两个子函数的阶数都降到了 2,比原来的 5 阶不知道高到哪去了。

快速傅里叶变换(FFT)算法学习

  • 推广这一想法,如果我们有一个 n-1 阶多项式,我们想计算它在 n 个点的函数值,我们可以将多项式分为 奇 / 偶两部分,每部分都只有 n/2 - 1 阶
  • 对于这两个只有一半阶的多项式,我们怎么计算他们在对应点的值呢? 这又是一个求值问题,不过这次我们需要计算我们所给的点的平方的函数值。因为我们一开始取了一对对相反数,所以平方之后正好只剩 n/2 个点了,有没有一点像递归算法。
  • 总结:计算多项式 P 在 n 个点上的值,这 n 个点是一对对的相反数。我们把多项式分成(如上所述)的两个部分,从而我们有两个阶为 n/2 - 1 的多项式,每个多项式也只需要求 n/2 个点的值。我们只需要递归地求这两个小多项式的值,利用下方这两个公式带回去,就可以得到原多项式的 n 个的值。最后我们就得到了原多项式的值的表达。

快速傅里叶变换(FFT)算法学习

如果上述的一切都行得通,那么我们的时间复杂度仅为 O(nlogn) ,因为两个子问题都是原问题规模的一半,而且我们只需要线性时间来计算原多项式的值。

  • (一个问题)在递归步骤:我们假设了每个多项式我们都使用相反数来对其进行求值。注意对子问题而言,每个求值点都是平方数,所以都是正的,递归不成立。
  • 如何将新的求值点也搞成相反数对?
  • 唯一的方法:就是将这些点都取成复数。这也正是 FFT 算法最奇思妙想的地方。

我们需要专门挑一些复数,使得它们平方之后,依旧是正负成对出现的。

现在又有一个问题来了:该怎么取这些复数呢?


快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习
快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

  • 我们可以通过一个逆向工程来得到答案。

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习
快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习

快速傅里叶变换(FFT)算法学习
快速傅里叶变换(FFT)算法学习文章来源地址https://www.toymoban.com/news/detail-447191.html

到了这里,关于快速傅里叶变换(FFT)算法学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MATLAB——FFT(快速傅里叶变换)

    基础知识 FFT即快速傅里叶变换,利用周期性和可约性,减少了DFT的运算量。常见的有按时间抽取的基2算法(DIT-FFT)按频率抽取的基2算法(DIF-FFT)。 1.利用自带函数fft进行快速傅里叶变换 若已知序列 x = [ 4 , 3 , 2 , 6 , 7 , 8 , 9 , 0 ] x=[4,3,2,6,7,8,9,0] x = [ 4 , 3 , 2 , 6 , 7 , 8 , 9 , 0 ]

    2024年02月03日
    浏览(62)
  • 快速傅里叶变换(FFT)c语言实现

    基本原理在这里就不多讲了,可以看看其他高浏览量的博文,这篇文章针对c语言的实现         我们都知道C语言本身是没有复数运算的,很多DSP、单片机要用到也没有开源库可以使用复数运算,针对FFT在硬件上运行只能手动从底层开始 定义复数类型         这里用最简单

    2023年04月15日
    浏览(38)
  • 快速傅里叶变换(FFT)的频谱分辨率

    快速傅里叶变换Fast Fourier Transform (FFT)是快速计算离散傅里叶变换的一种算法,是我们在编程时进行傅里叶变换的主要方法。 FFT的输入与输出的个数一致,比如对于长度为1024的一维向量,其输出也为长度为1024的一维向量。而根据Nyquist-Shannon 采样定律,当采样率 为1Mhz(每秒

    2024年02月13日
    浏览(39)
  • Python中利用FFT(快速傅里叶变换)进行频谱分析

    本文将从实例的角度出发讲解fft函数的基本使用,不包含复杂的理论推导。 要对一个信号进行频谱分析,首先需要知道几个基本条件。 采样频率fs 信号长度N(信号的点数) 采样频率fs: 根据采样定理可知,采样频率应当大于等于被测信号里最高频率的2倍,才能保证不失真

    2024年01月17日
    浏览(40)
  • Matlab信号处理3:fft(快速傅里叶变换)标准使用方式

    运行效果:

    2024年02月09日
    浏览(36)
  • 基于STM32&FFT(快速傅里叶变换)音频频谱显示功能实现

    + v hezkz17进数字音频系统研究开发交流答疑 一实验效果   二 设计过程 要用C语言实现STM32频谱显示功能,可以按照以下步骤进行操作: 1 确保已经安装好了适当的开发环境和工具链,例如Keil MDK或者GCC工具链。 2 创建一个新的STM32项目,并选择适合的MCU型号。 3 配置GPIO引脚用

    2024年02月12日
    浏览(31)
  • 【快速傅里叶变换(fft)和逆快速傅里叶变换】生成雷达接收到的经过多普勒频移的脉冲雷达信号(Matlab代码实现)

     💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 本文的

    2024年02月10日
    浏览(36)
  • 【MATLAB】全网唯一的13种信号分解+FFT傅里叶频谱变换联合算法全家桶

    有意向获取代码,请转文末观看代码获取方式~ 大家吃一顿火锅的价格便可以拥有13种信号分解+FFT傅里叶频谱变换联合算法,绝对不亏,知识付费是现今时代的趋势,而且都是我精心制作的教程,有问题可随时反馈~也可单独获取某一算法的代码(见每一算法介绍后文)~ EMD 是

    2024年02月05日
    浏览(46)
  • 傅里叶变换(FFT)笔记存档

    参考博客:https://www.luogu.com.cn/blog/command-block/fft-xue-xi-bi-ji 目录: FFT引入 复数相关知识 单位根及其相关性质 DFT过程(难点) DFT结论(重要) IDFT结论(重要) IDFT结论证明(难点)

    2024年02月10日
    浏览(40)
  • FFT64点傅里叶变换verilog蝶形运算,代码和视频

    名称:FFT64点verilog傅里叶变换 软件:Quartus 语言:Verilog 代码功能:     使用verilog代码实现64点FFT变换,使用蝶形运算实现傅里叶变换 演示视频:http://www.hdlcode.com/index.php?m=homec=Viewa=indexaid=208 FPGA代码资源下载网:hdlcode.com 代码下载: 软件:Quartus 语言:Verilog 代码功能:

    2024年02月08日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包