fft.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**************************************************************************
  2. **
  3. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  4. **
  5. ** Meschach Library
  6. **
  7. ** This Meschach Library is provided "as is" without any express
  8. ** or implied warranty of any kind with respect to this software.
  9. ** In particular the authors shall not be liable for any direct,
  10. ** indirect, special, incidental or consequential damages arising
  11. ** in any way from use of the software.
  12. **
  13. ** Everyone is granted permission to copy, modify and redistribute this
  14. ** Meschach Library, provided:
  15. ** 1. All copies contain this copyright notice.
  16. ** 2. All modified copies shall carry a notice stating who
  17. ** made the last modification and the date of such modification.
  18. ** 3. No charge is made for this software or works derived from it.
  19. ** This clause shall not be construed as constraining other software
  20. ** distributed on the same medium as this software, nor is a
  21. ** distribution fee considered a charge.
  22. **
  23. ***************************************************************************/
  24. /*
  25. Fast Fourier Transform routine
  26. Loosely based on the Fortran routine in Rabiner & Gold's
  27. "Digital Signal Processing"
  28. */
  29. static char rcsid[] = "$Id: fft.c,v 1.4 1996/08/20 14:21:05 stewart Exp $";
  30. #include <stdio.h>
  31. #include <math.h>
  32. #include "matrix.h"
  33. #include "matrix2.h"
  34. /* fft -- d.i.t. fast Fourier transform
  35. -- radix-2 FFT only
  36. -- vector extended to a power of 2 */
  37. #ifndef ANSI_C
  38. void fft(x_re,x_im)
  39. VEC *x_re, *x_im;
  40. #else
  41. void fft(VEC *x_re, VEC *x_im)
  42. #endif
  43. {
  44. int i, ip, j, k, li, n, length;
  45. Real *xr, *xi;
  46. Real theta, pi = 3.1415926535897932384;
  47. Real w_re, w_im, u_re, u_im, t_re, t_im;
  48. Real tmp, tmpr, tmpi;
  49. if ( ! x_re || ! x_im )
  50. error(E_NULL,"fft");
  51. if ( x_re->dim != x_im->dim )
  52. error(E_SIZES,"fft");
  53. n = 1;
  54. while ( x_re->dim > n )
  55. n *= 2;
  56. x_re = v_resize(x_re,n);
  57. x_im = v_resize(x_im,n);
  58. /* printf("# fft: x_re =\n"); v_output(x_re); */
  59. /* printf("# fft: x_im =\n"); v_output(x_im); */
  60. xr = x_re->ve;
  61. xi = x_im->ve;
  62. /* Decimation in time (DIT) algorithm */
  63. j = 0;
  64. for ( i = 0; i < n-1; i++ )
  65. {
  66. if ( i < j )
  67. {
  68. tmp = xr[i];
  69. xr[i] = xr[j];
  70. xr[j] = tmp;
  71. tmp = xi[i];
  72. xi[i] = xi[j];
  73. xi[j] = tmp;
  74. }
  75. k = n / 2;
  76. while ( k <= j )
  77. {
  78. j -= k;
  79. k /= 2;
  80. }
  81. j += k;
  82. }
  83. /* Actual FFT */
  84. for ( li = 1; li < n; li *= 2 )
  85. {
  86. length = 2*li;
  87. theta = pi/li;
  88. u_re = 1.0;
  89. u_im = 0.0;
  90. if ( li == 1 )
  91. {
  92. w_re = -1.0;
  93. w_im = 0.0;
  94. }
  95. else if ( li == 2 )
  96. {
  97. w_re = 0.0;
  98. w_im = 1.0;
  99. }
  100. else
  101. {
  102. w_re = cos(theta);
  103. w_im = sin(theta);
  104. }
  105. for ( j = 0; j < li; j++ )
  106. {
  107. for ( i = j; i < n; i += length )
  108. {
  109. ip = i + li;
  110. /* step 1 */
  111. t_re = xr[ip]*u_re - xi[ip]*u_im;
  112. t_im = xr[ip]*u_im + xi[ip]*u_re;
  113. /* step 2 */
  114. xr[ip] = xr[i] - t_re;
  115. xi[ip] = xi[i] - t_im;
  116. /* step 3 */
  117. xr[i] += t_re;
  118. xi[i] += t_im;
  119. }
  120. tmpr = u_re*w_re - u_im*w_im;
  121. tmpi = u_im*w_re + u_re*w_im;
  122. u_re = tmpr;
  123. u_im = tmpi;
  124. }
  125. }
  126. }
  127. /* ifft -- inverse FFT using the same interface as fft() */
  128. #ifndef ANSI_C
  129. void ifft(x_re,x_im)
  130. VEC *x_re, *x_im;
  131. #else
  132. void ifft(VEC *x_re, VEC *x_im)
  133. #endif
  134. {
  135. /* we just use complex conjugates */
  136. sv_mlt(-1.0,x_im,x_im);
  137. fft(x_re,x_im);
  138. sv_mlt(-1.0/((double)(x_re->dim)),x_im,x_im);
  139. sv_mlt( 1.0/((double)(x_re->dim)),x_re,x_re);
  140. }