//====================================================================================== //====================================================================================== /// <summary> /// Compute a 1D fast Fourier transform of a dataset of complex numbers (as pairs of float's). /// </summary> /// <param name="data"></param> /// <param name="length"></param> /// <param name="direction"></param> public static void FFT(float[] data, int length, FourierDirection direction) { Debug.Assert(data != null); Debug.Assert(data.Length >= length * 2); Debug.Assert(Fourier.IsPowerOf2(length) == true); Fourier.SyncLookupTableLength(length); int ln = Fourier.Log2(length); // reorder array Fourier.ReorderArray(data); // successive doubling int N = 1; int signIndex = (direction == FourierDirection.Forward) ? 0 : 1; for (int level = 1; level <= ln; level++) { int M = N; N <<= 1; float[] uRLookup = _uRLookupF[level, signIndex]; float[] uILookup = _uILookupF[level, signIndex]; for (int j = 0; j < M; j++) { float uR = uRLookup[j]; float uI = uILookup[j]; for (int evenT = j; evenT < length; evenT += N) { int even = evenT << 1; int odd = (evenT + M) << 1; float r = data[odd]; float i = data[odd + 1]; float odduR = r * uR - i * uI; float odduI = r * uI + i * uR; r = data[even]; i = data[even + 1]; data[even] = r + odduR; data[even + 1] = i + odduI; data[odd] = r - odduR; data[odd + 1] = i - odduI; } } } }
/// <summary> /// Compute a 2D fast fourier transform on a data set of complex numbers /// </summary> /// <param name="data"></param> /// <param name="xLength"></param> /// <param name="yLength"></param> /// <param name="direction"></param> public static void FFT2(Complex[] data, int xLength, int yLength, FourierDirection direction) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length < xLength * yLength) { throw new ArgumentOutOfRangeException("data.Length", data.Length, "must be at least as large as 'xLength * yLength' parameter"); } if (Fourier.IsPowerOf2(xLength) == false) { throw new ArgumentOutOfRangeException("xLength", xLength, "must be a power of 2"); } if (Fourier.IsPowerOf2(yLength) == false) { throw new ArgumentOutOfRangeException("yLength", yLength, "must be a power of 2"); } int xInc = 1; int yInc = xLength; if (xLength > 1) { Fourier.SyncLookupTableLength(xLength); for (int y = 0; y < yLength; y++) { int xStart = y * yInc; Fourier.LinearFFT_Quick(data, xStart, xInc, xLength, direction); } } if (yLength > 1) { Fourier.SyncLookupTableLength(yLength); for (int x = 0; x < xLength; x++) { int yStart = x * xInc; Fourier.LinearFFT_Quick(data, yStart, yInc, yLength, direction); } } }
/// <summary> /// Compute a 1D fast Fourier transform of a dataset of complex numbers. /// </summary> /// <param name="data"></param> /// <param name="length"></param> /// <param name="direction"></param> public static void FFT(Complex[] data, int length, FourierDirection direction) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length < length) { throw new ArgumentOutOfRangeException("length", length, "must be at least as large as 'data.Length' parameter"); } if (Fourier.IsPowerOf2(length) == false) { throw new ArgumentOutOfRangeException("length", length, "must be a power of 2"); } Fourier.SyncLookupTableLength(length); int ln = Fourier.Log2(length); // reorder array Fourier.ReorderArray(data); // successive doubling int N = 1; int signIndex = (direction == FourierDirection.Forward) ? 0 : 1; for (int level = 1; level <= ln; level++) { int M = N; N <<= 1; double[] uRLookup = _uRLookup[level, signIndex]; double[] uILookup = _uILookup[level, signIndex]; for (int j = 0; j < M; j++) { double uR = uRLookup[j]; double uI = uILookup[j]; for (int even = j; even < length; even += N) { int odd = even + M; double r = data[odd].Re; double i = data[odd].Im; double odduR = r * uR - i * uI; double odduI = r * uI + i * uR; r = data[even].Re; i = data[even].Im; data[even].Re = r + odduR; data[even].Im = i + odduI; data[odd].Re = r - odduR; data[odd].Im = i - odduI; } } } }