public static void FullForwardFFT(this Complex[] data, double[] temporaryArray = null) { int N = data.Length; Stack <int> factors = new Stack <int>(FourierTransform235.GetSlowFactorization(N).OrderBy(x => x)); Complex[] roots = null; Complex[] temp = null; Complex[] simpleRoots = null; ReversedPowersFFTSwapAtEnd(data, 0, N, factors, 0, 1, ref roots, ref temp, ref simpleRoots); if (temporaryArray == null || temporaryArray.Length < N * 2) { Array.Resize(ref temporaryArray, N * 2); } for (int i = N; --i >= 0;) { var number = data[i]; temporaryArray[i * 2 + 0] = number.Real; temporaryArray[i * 2 + 1] = number.Imaginary; } FourierTransform235.ReversedBaseIterate(factors, (i, reversed) => data[reversed] = new Complex(temporaryArray[i * 2 + 0], temporaryArray[i * 2 + 1])); }
public static void FullForwardFFT(this ComplexNumber[] data, RealNumber[] temporaryArray = null) { int N = data.Length; int precisionDigits = 1; for (int i = data.Length; --i >= 0;) { precisionDigits = Math.Max(precisionDigits, data[i].GetPrecisionDigits()); } FFTRealConstants precision = new FFTRealConstants(precisionDigits); List <int> factors = FourierTransform235.GetSlowFactorization(N).OrderBy(x => x).ToList(); ComplexNumber[] roots = null; ComplexNumber[] temp = null; ComplexNumber[] simpleRoots = null; List <int> factorDigits = new List <int>(); List <int> decimalRepresentation = new List <int>(); List <ComplexNumber> incrementalProduct = new List <ComplexNumber>(); int totalProduct = 1; int N1 = N; int count = 1; foreach (int factor in factors) { int N2 = N1; N1 /= factor; totalProduct *= factor; factorDigits.Add(factor); incrementalProduct.Clear(); int partialProduct = totalProduct; for (int i = 0; i < factorDigits.Count; i++) { incrementalProduct.Add(ComplexNumber.FromPolarAngle((precision.PI << 1) / partialProduct)); partialProduct /= factorDigits[i]; } ComplexNumber[] exactProduct = new ComplexNumber[factorDigits.Count - 1]; if (factorDigits.Count > 1) { exactProduct[factorDigits.Count - 2] = incrementalProduct[factorDigits.Count - 2]; for (int i = factorDigits.Count - 2; --i >= 0;) { exactProduct[i] = exactProduct[i + 1] * (incrementalProduct[i] * incrementalProduct[i + 2].Conjugate); } } decimalRepresentation.Clear(); decimalRepresentation.AddRange(Enumerable.Repeat(0, factorDigits.Count - 1)); ComplexNumber exactPower = ComplexNumber.One; for (int i = 0; i < count; i++) { DirectFFTWithStartTwiddle(data, i * N2, N1, N1, factor, precision, ref roots, ref temp, ref simpleRoots, exactPower); getIncrement(ref exactPower, decimalRepresentation, factorDigits, exactProduct); } count = totalProduct; } if (temporaryArray == null || temporaryArray.Length < N * 2) { Array.Resize(ref temporaryArray, N * 2); } for (int i = N; --i >= 0;) { var number = data[i]; temporaryArray[i * 2] = number.Real; temporaryArray[i * 2 + 1] = number.Imaginary; } FourierTransform235.ReversedBaseIterate(factors, (i, reversed) => data[reversed] = new ComplexNumber(temporaryArray[i * 2], temporaryArray[i * 2 + 1])); }