home *** CD-ROM | disk | FTP | other *** search
- /*
- * fft.c
- *
- * Performs a Cooley-Tukey Fast Fourier Transform.
- *
- * Original version Pascal written in "Simple Calculations with
- * Complex Numbers by David Clark Doctor Dobbs Journal 10/84
- *
- * Translated to C by R. Hellman 02/21/86
- * Released to Public Domain
- *
- * Difference from original version:
- *
- * As in fortran versions that I have worked with, instead of
- * specifying total array size in decimal - instead specify number
- * of array members as power of two. Forward or reverse fft is
- * specified by the sign of this argument.
- *
- * ****IMPORTANT****
- * For convenience sake members of an array are taken to begin at [1]
- * rather than [0] thus for an fft on a 64 member array of pointers
- * to complex numbers, there must be 65 members.
- *
- * f is a one dimensional array of pointers to complex numbers with
- * length (2**abs(ln)). The sign of ln determines in which direction
- * the transform will be performed. If ln is positive, then isinverse
- * is set to -1 and a forward transform is carried out. If ln is
- * negative then isinverse is set to 1 and a reverse transform is
- * calculated.
- *
- * For numpoints = (2**abs(ln)),
- * transform[j] = sum(f[i] * w ^ ((i-1) * (j-1))),
- * where i, j are 1 to numpoints and
- * w = exp(isinverse * 2 * pi * sqrt(-1)/numpoints).
- *
- * The program also computes the inverse transform, for which the
- * defining expression is:
- * inverse DFT = (1/numpoints) * sum(f[i] * w ^ ((i-1) * (j-1))).
- *
- * Run time is proportional to numpoints * log2(numpoints) rather than
- * to numpoints ** 2 for the classical discrete Fourier transform.
- */
-
- #include <stdio.h>
- #include "complex.c"
-
- fft(f, ln)
- complex *f[];
- int ln;
- {
- int i, isinverse, numpoints;
-
- if (ln > 0) {
- puts("Calculating forward Fourier transform\n");
- isinverse = -1;
- numpoints = pow(2.0, ln);
- }
- else {
- puts("Calculating reverse Fourier transform\n");
- isinverse = 1;
- numpoints = (int) pow(2.0, -ln);
- }
-
- bitreverse(numpoints, f);
- butterfly(numpoints, isinverse, f);
- }
-
- /*
- * Reverse the bits
- *
- */
-
- static bitreverse(numpoints, f)
- int numpoints;
- complex *f[];
- {
- int i, j, m;
- complex *temp;
-
- j = 1;
- for (i = 1; i <= numpoints; i++) {
- if (i < j) {
- temp = f[j];
- f[j] = f[i];
- f[i] = temp;
- }
-
- m = numpoints >> 1;
-
- if (m < j)
- while (m < j) {
- j -= m;
- m = (m + 1) >> 1;
- }
-
- j += m;
- }
- }
-
- /*
- * Calculate the butterflies for the bit reversed data
- * Normalize if a reverse fft is performed
- *
- */
-
- static butterfly(numpoints, isinverse, f)
- int numpoints, isinverse;
- complex *f[];
- {
- int mmax, step, index, m, i, j;
- double theta;
- complex w, cn, temp;
-
- mmax = 1;
-
- while (numpoints > mmax) {
-
- step = mmax << 1;
-
- for (m = 1; m <= mmax; m++) {
-
- theta = M_PI * ((double)(isinverse) *
- (double)(m - 1)) / (double)(mmax);
-
- w.re = cos(theta);
- w.im = sin(theta);
-
- for (i = 1; i <= ((numpoints-m) / step) + 1; i++) {
-
- index = m + ((i-1) * step);
- j = index + mmax;
-
- cmult(&temp, &w, f[j]);
- csub(f[j], f[index], &temp);
- cadd(f[index], f[index], &temp);
- }
- }
-
- mmax = step;
- }
-
- if (isinverse == 1) {
- cn.re = numpoints;
- cn.im = 0.0;
-
- for (i = 1; i <= numpoints; i++)
- cdiv(f[i], f[i], &cn);
- }
- }
-