Path: utzoo!attcan!uunet!lll-winken!ames!pasteur!ucbvax!hplabs!hp-pcd!hplsla!jima
From: jima@hplsla.HP.COM (Jim Adcock)
Newsgroups: comp.lang.c++
Subject: Re: mixed radix FFT in C++
Message-ID: <6590231@hplsla.HP.COM>
Date: 17 Aug 89 19:37:43 GMT
References: <11612@cit-vax.Caltech.Edu>
Organization: HP Lake Stevens, WA
Lines: 74

#include 
#include 

// fft a double precision complex array x of size (2 to the m)
// this is like I have posted before, but contains a bug workaround
// necessary for some C++ compilers.

int fft(complex* x, unsigned m)
{
    complex u, w, t;
    unsigned n = 1 << m;
    unsigned nv2 = n >> 1;
    unsigned nm1 = n - 1;
    unsigned j = 0;

    for (unsigned i = 0; i < nm1; ++i)
    {
	if (i < j) {t = x[j]; x[j] = x[i]; x[i] = t;}
	unsigned k = nv2;
	while ((k-1) < j) {j -= k; k >>= 1;}
	j += k;
    }

    for (unsigned l = 1; l <= m; ++l)
    {
        unsigned le = 1 << l;
        unsigned le1 = le >> 1;
        complex u(1.0, 0.0);

        double cs = cos(M_PI/double(le1)); //temporaries introduced to fix bug
	double sn = sin(M_PI/double(le1));

        complex w(cs,sn);

        for (j = 0; j < le1; ++j)
        {
	    for (i = j; i < n; i += le)
	    {
		unsigned ip = i + le1;
		t = x[ip] * u;
		x[ip] = x[i] - t;
		x[i] += t;
            }
	    u *= w;
        }
    }
    return m;
}


#define SZ 16 
#define LGSZ 4

main()
{
    complex x[SZ];
    for (long i = 0; i < SZ; ++i)
    {
	for (long j = 0; j < SZ; ++j) x[j] = 0.0;
	x[i] = 1.0;
	fft(x, LGSZ);
	fft(x, LGSZ);   //two ffts in a row without conjugation causes time
			//reversal and scaling by SZ
	for (j = 0; j < SZ; ++j) 
	{
	  //to make a pretty output force small numbers to zero
	  if (abs(real(x[j])) < 1.0e-10) x[j] = complex(0.0,imag(x[j]));
	  if (abs(imag(x[j])) < 1.0e-10) x[j] = complex(real(x[j]),0.0);

	  cout << "(" << real(x[j]) << "+i" << imag(x[j]) << ")" << " ";
        }
	cout << "\n\n";
    }
}