This quite short FFT program implements an algorithm published almost 40 years ago by M. L. Ulrich, "FFT's without sorting", IEEE Transactions on Acoustics and Electroacoustics, vol. AU-17, no. 2, 1969, pp. 170 - 172. Originally it was written on an old programming language Fortran. This is why below it is rewritten on C using a special structure for complex numbers and a few utilities to manipulate with complex numbers. You may easily rewrtite it on Java.
#define COMPLEX struct complex_type COMPLEX { double real; /* real part of the complex number real + sqrt(-1)*imag */ double imag; /* imaginary part of the complex number */ }; #define PI2 6.2831853 void fft1d( COMPLEX *fftarray, int narray, int direction ){ /* * Fast Fourier Transform of a 1D complex data array of size narray * (narray is a power of two number, i.e. narray = 2^nstage * ------------------------------------------------------------------ * fftarray[ 2*narray] - working complex array of input/output data * direction = +1 or -1 for the inverse and forward FFT, respectively * * Input for the direct and inverse FFT, output for the inverse FFT * and unnormalised output for the forward FFT : in the first half * of the working array: fftarray[0]...fftarray[narray-1] * Normalised output for the forward FFT: in the second half of the * working array: fftarray[narray]...fftarray[2*narray-1] * ------------------------------------------------------------------ */ int i, in2k, ir, isub, isub1, isub2, isub3, k, k2k; int n2k, n2array, ni, nstage; double pi2n, temp; COMPLEX w, prod; nstage = (int)log2( (double)narray ); pi2n = PI2 * (double)direction / (double)narray; n2array = narray / 2; for( k = 1, k2k = 2; k <= nstage; k++, k2k *= 2 ) { n2k = narray / k2k; ni = k2k / 2; for( i = 0; i < ni; i++ ) { in2k = i * n2k; temp = (double)in2k * pi2n; w.real = cos( temp ); w.imag = sin( temp ); for( ir = 0; ir < n2k; ir++ ){ isub = ir + in2k; isub1 = ir + in2k * 2; isub2 = isub1 + n2k; isub3 = isub + n2array; prod = multiply_complex( w, fftarray[ isub2 ] ); fftarray[ isub + narray ] = add_complex( fftarray[ isub1 ], prod ); fftarray[ isub3 + narray ] = subtract_complex( fftarray[ isub1 ], prod ); } } for( ir = 0; ir < narray; ir++ ) { fftarray[ ir ] = copy_complex( fftarray[ ir + narray ] ); } } for( ir = 0; ir < narray; ir++ ) { fftarray[ ir + narray ] = scale_complex( fftarray[ ir ], (double)narray ); } } /*===================== Utilities ===============================================*/ COMPLEX copy_complex( COMPLEX var ){ /* * assign one complex value var to another variable */ COMPLEX new; new.real = var.real; new.imag = var.imag; return new; } COMPLEX scale_complex( COMPLEX var, double scale ){ /* * divide a complex value var by real scale */ COMPLEX new; new.real = var.real / scale; new.imag = var.imag / scale; return new; } COMPLEX multiply_complex( COMPLEX var1, COMPLEX var2 ){ /* * multiply a complex value var1 to another value var2 */ COMPLEX product; product.real = var1.real * var2.real - var1.imag * var2.imag; product.imag = var1.real * var2.imag + var1.imag * var2.real; return product; } COMPLEX add_complex( COMPLEX var1, COMPLEX var2 ){ /* * sum complex values var1 and var2 */ COMPLEX sum; sum.real = var1.real + var2.real; sum.imag = var1.imag + var2.imag; return sum; } COMPLEX subtract_complex( COMPLEX var1, COMPLEX var2 ){ /* * subtract a complex value var2 from var1 */ COMPLEX diff; diff.real = var1.real - var2.real; diff.imag = var1.imag - var2.imag; return diff; }
This FFT algorithm assumes that the size of input data is a power of two:
N = 2n (the values N and n are represented with
the program variables narray and nstage, respectively. Here, the
forward and inverse FFT of the complex input data differ only by the sign of
the exponent ("−" for the forward and "+" for the
inverse FFT, respectively, and by normalisation of only the forward FFT output: