快速傅立叶变换FFT模板
递归版
//容易暴栈,但是很好理解
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
const int maxlongint=2147483647;
const int mo=1e9+7;
const int N=400005;
const double pi=acos(-1);
using namespace std;
struct arr
{
double x,y;
arr() {x=y=0;}
arr(double x,double y):x(x),y(y) {}
}a[N],b[N],c[N];
arr operator +(arr x,arr y) {return arr(x.x+y.x,x.y+y.y);}
arr operator -(arr x,arr y) {return arr(x.x-y.x,x.y-y.y);}
arr operator *(arr x,arr y) {return arr(x.x*y.x-x.y*y.y,x.x*y.y+y.x*x.y);}
int n,m,fn;
void FFT(arr *y,int n,int t)
{
if(n==1) return;
arr a0[n>>1],a1[n>>1];
for(int i=0;i<n;i+=2) a0[i>>1]=y[i],a1[i>>1]=y[i+1];
FFT(a0,n>>1,t),FFT(a1,n>>1,t);
arr w1(cos(2*pi/n),t*sin(2*pi/n)),w0(1,0);
for(int i=0;i<n>>1;i++,w0=w0*w1) y[i]=a0[i]+w0*a1[i],y[i+(n>>1)]=a0[i]-w0*a1[i];
}
int main()
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) scanf("%lf",&a[i].x);
for(int i=0;i<=m;i++) scanf("%lf",&b[i].x);
fn=1;
while(fn<=n+m) fn<<=1;
FFT(a,fn,1),FFT(b,fn,1);
for(int i=0;i<fn;i++) c[i]=a[i]*b[i];
FFT(c,fn,-1);
for(int i=0;i<=n+m;i++) printf("%.0lf ",abs(c[i].x/fn));
}
非递归版
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
const int maxlongint=2147483647;
const int mo=1e9+7;
const int N=400005;
const double pi=acos(-1);
using namespace std;
struct arr
{
double x,y;
arr() {x=y=0;}
arr(double x1,double y1) {x=x1,y=y1;};
}q[N],r[N],f[N],f1[N];
int n,fn;
double qq[N];
arr operator + (arr x,arr y) {return arr(x.x+y.x,x.y+y.y);}
arr operator - (arr x,arr y) {return arr(x.x-y.x,x.y-y.y);}
arr operator * (arr x,arr y) {return arr(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);}
void FFT(arr *a,int n,int t)
{
for(int i=0,p=0;i<n;i++)
{
if(i<p) swap(a[i],a[p]);
for(int j=n>>1;(p^=j)<j;j>>=1);
}
for(int m=2;m<=n;m<<=1)
{
int half=m>>1;
for(int i=0;i<half;i++)
{
arr w0(cos(i*pi*t/half),sin(i*pi*t/half)),aj;
for(int j=i;j<n;j+=m) aj=a[j],a[j]=aj+w0*a[j+half],a[j+half]=aj-w0*a[j+half];
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lf",&qq[i]),r[i].x=1.0/i/i,q[i].x=qq[i];
for(fn=1;fn<n*2+1;fn<<=1);
FFT(q,fn,1),FFT(r,fn,1);
for(int i=0;i<fn;i++) f[i]=q[i]*r[i];
FFT(f,fn,-1);
memset(q,0,sizeof(q));
memset(r,0,sizeof(r));
for(int i=1;i<=n;i++) r[i].x=1.0/i/i,q[i].x=qq[n-i+1];
FFT(q,fn,1),FFT(r,fn,1);
for(int i=0;i<fn;i++) f1[i]=q[i]*r[i];
FFT(f1,fn,-1);
for(int i=1;i<=n;i++) printf("%.3lf\n",(f[i].x-f1[n-i+1].x)/fn);
}
快速傅立叶变换FFT模板的更多相关文章
- 快速傅立叶变换(FFT)算法
已知多项式f(x)=a0+a1x+a2x2+...+am-1xm-1, g(x)=b0+b1x+b2x2+...+bn-1xn-1.利用卷积的蛮力算法,得到h(x)=f(x)g(x),这一过程的时间复 ...
- 为什么要进行傅立叶变换?傅立叶变换究竟有何意义?如何用Matlab实现快速傅立叶变换
写在最前面:本文是我阅读了多篇相关文章后对它们进行分析重组整合而得,绝大部分内容非我所原创.在此向多位原创作者致敬!!!一.傅立叶变换的由来关于傅立叶变换,无论是书本还是在网上可以很容易找到关于傅立叶 ...
- 离散傅立叶变换与快速傅立叶变换(DFT与FFT)
自从去年下半年接触三维重构以来,听得最多的词就是傅立叶变换,后来了解到这个变换在图像处理里面也是重点中的重点. 本身自己基于高数知识的理解是傅立叶变换是将一个函数变为一堆正余弦函数的和的变换.而图像处 ...
- $\mathcal{FFT}$·$\mathcal{Fast \ \ Fourier \ \ Transformation}$快速傅立叶变换
\(2019.2.18upd:\) \(LINK\) 之前写的比较适合未接触FFT的人阅读--但是有几个地方出了错,大家可以找一下233 啊-本来觉得这是个比较良心的算法没想到这么抽搐这个算法真是将一 ...
- BZOJ 2194 快速傅立叶变换之二 | FFT
BZOJ 2194 快速傅立叶变换之二 题意 给出两个长为\(n\)的数组\(a\)和\(b\),\(c_k = \sum_{i = k}^{n - 1} a[i] * b[i - k]\). 题解 ...
- 快速傅立叶变换(FFT)
多项式 系数表示法 设\(f(x)\)为一个\(n-1\)次多项式,则 \(f(x)=\sum\limits_{i=0}^{n-1}a_i*x_i\) 其中\(a_i\)为\(f(x)\)的系数,用这 ...
- 傅立叶变换—FFT
FFT(快速傅立叶变换)使用“分而治之”的策略来计算一个n阶多项式的n阶DFT系数的值.定义n为2的整数幂数,为了计算一个n阶多项式f(x),算法定义了连个新的n/2阶多项式,函数f[0](x)包含了 ...
- NVIDIA GPU的快速傅立叶变换
NVIDIA GPU的快速傅立叶变换 cuFFT库提供GPU加速的FFT实现,其执行速度比仅CPU的替代方案快10倍.cuFFT用于构建跨学科的商业和研究应用程序,例如深度学习,计算机视觉,计算物理, ...
- 傅立叶变换系列(五)快速傅立叶变换(FFT)
说明: 傅里叶级数.傅里叶变换.离散傅里叶变换.短时傅里叶变换...这些理解和应用都非常难,网上的文章有两个极端:“Esay” Or “Boring”!如果单独看一两篇文章就弄懂傅里叶,那说明你真 ...
随机推荐
- ######<待随时补充>我的学习规划######
一.关于Python 1.demo 一些基础实验,包含Python基础知识等,约300-500个 2.Python常见模块的了解学习,如 time datetime random 随机数 os 与 ...
- Linux系列之putty远程登录
在工作中,我们通常都是通过远程操作Linux服务器的,因此必须熟悉一些远程登录的软件,在此使用的是putty,在Windows上安装putty软件,通过该软件访问Linux主机. 1.远程登录步骤 1 ...
- imx8移植opencv(3.0以上版本)笔记
基本步骤参考我同事的博客:https://blog.csdn.net/hunzhangzui9837/article/details/89846928 以下是在移植到imx8平台时的笔记和遇到的问题及 ...
- lunix部署其前端项目常见报错
1.npm install 报权限错误,如: 解决办法: 添加--unsafe-perm 参数,如 #npm install --registry=https://registry.npm.taoba ...
- 分库分布的几件小事(五)MYSQL读写分离
1.为什么进行读写分离 这个,高并发这个阶段,那肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是app,其实都是读多写少.所以针对这个情况,就是写一个主库,但是主库挂多个 ...
- LeetCode:595.大的国家
题目链接:https://leetcode-cn.com/problems/big-countries/ 题目 这里有张 World 表 +-----------------+------------ ...
- logback替换log4j
1.新建logback.xml放在src目录下(放在src下会自动加载,不需要再web.xml配置) 2.引入必要的jar包:
- 基于光线追踪的渲染中景深(Depth of field)效果的实现
图形学离线渲染中常用的透视摄像机模型时根据小孔成像的原理建立的,其实现通常是从向成像平面上发射ray,并把trace这条ray的结果作为成像平面上对应交点的采样结果.即: 图片来自<Fundam ...
- 正着打星星(js)
//让用户输入行数,使用for循环嵌套打出正着的星星来,行数等于用户输入的数字 //例如:用户输入6 // * // *** // ***** // ******* // ********* // * ...
- im_master_search_specification
中文 http://accel-archives.intra-mart.jp/2014-winter/document/iap/public_zh_CN/im_master/im_master_sea ...