FFT(快速傅里叶) c语言版

一、基本原理

      FFT算法是把长序列的DFT逐次分解为较短序列的DFT。
      按照抽取方式的不同可分为DIT-FFT(按时间抽取)和DIF-FFT(按频率抽取)算法。按蝶形运算的构成不同可分为基2,基4,基8,以及任意因子的类型。


二、计算过程


FFT(快速傅里叶) c语言版_第1张图片


按照上述公式的规律进行逐级分解,直到2点DFT,如下是N=8时的蝶形算法分析图:


    FFT(快速傅里叶) c语言版_第2张图片


三、FFT中码位倒置排序

1码位倒置的实现方法:
        (1)简单的利用按位与、或循环实现
        (2)利用公式推导的迭代方法
2、为什么要进行码位倒置
  因为由于FFT的计算特性,如果按照正常顺序输入,而没有进行码位倒置的话,就会以乱序输出,就不便于我们后续对信号的相关性质进行研究了,所以DIT-FFT算法就是在进行FFT计算之前,进行分奇偶后的码位倒置运算,即二进制数的倒位。       


3、倒位序由奇偶分组造成,以N=8为例,说明如下:

FFT(快速傅里叶) c语言版_第3张图片

FFT(快速傅里叶) c语言版_第4张图片



四、FFT代码如下

#include   
#include   
#define N 1000  
/*定义复数类型*/  
typedef struct{  
double real;  
double img;  
}complex;  
  
  
complex x[N], *W; /*输入序列,变换核*/  
int size_x=0;      /*输入序列的大小,在本程序中仅限2的次幂*/  
double PI;         /*圆周率*/  
void fft();     /*快速傅里叶变换*/  
void initW();   /*初始化变换核*/  
void change(); /*变址*/  
void add(complex ,complex ,complex *); /*复数加法*/  
void mul(complex ,complex ,complex *); /*复数乘法*/  
void sub(complex ,complex ,complex *); /*复数减法*/  
void output();/*输出快速傅里叶变换的结果*/  
  
  
  
  
int main()  
{  
    int i;                             /*输出结果*/  
    system("cls");  
    PI=atan(1)*4;  
    printf("                                        输出DIT方法实现的FFT结果\n");  
    printf("Please input the size of x:\n");//输入序列的大小  
    scanf("%d",&size_x);  
    printf("Please input the data in x[N]:\n");//输入序列的实部和虚部  
    for(i=0;i0 )    //利用按位与以及循环实现码位颠倒  
  {  
    j=j<<1;  
    j|=(k & 1);  
    k=k>>1;  
  }  
  if(j>i)    //将x(n)的码位互换  
  {  
    temp=x[i];  
    x[i]=x[j];  
    x[j]=temp;  
  }  
  }  
  output();  
}  
  
  
  
/*输出傅里叶变换的结果*/  
void output()  
{  
    int i;  
    printf("The result are as follows:\n");  
    for(i=0;i=0.0001)printf("+%.4fj\n",x[i].img);  
        else if(fabs(x[i].img)<0.0001)printf("\n");  
        else printf("%.4fj\n",x[i].img);  
    }  
}  
  
  
void add(complex a,complex b,complex *c)  //复数加法的定义  
{  
    c->real=a.real+b.real;  
    c->img=a.img+b.img;  
}  
  
  
void mul(complex a,complex b,complex *c)  //复数乘法的定义  
{  
    c->real=a.real*b.real - a.img*b.img;  
    c->img=a.real*b.img + a.img*b.real;  
}  
  
  
void sub(complex a,complex b,complex *c)  //复数减法的定义  
{  
    c->real=a.real-b.real;  
    c->img=a.img-b.img;  
}  


你可能感兴趣的:(算法小知识)