fft.c
上传用户:bjtelijie
上传日期:2010-01-01
资源大小:87k
文件大小:6k
源码类别:

数学计算

开发平台:

Visual C++

  1. #include  <stdio.h>
  2. #include  <stdlib.h>
  3. #include  <math.h>
  4. #define  PI  3.14159265358979323846
  5. struct  COMPLEX
  6. {
  7. float  re;
  8. float  im;
  9. } cplx , * Hfield , * S , * R , * w;
  10. int  n , m;
  11. int  ln , lm;
  12. void  initiate ();
  13. void  dfft ();
  14. void  rdfft ();
  15. void  showresult ();
  16. void  fft (int l , int k);
  17. int  reverse (int t , int k);
  18. void  W (int l);
  19. int  loop (int l);
  20. void  conjugate ();
  21. void  add (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z);
  22. void  sub (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z);
  23. void  mul (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z);
  24. struct  COMPLEX  * Hread(int i , int j);
  25. void  Hwrite (int i , int j , struct  COMPLEX x);
  26. void  main ()
  27. {
  28. initiate ();
  29. printf("n原始数据:n");
  30. showresult();
  31. getchar ();
  32. dfft ();
  33. printf("n快速复利叶变换后的结果:n");
  34. showresult ();
  35. getchar ();
  36. rdfft ();
  37. printf("n快速复利叶逆变换后的结果:n");
  38. showresult ();
  39. getchar ();
  40. free (Hfield);
  41. }
  42. void  initiate ()
  43. {//程序初始化操作,包括分配内存、读入要处理的数据、进行显示等
  44. FILE  * df;
  45.     
  46. df = fopen ("data.txt" , "r");
  47. fscanf (df , "%5d" , &n);
  48. fscanf (df , "%5d" , &m);
  49. if ((ln = loop (n)) == -1)
  50. {
  51. printf (" 列数不是2的整数次幂 ");
  52. exit (1);
  53. }
  54. if ((lm = loop (m)) == -1)
  55. {
  56. printf (" 行数不是2的整数次幂 ");
  57. exit (1);
  58. }
  59. Hfield = (struct  COMPLEX *) malloc (n * m * sizeof (cplx));
  60. if (fread (Hfield , sizeof (cplx) , m * n , df) != (unsigned) (m * n))
  61. {
  62. if (feof (df)) printf (" Premature end of file ");
  63. else printf (" File read error ");
  64. }
  65. fclose (df);
  66. }
  67. void  dfft ()
  68. {//进行二维快速复利叶变换
  69. int  i , j;
  70. int  l , k;
  71.     
  72. l = n;
  73. k = ln;
  74. w = (struct  COMPLEX *) calloc (l , sizeof (cplx));
  75. R = (struct  COMPLEX *) calloc (l , sizeof (cplx));
  76. S = (struct  COMPLEX *) calloc (l , sizeof(cplx));
  77. W (l);
  78. for ( i = 0 ; i < m ; i++ )
  79. {//按行进行快速复利叶变换
  80. for (j = 0 ; j < n ; j++)
  81. {
  82. S[j].re = Hread (i , j)->re;
  83. S[j].im = Hread (i , j)->im;
  84. }
  85. fft(l , k);
  86. for (j = 0 ; j < n ; j++)
  87. Hwrite (i , j , R[j]);
  88. }
  89. free (R);
  90. free (S);
  91. free (w);
  92. l = m;
  93. k = lm;
  94. w = (struct  COMPLEX *) calloc (l , sizeof (cplx));
  95. R = (struct  COMPLEX *) calloc (l , sizeof (cplx));
  96. S = (struct  COMPLEX *) calloc (l , sizeof (cplx));
  97. W (l);
  98. for (i = 0 ; i < n ; i++)
  99. {//按列进行快速复利叶变换
  100. for(j = 0 ; j < m ; j++)
  101. {
  102. S[j].re = Hread(j , i)->re;
  103. S[j].im = Hread(j , i)->im;
  104. }
  105. fft(l , k);
  106. for (j = 0 ; j < m ; j++)
  107. Hwrite (j , i , R[j]);
  108. }
  109. free (R);
  110. free (S);
  111. free (w);
  112. }
  113. void  rdfft ()
  114. {
  115. conjugate ();
  116. dfft ();
  117. conjugate ();
  118. }
  119. void  showresult ()
  120. {
  121. int  i , j;
  122. for (i = 0 ; i < m ; i++)
  123. {
  124. printf ( " n第%d行n " , i);
  125. for (j = 0 ; j < n ; j++)
  126. {
  127. if (j % 4 == 0) printf (" n ");
  128. printf(" (%5.2f,%5.2fi) " , Hread (i , j)->re , Hread (i , j)->im);
  129. }
  130. }
  131. }
  132. void  fft (int l , int k)
  133. {
  134. int  i , j , s , nv , t;
  135. float  c;
  136. struct  COMPLEX  mp , r;
  137. nv = l;
  138. c = (float) l;
  139. c = pow (c , 0.5);
  140. for (i = 0 ; i < k ; i++)
  141. {
  142. for (t = 0 ; t < l ; t += nv)
  143. {
  144. for (j = 0 ; j < nv / 2 ; j++)
  145. {
  146. s = (t + j) >> (k - i -1);
  147. s = reverse(s , k);
  148. r.re = S[t + j].re;
  149. r.im = S[t + j].im;
  150. mul (&w[s] , &S[t + j + nv / 2] , &mp);/////////讲解传递结构指针和结构本身的区别
  151. add (&r , &mp , &S[t + j]);
  152. sub (&r , &mp , &S[t + j + nv / 2]);
  153. }
  154. }
  155. nv = nv >> 1;
  156. }
  157. for (i = 0 ; i < l ; i++)
  158. {
  159. j = reverse(i , k);
  160. R[j].re = S[i].re / c;
  161. R[j].im = S[i].im / c;
  162. }
  163. }
  164. int  reverse (int t , int k)
  165. {
  166. int  i , x , y;
  167. y = 0;
  168. for (i = 0 ; i < k ; i++)
  169. {
  170. x = t & 1;
  171. t = t >> 1;
  172. y = (y << 1) + x;
  173. }
  174. return y;
  175. }
  176. void  W (int l)
  177. {
  178. int i;
  179. float c , a;
  180. c = (float) l;
  181. c = 2 * PI / c;
  182. for (i = 0 ; i < l ; i++)
  183. {
  184. a = (float) i;
  185. w[i].re = (float) cos(a * c);
  186.     
  187. w[i].im = -(float) sin(a * c);
  188. }
  189. }
  190. int  loop (int l)
  191. {//检验输入数据是否为2的整数次幂,如果是返回用2进制表示时的位数
  192. int  i , m;
  193. if (l != 0)
  194. {
  195. for (i = 1 ; i < 32 ; i++)
  196. {
  197. m = l >> i;
  198. if (m == 0)
  199. break;
  200. }
  201. if (l == (1 << (i - 1)))
  202. return i - 1;
  203. }
  204. return -1;
  205. }
  206. void  conjugate ()
  207. {//求复数矩阵的共轭矩阵
  208. int  i , j;
  209. for (i = 0 ; i < m ; i++)
  210. {
  211. for (j = 0 ; j < n ; j++)
  212. {
  213. Hread (i , j)->im *= -1;
  214. }
  215. }
  216. }
  217. struct  COMPLEX  * Hread (int i , int j)
  218. {//按读矩阵方式返回Hfield中指定位置的指针
  219. return (Hfield + i * n + j);
  220. }
  221. void  Hwrite (int i , int j , struct  COMPLEX x)
  222. {//按写矩阵方式将复数结构x写到指定的Hfield位置上
  223. (Hfield + i * n + j)->re = x.re;
  224. (Hfield + i * n + j)->im = x.im;
  225. }
  226. void  add (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z)
  227. {//定义复数加法
  228. z->re = x->re + y->re;
  229. z->im = x->im + y->im;
  230. }
  231. void  sub (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z)
  232. {//定义复数减法
  233. z->re = x->re - y->re;
  234. z->im = x->im - y->im;
  235. }
  236. void  mul (struct  COMPLEX  * x , struct  COMPLEX  * y , struct  COMPLEX  * z)
  237. {//定义复数乘法
  238.     z->re = (x->re) * (y->re) - (x->im) * (y->im);
  239. z->im = (x->im) * (y->re) + (x->re) * (y->im);
  240. }