transformRadix2 method

void transformRadix2 (Float64List real, Float64List imag)

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;
      }
    }
  }
}