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: