/// <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 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]; } } // 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]; } } }
private static void fftpc(ref Complex[,] data, Direction direction, int start, int end, int rows) { Complex[] col = new Complex[rows]; for (int j = start; j < end; j++) { // copy column for (int i = 0; i < rows; i++) { col[i] = data[i, j]; } // transform it FourierTransform.FFT(col, direction); // copy back for (int i = 0; i < rows; i++) { lock (data) { data[i, j] = col[i]; } } } }
private static void fftpr(ref Complex[,] data, Direction direction, int start, int end, int cols) { Complex[] row = new Complex[cols]; for (int i = start; i < end; i++) { // copy row for (int j = 0; j < cols; j++) { row[j] = data[i, j]; } // transform it FourierTransform.FFT(row, direction); // copy back for (int j = 0; j < cols; j++) { lock (data) { data[i, j] = row[j]; } } } }