Exemplo n.º 1
0
        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]));
        }
Exemplo n.º 2
0
        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]));
        }