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 ...
随机推荐
- 【题解】Luogu P5319 [BJOI2019]奥术神杖
原题传送门 题目让我们最大化\(val=\sqrt[k]{\prod_{i=1}^k w_i}\),其中\(k\)是咒语的个数,\(w_i\)是第\(i\)个咒语的神力 看着根号和累乘不爽,我们两边同 ...
- FusionInsight大数据开发---Spark应用开发
Spark应用开发 要求: 了解Spark基本原理 搭建Spark开发环境 开发Spark应用程序 调试运行Spark应用程序 YARN资源调度,可以和Hadoop集群无缝对接 Spark适用场景大多 ...
- flask异常处理:abort、errorhandler、app_errorhandler,封装全局异常处理
目录 1. abort() 1.1 使用方式一:传递一个错误码 1.2 使用方式二:传递一个json格式字符串 1.3 使用方式三:传递一个响应体 2. errorhandler 2.1 简单使用: ...
- 史上最全HashMap红黑树解析
HashMap红黑树解析 红黑树介绍 TreeNode结构 树化的过程 红黑树的左旋和右旋 TreeNode的左旋和右旋 红黑树的插入 TreeNode的插入 红黑树的删除 TreeNode的删除节点 ...
- Java Mockito 笔记
Mockito 1 Overview 2 Maven 项目初始化 3 示例 3.1 第一个示例 3.2 自动 Mock 3.3 Mock 返回值 3.4 Mock 参数 3.5 自动注入 Mock 对 ...
- C#读写修改设置调整UVC摄像头画面-清晰度
有时,我们需要在C#代码中对摄像头的清晰度进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄 ...
- DEVexpress GridControl 属性设置
1. 如何解决单击记录整行选中的问题 View->OptionsBehavior->EditorShowMode 设置为:Click 2. 如何新增一条记录 (1).gridView.Ad ...
- WindowsXP序列号产生原理(椭圆曲线法)
WindowsXP序列号产生原理(椭圆曲线法) 来源 https://blog.csdn.net/zhiyuan411/article/details/5156330 参考 https://www. ...
- k8s+jenkins(DevOps全流程)
k8s集群搭建是参照别人的,链接找不到了.需要5台机器,3主2从,主最少搭建3台才能实现高可用. 流程jenkins打包代码 >> 把打包代码生成镜像 >> 备份镜像库旧镜像 ...
- Python基础7
深复制 & 浅复制 列表,字符串 都有深浅复制,用 id() 函数来看 所谓“旧瓶装新酒,新瓶装旧酒”