快速傅里叶变换(FFT) 笔记
2.upd.2025.7.10
oi.polo.fft
快速傅里叶变换(Fast Fourier Transform)
FFT三问:
1.什么是FFT
- 一个快速处理卷积的算法
2.什么是卷积
- 就是多项式乘法
3.FFT有多快
- 常规卷积或是DFT时间复杂度为\(O(n^2)\),而FFT为\(O(nlog_2n)\),比常规卷积快了将近一阶
算法实现:
$Chapter1: $ 首先我们先来看两种多项式的表示形式
1.记录系数
2.记录点
首先我们先来看1.记录系数:
假设我现在有一个多项式叫做\(P(x)\),它有\(n\)个系数(n项)
那么不难发现它代数形式肯定能写成:
\(P(x) = a_0 +a_1x+a_2x+...+a_{n-2}x^{n-2}+a_{n-1}x^{n-1}\)
因此我记录\(P(x)\)也只需要记录其系数\({\{a_n\}}\)序列
我们再来看2.记录点
我们都学过待定系数法
因此我们知道对于一个\(n\)次函数,我们只需要取\(n+1\)个点就可以求出这个函数的代数式了!
所以我们只要记录\(n\)个点就可以表示这个\(n\)项多项式\(P(x)\)了
$Chapter2: $这两种存储方式该如何进行卷积运算?
1.记录系数方式的卷积:
很简单,我们直接用乘法分配律去算,但是对于两个项数为\(n\)的多项式,这样做的时间复杂度为\(O(n^2)\), 非常菜
2.记录点坐标方式的卷积:
设\(n\)阶多项式\(F(x)\)与\(m\)阶多项式\(G(x)\)相乘,结果为\(n+m\)阶多项式\(P(x)\) \(\Rightarrow\) \(P(x) = F(x)*G(x)\)
因此我们取\(F(x)\)和\(G(x)\)共\(n+m\)个点,将每一个点\((x_0,F(x))\)和\((x_0,G(x))\)相乘,得到\((x_0,F(x)*G(x)),这个点一定在P(x)上\)
但是我们发现取点需要\(O(n)\),计算需要\(O(n)\),总共还是要\(O(n^2)\),目前我们优化卷积还是毫无进展
$Chapter3: $对于记录点坐标方式卷积的优化
假设我现在要对于\(F(x)=x^2+1\)取\(m\)个点,我们要怎么做呢
一种方法是直接简单的取m个点,如取\(x=1,2,3,...,m\),并分别计算\(F(x)\),需要算2*m次(2为F(x)的项数)
但是我们思考\(F(x)\)的性质,它是一个偶函数欸!
\(F(x) = F(-x)\)
因此如果我们取 \(\pm 1,\pm2\)这样,我们计算出\(F(x)\)就相当于计算出了\(F(-x)\)!,要算\(m\)次
同理,对于奇函数我们也是如此
但是万一我的函数非奇非偶呢???
给定多项式\(F(x)=a_0+a_1x+a_2x^2+...+a_{n-1}x^{n-1}+a_{n}x^{n}\),为方便讨论我们假设\(n\)为偶数
我们有什么办法给\(F(x)\)施加奇偶性呢?
我们按照\(x\)的次数分为两类:
\(F(x) = (a_0 +a_2x^2+a_4x^4+...+a_nx^n) + (a_1x+a_3x^3+...+a_{n-1}x^{n-1})\)
我们令\(F_{even}(x^2)=a_0+a_2x^2+a_4x^4 + ...+a_nx^n,F_{odd}(x^2)=a_1+a_3x^2+...+a_{n-1}x^{n-2}\)
\(F(x)=F_{even}(x^2) + xF_{odd}(x^2)\)!
\(F(-x)=F_{even}(x^2) - xF_{odd}(x^2)\)
我们不难发现现在我们的\(F(x)\)被拆成了一个偶函数\(F_{even}(x^2)\)和一个奇函数\(xF_{odd}(x^2)\)
现在我们对于取的点\((x_0,F(x_0))\)计算出\(F_{even}(x_0^2)\)和\(F_{odd}(x_0^2)\)后相加可得\(F(x)\),相减可得\(F(-x)\)
那我们怎么计算\(F_{even}(x_0^2)\)和\(F_{odd}(x_0^2)\)?
这不就是一个递归嘛,将\(x_0^2\)看作变量,继续来一遍拆分,直到我的函数只有常数项为止,由主定理可得时间复杂度为\(O(nlog_2n)\)
但是,我有\(x_0^2\)啊,原来的\(\pm x_0\)都会变成\(x_0^2\),我在递归去求子函数的值的时候取点全会变成正的,无法正负取点了,所以递归无法进行。
\(Chapter4:\) 数域推广
现在我们需要寻找一类数\(S\),满足\(\forall x \in S,-x \in S\)且对于由\(\forall x \in S, x^2\)构成的集合\(S'\)和\(S\)满足同样的性质
实数无法满足的原因是你无法在\(S'\)中找到\(-x\),因此我们将数域推广至复数
以前的注意力大神发现了单位根 就满足这样的性质
什么是单位根?
单位根\(\{\omega_n\}\)就是在复数域下所有满足 \(x^n=1\)的\(x\)构成的集合
我们不难发现\(\{\omega_n\}\)将复平面上的单位圆进行了\(n\)等分,所以我们可以得到单位根的表达式:
\(\omega^k_n = cos\theta+isin\theta,\theta=\frac{2\pi k}{n}\)
我们这个时候取点取\(\{\omega_n\}\)就可以满足条件了
\(Chapter5:\) FFT完全版
- 对于n项多项式\(F(x)\)取\(n\)次单位根为点
- 分奇偶函数递归计算\(F(\omega_n^i)\)
- 同样计算\(G(x)\)
- 将\(G(x)\)与\(F(x)\)以点坐标形式相乘
这就是FFT,很简单吧
但是我们发现这离结果还远着呢,所以我们需要从点表示转换为系数表示,因此我们需要插值操作
\(Chapter6:\) 插值
我们将待定系数列的方程组写为矩阵形式(\(P(x)\)系数为\(\{a_n\}\))
\(
{\begin{bmatrix}
P(\omega^0) \\\\
P(\omega^1) \\\\
P(\omega^2) \\\\
\vdots \\\\
P(\omega^{n-1}) \\\\
\end{bmatrix}} = {\begin{bmatrix}
1 & 1 & 1 & ... &1\\\\
1 & \omega & \omega^2 & ... & \omega^{n-1}\\\\
1&\omega^2&\omega^4&...&\omega^{2
(n-1)}\\\\
\vdots&\vdots&\vdots&\ddots&\vdots\\\\
1&\omega^{n-1}&\omega^{2(n-1)}&...&\omega^{(n-1)(n-1)}
\end{bmatrix}} {\begin{bmatrix}
a_0 \\\\
a_1\\\\
a_2 \\\\
\vdots \\\\
a_{n-1} \\\\
\end{bmatrix}}
\)
移项将\(\{a_n\}\)解出
\(
{\begin{bmatrix}
a_0 \\\\
a_1\\\\
a_2 \\\\
\vdots \\\\
a_{n-1}
\end{bmatrix}} = {\begin{bmatrix}
1 & 1 & 1 & ... &1\\\\
1 & \omega & \omega^2 & ... & \omega^{n-1}\\\\
1&\omega^2&\omega^4&...&\omega^{2
(n-1)}\\\\
\vdots&\vdots&\vdots&\ddots&\vdots\\\\
1&\omega^{n-1}&\omega^{2(n-1)}&...&\omega^{(n-1)(n-1)}
\end{bmatrix}}^{-1} {\begin{bmatrix}
P(\omega^0) \\\\
P(\omega^1) \\\\
P(\omega^2) \\\\
\vdots \\\\
P(\omega^{n-1})
\end{bmatrix}}
\)
我们发现中间的那个矩阵为DFT(离散傅里叶变换)矩阵,因此可得
\(
{\begin{bmatrix}
a_0 \\\\
a_1\\\\
a_2 \\\\
\vdots \\\\
a_{n-1}
\end{bmatrix}} = \frac{1}{n}{\begin{bmatrix}
1 & 1 & 1 & ... &1\\\\
1 & \omega^{-1} & \omega^{-2} & ... & \omega^{-(n-1)}\\\\
1&\omega^{-2}&\omega^{-4}&...&\omega^{-2
(n-1)}\\\\
\vdots&\vdots&\vdots&\ddots&\vdots\\\\
1&\omega^{-(n-1)}&\omega^{-2(n-1)}&...&\omega^{-(n-1)(n-1)}
\end{bmatrix}} {\begin{bmatrix}
P(\omega^0) \\\\
P(\omega^1) \\\\
P(\omega^2) \\\\
\vdots \\\\
P(\omega^{n-1})
\end{bmatrix}}
\)
然后我们发现我们只需要求解这个矩阵乘法即可
矩阵乘法是什么?卷积,卷积是什么?多项式乘法
因此我们再FFT一遍就行了
end.
快速傅里叶变换(FFT) 笔记的更多相关文章
- [学习笔记] 多项式与快速傅里叶变换(FFT)基础
引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...
- 【学习笔记】快速傅里叶变换(FFT)
[学习笔记]快速傅里叶变换 学习之前先看懂这个 浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理--gzy hhh开个玩笑. 讲一下\(FFT\) ...
- 快速傅里叶变换(FFT)学习笔记
定义 多项式 系数表示法 设\(A(x)\)表示一个\(n-1\)次多项式,则所有项的系数组成的\(n\)维向量\((a_0,a_1,a_2,\dots,a_{n-1})\)唯一确定了这个多项式. 即 ...
- 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)
再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...
- 快速傅里叶变换(FFT)学习笔记(其一)
再探快速傅里叶变换(FFT)学习笔记(其一) 目录 再探快速傅里叶变换(FFT)学习笔记(其一) 写在前面 为什么写这篇博客 一些约定 前置知识 多项式卷积 多项式的系数表达式和点值表达式 单位根及其 ...
- 快速傅里叶变换(FFT)学习笔记(其二)(NTT)
再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 写在前面 一些约定 前置知识 同余类和剩余系 欧拉定理 阶 原根 求原根 NTT ...
- 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】
原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...
- 快速傅里叶变换(FFT)
扯 去北京学习的时候才系统的学习了一下卷积,当时整理了这个笔记的大部分.后来就一直放着忘了写完.直到今天都腊月二十八了,才想起来还有个FFT的笔记没整完呢.整理完这个我就假装今年的任务全都over了吧 ...
- 快速傅里叶变换FFT
多项式乘法 #include <cstdio> #include <cmath> #include <algorithm> #include <cstdlib ...
- 快速傅里叶变换FFT& 数论变换NTT
相关知识 时间域上的函数f(t)经过傅里叶变换(Fourier Transform)变成频率域上的F(w),也就是用一些不同频率正弦曲线的加 权叠加得到时间域上的信号. \[ F(\omega)=\m ...
随机推荐
- this 和super 关键字的区别
this关键字 (1) 每个类的每个非静态方法(没有被static修饰)都会隐含一个this关键字,它指向调用这个方法的对象:当在方法中使用本类属性时,都会隐含地使用this关键字,当然也可以明确使用 ...
- Sentinel源码—4.FlowSlot实现流控的原理
大纲 1.FlowSlot根据流控规则对请求进行限流 2.FlowSlot实现流控规则的快速失败效果的原理 3.FlowSlot实现流控规则中排队等待效果的原理 4.FlowSlot实现流控规则中Wa ...
- Go 1.22 相比 Go 1.21 有哪些值得注意的改动?
本系列旨在梳理 Go 的 release notes 与发展史,来更加深入地理解 Go 语言设计的思路. https://go.dev/doc/go1.22 Go 1.22 值得关注的改动: for ...
- 【工具】秘塔AI搜索|推荐一个现在还免费的AI聚合搜索工具
网址:https://metaso.cn/ 使用时间:2024/03/27 . 2024/04/10 以前其实用过它家的秘塔写作猫,当时感觉非常不错. 这次看到它出AI搜索,感觉开发者挺有野心和实力的 ...
- 突破Excel百万数据导出瓶颈:全链路优化实战指南
在日常工作中,Excel数据导出是一个常见的需求. 然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈. 当用户点击"导出"按钮时,后台系统往往会陷入三重困境: 内 ...
- 鸿蒙Next开发实战教程—电影app
最近忙忙活活写了不少教程,但是总感觉千篇一律,没什么意思,大家如果有感兴趣的项目可以私信给幽蓝君写一写. 今天分享一个电影App. 这个项目也比较简单,主要是一些简单页面的开发和本地视频的播放以及 ...
- ShadowSql之开源不易
ShadowSql集本人以前为公司内部开发的ORM之众长 再次进化而来,性能更好也更通用 其一.历时3个多月,已经发布了8个版本 在此期间深感做个开源项目非常的不易 好在现在本人想要的功能基本都已经开 ...
- 使用Vite创建一个动态网页的前端项目
1. 引言 虽然现在的前端更新换代的速度很快,IDE和工具一批批的换,但是我们始终要理解一点基本的程序构建的思维,这些环境和工具都是为了帮助我们更快的发布程序.笔者还记得以前写前端代码的时候,只使用文 ...
- 虚拟机搭建CDH6详细过程_三节点为例
准备工作 一.安装虚拟机.centos 1.安装VMwareWorkstation虚拟化软件 首先我们使用VMwareWorkstation来快速的进行虚拟机的新建. 本文使用的版本为VMwareWo ...
- 从零开发Vim-like编辑器(01)起步
前言 Vim和Neovim因其独特的模态编辑和高度可定制化,被列为程序员常用的文本编辑器选项之一,与Sublime Text.VS Code.Emacs等编辑器共同丰富了开发者工具生态.就目前而言,网 ...