FFT —— 快速傅里叶变换
问题:
已知A[], B[], 求C[],使:

定义C是A,B的卷积,例如多项式乘法等。
朴素做法是按照定义枚举i和j,但这样时间复杂度是O(n2).
能不能使时间复杂度降下来呢?
点值表示法:
我们把A,B,C看作表达式。
即:
A(x)=a0 + a1* x + a2 * x2 +...
将A={(x1,A(x1)), (x2,A(x2)), (x3,A(x3))...}叫做A的点值表示法。
那么使用点值表示法做多项式乘法就很简单了:对应项相乘。
那么,如何将A和B转换成点值表示法,再将C转化回系数表示法(即最初的表示方法)呢?
如果任取n个点,按照定义计算,那么还是O(n2)的。
这样就要用到快速傅里叶变换。
快速傅里叶变换:
既然任取n个点,按照定义计算太慢,就要找一些特殊点。
我们用n个n次单位复数根(1的n次方根,涉及到复数,1的方根不止1和-1)来计算:
1的n次方根是
,其中i是虚数单位。
我们定义wn = e^(2∏i)是主n次单位根,那么所有n次单位复数根都是它的次方。
我们要求出A(wnk),就要采用分治思想。
我们将奇偶系数分离(先假设n为偶数),即定义
A1(x)=a0 + a2* x + a4 * x2 +...
A2(x)=a1 + a3* x + a5 * x2 +...
那么A(x)=A1(x2) + xA2(x2)。
要计算A(wnk)=A1((wnk)2) + wnkA2((wnk)2),
就要用到(wnk)2 = wn/2k mod (n / 2)(证略)。
所以A(wnk)=A1(wn/2k mod (n / 2)) + wnkA2(wn/2k mod (n / 2))
我们发现A1,A2都是n/2项的,且只需要算wn/2k的值,那么这就和开始的问题一样了,可以分治。
边界也很容易:n=1的时候A1本身就是值。
合并解。
A(wnk)=A1(wn/2k mod (n / 2)) + wnkA2(wn/2k mod (n / 2))
那么可以A(wnk)和A(wnk+n/2)一起算(0<=k<n/2):
设u = A1(wn/2k), t = wnkA2(wn/2k),
那么A(wnk) = u + t
A(wnk+n/2) = A1(wn/2k) + wnk + n/2 A2(wn/2k)
= A1(wn/2k) + wnk wnn/2 A2(wn/2k)
= A1(wn/2k) - wnk A2(wn/2k)
= u - t
所以这样就能算出A的点值表示法。
一个问题:分治要求n是2的幂,不是怎么办? 补0, 直到是2的幂。
剩下的问题:如何把C转化回系数表示法。
快速傅里叶逆变换:
我们把C做一遍快速傅立叶变换,只是求的是wnn, wnn-1, ..., wn1的值而不是wn0, wn1, ..., wnn-1的值,最后每一项除以n即可。
证略。
void Rader(complex y[],int len)
{
int i,j,k;
, j = len/;i < len-;i++)
{
if(i < j)swap(y[i],y[j]);
k = len/;
while( j >= k)
{
j -= k;
k /= ;
}
if(j < k)j += k;
}
}
void FFT(complex y[],int len,int on) //on = 1 快速傅里叶变换, on = -1 快速傅里叶逆变换
{
Rader(y,len);
;h <= len;h <<= )
{
complex wn(cos(-on**PI/h),sin(-on**PI/h)); //e^ki = cosk + isink
;j < len;j += h)
{
complex w(,);
;k++)
{
complex u = y[k];
complex t = w*y[k+h/];
y[k] = u+t;
y[k+h/] = u-t;
w = w*wn;
}
}
}
)
;i < len;i++)
y[i].r /= len;
}
39 //复数实现略
FFT —— 快速傅里叶变换的更多相关文章
- FFT 快速傅里叶变换 学习笔记
FFT 快速傅里叶变换 前言 lmc,ikka,attack等众多大佬都没教会的我终于要自己填坑了. 又是机房里最后一个学fft的人 早背过圆周率50位填坑了 用处 多项式乘法 卷积 \(g(x)=a ...
- CQOI2018 九连环 打表找规律 fft快速傅里叶变换
题面: CQOI2018九连环 分析: 个人认为这道题没有什么价值,纯粹是为了考算法而考算法. 对于小数据我们可以直接爆搜打表,打表出来我们可以观察规律. f[1~10]: 1 2 5 10 21 4 ...
- 「学习笔记」FFT 快速傅里叶变换
目录 「学习笔记」FFT 快速傅里叶变换 啥是 FFT 呀?它可以干什么? 必备芝士 点值表示 复数 傅立叶正变换 傅里叶逆变换 FFT 的代码实现 还会有的 NTT 和三模数 NTT... 「学习笔 ...
- [C++] 频谱图中 FFT快速傅里叶变换C++实现
在项目中,需要画波形频谱图,因此进行查找,不是很懂相关知识,下列代码主要是针对这篇文章. http://blog.csdn.net/xcgspring/article/details/4749075 ...
- matlab中fft快速傅里叶变换
视频来源:https://www.bilibili.com/video/av51932171?t=628. 博文来源:https://ww2.mathworks.cn/help/matlab/ref/ ...
- FFT快速傅里叶变换算法
1.FFT算法概要: FFT(Fast Fourier Transformation)是离散傅氏变换(DFT)的快速算法.即为快速傅氏变换.它是根据离散傅氏变换的奇.偶.虚.实等特性,对离散傅立叶变换 ...
- FFT快速傅里叶变换
FFT太玄幻了,不过我要先膜拜HQM,实在太强了 1.多项式 1)多项式的定义 在数学中,由若干个单项式相加组成的代数式叫做多项式.多项式中的每个单项式叫做多项式的项,这些单项式中的最高项次数,就是这 ...
- [学习笔记]FFT——快速傅里叶变换
大力推荐博客: 傅里叶变换(FFT)学习笔记 一.多项式乘法: 我们要明白的是: FFT利用分治,处理多项式乘法,达到O(nlogn)的复杂度.(虽然常数大) FFT=DFT+IDFT DFT: 本质 ...
- FFT(快速傅里叶变换)
学习了FFT用来求多项式的乘法,看了算导上的介绍,上面讲的非常明白,概括一下FFT的原理就是,我们在计算多项式的乘法时,如果暴力模拟的话是n^2 复杂度的,就像小学学的竖式乘法一样,比如一个n位数乘上 ...
随机推荐
- Windows Server 2008 R2 配置AD(Active Directory)域控制器 -zhai zi wangluo
http://files.cnblogs.com/zhongweiv/Windows_Server_2008_R2_%E9%85%8D%E7%BD%AEActive_Directory%E5%9F%9 ...
- poj 1438--One-way Traffic(边的双连通)
给定一个图,并给定边,a b c(c==1||c==2) 表示ab之间有c条边 求把尽可能多的有向边定向变成强联通图. 先把图当做无向图,加边时记录是否有边,dfs的时候不要把本没有的边用到!因为这个 ...
- windows蓝屏代码大全及常见蓝屏解决方案
对于以下的代码查询建议使用ctrl+F查询,而且很多蓝屏与黑屏的问题多是最近操作引起的,例如更新驱动,安装新的硬件.软件--把相关的配置调到最近的正常状况大多可以解决,确实不行时方可考虑重装系统,解决 ...
- C#基础知识学习手记1
这篇随笔主要用来记录我在C#学习过程做的笔记,算作是一门课程中的小知识点吧. 1. 变量和表达式 1.1 如何在输出带有引号(英文双引号.英文单引号)以 ...
- 在大型软件中用Word做报表: 书签的应用
本文转载:http://www.cnblogs.com/huyong/archive/2011/08/24/2151599.html 报表基本上在每一个项目中占有很大的比例,做报表也是我们开发人员必须 ...
- Redis学习手册(实例代码)
在之前的博客中已经非常详细的介绍了Redis的各种操作命令.运行机制和服务器初始化参数配置.本篇博客是该系列博客中的最后一篇,在这里将给出基于Redis客户端组件访问并操作Redis服务器的代码示例. ...
- 新型信用卡MasterPass
Xsolla与masterpass合作.提供新型支付方式 "电子支付的未来在这里. "在万事达卡宣布发行一种全新的被称为MasterPass的支付解决方式的两年后.从2014年底開 ...
- crash recovery
2016-07-02 17:56:07 5772 [Note] InnoDB: Database was not shutdown normally!2016-07-02 17:56:07 5772 ...
- Dynamic SQL--官方文档
https://ibatis.apache.org/docs/dotnet/datamapper/ch03s09.html 3.9. Dynamic SQL A very common problem ...
- Linux--------------安装vim
1.相关提示 -bash: vim: command not found 2.查看vim是否安装 rpm -qa|grep vim vim-en ...