快速傅里叶变换(FFT)c语言实现

[复制链接]
1102|1
 楼主| linfelix 发表于 2023-9-28 10:00 | 显示全部楼层 |阅读模式
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>


  5. #define PI 3.1415926
  6. struct complex
  7. {
  8.     double real;
  9.     double image;
  10. };
  11. struct complex complex_add(struct complex c1,struct complex c2);
  12. struct complex complex_sub(struct complex c1,struct complex c2);
  13. struct complex complex_multi(struct complex c1,struct complex c2);
  14. struct complex rotation_factor(int N,int n,int k);
  15. double mold_length(struct complex c);
  16. void fft(int len, struct complex in_x[],struct complex out_y[]);




  17. int main()
  18. {
  19.     int sam[8] = {1,-1,1,-1,1,-1,1,-1};
  20.     int jhg[8] = {0,0,0,0,0,0,0,0};
  21.     struct complex x[8];
  22.     struct complex y[8];

  23.     for(int i=0;i<8;i++)
  24.     {
  25.         x[i].real = sam[i];
  26.         x[i].image = jhg[i];
  27.     }
  28.     printf("时域序列\n");

  29.     for(int i=0;i<8;i++)
  30.     {
  31.         printf("(%.2f, %.2fi) \n",x[i].real,x[i].image);
  32.     }

  33.     fft(8,x,y);

  34.     printf("频域序列\n");

  35.     for(int i=0;i<8;i++)
  36.     {
  37.         printf("(%.2f, %.2fi)\n",y[i].real,y[i].image);
  38.     }

  39.    

  40.     return 0;
  41. }

  42. struct complex complex_add(struct complex c1,struct complex c2)     //复数加法
  43. {
  44.     struct complex p;

  45.     p.real = c1.real + c2.real;
  46.     p.image = c1.image + c2.image;

  47.     return p;

  48. }

  49. struct complex complex_sub(struct complex c1,struct complex c2)     //复数减
  50. {
  51.     struct complex p;

  52.     p.real = c1.real - c2.real;
  53.     p.image = c1.image - c2.image;

  54.     return p;

  55. }

  56. struct complex complex_multi(struct complex c1,struct complex c2)  //复数乘法
  57. {
  58.     struct complex c3;
  59.     c3.real=c1.real*c2.real - c1.image *c2.image;
  60.     c3.image = c2.real* c1.image + c1.real*c2.image;

  61.     return c3;
  62. };



  63. struct complex rotation_factor(int N,int n,int k)       //旋转因子
  64. {
  65.     struct complex w;

  66.     w.real = cos(2* PI * n * k /N);
  67.     w.image = - sin(2* PI * n * k /N);

  68.     return w;
  69. }

  70. double mold_length(struct complex c)        //幅度
  71. {
  72.     return sqrt(c.real * c.real + c.image * c.image);
  73. };


  74. int reverse_num(int l,int oringin_num)          //反位序
  75. {
  76.     int q=0,m=0;

  77.     for(int k=l-1;k>=0;k--)
  78.     {
  79.         q = oringin_num % 2;
  80.         m += q*(1<<k);
  81.         oringin_num = oringin_num / 2;
  82.     }

  83.     return m;
  84. }


  85. void fft(int len, struct complex in_x[],struct complex out_y[])
  86. {
  87.     /*
  88.         param len 序列长度,目前只能是2的指数
  89.         param in_x输入的序列
  90.         param out_y输出的序列
  91.     */

  92.     int l,k,r,z,dist,q,j;       //l是级
  93.     struct complex w,tmp;
  94.     struct complex in_x_mem[len];

  95.     l = log2(len);

  96.     for(k=0;k<len;k++)
  97.     {
  98.         in_x_mem[k] = in_x[reverse_num(l,k)];       //反位序号操作
  99.     }

  100.     for(r = 0;r<l;r++)      //遍历每一级蝶形运算
  101.     {

  102.         dist = 1<<r;        //提前计算每一级的间隔距离

  103.         for( j=0;j<dist;j++ )      //计算策略是拆成上下两组,先上计算,后下计算,j是计算的起始序号
  104.         {
  105.             for(k=j;k<len;k+=(dist<<1))     //不好解释,得画图理解
  106.             {
  107.                 q = k+dist; //q同一组蝶形运算第二个序号
  108.                 z = k << (l - r -1);    //确定旋转因子的指数

  109.                 w = rotation_factor(len,1,z);
  110.                 //由于不是并行计算,必须先缓存
  111.                 tmp = in_x_mem[k];

  112.                 in_x_mem[k] = complex_add( in_x_mem[k] , complex_multi(w, in_x_mem[q]) );
  113.                 in_x_mem[q] = complex_sub(tmp , complex_multi(w, in_x_mem[q]) );

  114.             }
  115.         }
  116.     }
  117.     memcpy(out_y,in_x_mem,len*sizeof(struct complex));
  118. }




AloneKaven 发表于 2023-9-29 22:13 来自手机 | 显示全部楼层
还是没看懂是怎么实现的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

42

主题

1541

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部