70 lines
2.2 KiB
JavaScript
70 lines
2.2 KiB
JavaScript
/*===========================================================================*\
|
|
* Fast Fourier Transform (Cooley-Tukey Method)
|
|
*
|
|
* (c) Vail Systems. Joshua Jung and Ben Bryan. 2015
|
|
*
|
|
* This code is not designed to be highly optimized but as an educational
|
|
* tool to understand the Fast Fourier Transform.
|
|
\*===========================================================================*/
|
|
|
|
//------------------------------------------------
|
|
// Note: Some of this code is not optimized and is
|
|
// primarily designed as an educational and testing
|
|
// tool.
|
|
// To get high performace would require transforming
|
|
// the recursive calls into a loop and then loop
|
|
// unrolling. All of this is best accomplished
|
|
// in C or assembly.
|
|
//-------------------------------------------------
|
|
|
|
//-------------------------------------------------
|
|
// The following code assumes a complex number is
|
|
// an array: [real, imaginary]
|
|
//-------------------------------------------------
|
|
var complex = require("./complex"),
|
|
fftUtil = require("./fftutil");
|
|
|
|
//-------------------------------------------------
|
|
// Calculate FFT for vector where vector.length
|
|
// is assumed to be a power of 2.
|
|
//-------------------------------------------------
|
|
export function fft(vector) {
|
|
var X = [],
|
|
N = vector.length;
|
|
|
|
// Base case is X = x + 0i since our input is assumed to be real only.
|
|
if (N == 1) {
|
|
if (Array.isArray(vector[0]))
|
|
//If input vector contains complex numbers
|
|
return [[vector[0][0], vector[0][1]]];
|
|
else return [[vector[0], 0]];
|
|
}
|
|
|
|
// Recurse: all even samples
|
|
var X_evens = fft(vector.filter(even)),
|
|
// Recurse: all odd samples
|
|
X_odds = fft(vector.filter(odd));
|
|
// console.log(`vector.length:${vector.length}, evens:${X_evens.length}, odds:${X_odds.length}`);
|
|
|
|
// Now, perform N/2 operations!
|
|
for (var k = 0; k < N / 2; k++) {
|
|
// t is a complex number!
|
|
var t = X_evens[k];
|
|
// console.log(`k:${k}, N:${N}, t:${t}, X_odds[k]: ${X_odds[k]}`);
|
|
var e = complex.multiply(fftUtil.exponent(k, N), X_odds[k]);
|
|
|
|
X[k] = complex.add(t, e);
|
|
X[k + N / 2] = complex.subtract(t, e);
|
|
}
|
|
|
|
function even(__, ix) {
|
|
return ix % 2 == 0;
|
|
}
|
|
|
|
function odd(__, ix) {
|
|
return ix % 2 == 1;
|
|
}
|
|
|
|
return X;
|
|
}
|