Пример #1
0
        public static IList <double> GetCubicPolynomialRoots(IList <double> coefficients)
        {
            if (coefficients == null)
            {
                throw new ArgumentNullException(nameof(coefficients));
            }
            if (coefficients.Count < 4)
            {
                throw new ArgumentException("The coefficients should at least have length 4.");
            }
            double coefficient1 = coefficients[3];

            if (coefficient1 == 0.0)
            {
                throw new ArgumentException("Coefficient a is zero.");
            }
            double coefficient2 = coefficients[2];
            double coefficient3 = coefficients[1];
            double coefficient4 = coefficients[0];
            double num1         = coefficient2 * coefficient2;
            double num2         = coefficient1 * coefficient3;
            double num3         = coefficient1 * coefficient4;
            double a            = num1 - 3.0 * num2;
            double num4         = coefficient2 * (2.0 * num1 - 9.0 * num2) + 27.0 * coefficient1 * num3;
            double d            = num4 * num4 - 4.0 * a * a * a;

            double[] numArray;
            if (d < -8.88178419700125E-16)
            {
                double   num5      = System.Math.Sqrt(-d);
                ComplexD complexD  = new ComplexD(0.5 * num4, 0.5 * num5);
                ComplexD v         = ComplexD.FromModulusAndArgument(System.Math.Pow(complexD.GetModulusSquared(), 1.0 / 6.0), 1.0 / 3.0 * complexD.GetArgument());
                ComplexD conjugate = v.GetConjugate();
                double   num6      = -1.0 / (3.0 * coefficient1);
                numArray = new double[3]
                {
                    num6 *(coefficient2 + v.Real + conjugate.Real),
                    num6 *(coefficient2 + ComplexD.MultiplyAndGetReal(MathUtil.complexD_2, v) + ComplexD.MultiplyAndGetReal(MathUtil.complexD_3, conjugate)),
                    num6 *(coefficient2 + ComplexD.MultiplyAndGetReal(MathUtil.complexD_4, v) + ComplexD.MultiplyAndGetReal(MathUtil.complexD_5, conjugate))
                };
            }
            else if (d > 8.88178419700125E-16)
            {
                double num5 = System.Math.Sqrt(d);
                double x1   = 0.5 * (num4 + num5);
                double x2   = 0.5 * (num4 - num5);
                double num6 = x1 >= 0.0 ? System.Math.Pow(x1, 1.0 / 3.0) : -System.Math.Pow(-x1, 1.0 / 3.0);
                double num7 = x2 >= 0.0 ? System.Math.Pow(x2, 1.0 / 3.0) : -System.Math.Pow(-x2, 1.0 / 3.0);
                numArray = new double[1]
                {
                    -(coefficient2 + num6 + num7) / (3.0 * coefficient1)
                };
            }
            else if (MathUtil.AreApproxEqual(a, 0.0, 8.88178419700125E-16))
            {
                numArray = new double[1]
                {
                    -coefficient2 / (3.0 * coefficient1)
                }
            }
            ;
            else
            {
                numArray = new double[2]
                {
                    (9.0 * num3 - coefficient2 * coefficient3) / (2.0 * a),
                    (4.0 * coefficient2 * num2 - 9.0 * coefficient1 * num3 - coefficient2 * num1) / (coefficient1 * a)
                }
            };
            return((IList <double>)numArray);
        }