【学习笔记】快速傅里叶变换

学习之前先看懂这个

浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理——gzy

hhh开个玩笑。

讲一下\(FFT\) 的流程,我也不准备长篇大论地分析\(FFT...\)

  • 将系数表示法转换为点值表示法 \(O(n \log n)​\)
  • 对于点值表示法直接进行操作 \(O(n)\)
  • 将点值表示法转换为系数表示法 \(O(n \log n)​\)

这样的流程,最终复杂度是\(O(n \log n)\) 的,现在我们从最简单的点值表示法讲起。

对于点值表示法直接进行操作 :

  • 一个\(n​\)次多项式可以被\(n+1​\)个点唯一确定。

证明:显然。设\(f(x)=\Sigma_i^{n+1} a_ix^{i-1}\),直接通过待定系数法解即可。

  • 将两个多项式相加,(从函数的角度上理解),就是\(x\)不变,\(y\)相加,减法同理
  • 将两个多项式相乘,(从函数的角度上理解),就是\(x​\)不变,\(y​\)相乘。除法求逆

那么假如我们已经有了多项式的点值表示法了,怎么办乘起来呢?

for(register int t=0;t< len;++t) A[t]*=B[t];

就是这样简单。

将系数表示法转换为点值表示法 \((DFT)\)

朴素的想法是带入\(O(n^2)​\)求值,还是用了秦六韶的情况下...

为什么我们不能考虑优化,是因为不同的\(x\)的值是不一样的(不然呢)

但是考虑一种特殊情况:

\[(-1)^2=1^2
\]

是不是就一样了这为我们优化复杂度创造了条件,引入复数的概念。利用复数中的"单位负根"的性质我们可以直接分治求值。

详细证明我最后放连接。

将点值表示法转换为系数表示法\((IDFT)\)

还记得开头提到的范德蒙德(Vandermonde)方阵吗...

如果不知道请转到《工程数学——线性代数(第六版)》高等教育出版社第\(18​\)面,或者浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理——gzy

\[\bold V=\begin{pmatrix}
{1}&{1}&{\cdots}&{1}\\
{x_{0}}&{x_{1}}&{\cdots}&{x_{n-1}}\\
{x_{0}^2}&{x_{1}^2}&{\cdots}&{x_{n-1}^2}\\
{\vdots}&{\vdots}&{}&{\vdots}\\
{x_{0}^{n-1}}&{x_{1}^{n-1}}&{\cdots}&{x_{n-1}^{n-1}}\\
\end{pmatrix}
\]

考虑拿个系数右乘这个矩阵

\[{\begin{pmatrix}
{a_0}\\
{a_1}\\
{a_2}\\
{\vdots}\\
{a_{n-1}}\\
\end{pmatrix}
}^T\begin{pmatrix}
{1}&{1}&{\cdots}&{1}\\
{x_{0}}&{x_{1}}&{\cdots}&{x_{n-1}}\\
{x_{0}^2}&{x_{1}^2}&{\cdots}&{x_{n-1}^2}\\
{\vdots}&{\vdots}&{}&{\vdots}\\
{x_{0}^{n-1}}&{x_{1}^{n-1}}&{\cdots}&{x_{n-1}^{n-1}}\\
\end{pmatrix}={
\begin{pmatrix}
{y_0}\\
{y_1}\\
{y_2}\\
{\vdots}\\
{y_{n-1}}
\end{pmatrix}}^T
\]

实际上就是把\(x_0->x_{n-1}\)这么多变量带入式子。

范德蒙德这个矩阵是可逆的,于是我们有

\[{\begin{pmatrix}
{a_0}\\
{a_1}\\
{a_2}\\
{\vdots}\\
{a_{n-1}}\\
\end{pmatrix}}^T
={\begin{pmatrix}
{y_0}\\
{y_1}\\
{y_2}\\
{\vdots}\\
{y_{n-1}}
\end{pmatrix}}^T
\begin{pmatrix}
{1}&{1}&{\cdots}&{1}\\
{x_{0}}&{x_{1}}&{\cdots}&{x_{n-1}}\\
{x_{0}^2}&{x_{1}^2}&{\cdots}&{x_{n-1}^2}\\
{\vdots}&{\vdots}&{}&{\vdots}\\
{x_{0}^{n-1}}&{x_{1}^{n-1}}&{\cdots}&{x_{n-1}^{n-1}}\\
\end{pmatrix}^{-1}
\]

假如我们可以快速求出范德蒙德矩阵的逆矩阵,然后顺便对于这个特殊的矩阵乘法快速求值,这样我们就可以得到原来的系数是吧。

同样利用上面\(IDT​\)的方法,可以做到\(n\log n​\),甚至只要在某个地方把\(1->-1​\),数学是不是很神奇?所以最后的代码很短,大概是这样的:

FFT(A,1);
FFT(B,1);
for(register int t=0;t<=len;++t) A[t]*=B[t];
FFT(A,-1);

是不是很神奇?


我在这里讲得很省略,主要是为了给自己梳理思路(方便记忆),\(FFT\)有许多有趣的数学推理,大家可以自己去查阅资料,限于篇幅和笔者水平这里就略去了咕咕咕。

注意!如果你就看了我的解析你绝对看不懂下面的代码,除非你是神仙(那你还是看吧,这位神仙)

#include<bits/stdc++.h>
using namespace std; typedef long long ll;
template < class ccf > inline ccf qr(ccf ret){ ret=0;
register char c=getchar();
while(c<48||c>57) c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return ret;
}
inline int qr(){return qr(1);}
const int maxn=1<<21|1;
const double pi=acos(-1.0);
const double eps=1e-5;
int n,m,len(1);
typedef complex<double> is;
is A[maxn];
is B[maxn];
int r[maxn]; inline void FFT(is*a,double ty){
is w,temp,wn,*a1,*a0;
for(register int t=0;t< len;++t)
if(t<r[t]) swap(a[t],a[r[t]]);
for(register int t=1;t<len;t<<=1){
wn=is(cos(pi/t),sin(pi/t)*ty);
for(register int j=0;j<len;j+=t<<1){
a1=t+(a0=a+j); w=is(1,0);
for(register int k=0;k<t;++k,++a0,++a1,w*=wn)
temp=*a1*w, *a1=*a0-temp, *a0=*a0+temp;
}
}
} int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
n=qr();m=qr();
int cnt=0;
while(len<=n+m)len<<=1,++cnt;
for(register int t=0;t<=n;++t) A[t]=qr();
for(register int t=0;t<=m;++t) B[t]=qr();
for(register int t=0;t< len;++t) r[t]=(r[t>>1]>>1)|((t&1)<<(cnt-1));
FFT(A,1); FFT(B,1);
for(register int t=0;t< len;++t) A[t]*=B[t];
FFT(A,-1);
for(register int t=0;t<=m+n;++t) printf("%.0lf%c",fabs((A[t].real())/len+eps),t==m+n?'\n':' ');
return 0;
}

参考资料

比较严谨而详细的但不生涩的好总结

假如你不想看那些具体而不够抽象也不够严谨的讲解并且想一次完全明白FFT(数学基础要好)

浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理——gzy

代码实现看起来常数很小的总结

【学习笔记】快速傅里叶变换(FFT)的更多相关文章

  1. 学习笔记 - 快速傅里叶变换 / 大数A * B的另一种解法

    转: 学习笔记 - 快速傅里叶变换 / 大数A * B的另一种解法 文章目录 前言 ~~Fast Fast TLE~~ 一.FFT是什么? 二.FFT可以干什么? 1.多项式乘法 2.大数乘法 三.F ...

  2. [学习笔记] 多项式与快速傅里叶变换(FFT)基础

    引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...

  3. 快速傅里叶变换(FFT)学习笔记

    定义 多项式 系数表示法 设\(A(x)\)表示一个\(n-1\)次多项式,则所有项的系数组成的\(n\)维向量\((a_0,a_1,a_2,\dots,a_{n-1})\)唯一确定了这个多项式. 即 ...

  4. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  5. 快速傅里叶变换(FFT)学习笔记(其一)

    再探快速傅里叶变换(FFT)学习笔记(其一) 目录 再探快速傅里叶变换(FFT)学习笔记(其一) 写在前面 为什么写这篇博客 一些约定 前置知识 多项式卷积 多项式的系数表达式和点值表达式 单位根及其 ...

  6. 快速傅里叶变换(FFT)学习笔记(其二)(NTT)

    再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其二)(NTT) 写在前面 一些约定 前置知识 同余类和剩余系 欧拉定理 阶 原根 求原根 NTT ...

  7. 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】

    原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...

  8. 快速傅里叶变换(FFT)

    扯 去北京学习的时候才系统的学习了一下卷积,当时整理了这个笔记的大部分.后来就一直放着忘了写完.直到今天都腊月二十八了,才想起来还有个FFT的笔记没整完呢.整理完这个我就假装今年的任务全都over了吧 ...

  9. 图像傅里叶变换(快速傅里叶变换FFT)

    学习DIP第7天,图像傅里叶变换 转载请标明出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对 ...

随机推荐

  1. 2017省选集训测试赛(二十五)Problem B recollection

    @(XSY)[后缀数组, 启发式合并, ST表] Description Solution 后缀数组 + 启发式合并 + Sparse Table. 这是第一次写树上后缀数组. 对以每个点为根的子树统 ...

  2. 查询执行慢的SQL

    --执行慢的SQL: SELECT S.SQL_TEXT, S.SQL_FULLTEXT, S.SQL_ID, ROUND(ELAPSED_TIME / 1000000 / (CASE WHEN (E ...

  3. java项目热加载工具jrebel

    flask有热加载的功能,修为代码后,自动生效. java项目也有类似的功能,不过需要使用收费的插件jrebel 提供一个免费的注册服务器:http://139.199.89.239:1008/884 ...

  4. VS2010 MFC中 给菜单项添加消息响应函数

    久了没用,居然忘记了该怎样给菜单项添加响应函数了~~~~~~~~T_T 特记于此: 1. 在资源视图的Menu里找到自己要添加的菜单,然后输入菜单项. 2. 右击菜单项选属性,设置Popup为Fals ...

  5. Linux内核的引导

    1,当系统上电或复位时,CPU会将PC指针赋值为一个特定的地址0xFFFF0并执行该地址处的指令.在PC机中,该地址位于BIOS中,它保存在主板上的ROM或Flash中 2,BIOS运行时按照CMOS ...

  6. 细微之处见功夫!这5点让Wish3D Earth与众不同

    产品的体验是全方位的,任何一点,都可能决定成败.细微之处见功夫,5个细节,告诉你Wish3D Earth为什么与众不同. 中科图新最新发布的Wish3D Earth,是基于WebGL技术的网页版三维地 ...

  7. 2016.11.25 activiti的配置文件解析

    参考来自activiti的用户手册.   activiti的配置文件解析 1.processEngine的配置 注意,单独创建流程引擎与spring方式创建流程引擎是不一样的,区别在于:process ...

  8. Intellij IDEA 拷贝的项目变为红色名字

    Intellij IDEA 拷贝的项目变为红色名字 学习了:https://blog.csdn.net/lishaoran369/article/details/72991805 settings & ...

  9. Mark一下, dp状态转移方程写对,可是写代码都错,poj 1651 poj 1179

    dp题: 1.写状态转移方程; 2.考虑初始化边界,有意义的赋定值.还没计算的赋边界值: 3.怎么写代码自底向上计算最优值 今天做了几个基础dp,所有是dp方程写对可是初始化以及计算写错 先是poj ...

  10. typedef,结构体,共用体,联合体

    typedef的用途: 封装数据类型,方便移植 简化函数指针的定义 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcXVhbg==/ ...