第一步复数类型头文件
#ifndef COMPLEXNUMBER_H
#define COMPLEXNUMBER_H
#include <iostream>
#include <math.h>
#include <QDebug>
#define PI acos(-1)
using namespace std;
class ComplexNumber
{
public:
double Re,Im;//Re实数,Im虚数
ComplexNumber(double Re=0,double Im=0);//构造函数
};
ComplexNumber operator*(ComplexNumber j,ComplexNumber q);//乘法
ComplexNumber operator-(ComplexNumber j,ComplexNumber q);//减法
ComplexNumber operator+(ComplexNumber j,ComplexNumber q);//加法
void fft(int limit,ComplexNumber *a,int type);//递归fft,type=1为fft,type=-1为ifft
void fft1(ComplexNumber *v,int n,ComplexNumber *tmp);//递归fft
void FFT(ComplexNumber *v, int n,int len,int type);//非递归fft
#endif // COMPLEXNUMBER_H
第二步复数类型源文件
#include "complexnumber.h"
ComplexNumber::ComplexNumber(double Re, double Im)//构造函数
:Re(Re),Im(Im)
{
}
ComplexNumber operator*(ComplexNumber j,ComplexNumber q)//复数乘法
{
ComplexNumber output;
output.Re=j.Re*q.Re-j.Im*q.Im;
output.Im=j.Re*q.Im+j.Im*q.Re;
return output;
}
ComplexNumber operator-(ComplexNumber j,ComplexNumber q)//复数减法
{
ComplexNumber output;
output.Re=j.Re-q.Re;
output.Im=j.Im-q.Im;
return output;
}
ComplexNumber operator+(ComplexNumber j,ComplexNumber q)//复数加法
{
ComplexNumber output;
output.Re=j.Re+q.Re;
output.Im=j.Im+q.Im;
return output;
}
void fft(int limit, ComplexNumber *v, int type)
{
if(limit==1)//
return;
//limit>>1 = limit/2;
ComplexNumber ve[limit>>1],vo[limit>>1];
for(int i=0;i<limit;i+=2)
{
ve[i>>1]=v[i];
vo[i>>1]=v[i+1];
}
fft(limit>>1,ve,type);
fft(limit>>1,vo,type);
ComplexNumber Wn=ComplexNumber(cos(2.0*PI/limit),type*sin(2.0*PI/(double)limit));
ComplexNumber w=ComplexNumber(1,0);
//Wn单位根
for(int i=0;i<limit/2;i++,w=w*Wn)
{
v[i]=ve[i]+w*vo[i];
v[i+limit/2]=ve[i]-w*vo[i];
}
}
void fft1(ComplexNumber *v,int n,ComplexNumber *tmp)
{
if(n>1)
{
ComplexNumber *ve,*vo;
ve=tmp;
vo=tmp+n/2;
for(int i=0;i<n/2;i++)
{
ve[i]=v[2*i];
vo[i]=v[2*i+1];
}
fft1(ve,n/2,v);
fft1(vo,n/2,v);
for(int i=0;i<n/2;i++)
{
ComplexNumber w,z;
w.Re = cos(2*PI*i/(double)n);
w.Im = -sin(2*PI*i/(double)n);
z.Re = w.Re*vo[i].Re - w.Im*vo[i].Im; /* Re(w*vo[m]) */
z.Im = w.Re*vo[i].Im + w.Im*vo[i].Re; /* Im(w*vo[m]) */
v[ i ].Re = ve[i].Re + z.Re;
v[ i ].Im = ve[i].Im + z.Im;
v[i+n/2].Re = ve[i].Re - z.Re;
v[i+n/2].Im = ve[i].Im - z.Im;
}
}
}
void FFT(ComplexNumber *v, int n,int len,int type)
{
for(int i=0;i<n;i++)
{
int t=0;
for(int j=0;j<len;j++)
if((i>>j)&1)
t|=(1<<(len-j-1));
if(i<t)
swap(v[i],v[t]);
}
//处理V的位置
for(int i=1;i<n;i<<=1)
{
ComplexNumber Wn(cos(PI/i),type*sin(PI/i));
for(int L=i<<1,pos=0;pos<n;pos+=L)
{
ComplexNumber w(1,0);
for(int k=0;k<i;++k,w=w*Wn)
{
ComplexNumber x=v[pos+k];
ComplexNumber y=w*v[pos+k+i];
v[pos+k]=x+y;
v[pos+i+k]=x-y;
}
}
}
if(type==1)
return;
for(int i=0;i<=n;++i)
v[i].Re/=n;
}
第二步Qt使用复数类型
源代码链接:https://pan.baidu.com/s/1hRIcMgN70kA9NEf_-LuGuA?pwd=1fsa
提取码:1fsa