/// <summary>
/// One dimensional Fast Fourier Transform.
/// </summary>
///
/// <param name="data">Data to transform.</param>
/// <param name="direction">Transformation direction.</param>
///
/// <remarks><para><note>The method accepts <paramref name="data"/> array of 2<sup>n</sup> size
/// only, where <b>n</b> may vary in the [1, 14] range.</note></para></remarks>
///
/// <exception cref="ArgumentException">Incorrect data length.</exception>
///
public static void FFT(Complex[] data, Direction direction)
{
int n = data.Length;
int m = Tools.Log2(n);
// reorder data first
ReorderData(data);
// compute FFT
int tn = 1, tm;
for (int k = 1; k <= m; k++)
{
Complex[] rotation = FourierTransform.GetComplexRotation(k, direction);
tm = tn;
tn <<= 1;
for (int i = 0; i < tm; i++)
{
Complex t = rotation[i];
for (int even = i; even < n; even += tn)
{
int odd = even + tm;
Complex ce = data[even];
Complex co = data[odd];
double tr = co.Real * t.Real - co.Imaginary * t.Imaginary;
double ti = co.Real * t.Imaginary + co.Imaginary * t.Real;
data[even] += new Complex(tr, ti);
data[odd] = new Complex(ce.Real - tr, ce.Imaginary - ti);
}
}
}
if (direction == Direction.Forward)
{
for (int i = 0; i < data.Length; i++)
{
data[i] /= (double)n;
}
}
}