FFT快速傅立叶算法纯C语言版本(转)


 
 
  1. </pre><p>快速离散傅立叶变换FFT利用DFT计算的对称性实现的,具体的介绍网上一大堆。这次自己写了个定点FFT头文件,直接用C语言写的很容易移植。</p><p></p><p><pre name= "code" class= "cpp"> /*
  2. 快速离散傅立叶算法V1.0
  3. 含有:FFT,IFFT
  4. made by xyt
  5. 2015/7/8
  6. C语言
  7. */
  8. #ifndef _FFT_H
  9. #define _FFT_H
  10. #include<math.h>
  11. #define FFT_N 8 //点数,要求2的次方
  12. #define PI 3.14159265354
  13. struct fft_complex{
  14. double r,i;
  15. };
  16. int fft_fi(double in){ //四舍五入转整
  17. if((in-( int)in)> 0.5) return ( int)in+ 1;
  18. else return ( int)in;
  19. }
  20. int fft_fac2(int n){ //返回log2(n)
  21. int count= 0;
  22. while(n/ 2!= 0){
  23. n/= 2;count++;
  24. }
  25. return count;
  26. }
  27. int fft_turndat(int n,int num){
  28. int g=n,m,r= 0;
  29. int count= 0;
  30. while(num/ 2!= 0){
  31. num/= 2;count++;
  32. }
  33. while(count>= 0){
  34. m=g% 2;
  35. r+=m* pow( 2,--count);
  36. g/= 2;
  37. }
  38. return r;
  39. }
  40. fft_complex fft_t(fft_complex a){
  41. fft_complex tmp;
  42. tmp.i= -1*a.i;
  43. tmp.r= -1*a.r;
  44. return tmp;
  45. }
  46. fft_complex fft_multi(fft_complex a,fft_complex b){
  47. fft_complex tmp;
  48. tmp.r=a.r*b.r-a.i*b.i;
  49. tmp.i=a.r*b.i+a.i*b.r;
  50. return tmp;
  51. }
  52. fft_complex fft_add(fft_complex a,fft_complex b){
  53. fft_complex tmp;
  54. tmp.r=a.r+b.r;
  55. tmp.i=a.i+b.i;
  56. return tmp;
  57. }
  58. /* 定点FFT,返回两个double型数组分别是实部和虚部 */
  59. void FFT(int *in,double *outr,double *outi)
  60. {
  61. int i,j;
  62. int deep;
  63. const int N=FFT_N/ 2;
  64. fft_complex W[N];
  65. W[ 0].r= 1;W[ 0].i= 0;
  66. W[ 1].r= cos( 2.0*PI/FFT_N);
  67. W[ 1].i= sin( 2.0*PI/FFT_N);
  68. for(i= 2;i<N;i++){
  69. W[i]=fft_multi(W[ 1],W[i -1]);
  70. }
  71. deep=fft_fac2(FFT_N);
  72. int g= 1;
  73. int ne= 0,ge= 0;
  74. fft_complex left[FFT_N];
  75. fft_complex right[FFT_N];
  76. for(i= 0;i<FFT_N;i++){
  77. left[i].r=in[fft_turndat(i,FFT_N)];
  78. left[i].i= 0;
  79. }
  80. fft_complex tpp;
  81. int mggtmp;
  82. while( 1)
  83. {
  84. if(deep== 0) break;
  85. int adt= pow( 2,deep -1);
  86. mggtmp= pow( 2,g);
  87. for(i= 0;i<FFT_N;i+=mggtmp){
  88. ne= 0;ge= 0;
  89. for(j= 0;j<mggtmp;j++){
  90. if(j<mggtmp/ 2){
  91. tpp=fft_multi(left[i+j+mggtmp/ 2],W[ne]);
  92. right[i+j]=fft_add(left[i+j],tpp);ne+=adt;
  93. } else{
  94. tpp= fft_t(fft_multi(left[i+j],W[ge]));
  95. right[i+j]=fft_add(left[i+j-mggtmp/ 2],tpp);ge+=adt;
  96. }
  97. }
  98. }
  99. for(i= 0;i<FFT_N;i++){
  100. left[i]=right[i];
  101. }
  102. deep--;g++;
  103. }
  104. for(i= 0;i<FFT_N;i++){
  105. outr[i]=left[i].r;
  106. outi[i]= -1*left[i].i;
  107. }
  108. }
  109. /* 定点IFFT,输入实部和虚部,返回时域int类型 */
  110. void IFFT(double *inr,double *ini,int *out)
  111. {
  112. int i,j;
  113. int deep;
  114. const int N=FFT_N/ 2;
  115. fft_complex W[N];
  116. W[ 0].r= 1;W[ 0].i= 0;
  117. W[ 1].r= cos( 2.0*PI/FFT_N);
  118. W[ 1].i= -1* sin( 2.0*PI/FFT_N);
  119. for(i= 2;i<N;i++){
  120. W[i]=fft_multi(W[ 1],W[i -1]);
  121. }
  122. deep=fft_fac2(FFT_N);
  123. int g= 1;
  124. int ne= 0,ge= 0;
  125. fft_complex left[FFT_N];
  126. fft_complex right[FFT_N];
  127. for(i= 0;i<FFT_N;i++){
  128. left[i].r=inr[fft_turndat(i,FFT_N)];
  129. left[i].i= -1*ini[fft_turndat(i,FFT_N)];
  130. }
  131. fft_complex tpp;
  132. int mggtmp;
  133. while( 1)
  134. {
  135. if(deep== 0) break;
  136. int adt= pow( 2,deep -1);
  137. mggtmp= pow( 2,g);
  138. for(i= 0;i<FFT_N;i+=mggtmp){
  139. ne= 0;ge= 0;
  140. for(j= 0;j<mggtmp;j++){
  141. if(j<mggtmp/ 2){
  142. tpp=fft_multi(left[i+j+mggtmp/ 2],W[ne]);
  143. right[i+j]=fft_add(left[i+j],tpp);ne+=adt;
  144. } else{
  145. tpp= fft_t(fft_multi(left[i+j],W[ge]));
  146. right[i+j]=fft_add(left[i+j-mggtmp/ 2],tpp);ge+=adt;
  147. }
  148. }
  149. }
  150. for(i= 0;i<FFT_N;i++){
  151. left[i]=right[i];
  152. }
  153. deep--;g++;
  154. }
  155. for(i= 0;i<FFT_N;i++){
  156. out[i]=fft_fi(left[i].r/FFT_N);
  157. }
  158. }
  159. #endif




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值