[学习资料] C语言FFT

[复制链接]
1861|19
 楼主| dspmana 发表于 2023-3-27 10:00 | 显示全部楼层 |阅读模式
  1. /************FFT***********/

  2. #include < stdio.h >
  3.     #include < math.h >
  4.     #include < stdlib.h >
  5.     #define N 1000
  6. typedef struct

  7. {

  8.     double real;

  9.     double img;

  10. }
  11. complex;

  12. void fft(); /*快速傅里叶变换*/

  13. void ifft(); /*快速傅里叶逆变换*/

  14. void initW();

  15. void change();

  16. void add(complex, complex, complex * ); /*复数加法*/

  17. void mul(complex, complex, complex * ); /*复数乘法*/

  18. void sub(complex, complex, complex * ); /*复数减法*/

  19. void divi(complex, complex, complex * ); /*复数除法*/

  20. void output(); /*输出结果*/

  21. complex x[N], * W; /*输出序列的值*/

  22. int size_x = 0; /*输入序列的长度,只限2的N次方*/

  23. double PI;

  24. int main()

  25. {

  26.     int i, method;

  27.     system("cls");

  28.     PI = atan(1) * 4;

  29.     printf("Please input the size of x:\n");

  30.     /*输入序列的长度*/

  31.     scanf("%d", & size_x);

  32.     printf("Please input the data in x[N]:(such as:5 6)\n");

  33.     /*输入序列对应的值*/

  34.     for (i = 0; i < size_x; i++)

  35.         scanf("%lf %lf", & x[i].real, & x[i].img);

  36.     initW();

  37.     /*选择FFT或逆FFT运算*/

  38.     printf("Use FFT(0) or IFFT(1)?\n");

  39.     scanf("%d", & method);

  40.     if (method == 0)

  41.         fft();

  42.     else

  43.         ifft();

  44.     output();

  45.     return 0;

  46. }

  47. /*进行基-2 FFT运算*/

  48. void fft()

  49. {

  50.     int i = 0, j = 0, k = 0, l = 0;

  51.     complex up, down, product;

  52.     change();

  53.     for (i = 0; i < log(size_x) / log(2); i++)

  54.     {

  55.         l = 1 << i;

  56.         for (j = 0; j < size_x; j += 2 * l)

  57.         {

  58.             for (k = 0; k < l; k++)

  59.             {

  60.                 mul(x[j + k + l], W[size_x * k / 2 / l], & product);

  61.                 add(x[j + k], product, & up);

  62.                 sub(x[j + k], product, & down);

  63.                 x[j + k] = up;

  64.                 x[j + k + l] = down;

  65.             }

  66.         }

  67.     }

  68. }

  69. void ifft()

  70. {

  71.     int i = 0, j = 0, k = 0, l = size_x;

  72.     complex up, down;

  73.     for (i = 0; i < (int)(log(size_x) / log(2)); i++) /*蝶形运算*/

  74.     {

  75.         l /= 2;

  76.         for (j = 0; j < size_x; j += 2 * l)

  77.         {

  78.             for (k = 0; k < l; k++)

  79.             {

  80.                 add(x[j + k], x[j + k + l], & up);

  81.                 up.real /= 2;
  82.                 up.img /= 2;

  83.                 sub(x[j + k], x[j + k + l], & down);

  84.                 down.real /= 2;
  85.                 down.img /= 2;

  86.                 divi(down, W[size_x * k / 2 / l], & down);

  87.                 x[j + k] = up;

  88.                 x[j + k + l] = down;

  89.             }

  90.         }

  91.     }

  92.     change();

  93. }

  94. void initW()

  95. {

  96.     int i;

  97.     W = (complex * ) malloc(sizeof(complex) * size_x);

  98.     for (i = 0; i < size_x; i++)

  99.     {

  100.         W[i].real = cos(2 * PI / size_x * i);

  101.         W[i].img = -1 * sin(2 * PI / size_x * i);

  102.     }

  103. }

  104. void change()

  105. {

  106.     complex temp;

  107.     unsigned short i = 0, j = 0, k = 0;

  108.     double t;

  109.     for (i = 0; i < size_x; i++)

  110.     {

  111.         k = i;
  112.         j = 0;

  113.         t = (log(size_x) / log(2));

  114.         while ((t--) > 0)

  115.         {

  116.             j = j << 1;

  117.             j |= (k & 1);

  118.             k = k >> 1;

  119.         }

  120.         if (j > i)

  121.         {

  122.             temp = x[i];

  123.             x[i] = x[j];

  124.             x[j] = temp;

  125.         }

  126.     }

  127. }

  128. void output() /*输出结果*/

  129. {

  130.     int i;

  131.     printf("The result are as follows\n");

  132.     for (i = 0; i < size_x; i++)

  133.     {

  134.         printf("%.4f", x[i].real);

  135.         if (x[i].img >= 0.0001)

  136.             printf("+%.4fj\n", x[i].img);

  137.         else if (fabs(x[i].img) < 0.0001)

  138.             printf("\n");

  139.         else

  140.             printf("%.4fj\n", x[i].img);

  141.     }

  142. }

  143. void add(complex a, complex b, complex * c)

  144. {

  145.     c - > real = a.real + b.real;

  146.     c - > img = a.img + b.img;

  147. }

  148. void mul(complex a, complex b, complex * c)

  149. {

  150.     c - > real = a.real * b.real - a.img * b.img;

  151.     c - > img = a.real * b.img + a.img * b.real;

  152. }

  153. void sub(complex a, complex b, complex * c)

  154. {

  155.     c - > real = a.real - b.real;

  156.     c - > img = a.img - b.img;

  157. }

  158. void divi(complex a, complex b, complex * c)

  159. {

  160.     c - > real = (a.real * b.real + a.img * b.img) / (

  161.         b.real * b.real + b.img * b.img);

  162.     c - > img = (a.img * b.real - a.real * b.img) / (b.real * b.real + b.img * b.img);

  163. }


wowu 发表于 2023-4-13 17:31 | 显示全部楼层
FFT(Fast Fourier Transformation),即为快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的
tpgf 发表于 2023-4-14 09:20 | 显示全部楼层
想要看懂这个代码 就得懂傅里叶变换 就得明白复数是什么
xiaoqizi 发表于 2023-4-14 11:10 | 显示全部楼层
在这个过程中我们如何解决复数运算的问题呢
木木guainv 发表于 2023-4-14 11:30 | 显示全部楼层
FFT算法是把长序列的DFT逐次分解为较短序列的DFT
磨砂 发表于 2023-4-14 12:04 | 显示全部楼层
FFT即为快速傅里叶变换,是离散傅里叶变换的快速算法,它是根据离散傅里叶变换的奇、偶、虚、实等特性,对离散傅里叶变换的算法进行改进获得的
晓伍 发表于 2023-4-14 12:19 | 显示全部楼层
FFT算法按照抽取方式的不同可分为DIT-FFT(按时间抽取)和DIF-FFT(按频率抽取)算法
abotomson 发表于 2023-5-11 15:25 | 显示全部楼层
二维FFT相当于对行和列分别进行一维FFT运算?
mickit 发表于 2023-5-11 16:21 | 显示全部楼层
MATLAB和Python等科学计算工具中都包括了FFT相关的库函数
jimmhu 发表于 2023-5-11 16:52 | 显示全部楼层
如何用C语言或汇编语言实现FFT(快速傅里叶)变换,
lihuami 发表于 2023-5-11 17:39 | 显示全部楼层
实现FFT需要了解FFT算法原理,以及掌握C语言的相关编程技巧。
sdCAD 发表于 2023-5-11 18:57 | 显示全部楼层
C语言中有一些现成的FFT库函数,例如FFTW、PFFFT等。使用这些库函数可以更方便地实现FFT操作,而且通常具有较高的精度和效率。
averyleigh 发表于 2023-5-11 19:18 | 显示全部楼层
如果想要深入学习FFT算法或者需要对FFT算法进行优化,则可以手动编写FFT代码。FFT算法包括Cooley-Tukey算法、Radix-2算法等,可以根据具体情况进行选择
kkzz 发表于 2023-5-11 19:35 | 显示全部楼层
用C语言实现FFT算法,还要做频谱分析
fengm 发表于 2023-5-11 20:41 | 显示全部楼层
想用C语言实现一个1024点的FFT
jimmhu 发表于 2023-5-11 20:53 | 显示全部楼层
傅里叶变换用C语言程序怎么实现?
youtome 发表于 2023-5-11 21:03 | 显示全部楼层
FFT的最优算法是什么?              
qiufengsd 发表于 2023-5-11 22:05 | 显示全部楼层
使用现成的库函数,可以快速实现FFT操作。
理想阳 发表于 2023-8-10 09:37 | 显示全部楼层
要实现FFT需要了解FFT算法的原理,并掌握c语言的编程技巧。
LinkMe 发表于 2023-8-10 09:49 | 显示全部楼层
二维FFT分别相当于一维FFT的行和列计算?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

2858

帖子

2

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