声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2376|回复: 2

[共享资源] C++编写的FFT算法函数(两种方法)

[复制链接]
发表于 2007-12-17 18:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
读研的时候用C++写的两种方法的FFT算法,FFT和IFFT是浙江大学出版社《数值分析》书的方法,记不得名字了。FFT2和IFFT2是一般信号处理书上讲的蝶形算法,都经过调试与matlab校验过。需要说明的是函数中用到的MatrixC是我自己用C++构造的一个复数矩阵类,Complex也是自己构造的复数类,各自封装了一些方法以便简化主程序,提高可读性。
void FFT(MatrixC &fk,MatrixC &Fn,int N){
  const double pi=3.1415926;
  int k,n,P,q;
  P=(int)(log10(N)/log10(2));
  MatrixC temp(fk);
  for(q=1;q<=P;q++)
  {
    for(k=0;k<(int)(pow(2,(P-q)));k++)
    {
      for(n=0;n<(int)(pow(2,(q-1)));n++)
      {
        Fn((int)(k*pow(2,q)+n),0)=temp((int)(k*pow(2,q-1)+n),0)
          +temp((int)(k*pow(2,q-1)+n+pow(2,P-1)),0);
        Fn((int)(k*pow(2,q)+n+pow(2,q-1)),0)=(temp((int)(k*pow(2,q-1)+n),0)
          -temp((int)(k*pow(2,q-1)+n+pow(2,P-1)),0))
          *Complex(cos(2*pi*k*pow(2,q-1)/N),-sin(2*pi*k*pow(2,q-1)/N));
      }
    }
    temp=Fn;
  }
}

void IFFT(MatrixC &fk,MatrixC &Fn,int N){
  const double pi=3.1415926;
  int k,n,P,q;
  P=(int)(log10(N)/log10(2));
  MatrixC temp(Fn);
  for(q=1;q<=P;q++)
  {
    for(k=0;k<(int)(pow(2,(P-q)));k++)
    {
      for(n=0;n<(int)(pow(2,(q-1)));n++)
      {
        fk((int)(k*pow(2,q)+n),0)=temp((int)(k*pow(2,q-1)+n),0)
          +temp((int)(k*pow(2,q-1)+n+pow(2,P-1)),0);
        fk((int)(k*pow(2,q)+n+pow(2,q-1)),0)=(temp((int)(k*pow(2,q-1)+n),0)
          -temp((int)(k*pow(2,q-1)+n+pow(2,P-1)),0))
          *Complex(cos(2*pi*k*pow(2,q-1)/N),sin(2*pi*k*pow(2,q-1)/N));
      }
    }
    temp=fk;
  }
  fk=fk*(1.0/N);
}

void FFT2(MatrixC &fk,MatrixC &Fn,int N){
  MatrixC ifk(fk);
  int n=(int)(log10(N)/log10(2));
  int i;
  //inverse the order of the index of fk
  int order,inverse,temp;
  for(order=0;order<N;order++){
   inverse=0;
   for(i=0;i<n;i++){
  temp=(order>>i)&1;
  temp=temp<<(n-1-i);
  inverse=inverse|temp;
   }
      ifk(order,0)=fk(inverse,0);
  }
  //FFT algorithm like butterfly
  Fn=ifk;
  int j,k,kk,d,w;
  const double pi=3.1415926;
  Complex W,Fn_temp;
  for(i=1;i<=n;i++){
   w=(int)pow(2,i);
   d=w/2;
   for(j=0;j<d;j++){
    k=j;
    W=Complex(cos(-2*pi/pow(2,i)*j),sin(-2*pi/pow(2,i)*j));
    while(k<N){
     kk=k+d;
     Fn_temp=Fn(k,0);
        Fn(k,0)=Fn(k,0)+W*Fn(kk,0);
     Fn(kk,0)=Fn_temp-W*Fn(kk,0);
     k+=w;
    }
   }
  }   
}

void IFFT2(MatrixC &fk,MatrixC &Fn,int N){
  MatrixC iFn(Fn);
  int n=(int)(log10(N)/log10(2));
  int i;
  //inverse the order of the index of fk
  int order,inverse,temp;
  for(order=0;order<N;order++){
   inverse=0;
   for(i=0;i<n;i++){
  temp=(order>>i)&1;
  temp=temp<<(n-1-i);
  inverse=inverse|temp;
   }
      iFn(order,0)=Fn(inverse,0);
  }
  //FFT algorithm like butterfly
  fk=iFn;
  int j,k,kk,d,w;
  const double pi=3.1415926;
  Complex W,fk_temp;
  for(i=1;i<=n;i++){
   w=(int)pow(2,i);
   d=w/2;
   for(j=0;j<d;j++){
    k=j;
    W=Complex(cos(-2*pi/pow(2,i)*j),-sin(-2*pi/pow(2,i)*j));
    while(k<N){
     kk=k+d;
     fk_temp=fk(k,0);
        fk(k,0)=fk(k,0)+W*fk(kk,0);
     fk(kk,0)=fk_temp-W*fk(kk,0);
     k+=w;
    }
   }
  }
  fk=fk*(1.0/N);
}

[ 本帖最后由 花如月 于 2007-12-17 18:13 编辑 ]

评分

1

查看全部评分

回复
分享到:

使用道具 举报

 楼主| 发表于 2007-12-17 18:02 | 显示全部楼层
其实现在数学工具强大,我当时自己编的原因:一是对算法本身感兴趣,二是考验下自己的C++应用能力。收获是:我现在对FFT的理论和物理意义都比较了解了。呵呵。
     有点难以看懂,我现在都看不懂了,当时注释写太少了(不好的编程习惯),不好意思!

[ 本帖最后由 hyl2323 于 2007-12-17 18:06 编辑 ]
发表于 2007-12-17 22:17 | 显示全部楼层
学习了,多谢分享!!
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-11-18 12:24 , Processed in 0.082277 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表