예제 #1
0
        public static void EvenDCTType3(this RealNumber[] data, ComplexNumber[] v = null)
        {
            int N = data.Length;

            if ((N & 1) != 0)
            {
                throw new Exception("Inverse DCT operates only on even data sizes.");
            }
            N >>= 1;
            Array.Resize(ref v, N);
            v[0] = new ComplexNumber(data[0] + data[N], data[0] - data[N]);
            //A.Conjug * B = (A * B.Conjug).Conjug

            int precisionDigits = 1;

            for (int i = data.Length; --i >= 0;)
            {
                precisionDigits = Math.Max(precisionDigits, data[i].GetPrecisionDigits());
            }
            RealNumber INV_SQRT_2 = new RealNumber(0.5, precisionDigits).GetSqrt();
            RealNumber PI         = RealNumber.GetPI(precisionDigits);

            var           scalej         = new ComplexNumber(INV_SQRT_2, INV_SQRT_2);
            ComplexNumber firstRoot      = ComplexNumber.FromPolarAngle((-PI >> 2) / N);
            ComplexNumber secondRoot     = ComplexNumber.FromPolarAngle((-PI * 5 >> 2) / N);
            ComplexNumber firstIterator  = INV_SQRT_2 * firstRoot;
            ComplexNumber secondIterator = INV_SQRT_2 * secondRoot.DivI();

            for (int i = 1, j = N - 1; i <= j; i++, j--)
            {
                var a  = new ComplexNumber(data[i], data[N * 2 - i]);
                var b  = new ComplexNumber(data[j], -data[N * 2 - j]) * scalej;
                var t1 = (a + b) * firstIterator;
                var t2 = (a - b) * secondIterator;
                v[i]            = (t1 - t2);
                v[j]            = (t1 + t2).Conjugate;
                firstIterator  *= firstRoot;
                secondIterator *= secondRoot;
            }

            FullForwardIFFT(v, data);

            for (int i = N; --i >= 0;)
            {
                var number = v[i];
                data[map1(i * 2, N * 2)]     = number.Real;
                data[map1(i * 2 + 1, N * 2)] = number.Imaginary;
            }
        }