声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 3620|回复: 8

[FFT] [讨论]关于fft算法问题

[复制链接]
发表于 2005-9-20 09:48 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 wdhd 于 2016-3-14 14:51 编辑

傅立叶变换的程序贴出如下:



  1. #include <stdio.h>
  2. #include <math.h>
  3. #define N 64
  4. #define m 6 //2^m=N
  5. /*
  6. float twiddle[N/2]={1.0,0.707,0.0,-0.707,};
  7. float x_r[N]={1,1,1,1,0,0,0,0,};
  8. float x_i[N]; //N=8
  9. */
  10. float twiddle[N/2]={1,0.9951,0.9808,0.9570,0.9239,0.8820,0.8317,0.7733,
  11. 0.7075,0.6349,0.5561,0.4721,0.3835,0.2912,0.1961,0.0991,
  12. 0.0000,-0.0991,-0.1961,-0.2912,-0.3835,-0.4721,-0.5561,-0.6349,
  13. -0.7075,-0.7733,0.8317,-0.8820,-0.9239,-0.9570,-0.9808,-0.9951,}; //N=64
  14. float x_r[N]={1,1,1,1,1,1,1,1,
  15. 1,1,1,1,1,1,1,1,
  16. 1,1,1,1,1,1,1,1,
  17. 1,1,1,1,1,1,1,1,
  18. 0,0,0,0,0,0,0,0,
  19. 0,0,0,0,0,0,0,0,
  20. 0,0,0,0,0,0,0,0,
  21. 0,0,0,0,0,0,0,0,};
  22. float x_i[N];

  23. void fft_init()
  24. {
  25. int i;
  26. for(i=0;i<N;i++)
  27. x_i[i]=0.0;
  28. }
  29. void bitrev()
  30. {
  31. int p=1,q,i;
  32. int bit_rev[N];
  33. float xx_r[N];
  34. bit_rev[0]=0;
  35. while(p<N)
  36. {
  37. for(q=0;q<p;q++)
  38. {
  39. bit_rev[q]=bit_rev[q]*2;
  40. bit_rev[q+p]=bit_rev[q]+1;
  41. }
  42. p=p*2;
  43. }
  44. for(i=0;i<N;i++)
  45. {
  46. xx_r[i]=x_r[i];
  47. }
  48. for(i=0;i<N;i++)
  49. {
  50. x_r[i]=xx_r[bit_rev[i]];
  51. }
  52. }

  53. void display()
  54. {
  55. int i;
  56. for(i=0;i<N;i++)
  57. printf("%f\t%f\n",x_r[i],x_i[i]);
  58. }

  59. void fft1()
  60. {
  61. int L,i,b,j,p,k,tx1,tx2;
  62. float TI,TR,temp;
  63. float tw1,tw2;

  64. for(L=1;L<=m;L++)
  65. { /* for(1) */
  66. b=1; i=L-1;
  67. while(i>0)
  68. {b=b*2;i--;} /* b= 2^(L-1) */
  69. for(j=0;j<=b-1;j++) /* for (2) */
  70. { p=1; i=m-L;
  71. while(i>0) /* p=pow(2,7-L)*j; */
  72. {p=p*2; i--;}
  73. p=p*j;
  74. tx1=p%(N);
  75. tx2=tx1+(3*N)/4;
  76. tx2=tx2%(N);
  77. if (tx1>=(N/2))
  78. tw1=-twiddle[tx1-(N/2)];
  79. else
  80. tw1=twiddle[tx1];
  81. if (tx2>=(N/2))
  82. tw2=-twiddle[tx2-(N/2)];
  83. else
  84. tw2=twiddle[tx2];
  85. for(k=j;k<N;k=k+2*b) /* for (3) */
  86. {TR=x_r[k]; TI=x_i[k]; temp=x_r[k+b];
  87. x_r[k]=x_r[k]+x_r[k+b]*tw1+x_i[k+b]*tw2;
  88. x_i[k]=x_i[k]-x_r[k+b]*tw2+x_i[k+b]*tw1;
  89. x_r[k+b]=TR-x_r[k+b]*tw1-x_i[k+b]*tw2;
  90. x_i[k+b]=TI+temp*tw2-x_i[k+b]*tw1;
  91. }
  92. }
  93. }

  94. }

  95. void dft()
  96. {
  97. int i,n,k,tx1,tx2;
  98. float tw1,tw2;
  99. float xx_r[N],xx_i[N];
  100. //clear any data in Real and Imaginary result arrays prior to DFT
  101. for(k=0;k<=N-1;k++)
  102. xx_r[k]=xx_i[k]=x_i[k]=0.0;
  103. //caculate the DFT
  104. for(k=0;k<=(N-1);k++)
  105. {
  106. for(n=0;n<=(N-1);n++)
  107. {
  108. tx1=(n*k);
  109. tx2=tx1+(3*N)/4;
  110. tx1=tx1%(N);
  111. tx2=tx2%(N);
  112. if (tx1>=(N/2))
  113. tw1=-twiddle[tx1-(N/2)];
  114. else
  115. tw1=twiddle[tx1];
  116. if (tx2>=(N/2))
  117. tw2=-twiddle[tx2-(N/2)];
  118. else
  119. tw2=twiddle[tx2];
  120. xx_r[k]=xx_r[k]+x_r[n]*tw1;
  121. xx_i[k]=xx_i[k]+x_r[n]*tw2;
  122. }
  123. xx_i[k]=-xx_i[k];
  124. }
  125. //display
  126. for(i=0;i<N;i++)
  127. printf("%f\t%f\n",xx_r[i],xx_i[i]);

  128. }

  129. void main()
  130. {
  131. /*
  132. fft_init();
  133. bitrev();
  134. fft1();
  135. display(); //FFT
  136. */
  137. dft(); //DFT
  138. }
复制代码
回复
分享到:

使用道具 举报

 楼主| 发表于 2005-9-20 09:49 | 显示全部楼层

回复:(simon21)[讨论]关于fft算法问题

本帖最后由 wdhd 于 2016-3-14 14:51 编辑

  其中分别使用fft和dft做变换

  源程序如上: 其中函数fft1()代表fft变换,函数dft()代表dft变换.

  当取N=8的时候,fft和dft算出来的数据是一样的.

  fft和dft计算结果如下:

  4.000000 0.000000

  1.000000 -2.414000

  0.000000 0.000000

  1.000000 -0.414000

  0.000000 0.000000

  1.000000 0.414000

  0.000000 0.000000

  1.000000 2.414000

  Press any key to continue

  但是,当N=64的时候,fft和dft算出的数据x_r[ i ],x_ i[i ]就不相同:

  fft算出的结果如下:

  32.000000 0.000000

  0.968460 -20.365383

  0.000000 0.000000

  0.993620 -6.749197

  0.000000 0.000000

  3.875856 -1.388196

  0.000000 0.000000

  ... ... ... ... ;这里只取i=0~6的x_r[ i ],x_ i[i ]显示

  dft算出的结果如下:

  32.000000 0.000000

  2.663399 -18.705200

  -0.000000 0.000001

  2.663400 -8.407199

  0.000000 0.000000

  2.663400 -2.332000

  0.000000 0.000000

  ... ... ... ... ;这里只取i=0~6的x_r[ i ],x_ i[i ]显示

  书上说,dft和fft的计算结果应该是完全一样的.这是怎么会事?是不是程序中有问题,谢谢!
发表于 2005-9-22 21:28 | 显示全部楼层

回复:(simon21)[讨论]关于fft算法问题

本帖最后由 wdhd 于 2016-8-31 15:29 编辑

  fft的源程序不是现成的吗?看看这个网站,上面有世界上最优秀的fft算法,而且是免费的,matlab的fft就是用的他的算法。

  http://www.fftw.org/
 楼主| 发表于 2005-9-23 09:00 | 显示全部楼层

回复:(Anonymous)回复:(simon21)[讨论]关于fft算...

在某些场合也不完全通用吧,需要自己更具情况写
发表于 2005-9-23 15:45 | 显示全部楼层

回复:(simon21)回复:(Anonymous)回复:(simon2...

本帖最后由 wdhd 于 2016-3-14 14:51 编辑

  以下是引用simon21在2005-9-23 9:00:07的发言:

  在某些场合也不完全通用吧,需要自己更具情况写

  有啥不能通用的地方说来听听,长长见识啦,偶没有自己编过,

  //一向都觉得只是调用个子程序罢了

  [em06]

  
[此贴子已经被作者于2005-9-23 15:45:38编辑过]

发表于 2005-9-23 18:14 | 显示全部楼层
如果只是用在信号处理里这些程序基本够了,不过我见过一篇文章将FFT和其他算法结合起来做数值分析的,用通用程序就不行了
发表于 2005-9-24 19:03 | 显示全部楼层

回复:(simon21)[讨论]关于fft算法问题

个人感觉自己写一遍对FFT的理解程度能提高一个层次<BR>要用FFT的还是要自己写一下,不管最后用不用
发表于 2006-3-3 10:52 | 显示全部楼层
我也正在编程中.
发表于 2006-3-4 16:19 | 显示全部楼层
好主意!
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

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

GMT+8, 2024-4-28 18:33 , Processed in 0.052058 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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