// ConsoleTemplate.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#define N 8//1024//
#define M 3////10
#define PI 3.1415927
typedef struct comp_number
{
double real;
double img;
}comp_num;
int reverse(int p)
{
int i,t=0;
for(i=M-1;i>=0&&p;i--)
{
t+=(p%2)<<i;
p/=2;
}
return t;
}
//复数相乘
comp_num comp_multy(comp_num a,comp_num b)
{
comp_num c;
c.real=a.real*b.real-a.img*b.img;
c.img=a.real*b.img+a.img*b.real;
return c;
}
//复数相加
comp_num comp_add(comp_num a,comp_num b)
{
comp_num c;
c.real=a.real+b.real;
c.img=a.img+b.img;
return c;
}
//复数相减
comp_num comp_minus(comp_num a,comp_num b)
{
comp_num c;
c.real=a.real-b.real;
c.img=a.img-b.img;
return c;
}
//comp_adjoint复数共轭
comp_num comp_adjoint(comp_num a )
{
comp_num c;
c.real=a.real;
c.img= -a.img;
return c;
}
void FFT( comp_num xt[N], comp_num cur_x[N], comp_num nex_x[N]);
void IFFT( comp_num xt[N], comp_num cur_x[N], comp_num nex_x[N]);
//int main(void)
int _tmain(int argc, _TCHAR* argv[])
{
comp_num xt[N],cur_x[N],nex_x[N];
comp_num W,sec;//蝶形运算的第二部分
int i,j,k;
int t,wn;
double x;
//初始化原始信号数据
for(i=0;i<N;i++)
{
xt[i].real= 0.001*(i+1);//cos( 2* PI* 100* i)/**/;
xt[i].img= 1;//0.0;
}
printf( "/n原结果:/n");
for(i=0;i<N;i++)
{
if(xt[i].img>=0)
printf("%lf+%lfi/n",xt[i].real,xt[i].img);
else
printf("%lf%lfi/n",xt[i].real,xt[i].img);
}
//FFT变换
FFT( xt,cur_x, nex_x);
printf( "/nFFT结果:/n");
for(i=0;i<N;i++)
{
if(cur_x[i].img>=0)
printf("%lf+%lfi/n",cur_x[i].real,cur_x[i].img);
else
printf("%lf%lfi/n",cur_x[i].real,cur_x[i].img);
//为IFFT铺垫,保存
nex_x[ i]=cur_x[ i];
}
//FFT逆变换
IFFT( nex_x,cur_x, nex_x);
//cout<<"/nIFFT还原结果/n";
printf( "/nIFFT还原结果/n");
for(i=0;i<N;i++)
{
if(cur_x[i].img>=0)
printf("%lf+%lfi/n",cur_x[i].real,cur_x[i].img);
else
printf("%lf%lfi/n",cur_x[i].real,cur_x[i].img);
}
scanf("%f", i);
return 0;
}
//FFT蝶形算法
//xt为原数据,cur_x为最后所求的数据,nex_x为中间变量
void FFT( comp_num xt[N], comp_num cur_x[N], comp_num nex_x[N])
{
int i,j,k;
int t,wn;
double x;
comp_num W,sec;//蝶形运算的第二部分
//调整数据顺序
for(i=0;i<N;i++)
{
j=reverse(i);//反向进位法
cur_x[j]=xt[i];
}
//FFT
for(i=0;i<M;i++)
{
t=1<<i;//间隔
wn=t*2;//计算W变量
for(j=0;j<N/wn;j++)
{
for(k=0;k<t;k++)//连续加号个数
{
x=2*PI*k/wn;
W.real=cos(x);W.img=-sin(x);
sec=comp_multy(W,cur_x[j*wn+t+k]);
nex_x[j*wn+k]=comp_add(cur_x[j*wn+k],sec);
nex_x[j*wn+t+k]=comp_minus(cur_x[j*wn+k],sec);
}
}
for(j=0;j<N;j++)
cur_x[j]=nex_x[j];
}
}
//IFFT:调用FFT
//xt为原数据,cur_x为最后所求的数据,nex_x为中间变量
void IFFT( comp_num xt[N], comp_num cur_x[N], comp_num nex_x[N])
{
int i;
for(i=0;i<N;i++)
{
nex_x[ i]=comp_adjoint( xt[ i]);
}
FFT( nex_x,cur_x, nex_x);
for(i=0;i<N;i++)
{
cur_x[ i]=comp_adjoint( cur_x[ i]);
cur_x[i].real /= N; cur_x[i].img /= N;
}
}