快速傅里叶变换(FFT)源代码

为了看明白那堆积分变换,不得不把复变函数扫了一遍,可看完了,才发现原来这堆变换说白了只是一些数字游戏,也没用到啥复变函数的知识。最后,用C++程序实现了下FFT,也算告一段落,代码如下:

 

  1. #include <iostream>
  2. #include <fstream>
  3. #include <math.h>
  4. using namespace std;
  5. const double PI = 3.14159265358979323846;
  6. int n;  // 数据个数 = 2的logn次方
  7. int logn;
  8. /// 复数结构体
  9. struct stCompNum 
  10. {
  11.     double re;
  12.     double im;
  13. };
  14. stCompNum* pData1 = NULL;
  15. stCompNum* pData2 = NULL;
  16. /// 正整数位逆序后输出
  17. int reverseBits(int value, int bitCnt)
  18. {
  19.     int i;
  20.     int ret = 0;
  21.     
  22.     for(i=0; i<bitCnt; i++)
  23.     {
  24.         ret |= (value & 0x1) << (bitCnt - 1 - i);
  25.         value >>= 1;
  26.     }
  27.     return ret;
  28. }
  29. void main()
  30. {
  31.     ifstream fin("data.txt");
  32.     int i,j,k;
  33.     // input logn
  34.     fin>>logn;
  35.     // calculate n
  36.     for(i=0, n=1; i<logn; i++) n *= 2;
  37.     // malloc memory space
  38.     pData1 = new stCompNum[n];
  39.     pData2 = new stCompNum[n];
  40.     // input raw data
  41.     for(i=0; i<n; i++) fin>>pData1[i].re;
  42.     for(i=0; i<n; i++) fin>>pData1[i].im;
  43.     // FFT transform
  44.     int cnt = 1;
  45.     for(k=0; k<logn; k++)
  46.     {
  47.         for(j=0; j<cnt; j++)
  48.         {
  49.             int len = n / cnt;
  50.             double c = - 2 * PI / len;
  51.             for(i=0; i<len/2; i++)
  52.             {
  53.                 int idx = len * j + i;
  54.                 pData2[idx].re = pData1[idx].re + pData1[idx + len/2].re;
  55.                 pData2[idx].im = pData1[idx].im + pData1[idx + len/2].im;
  56.             }
  57.             for(i=len/2; i<len; i++)
  58.             {
  59.                 double wcos = cos(c * (i - len/2));
  60.                 double wsin = sin(c * (i - len/2));
  61.                 int idx = len * j + i;
  62.                 stCompNum tmp;
  63.                 tmp.re = pData1[idx - len/2].re - pData1[idx].re;
  64.                 tmp.im = pData1[idx - len/2].im - pData1[idx].im;
  65.                 pData2[idx].re = tmp.re * wcos - tmp.im * wsin;
  66.                 pData2[idx].im = tmp.re * wsin + tmp.im * wcos;
  67.             }
  68.         }
  69.         cnt <<= 1;
  70.         stCompNum* pTmp = NULL;
  71.         pTmp   = pData1;
  72.         pData1 = pData2;
  73.         pData2 = pTmp;
  74.     }
  75.     // resort
  76.     for(i=0; i<n; i++)
  77.     {
  78.         int rev = reverseBits(i, logn);
  79.         stCompNum tmp;
  80.         if(rev > i)
  81.         {
  82.             tmp         = pData1[i];
  83.             pData1[i]   = pData1[rev];
  84.             pData1[rev] = tmp;
  85.         }
  86.     }
  87.     // output result data
  88.     for(i=0; i<n; i++) cout<<pData1[i].re<<"/t";
  89.     cout<<endl;
  90.     for(i=0; i<n; i++) cout<<pData1[i].im<<"/t";
  91.     cout<<endl;
  92.     // free memory space
  93.     delete []pData1;
  94.     delete []pData2;
  95.     fin.close();
  96.     system("pause");
  97. }

输入文件data.txt的内容如下:

4

2.2 4.5 6.7 8.5 10.2 12.3 14.5 16.2 19.3 21.2 25.2 29.4 36.4 39.2 45.2 50.1

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

 

你可能感兴趣的:(快速傅里叶变换(FFT)源代码)