/// <summary>
/// Two 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 in each dimension, where <b>n</b> may vary in the [1, 14] range. For example, 16x16 array
/// is valid, but 15x15 is not.</note></para></remarks>
///
/// <exception cref="ArgumentException">Incorrect data length.</exception>
///
public static void FFT2(Complex[,] data, Direction direction)
{
int k = data.GetLength(0);
int n = data.GetLength(1);
// check data size
if (!Tools.IsPowerOf2(k) || !Tools.IsPowerOf2(n))
{
throw new ArgumentException("The matrix rows and columns must be a power of 2.");
}
if (k < minLength || k > maxLength || n < minLength || n > maxLength)
{
throw new ArgumentException("Incorrect data length.");
}
// process rows
var row = new Complex[n];
for (int i = 0; i < k; i++)
{
// copy row
for (int j = 0; j < row.Length; j++)
{
row[j] = data[i, j];
}
// transform it
FourierTransform.FFT(row, direction);
// copy back
for (int j = 0; j < row.Length; j++)
{
data[i, j] = row[j];
}
}
// process columns
var col = new Complex[k];
for (int j = 0; j < n; j++)
{
// copy column
for (int i = 0; i < k; i++)
{
col[i] = data[i, j];
}
// transform it
FourierTransform.FFT(col, direction);
// copy back
for (int i = 0; i < k; i++)
{
data[i, j] = col[i];
}
}
}