home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume1
/
8707
/
48
/
fftn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-13
|
3KB
|
130 lines
#include <math.h>
#include "complex.h"
/* Use 4-multiply complex multiply for MSC */
#ifdef DOS /* IBM C */
#define MULT4
#endif
#ifdef MSDOS /* Microsoft C */
#define MULT4
#endif
#define PI 3.1415926535979
fftn(data, nn, ndim, isign)
#ifdef SPEED
struct fcomplex data[];
#else
struct complex data[];
#endif
unsigned nn[];
int ndim, isign;
{
int idim;
unsigned i1, i2rev, i3rev, ibit;
unsigned ip2, ifp1, ifp2, k2, n;
unsigned nprev = 1, nrem, ntot = 1;
register unsigned i2, i3;
double theta;
struct complex w, wp;
#ifdef SPEED
float wtemp;
struct fcomplex temp, wt;
#else
double wtemp;
struct complex temp, wt;
#endif
#ifndef MULT4 /* Temporary variables needed for 3-multiply complex mult. */
double t1, t2;
#endif
/* Compute total number of complex values */
for (idim = 0; idim < ndim; ++idim)
ntot *= nn[idim];
for (idim = ndim - 1; idim >= 0; --idim) {
n = nn[idim];
nrem = ntot / (n * nprev);
ip2 = nprev * n; /* Unit step for next dimension */
i2rev = 0; /* Bit reversed i2 */
/* This is the bit reversal section of the routine */
/* Loop over current dimension */
for (i2 = 0; i2 < ip2; i2 += nprev) {
if (i2 < i2rev)
/* Loop over lower dimensions */
for (i1 = i2; i1 < i2 + nprev; ++i1)
/* Loop over higher dimensions */
for (i3 = i1; i3 < ntot; i3 += ip2) {
i3rev = i3 + i2rev - i2;
temp = data[i3];
data[i3] = data[i3rev];
data[i3rev] = temp;
}
ibit = ip2;
/* Increment from high end of i2rev to low */
do {
ibit >>= 1;
i2rev ^= ibit;
} while (ibit >= nprev && !(ibit & i2rev));
}
/* Here begins the Danielson-Lanczos section of the routine */
/* Loop over step sizes */
for (ifp1 = nprev; ifp1 < ip2; ifp1 <<= 1) {
ifp2 = ifp1 << 1;
/* Initialize for the trig. recurrence */
theta = isign * 2.0 * PI / (ifp2 / nprev);
wp.x = sin(0.5 * theta);
wp.x *= -2.0 * wp.x;
wp.y = sin(theta);
w.x = 1.0;
w.y = 0.0;
/* Loop by unit step in current dimension */
for (i3 = 0; i3 < ifp1; i3 += nprev) {
/* Loop over lower dimensions */
for (i1 = i3; i1 < i3 + nprev; ++i1)
/* Loop over higher dimensions */
for (i2 = i1; i2 < ntot; i2 += ifp2) {
/* Danielson-Lanczos formula */
k2 = i2 + ifp1;
wt = data[k2];
#ifdef MULT4
/* Complex multiply using 4 real multiplies. Faster in MSC */
data[k2].x = data[i2].x - (temp.x = w.x * wt.x - w.y * wt.y);
data[k2].y = data[i2].y - (temp.y = w.x * wt.y + w.y * wt.x);
#else
/* Complex multiply using 3 real multiplies. Should usually be faster. */
data[k2].x = data[i2].x - (temp.x =
(t1 = w.x * wt.x) - (t2 = w.y * wt.y));
data[k2].y = data[i2].y - (temp.y =
(w.x + w.y) * (wt.x + wt.y) - t1 - t2);
#endif
data[i2].x += temp.x;
data[i2].y += temp.y;
}
/* Trigonometric recurrence */
wtemp = w.x;
#ifdef MULT4
/* Complex multiply using 4 real multiplies. */
w.x += w.x * wp.x - w.y * wp.y;
w.y += wtemp * wp.y + w.y * wp.x;
#else
/* Complex multiply using 3 real multiplies. */
w.x += (t1 = w.x * wp.x) - (t2 = w.y * wp.y);
w.y += (wtemp + w.y) * (wp.x + wp.y) - t1 - t2;
#endif
}
}
nprev *= n;
}
}