transformRadix2 method
Computes the discrete FFT of a complex array in place.
real
= the real values of the array
imag
= the imaginary values of the array.
Throws if real
and imag
have different lengths, and if the
length is not a power of 2.
The result is again complex, and is contained in the original array.
The resulting array values are scaled relatively (non absolute values).
Uses the Cooley-Tukey decimation-in-time radix-2 algorithm.
Implementation
static void transformRadix2(Float64List real, Float64List imag) {
// Initialization
if (real.length != imag.length) throw "Mismatched lengths";
int n = real.length;
if (n == 1) {
// Trivial transform
return;
}
int levels = -1;
for (int i = 0; i < 32; i++) {
if (1 << i == n) levels = i; // Equal to log2(n)
}
if (levels == -1) throw "Length is not a power of 2";
Float64List cosTable = Float64List(n ~/ 2);
Float64List sinTable = Float64List(n ~/ 2);
for (int i = 0; i < n / 2; i++) {
cosTable[i] = math.cos(2 * math.pi * i / n);
sinTable[i] = math.sin(2 * math.pi * i / n);
}
// Bit-reversed addressing permutation
for (int i = 0; i < n; i++) {
int j = reverseBits(i, levels);
if (j > i) {
double temp = real[i];
real[i] = real[j];
real[j] = temp;
temp = imag[i];
imag[i] = imag[j];
imag[j] = temp;
}
}
// Cooley-Tukey decimation-in-time radix-2 FFT
for (int size = 2; size <= n; size *= 2) {
int halfsize = size ~/ 2;
int tablestep = n ~/ size;
for (int i = 0; i < n; i += size) {
for (int j = i, k = 0; j < i + halfsize; j++, k += tablestep) {
double tpre = real[j + halfsize] * cosTable[k] +
imag[j + halfsize] * sinTable[k];
double tpim = -real[j + halfsize] * sinTable[k] +
imag[j + halfsize] * cosTable[k];
real[j + halfsize] = real[j] - tpre;
imag[j + halfsize] = imag[j] - tpim;
real[j] += tpre;
imag[j] += tpim;
}
}
}
}