多项式算法1:FFT(快速傅里叶变换)

十分简明易懂的FFT(快速傅里叶变换) FFT有什么用 快速傅里叶变换 (fast Fourier transform),即利用计算机计算离散傅里叶变换(DFT)的高效、快速计算方法的统称,简称FFT。快速傅里叶变换是1965年由J.W.库利和T.W.图基提出的。采用这种算法能使计算机计算离散傅里叶变换所需要的乘法次数大为减少,特别是被变换的抽样点数N越多,FFT算法计算量的节省就越显著。 FFT(Fast Fouri... 阅读详情

多项式算法1:FFT(快速傅里叶变换)

前言

算法简介

快速傅里叶变换 (fast Fourier transform), 即利用计算机计算离散傅里叶变换(DFT)的高效、快速计算方法的统称,简称FFT。快速傅里叶变换是1965年由J.W.库利和T.W.图基提出的。采用这种算法能使计算机计算离散傅里叶变换所需要的乘法次数大为减少,特别是被变换的抽样点数N越多,FFT算法计算量的节省就越显著。——百度百科

其实是一个用于快速求解多项式之积的算法。
多项式:形如 A ( x ) = ∑ j = 0 n − 1 a j x j A(x)=\sum_{j=0}^{n-1}a_jx^j A(x)=j=0∑n−1​aj​xj的式子,展开来就是 A ( x ) = a 0 + a 1 x + a 2 x 2 + ⋯ + a n − 1 x n − 1 A(x)=a_0+a_1x+a_2x^2+\cdots+a_{n-1}x^{n-1} A(x)=a0​+a1​x+a2​x2+⋯+an−1​xn−1
如果我们用 A ( x ) A(x) A(x), B ( x ) B(x) B(x)表示两个不同的多项式,现在要求解两个数的乘积,朴素求法是直接相乘,时间复杂度为 Θ ( n 2 ) \varTheta(n^2) Θ(n2)(过程请参考高精乘法),当 n = 1 0 5 n=10^5 n=105时会炸。
不过,当我们换一种方法来表示多项式后,结果会不会好一点呢。考虑用离散的点来表示这个函数,根据高斯消元,不难看出,用至少n个不同的点来表示一个n元函数才可以唯一确定这个n元函数。现假设我用点 ( x 0 , A ( x 0 ) ) , ( x 1 , A ( x 1 ) ) , ( x 2 , A ( x 2 ) ) , ⋯   , ( x n − 1 , A ( x n − 1 ) ) (x_0,A(x_0)),(x_1,A(x_1)),(x_2,A(x_2)),\cdots,(x_{n-1},A(x_{n-1})) (x0​,A(x0​)),(x1​,A(x1​)),(x2​,A(x2​)),⋯,(xn−1​,A(xn−1​))来表示n元多项式 A ( x ) A(x) A(x),用点 ( x 0 , B ( x 0 ) ) , ( x 1 , B ( x 1 ) ) , ( x 2 , B ( x 2 ) ) , ⋯   , ( x n − 1 , B ( x n − 1 ) ) (x_0,B(x_0)),(x_1,B(x_1)),(x_2,B(x_2)),\cdots,(x_{n-1},B(x_{n-1})) (x0​,B(x0​)),(x1​,B(x1​)),(x2​,B(x2​)),⋯,(xn−1​,B(xn−1​))来表示n元多项式 B ( x ) B(x) B(x)。
不难看出 A ( x ) ∗ B ( x ) A(x)*B(x) A(x)∗B(x)(最高为 n − 1 n-1 n−1次)可用点 ( x 0 , A ( x 0 ) ∗ B ( x 0 ) ) , ( x 1 , A ( x 1 ) ∗ B ( x 1 ) ) , ( x 2 , A ( x 2 ) ∗ B ( x 2 ) ) , ⋯   , ( x n − 1 , A ( x n − 1 ) ∗ B ( x n − 1 ) ) (x_0,A(x_0)*B(x_0)),(x_1,A(x_1)*B(x_1)),(x_2,A(x_2)*B(x_2)),\cdots,(x_{n-1},A(x_{n-1})*B(x_{n-1})) (x0​,A(x0​)∗B(x0​)),(x1​,A(x1​)∗B(x1​)),(x2​,A(x2​)∗B(x2​)),⋯,(xn−1​,A(xn−1​)∗B(xn−1​))表示。
算法时间复杂度为 Θ ( n ) \varTheta(n) Θ(n),已经能达到我们的要求了,那是不是说明我们成功完成了任务了呢。不,那还早呢,我们要的是系数表示的多项式,而不是点值表达式,如果按照 1 → n 1\to n 1→n的方法来取 x 0 − x n − 1 x_0-x_{n-1} x0​−xn−1​的值,用秦九韶算法将系数多项式转为点值,用高斯消元将点值转为系数多项式,那么时间复杂度为 Θ ( n 2 ) \varTheta(n^2) Θ(n2)甚至更高。
那么,我们有没有一个好的算法来优化这一过程呢,这就是我们今天要讨论的问题了,这就是传说中的FFT(快速傅里叶变换)。

前置技能

DFT与IDFT
首先,我们要提一下什么是离散傅里叶变换(DFT),离散傅里叶变换就是将一个系数表达式变为一个点值表达式;而将一个点值表达式变化为一个系数表达式称为离散傅里叶逆变换(IDFT)。FFT就是以巨大常数为代价快速进行DFT和IDFT的算法。
复数
这个算法首先要在选未知数上做文章,如果未知数的乘幂一直都是1,那计算就方便许多。但是这样的数我们只能找到1和-1,如何找到更多满足条件的数呢?
这就有赖于数系的扩充了,在初中阶段,数学老师教育我们, − 1 \sqrt{-1} −1 ​这个数是不存在的。但在虚数中,数学家用符号 i i i来表示 − 1 \sqrt{-1} −1 ​。复数就是形如 a ∗ i + b a*i+b a∗i+b的所有数,当 a = 0 a=0 a=0时复数就是我们熟知的实数。下面要用到复数,如果还有不懂可以自行搜索,我这里就不再深入探讨复数了。
矩阵
在往下看之前最好要了解矩阵的基本概念,以及单位矩阵,逆矩阵的定义,不懂的请自行上网问度娘。
欧拉公式
e i x = cos ⁡ x + i sin ⁡ x e^{ix}=\cos x+ i \sin x eix=cosx+isinx

正文

对复数了解一点的人都知道,复数可以表示成平面直角坐标系上的一个点,如下图:
图1
该点可表示为 a + b ∗ i a+b*i a+b∗i。
在上文中,我们试着用数字1到n带入多项式来表示一个n次多项式,这样计算非常费力,我们需要谨慎选好带入的数。根据经验,乘幂为1或-1时非常好算,考虑1和-1。当n较大时,实数已经不能满足我们的需求了,此时,代入一些复数或许可以满足我们的要求。
以下是用结构体实现复数的代码:

const double pi = acos(-1.0);
struct virt{
   
   
	double r , i;
	virt( double r = 0.0 , double i = 0.0 ) {
   
   
		this->r = r;
		this->i = i;
	}
	virt operator + ( const virt &x ) {
   
   
		return virt( r + x.r , i + x.i );
	}
	virt operator - ( const virt &x ) {
   
   
		return virt( r - x.r , i - x.i );
	}
	virt operator * ( const virt &x ) {
   
   
		return virt( r * x.r - i * x.i , i * x.r + r * x.i );
	}
	//复数除法用不到,就不写了
};

单位复根
鉴于上图用坐标系表示复数,我们是否也可以找到一类复数,它们的乘幂都可能为1或-1?
答案是肯定的,如下图:
图2

在该单位圆上的所有复数都符合条件。
复数的乘法在复平面中表现为辐角相加,模长相乘。利用这一点,我们可以轻易地处理出所有复数的 n n n次幂。
复数 ω \omega ω满足 ω n = 1 \omega^n = 1 ωn=1称作 ω \omega ω是 n n n次单位根,下图包含了所有的4次单位根(图中圆的半径是1)。

图3
同样的,下图是所有的8次单位根。
图4
由此我们不难发现单位根有如下性质:
ω 2 n 2 m = ω n m \omega^{2m}_{2n} = \omega^{m}_{n} ω2n2m​=ωnm​ ω n m = − ω n m + n 2 \omega^{m}_{n} = -\omega^{m+ \frac{n}{2} }_{n} ωnm​=−ωnm+2n​​
FFT的具体过程
FFT就是将系数表示法转化成点值表示法相乘,再由点值表示法转化为系数表示法的过程,第一个过程叫做离散傅里叶变换(DFT),又称求值,第二个过程叫做离散傅里叶逆变换(IDFT),又称插值。
DFT详细过程
想要求出一个多项式的点值表示发,需要选出 n n n个数分别带入到多项式里面。带入一个数复杂度是 Θ ( n ) \varTheta(n) Θ(n),那么总复杂度是 Θ ( n 2 ) \varTheta(n^2) Θ(n2)的,这是无法接受的,但我们可以给多项式代入 ω n 0 ω n 1 … ω n n − 1 \omega_{n}^{0}\omega_{n}^{1} \dots \omega_{n}^{n - 1} ωn0​ωn1​…ωnn−1​来利用 n n n次单位根的性质来加速我们的运算。
设 A 0 ( X ) A_0(X) A0​(X)为 A ( X ) A(X) A(X)偶次项的和, A 1 ( X ) A_1(X) A1​(X)为 A ( X ) A(X) A(X)奇次项的和,则:
A 0 ( X ) = a 0 x 0 + a 2 x 1 + ⋯ + a n − 1 x n 2 A_0(X)=a_0x^0+a_2x^1+\dots+a_{n-1}x^{ \frac{n}{2} } A0​(X)=a0​x0+a2​x1+⋯+an−1​x2n​ A 1 ( X ) = a 1 x 0 + a 3 x 1 + ⋯ + a n − 2 x n 2 A_1(X)=a_1x^0+a_3x^1+\dots+a_{n-2}x^{ \frac{n}{2} } A1​(X)=a1​x0+a3​x1+⋯+an−2​x2n​因为: A ( ω n m ) = a 0 ω n 0 + a 1 ω n m + a 2 ω n 2 m + a 3 ω n 3 m + ⋯ + a n − 1 ω n ( n − 1 ) × m + a n ω n n m A(\omega^m_n)=a_0\omega^{0}_n+a_1\omega^{m}_n+a_2\omega^{2m}_n+a_3\omega^{3m}_n+\dots+a_{n-1}\omega^{(n-1) \times m}_n+a_n\omega^{nm}_n A(ωnm​)=a0​ωn0​+a1​ωnm​+a2​ωn2m​+a3​ωn3m​+⋯+an−1​ω

【数字信号处理】【傅里叶分析】【FFT】快速傅里叶变换的完整公式推导 给出离散傅里叶变换DFT的公式: DFT[x(n)]=X(m)=∑n=0N−1x(n)exp(−j2πmnN),m∈[0,N−1]=x(0)exp(−j2πm0N)+x(1)exp(−j2πm1N)+x(2)exp(−j2πm2N)+x(3)exp(−j2πm3N)+...\begin{aligned} DFT[x(n)]=X(m)&=\sum_{n=0}^{N-1}x(n)exp(-j\frac{2\pi mn}{N}),m\in[0,N-1]\\ &=x(0)exp(-j\frac{2\ 阅读详情

相关推荐

快速傅里叶变换学习(超详细,附代码实现)

在学习快速傅里叶变换之前,我们首先需要了解傅里叶变换。傅里叶变换,是将信号从时域的表现形式换成频域上的表现形式。如下面的正弦波:

欢迎一起交流问题! 2万+

FFT多项式乘法学习笔记

基础知识了解:点击打开链接公式证明:点击打开链接综合了这两个博客我才懂了什么是FFT,所以这两个博客讲的比较细的我就不说了,说一些综合的.为什么选择n个n次单位复根?公式1: w(n.k)^2 = w(n/2,k)应用了这个公式才可以把原来n大小的问题变成n/2的问题,这就是分治得到log(n)的由来.将n个数分成奇数偶数分开处理得到公式F(x) = G(x^2) + xH(x^2),其中G(x)...

过路人丶的博客 586

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

算法的世界多么广大,我们可以将算法大致分为两类:第一类是较为有用的算法:比如一些经典的图算法,像 DFS 和 BFS(深度 / 广度优先算法),这些算法应用在很多方面,他们非常高效, 第二类算法是那些极具美感的算法:例如当我们第一次看到汉诺塔的递归实现算法时的状态,你肯定会觉得这个算法贼牛逼,甚至会被它的美感所震撼到,但这些算法或许并没有那么有用或者高效,不过我们还是会研究它,就像没事干了我们还是会看小说; 这些伟大而精妙的算法会激发我们的灵感,促使我们发散性思考,下面介绍一种同时属于以上两类的算法:快速傅

W_Oilpicture的博客 8772

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

FFT(快速傅里叶变换)算法学习笔记基本概念FFT(FastFourierTransformation)FFT (Fast Fourier Transformation)即快速傅里叶变换,是DFTDFT的加速算法,利用单位复数根的特殊性质,可以在Θ(nlogn)\Theta (nlogn)的时间内算出DFTDFT,利用相似性可以在同样的复杂度完成逆运算 DFT(DiscreteFourierTra

新的故事 旧的回忆 2万+

《算法导论》第 30 章:多项式与快速傅里叶变换(FFT)

本文深入讲解了多项式与快速傅里叶变换(FFT)的核心内容。FFT通过将时间复杂度从O(n²)降至O(nlogn),极大提升了多项式乘法的效率。文章首先对比了多项式的两种表示法(系数表示和点值表示),详细解析了离散傅里叶变换(DFT)的原理,并重点介绍了FFT的分治优化策略。通过递归和迭代两种实现方式,配合完整的C++代码示例,展示了如何用FFT高效计算多项式乘法。最后还探讨了FFT的并行化思路和实际应用场景。全文逻辑清晰,理论与实践结合,帮助读者透彻理解这一重要算法。

2302_80961196的博客 941

【算法讲15:多项式卷积】FFT | NTT

【算法讲15:多项式】多项式的表示法多项式的乘法与卷积多项式乘法FFTFFTFFT单位根离散傅里叶变换 DFTDFTDFTDFTDFTDFT 的详细讨论离散傅里叶逆变换 IDFTIDFTIDFT参考与查阅 多项式的表示法 系数表示:nnn 个系数确定一个 n−1n-1n−1 次多项式 (a0,a1,a2,⋯ ,an−1) (a_0,a_1,a_2,\cdots,a_{n-1}) (a0​,a1​,a2​,⋯,an−1​) 点值表示:nnn 个点确定一个 n−1n-1n−1 刺多项式 (x0,x1,x1,⋯

溢流眼泪的博客 5182

qemu(2) -- 定制开发板

向qemu源码中添加自定义开发板

xflm的博客 843

嵌入式设备低功耗设计误区:为什么你的RK3568总是被‘意外’唤醒?

本文深入分析RK3568嵌入式设备低功耗设计中的常见误区,重点探讨唤醒源管理不当导致的意外唤醒问题。通过解析硬件设计陷阱、软件配置错误及系统化审计方法,帮助开发者有效排查和解决GPIO配置、唤醒源设置等关键因素引起的功耗异常,提升设备续航能力。

php55的博客 460

一窥Memory测试算法及自我修复机制

摘要 为了满足新一代设备的需求,Memory的大小每三年就会增加4倍。深亚微米设备包含大量面积更小、访问速度更快的Memory。针对此类设计制定自动测试策略可以减少ATE(自动测试设备)的时间和成本。 内存故障的行为与经典的“Stuck-At”故障不同。因此,Memory的故障模型(由于其阵列结构)与标准逻辑的设计也是不同的。Memory测试除了进行故障检测和定位,还可以实现用冗余单元对...

路科验证 2万+

200SMART PLC时间不准?手把手教你用MCGS触摸屏实现自动校时(附完整代码)

本文针对西门子200SMART PLC时钟不准的常见问题,提供了一套基于MCGS触摸屏的自动校时解决方案。文章详细阐述了时钟偏差的根源、时间同步方案的技术选型,并手把手指导如何配置MCGS与PLC的通信,以及编写完整的PLC时间读取、转换与设置代码,最终实现稳定可靠的自动时间同步功能。

jupyter5notebook的博客 459

5种主流触觉传感器对比:GelSight、DIGIT、Taxim、GelSlim和TACTO怎么选?

本文深度对比了GelSight、DIGIT、Taxim、GelSlim和TACTO五种主流触觉传感器的技术原理与应用场景。针对机器人及VR项目的选型需求,文章从光学与电子传感的技术分野出发,分析了各传感器在分辨率、响应速度、集成难度和成本上的核心差异,并提供了从需求出发的实战选型决策框架,帮助开发者找到最适合的触觉解决方案。

weixin_29268637的博客 696

射频收发机(RF Transceiver)

2,既然原来外差的思路是把声音频率的信号,通过混频搬移到高频电磁波频率,那对高频率信号放大的时候,是不是也可以先在比较低的射频频率进行放大,然后再通过频率搬移的方式,将放大后的信号搬移到高频率呢?频率搬移过程中,中间预先设定的固定射频频率被称为“中频”(中间频率,IF,Intermediate Frequency),由于这个频率超出了声音可听的范围,是“超声波”(supersonic),所以被命名为“超外差”(Super-Heterodyne)。混频后的信号在0频率附近,可能会发生DC偏移。

2301_77317229的博客 1123

《C++等级认证CCF-GESP真题解析》专栏总目录

❤️ 专栏名称:《C++等级认证CCF-GESP真题解析》🌸 专栏介绍:中国计算机学会GESP《CCF编程能力等级认证》C++编程(1~8级)历届真题解析。🚀 订阅专栏:订阅后可阅读专栏内所有真题解析,真题持续更新中,欢迎订阅!

人生就是一个不断学习的过程 6293

SAP-ABAP:接口多继承与复合接口设计:复杂业务场景下的能力组合实现方案

本文介绍了ABAP中通过接口多继承与复合接口设计实现能力组合的方案。文章首先辨析了类实现多个接口与接口继承接口的核心概念,指出ABAP虽不支持类多继承,但可通过这两种机制灵活组合能力。随后详细讲解了类实现多个接口的语法规则与三种调用方式,并给出了五个基础能力接口的设计示例(日志记录、权限校验、数据导出、消息通知、格式转换)。作者通过对比单继承与接口多重实现的差异,强调后者在解耦和扩展性上的优势,为复杂业务场景下的能力组合提供了实用解决方案。

baidu_35680696的博客 247

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: 赛前总结
下一篇: 多项式算法2:NTT(快速数论变换)
ha_ing
博客等级 码龄8年 21粉丝 41原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值