FFT代码详解
关于FFT原理部分的介绍,在网上已经有很多了,所以在此只讲代码实现部分的内容。
原理可以参考https://www.cnblogs.com/RabbitHu/p/FFT.html
推荐看完它的原理解释再来看这里的代码解释
废话不多说,上代码(多项式乘法)
#include <iostream>
#include <cstdio>
#include <cmath>
#define N 4000001
using namespace std;
struct cp//手写复数类可以卡常
{
double real,imag;
};
cp operator +(cp a,cp b)
{
return (cp){a.real+b.real,a.imag+b.imag};
}
cp operator -(cp a,cp b)
{
return (cp){a.real-b.real,a.imag-b.imag};
}
复数乘法:设$R_{a}$表示$a$的实部系数,$I_{a}$表示$a$的虚部系数
则$a*b$
$=(R_{a}+I_{a})*(R_{b}+I_{b})$
$=R_{a}*R_{b}+R_{a}*I_{b}+R_{b}*I_{a}+I_{a}*I_{b}$
因为$i^2=-1$
所以结果的实部为$R_{a}*R_{b}-I_{a}*I_{b}$
虚部为$R_{a}*I_{b}+R_{b}*I_{a}$
cp operator *(cp a,cp b)
{
return (cp){a.real*b.real-a.imag*b.imag,a.real*b.imag+a.imag*b.real};
}
double pi=acos(-1.0);
int lim,rev[N],len;
cp w[N],inv[N],a[N],b[N];
void get_w()
{
for(int i=0;i<=lim;i++)
{
double angle=(double)i*2*pi/lim;
w[i].imag=sin(angle);
w[i].real=cos(angle);
inv[i]=(cp){w[i].real,-w[i].imag};
}
}
fft参数解释
$arr:$系数数组,在$fft$后变为点值数组,$arr_{i}$表示将$w^i_n$带入多项式后求得的值
$w:$预处理好的w单位根,在$fft$的时候正常带入即可,在$idft$的时候带入单位根的倒数(具体参见$idft$)void fft(cp *arr,cp *w)
{
for(int i=0;i<lim;i++)
{
//处理每一个系数在分治过程中的实际位置;
//if是因为只需交换一次,所以选择由小的一方来执行
if(i<rev[i]) swap(arr[i],arr[rev[i]]);
}
for(int i=2;i<=lim;i*=2)//枚举区间长度
{
int l=i/2;
for(int j=0;j<lim;j+=i)//枚举区间位置,这些区间是互不相交的
{
//枚举带入的单位根w(k,l),k>=l的单位根也可以在这里一并求出
for(int k=0;k<l;k++)
{
意义变更
在这里$arr$的意义从系数变为$w^k_i$的点值,$a_{j,j+i-1}$分别表示将$w^{0,i-1}_i$的点值
下面的的t相当于文首博客中的$w^k_n * A_2(w^k_{n \over 2})$
cp t=arr[j+k+l]*w[lim/i*k];//w(k,i)=w(k/i,1)=w(n*k/i,n)
arr[j+k+l]=arr[j+k]-t;
arr[j+k]=arr[j+k]+t;
}
}
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<=n;i++) scanf("%lf",&a[i].real);
for(int i=0;i<=m;i++) scanf("%lf",&b[i].real);
lim=1;
while(lim<=n+m) len++,lim<<=1;//这样会比用cmath的log要快?
for(int i=0;i<lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
get_w();
fft(a,w);
fft(b,w);
for(int i=0;i<=lim;i++) a[i]=a[i]*b[i];
fft(a,inv);
for(int i=0;i<=n+m;i++) printf("%d ", (int)(a[i].real/lim+0.5));
//除以lim的原因具体参见idft,0.5是为了四舍五入
}
FFT代码详解的更多相关文章
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- ASP.NET MVC 5 学习教程:生成的代码详解
原文 ASP.NET MVC 5 学习教程:生成的代码详解 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...
- Github-karpathy/char-rnn代码详解
Github-karpathy/char-rnn代码详解 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2016-1-10 ...
- 代码详解:TensorFlow Core带你探索深度神经网络“黑匣子”
来源商业新知网,原标题:代码详解:TensorFlow Core带你探索深度神经网络“黑匣子” 想学TensorFlow?先从低阶API开始吧~某种程度而言,它能够帮助我们更好地理解Tensorflo ...
- JAVA类与类之间的全部关系简述+代码详解
本文转自: https://blog.csdn.net/wq6ylg08/article/details/81092056类和类之间关系包括了 is a,has a, use a三种关系(1)is a ...
- Java中String的intern方法,javap&cfr.jar反编译,javap反编译后二进制指令代码详解,Java8常量池的位置
一个例子 public class TestString{ public static void main(String[] args){ String a = "a"; Stri ...
- Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测
Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测 2017年12月13日 17:39:11 机器之心V 阅读数:5931 近日,Artur Suilin 等人发布了 Kaggl ...
- 基础 | batchnorm原理及代码详解
https://blog.csdn.net/qq_25737169/article/details/79048516 https://www.cnblogs.com/bonelee/p/8528722 ...
- 非极大值抑制(NMS,Non-Maximum Suppression)的原理与代码详解
1.NMS的原理 NMS(Non-Maximum Suppression)算法本质是搜索局部极大值,抑制非极大值元素.NMS就是需要根据score矩阵和region的坐标信息,从中找到置信度比较高的b ...
随机推荐
- Neo4j学习——基本操作(一)
由于开始学习知识图谱,因此需要涉及到neo4j的使用一.介绍neo4j是一个图形数据库基于Java开发而成,因此需要配置jvm才可以运行配置请参考我前面的一篇blog:https://www.cnbl ...
- 『2019Summer Algorithms』
一个暑假两次集训,感觉学了好多好多的东西,也挖了好多好多的坑,于是就决定写一篇关于算法的总结,用于熟悉新算法,也留下一点对新算法的理解. AC自动机 简单的说就是在\(trie\)树上实现\(KMP\ ...
- Python Web 之 Flask SQLalchemy
Flask-SQLalchemy 一. 一对多 A表中的一条记录与B表中的多天记录关联 语法实现: 在"多"实体类中增加 外键列名 = db.Column(db.Integer, ...
- 封装:WPF基于MediaElement封装的视频播放器
原文:封装:WPF基于MediaElement封装的视频播放器 一.目的:应用MediaElement创建媒体播放器 二.效果图 三.目前支持功能 播放.暂停.停止.快进.快退.声音大小.添加播放列表 ...
- ElasticSearch 中文分词搜索环境搭建
ElasticSearch 是强大的搜索工具,并且是ELK套件的重要组成部分 好记性不如乱笔头,这次是在windows环境下搭建es中文分词搜索测试环境,步骤如下 1.安装jdk1.8,配置好环境变量 ...
- 14、vue-cli脚手架搭建项目
1:全局安装vue-cli:npm install --global vue-cli2:进入你的项目目录:cd myProject3:初始化创建项目:vue init webpack vue-demo ...
- python实现广度优先搜索
from collections import deque #解决从你的人际关系网中找到芒果销售商的问题#使用字典表示映射关系graph = {} graph["you"] = [ ...
- Appium-desktop元素定位
一.打开 appium-desktop ,点击 start session 二.打开后,点击屏幕右上角的搜索按钮 三.然后会打开配置页面,在本地服务配置信息同上面写的代码链接配置.填入正确的信息后,点 ...
- 微信小程序 子组件调用父组件方法
原文连接 ---> https://blog.csdn.net/qq_40190624/article/details/87972265 组件 js: var value = 123; ...
- TI DSP数据长度
环境CCS7.2 平台C6748 结果: sizeof short int is 2sizeof int is 4sizeof long is 4sizeof unsigned long is 4si ...