[应用相关] 快速傅里叶变换

[复制链接]
2050|20
 楼主| tifmill 发表于 2023-9-28 06:32 | 显示全部楼层 |阅读模式
  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. }




评论

有没有反傅里叶运算  发表于 2024-4-19 14:34
Henryko 发表于 2023-9-29 19:37 | 显示全部楼层
一直没搞明白这程序是怎么实现傅里叶变化的
呐咯密密 发表于 2024-4-19 14:34 | 显示全部楼层
这个计算一次需要多久
中国龙芯CDX 发表于 2024-4-28 18:16 | 显示全部楼层
楼主科普一下相关计算可以嘛?
周半梅 发表于 2024-9-6 07:03 | 显示全部楼层

每个电容与纹波电流源的引线阻抗一样
周半梅 发表于 2024-9-6 07:03 | 显示全部楼层

每个电容与纹波电流源的引线阻抗一样
Pulitzer 发表于 2024-9-6 08:06 | 显示全部楼层

时间片轮的设计思想
童雨竹 发表于 2024-9-6 10:02 | 显示全部楼层

大大减小与其他引线之间的容性耦合
Wordsworth 发表于 2024-9-6 11:05 | 显示全部楼层

需要在做项目的过程中经历磨难
Clyde011 发表于 2024-9-6 12:08 | 显示全部楼层

硬件设计和软件设计本来就是鱼和熊掌的关系,两者不可兼得
公羊子丹 发表于 2024-9-6 13:01 | 显示全部楼层

与电感和续流二极管相连
万图 发表于 2024-9-6 14:04 | 显示全部楼层

结构化模块化的程序设计的思想,使最基本的要求
Uriah 发表于 2024-9-6 15:07 | 显示全部楼层

确定好硬件原理图,硬件布线,最后才是软件的开发
Bblythe 发表于 2024-9-6 18:06 | 显示全部楼层

在实际的项目应用当中,单片机引脚的复用相当厉害
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

1625

帖子

0

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