Artemis.Engine.Maths.RootSolver.Cubic C# (CSharp) Метод

Cubic() публичный статический Метод

Solve for the real roots of a cubic. (Ax^3 + Bx^2 + Cx + D == 0)
public static Cubic ( double A, double B, double C, double D ) : double[]
A double
B double
C double
D double
Результат double[]
        public static double[] Cubic(double A, double B, double C, double D)
        {
            if (A == 0)
                return Quadratic(B, C, D);
            double B_over_A = B / A;
            double F, G, H;

            F = ((3*C / A) - (System.Math.Pow(B_over_A, 2.0))) / 3;
            G = ((2 * System.Math.Pow(B_over_A, 3.0)) - (9 * C * B_over_A / A) + (27 * D / A)) / 27;
            double G_over_2 = -G / 2.0;
            double G_over_2_sqrd = G_over_2 * G_over_2;
            H = G_over_2_sqrd + (System.Math.Pow(F / 3.0, 3.0));

            // Only one root is real.
            if (H > 0)
            {
                double sqrt_H = System.Math.Sqrt(H);
                double R, S, T, U;

                R = G_over_2 + sqrt_H;
                if (R < 0)
                    S = -System.Math.Pow(-R, 1.0 / 3.0);
                else
                    S = System.Math.Pow(R, 1.0 / 3.0);

                T = G_over_2 - sqrt_H;
                if (T < 0)
                    U = -System.Math.Pow(-T, 1.0 / 3.0);
                else
                    U = System.Math.Pow(T, 1.0 / 3.0);

                double X = S + U - B_over_A / 3.0;
                return new double[] { X };
            }
            // All 3 roots are real and equal.
            else if (F == G && G == H && H == 0)
            {
                double D_A = D / A;
                double X;
                if (D_A < 0)
                    X = System.Math.Pow(-D_A, 1.0 / 3.0);
                else
                    X = -System.Math.Pow(D_A, 1.0 / 3.0);
                return new double[] { X };
            }

            // All 3 roots are real.
            double I, J, K, L, M, N, P;
            I = System.Math.Sqrt(G_over_2_sqrd - H);
            J = System.Math.Pow(I, 1.0 / 3.0);
            K = System.Math.Acos(-(G / (2 * I))) / 3.0;
            L = -J;
            M = System.Math.Cos(K);
            N = System.Math.Sqrt(3) * System.Math.Sin(K);
            P = -B_over_A / 3.0;

            double X1, X2, X3;
            X1 = 2*J*System.Math.Cos(K) + P;
            X2 = L*(M + N) + P;
            X3 = L*(M - N) + P;

            var result = new double[] { X1, X2, X3 };
            Array.Sort(result);
            return result;
        }