aeusemrs@csun.UUCP (Mike Stump) (07/29/87)
All right, here it is! #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # fft.doc # fft.c # This archive created: Sun Jul 26 11:32:35 1987 export PATH; PATH=/bin:$PATH if test -f 'fft.doc' then echo shar: will not over-write existing file "'fft.doc'" else cat << \SHAR_EOF > 'fft.doc' Documentation for fft.c This program is a direct translation from FORTRAN IV of E. O. Brigham's program on the fast Fourier transform, The Fast Fourier Transform. I suggest reading the book, to get the details of the method. In translating this program from FORTRAN, I retained the bit swapping function described by Brigham. Using bit operators, I assume that a more efficient manner of bit swapping can be performed. I used pointers to the data to be transformed to allow the routine to be more general. Thus fft() needs to know the number of data points when it is called which is only limited by memory size, which can get used up quickly since each point is represented by two 8-byte numbers. A solution might be to hold the data on disk and use disk access functions, if you run out of memory for the data. This method should be avoided for small data sets, since the calculation time increases dramatically with more data points to transform. With disk overhead, calculation time will slow down considerably. To save memory space you can redefine the variable types from double to single precision at the expense of precision. I have compared the performance of the fft to a regular Fourier trans- form, and the fft wins out especially when there are more than 512 data points. The restriction of having the data be a multiple of 2 is usually not prohibi- tive since the data usually are generated by a computer in base 2, eg. radio astronomy (my original purpose for writing this program), image analysis, etc. Enclosed is some sample data and its transform. Use this to debug the program if necessary ( I hate to receive a data analysis program with no data to test the program ). These data have been checked for correctness by using a standard FFT from a mainframe computer math library. Finally if you have any questions or suggestions, please contact me: Jim Pisano P.O. Box 3134 Charlottesville, VA 22903 Or contact aeusemrs@csun.uucp (Mike Stump). INPUT OUTPUT index real imaginary real imaginary _____________________________________________________________________________ 1 -28.66 0.0 -00.11 0.0 2 -32.43 0.0 -29.98644 -38.211 3 -8.42 0.0 -62.32944 -23.91025 4 40.22 0.0 -58.32872 -10.02253 5 1.14 0.0 -58.46804 -7.78748 6 -25.05 0.0 -68.11068 -5.28995 7 12.14 0.0 -86.80929 -11.77746 8 27.82 0.0 -137.68 -0.06883 9 2.4 0.0 -33.03304 202.24 10 -19.68 0.0 82.43765 72.43995 11 7.55 0.0 25.90461 18.1517 12 17.22 0.0 8.26912 6.555 13 -0.58 0.0 -4.33195 3.91253 14 -12.5 0.0 -8.54575 -11.5672 15 0.89 0.0 -20.32586 -3.86289 16 10.45 0.0 -8.05521 10.74816 17 -1.16 0.0 1.77 0.0 18 -7.06 0.0 -8.0552 -10.74816 19 -0.23 0.0 -20.32586 3.86289 20 4.59 0.0 -8.54575 11.5672 21 1.45 0.0 -4.33195 -3.91253 22 -3.4 0.0 8.26913 -6.55501 23 3.03 0.0 25.9046 -18.15169 24 3.05 0.0 82.43763 -72.43996 25 3.67 0.0 -33.02996 -202.24 26 -0.51 0.0 -137.68 0.06884 27 -4.35 0.0 -86.80931 11.77746 28 -1.45 0.0 -68.11066 5.28995 29 5.64 0.0 -58.46805 7.78747 30 -0.96 0.0 -58.32872 10.02253 31 -4.46 0.0 -62.32945 23.91205 32 -1.25 0.0 -29.98643 38.21101 SHAR_EOF fi # end of overwriting check if test -f 'fft.c' then echo shar: will not over-write existing file "'fft.c'" else cat << \SHAR_EOF > 'fft.c' /* Introduced into UseNet By: aeusemrs@csun.uucp (Mike Stump) Sun Jul 26 11:26:31 PDT 1987 HEADER: TITLE: Fast Fourier Transform; DATE: 05/18/1985; DESCRIPTION: "Performs fast fourier transform using method described by E. O. Brigham. For details of the method, refer to Brigham's book. THE FAST FOURIER TRANSFORM"; KEYWORDS: Fourier, transform; FILENAME: FFT.C; WARNINGS: "This program is self-contained, all that is needed is a manner of getting the data into the array real_data (& imag_data, if applicable). The transformed data will reside in these two arrays upon return with the original data being destroyed." AUTHORS: Jim Pisano; COMPILERS: DeSmet; REFERENCES: AUTHORS: E. O. Brigham; TITLE: "THE FAST FOURIER TRANSFORM"; CITATION: ""; ENDREF */ /* file name fft.c * program name fft() ... Fast Fourier Transform * * Perform fast fourier transform using method described by E. O. Brigham. * For details of the method, refer to Brigham's book * * Translated to C from FORTRAN by * * Jim Pisano * P.O. Box 3134 * University Station * Charlottesville, VA 22903 * * This program is in the public domain & may be used by anyone for commercial * or non-commercial purposes. * * real_data ... ptr. to real part of data to be transformed * imag_data ... ptr. to imag " " " " " " * inv ..... Switch to flag normal or inverse transform * n_pts ... Number of real data points * nu ...... logarithm in base 2 of n_pts e.g. nu = 5 if n_pts = 32. * * This program is self-contained, all that is needed is a manner of getting * the data into the array real_data (& imag_data, if applicable). The * transformed data will reside in these two arrays upon return with the * original data being destroyed. */ #include <stdio.h> #include <math.h> /* declare math functions to use */ #define PI 3.1419527 fft( real_data, imag_data, n_pts, nu, inv ) double *real_data, *imag_data; int n_pts, nu, inv; { int n2, j, j1, l, i, ib, k, k1, k2; int sgn; double tr, ti, arg, nu1; /* intermediate values in calcs. */ double c, s; /* cosine & sine components of Fourier trans. */ n2 = n_pts / 2; nu1 = nu - 1.0; k = 0; /* * sign change for inverse transform */ sgn = inv ? -1 : 1; /* * Calculate the componets of the Fourier series of the function */ for( l = 0; l != nu; l++ ) { do { for( i = 0; i != n2; i++ ) { j = k / ( pow( 2.0, nu1 ) ); ib = bit_swap( j, nu ); arg = 2.0 * PI * ib / n_pts; c = cos( arg ); s = sgn * sin( arg ); k1 = k; k2 = k1 + n2; tr = *(real_data+k2) * c + *(imag_data+k2) * s; ti = *(imag_data+k2) * c - *(real_data+k2) * s; *(real_data+k2) = *(real_data+k1) - tr; *(imag_data+k2) = *(imag_data+k1) - ti; *(real_data+k1) = *(real_data+k1) + tr; *(imag_data+k1) = *(imag_data+k1) + ti; k++; } k += n2; } while( k < n_pts - 1); k = 0; nu1 -= 1.0; n2 /= 2; } for( k = 0; k != n_pts; k++ ) { ib = bit_swap( k, nu ); if( ib > k) { swap( (real_data+k), (real_data+ib) ); swap( (imag_data+k), (imag_data+ib) ); } } /* * If calculating the inverse transform, must divide the data by the number of * data points. */ if( inv ) for( k = 0; k != n_pts; k++) { *(real_data+k) /= n_pts; *(imag_data+k) /= n_pts; } } /* * Bit swaping routine in which the bit pattern of the integer i is reordered. * See Brigham's book for details */ bit_swap( i, nu ) int i, nu; { int ib, i1, i2; ib = 0; for( i1 = 0; i1 != nu; i1++ ) { i2 = i / 2; ib = ib * 2 + i - 2 * i2; i = i2; } return( ib ); } /* * Simple exchange routine where *x1 & *x2 are swapped */ swap( x1, x2 ) double *x1, *x2; { int *temp_iy; double *temp_x; *temp_x = *x1; *x1 = *x2; *x2 = *temp_x; } SHAR_EOF fi # end of overwriting check # End of shell archive exit 0 -- Mike Stump, Cal State Univ, Northridge Comp Sci Department uucp: {sdcrdcf, ihnp4, hplabs, ttidca, psivax, csustan}!csun!aeusemrs