Лістінг програми реалізації Дискретного Перетворення Фурьє
/*--------------------------------------------------------------------*
* SRFFT.C - Split-Radix Fast Fourier Transform *
* *
* This is a decimation-in-frequency version, using the steps *
* of the algorithm as described in Section 2.5. *
* *
* Author: Henrique S. Malvar. *
* Date: October 8, 1991. *
* *
* Usage: srfft(xr, xi, logm); -- for direct DFT *
* srifft(xr, xi, logm); -- for inverse DFT *
* *
* Arguments: xr (float) - input and output vector, length M, *
* real part. *
* xi (float) - imaginary part. *
* logm (int) - log (base 2) of vector length M, *
* e.g., for M = 256 -> logm = 8. *
*--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
#include <math.h>
/*--------------------------------------------------------------------*
* Error exit for program abortion. *
*--------------------------------------------------------------------*/
static void error_exit(void)
{
exit(1);
}
/*--------------------------------------------------------------------*
* Data unshuffling according to bit-reversed indexing. *
* *
* Bit reversal is done using Evan's algorithm (Ref: D. M. W. *
* Evans, "An improved digit-reversal permutation algorithm ...", *
* IEEE Trans. ASSP, Aug. 1987, pp. 1120-1125). *
*--------------------------------------------------------------------*/
static int brseed[256]; /* Evans' seed table */
static int brsflg; /* flag for table building */
void BR_permute(float *x, int logm)
{
int i, j, imax, lg2, n;
int off, fj, gno, *brp;
float tmp, *xp, *xq;
lg2 = logm >> 1;
n = 1 << lg2;
if (logm & 1) lg2++;
/* Create seed table if not yet built */
if (brsflg != logm) {
brsflg = logm;
brseed[0] = 0;
brseed[1] = 1;
for (j = 2; j <= lg2; j++) {
imax = 1 << (j - 1);
for (i = 0; i < imax; i++) {
brseed[i] <<= 1;
brseed[i + imax] = brseed[i] + 1;
}
}
}
/* Unshuffling loop */
for (off = 1; off < n; off++) {
fj = n * brseed[off]; i = off; j = fj;
tmp = x[i]; x[i] = x[j]; x[j] = tmp;
xp = &x[i];
brp = &brseed[1];
for (gno = 1; gno < brseed[off]; gno++) {
xp += n;
j = fj + *brp++;
xq = x + j;
tmp = *xp; *xp = *xq; *xq = tmp;
}
}
}
/*--------------------------------------------------------------------*
* Recursive part of the SRFFT algorithm. *
*--------------------------------------------------------------------*/
/* Compute tables */
for (n = 1; n < m4; n++) {
if (n == m8) continue;
ang = n * TWOPI / m;
c = cos(ang); s = sin(ang);
*cn++ = c; *spcn++ = - (s + c); *smcn++ = s - c;
ang = 3 * n * TWOPI / m;
c = cos(ang); s = sin(ang);
*c3n++ = c; *spc3n++ = - (s + c); *smc3n++ = s - c;
}
}
/* Call ssrec again with half DFT length */
srrec(xr, xi, logm-1);
/* Call ssrec again twice with one quarter DFT length.
Constants have to be recomputed, because they are static! */
m = 1 << logm; m2 = m / 2;
srrec(xr + m2, xi + m2, logm-2);
m = 1 << logm; m4 = 3 * (m / 4);
srrec(xr + m4, xi + m4, logm-2);
}
/*--------------------------------------------------------------------*
* Direct transform *
*--------------------------------------------------------------------*/