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; } }