/// <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]; } } }
/// <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)) || (k < minLength) || (k > maxLength) || (n < minLength) || (n > maxLength) ) { throw new ArgumentException("Incorrect data length."); } // process columns Complex[] 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]; } } // process rows Complex[] row = new Complex[n]; for (int i = 0; i < k; i++) { // copy row for (int j = 0; j < n; j++) { row[j] = data[i, j]; } // transform it FourierTransform.FFT(row, direction); // copy back for (int j = 0; j < n; j++) { data[i, j] = row[j]; } } }
private static void ReorderData(Complex[] data) { int num = data.Length; if (num < 2 || num > 16384 || !Tools.IsPowerOf2(num)) { throw new ArgumentException("Incorrect data length."); } int[] array = GetReversedBits(Tools.Log2(num)); for (int i = 0; i < num; i++) { int num2 = array[i]; if (num2 > i) { Complex complex = data[i]; data[i] = data[num2]; data[num2] = complex; } } }
// Reorder data for FFT using private static void ReorderData(Complex[] data) { int len = data.Length; // check data length if ((len < minLength) || (len > maxLength) || (!Tools.IsPowerOf2(len))) { throw new ArgumentException("Incorrect data length."); } int[] rBits = GetReversedBits(Tools.Log2(len)); for (int i = 0; i < len; i++) { int s = rBits[i]; if (s > i) { Complex t = data[i]; data[i] = data[s]; data[s] = t; } } }
public static void FFT2(Complex[,] data, Direction direction) { int length = data.GetLength(0); int length2 = data.GetLength(1); if (!Tools.IsPowerOf2(length) || !Tools.IsPowerOf2(length2) || length < 2 || length > 16384 || length2 < 2 || length2 > 16384) { throw new ArgumentException("Incorrect data length."); } Complex[] array = new Complex[length2]; for (int i = 0; i < length; i++) { for (int j = 0; j < length2; j++) { array[j] = data[i, j]; } FFT(array, direction); for (int k = 0; k < length2; k++) { data[i, k] = array[k]; } } Complex[] array2 = new Complex[length]; for (int l = 0; l < length2; l++) { for (int m = 0; m < length; m++) { array2[m] = data[m, l]; } FFT(array2, direction); for (int n = 0; n < length; n++) { data[n, l] = array2[n]; } } }