首页 > 其他分享 >FFT学习笔记

FFT学习笔记

时间:2024-02-22 20:55:21浏览次数:25  
标签:Fu int FFT mid 笔记 学习 8000005 cp

目录

FFT

推荐博客

快速傅里叶变换(FFT)超详解

浅谈 FFT (终于懂一点了~~)

十分简明易懂的FFT(快速傅里叶变换)

题目链接:P3803 【模板】多项式乘法(FFT)

大致流程

系数表示法<--O(NlongN)-->点值表示法

点值表示法O(n):对应点的函数值相乘

复数

共轭复数:a+bi,a-bi

运算

z1+z2=(a+c)+(b+d)i

z1z2=(ac-bd)+(ad+bc)i=(a1a2,θ1+θ2)(另一种形式,模长相乘,极角相加)

DFT

单位根(n等分)

img

\((w^1_n)^k=w^k_n\)

\(w^k_n=cos\frac{k}{n}2\pi+isin\frac{k}{n}2\pi\)

带入的x是\(w_n^{0,1,2...n-1}\)

性质

\(w^k_n=w^{2k}_{2n}\)

\(w^{k+\frac{n}{2}}_n=w^{k}_{n}\)

\(w^0_n=w^{n}_{n}\)

FFT

IFFT

将FFT中的\(w^k_n\),改为它的共轭复数

递归版

#include<bits/stdc++.h>
#define Fu(i,a,b) for(register int i=(a);i<=(b);i++)
#define cp complex<double>
using namespace std;
const double pi=acos(-1.0);
int n,m,len=1,x;
cp a[8000005],b[8000005];
void fft(int n,cp *a,int inv){
	if(n==1) return ;
	cp b[n];
	int mid=n>>1;
	Fu(i,0,mid-1) b[i]=a[i*2],b[i+mid]=a[i*2+1];
	Fu(i,0,n-1) a[i]=b[i];
	fft(mid,a,inv),fft(mid,a+mid,inv);
	Fu(i,0,mid-1){
		cp x(cos(i*2*pi/n),inv*sin(i*2*pi/n));
		b[i]=a[i]+x*a[i+mid],b[i+mid]=a[i]-x*a[i+mid];
	}
	Fu(i,0,n-1) a[i]=b[i];
}
int main(){
	scanf("%d%d",&n,&m);
	Fu(i,0,n) scanf("%d",&x),a[i].real(1.0*x);
	Fu(i,0,m) scanf("%d",&x),b[i].real(1.0*x);
	while(len<=n+m) len<<=1;
	fft(len,a,1),fft(len,b,1);
	Fu(i,0,len) a[i]*=b[i];
	fft(len,a,-1);
	Fu(i,0,n+m) printf("%.0f ",a[i].real()/len+0.49);
	return 0;
}

迭代版(蝴蝶变化)

快速傅里叶变换(FFT)的优化

可以发现\(w^i_n\)在最终的序列中的位置下标相当于\(i\)二进制下翻转得到的数。

Fu(i,0,n-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
#include<bits/stdc++.h> //三次变二次+预处理三角函数+蝴蝶变化 
#define Fu(i,a,b) for(register int i=(a);i<=(b);i++)
#define cp complex<double>
using namespace std;
const double pi=acos(-1.0);
double ccos[8000005],ssin[8000005]; 
int n,m,len=1,x,rev[8000005],bit;
cp a[8000005],b[8000005];
void fft(int n,cp *a,int inv){
	Fu(i,0,n) if(i<rev[i]) swap(a[i],a[rev[i]]);
	for(int mid=1;mid<n;mid<<=1){
		cp wn(ccos[mid],inv*ssin[mid]);
		for(int i=0;i<n;i+=mid<<1){
			cp w0(1,0);
			Fu(j,0,mid-1){
				cp x=a[i+j],y=w0*a[i+j+mid];
				a[i+j]=x+y,a[i+j+mid]=x-y,w0*=wn;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	Fu(i,0,n) scanf("%d",&x),a[i].real(1.0*x);
	Fu(i,0,m) scanf("%d",&x),a[i].imag(1.0*x);
	while(len<=n+m) len<<=1,bit++,ccos[len]=cos(pi/len),ssin[len]=sin(pi/len);
	Fu(i,0,len) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
	fft(len,a,1);
	Fu(i,0,len) a[i]*=a[i];
	fft(len,a,-1);
	Fu(i,0,n+m) printf("%.0f ",a[i].imag()/2/len+0.49);
	return 0;
}

标签:Fu,int,FFT,mid,笔记,学习,8000005,cp
From: https://www.cnblogs.com/zhy114514/p/18024041

相关文章

  • 第三章 信息方法 笔记
    在第三章中,我对信息方法有了更深入的了解。本节详细介绍了信息方法的基本概念、特点和应用领域,让我对如何在实际中运用信息方法有了更清晰的认识。首先,明确了信息方法的定义和特点。信息方法是一种特殊的系统方法,它强调利用信息来理解和解决问题。这种方法认为,信息是系统的重要组......
  • 第六章 亲自尝试压缩数据 笔记
    在本章中,我首先了解了数据压缩的基本概念。数据压缩就是通过特定的算法,去除数据中的冗余信息,从而减少数据的存储空间和传输时间。压缩后的数据需要通过解压缩才能恢复到原始状态。这个过程听起来简单,但实际上涉及到复杂的算法和精细的处理。接下来,作者详细介绍了两种主要的压缩方......
  • GPT-GNN论文阅读笔记
    Abstract训练GNN通常需要大量的特定于任务的标记数据,这些获取是非常昂贵的,减少标记工作的一种有效方法是对具有自监督的表达性GNN进行预训练,然后将学习到的模型转移到只有少量标签的下游任务中,本文提出了GPT-GNN的框架,通过生成式预训练来初始化GNN,GPT-GNN引入了一个自监督的属性......
  • 莫队算法学习笔记
    普通莫队形式¶假设\(n=m\),那么对于序列上的区间询问问题,如果从\([l,r]\)的答案能够\(O(1)\)扩展到\([l-1,r]\)\([l+1,r]\)\([l,r-1]\)\([l,r+1]\)(即与\([l,r]\)相邻的区间)的答案,那么可以在\(O(n\sqrt{n})\)的复杂度内求出所有询问的答案。实现¶离线后排序,顺序处理......
  • RabbitMQ 学习笔记
    AMQP协议模型Server:又称为Broker,接受客户端的链接,实现AMQP实体服务Connection:连接,应用程序与Broker的网络连接channel:网络信道,几乎所有的操作都在channel中进行,是消息读写的通道,可建立多个channel,每个channel代表一个会话任务Message:消息本体,由Properties和Body组成,P......
  • 安卓家庭记账本开发笔记7(补2月3日)
    完成收支记录界面的逻辑编写代码如下:packagecom.example.myapplication1;importandroid.os.Bundle;importandroid.view.View;importandroidx.appcompat.app.AppCompatActivity;importandroidx.fragment.app.Fragment;importandroidx.viewpager2.widget.ViewPager2;import......
  • 安卓家庭记账本开发笔记6(补2月2日)
    完成自定义软键盘的绘制和逻辑编写在res文件夹中创建一个文件包命名为xml。在里面创建一个名为key的xml文件,在其中完成自定义软键盘的绘制代码如下:<?xmlversion="1.0"encoding="utf-8"?><Keyboardxmlns:android="http://schemas.android.com/apk/res/android"......
  • 安卓家庭记账本开发笔记5(补2月1日)
    完成自定义软键盘的编写以及软键盘上面的备注和时间在记录页面的代码底下加上下面的代码<android.inputmethodservice.KeyboardViewandroid:id="@+id/frag_record_keyboard"android:layout_width="match_parent"android:layout_height="wrap_content"......
  • 【图论】基环树 学习笔记
    基环树下面几个条件互相等价:一个图(连通块)是基环树联通块有n个点n条边图上存在且仅存在一个环,且环上每个节点是一颗子树的根。通常情况下树指的都是无向图,但是有向图也可以构成基环树。内向基环树:每个点都有一条出边。容易发现沿着这条边一定会走到环上“向内走”。外......
  • 学习如何在C#中轻松实现串口数据接收:清晰步骤与实例代码
     概述:以上C#示例演示了如何使用SerialPort类实现串口数据接收。通过设置串口属性、定义数据接收事件处理程序,你可以轻松地打开串口、监听数据,并在事件处理程序中对接收到的数据进行处理。这提供了一个基本框架,可根据实际需求进行定制。在C#中实现串口数据接收通常需要使用Sys......