// f(x) = x^3 + cx + d = 0
        public static double[] Solve(double c, double d)
        {
            if (d < 0)
            {
                return(Solve(c, -d).Reverse().Select(x => - x).ToArray());
            }
            // 自明解
            if (d == 0 && c >= 0)
            {
                return new[] { 0D }
            }
            ;

            // 負の実数解
            var x1 = SolveNegative();

            // f(x) = (x - x_1) (x^2 + x_1 x + x_1^2 + c)
            return(QuadraticEquation0.Solve(1, x1, x1 * x1 + c).Prepend(x1).ToArray());

            double SolveNegative()
            {
                var f = CreateFunction(c, d);

                var f1 = CreateDerivative(c);
                var x0 = -1D;

                while (f(x0) > 0)
                {
                    x0 *= 2;
                }
                return(NewtonMethod.Solve(f, f1, x0));
            }
        }
    }
        // f(x) = ax^2 + bx + c = 0
        public static double[] Solve(double a, double b, double c)
        {
            if (a == 0)
            {
                throw new ArgumentException("The value must not be 0.", nameof(a));
            }
            if (a < 0)
            {
                return(Solve(-a, -b, -c));
            }

            var det = b * b - 4 * a * c;

            if (det.EqualsNearly(0))
            {
                return new[] { -b / (2 * a) }
            }
            ;
            if (det < 0)
            {
                return(new double[0]);
            }

            var f   = CreateFunction(a, b, c);
            var f1  = CreateDerivative(a, b);
            var x01 = (-b - Math.Max(det, 1)) / (2 * a);
            var x02 = (-b + Math.Max(det, 1)) / (2 * a);

            return(new[] { NewtonMethod.Solve(f, f1, x01), NewtonMethod.Solve(f, f1, x02) });
        }
    }
Exemple #3
0
        public static double[] Solve(double c, double d)
        {
            if (d < 0)
            {
                return(Solve(c, -d).Reverse().Select(x => - x).ToArray());
            }
            // 3重解の場合 (c = d = 0) を含む
            if (d == 0)
            {
                return c >= 0 ? new[] { 0D }
            }
            : new[] { -Sqrt(-c), 0D, Sqrt(-c) };

            // この式では誤差が大きくなることがあります。
            var det3 = -4 * c * c * c - 27 * d * d;

            // 重解の場合
            if (det3.EqualsNearly(0, 8))
            {
                return new[] { -2 * Sqrt(-c / 3), Sqrt(-c / 3) }
            }
            ;

            // 負の実数解
            var x1 = SolveNegative();

            if (det3 < 0)
            {
                return new[] { x1 }
            }
            ;

            // f(x) = (x - x_1) (x^2 + x_1 x + x_1^2 + c)
            var sqrt_det2 = Sqrt(-3 * x1 * x1 - 4 * c);

            return(new[] { x1, (-x1 - sqrt_det2) / 2, (-x1 + sqrt_det2) / 2 });

            double SolveNegative()
            {
                var f = CubicEquation1.CreateFunction(c, d);

                var f1 = CubicEquation1.CreateDerivative(c);
                var x0 = -1D;

                while (f(x0) > 0)
                {
                    x0 *= 2;
                }
                return(NewtonMethod.Solve(f, f1, x0));
            }
        }
    }
}
Exemple #4
0
        // f(x) = ax^3 + bx^2 + cx + d = 0
        public static double[] Solve(double a, double b, double c, double d)
        {
            if (a == 0)
            {
                throw new ArgumentException("The value must not be 0.", nameof(a));
            }
            if (a < 0)
            {
                return(Solve(-a, -b, -c, -d));
            }

            var f  = CreateFunction(a, b, c, d);
            var xc = -b / (3 * a);
            var yc = f(xc);

            if (yc < 0)
            {
                return(Solve(a, -b, c, -d).Reverse().Select(x => - x).ToArray());
            }

            var f1 = CreateDerivative(a, b, c);

            // 自明解
            if (yc == 0 && f1(xc) >= 0)
            {
                return new[] { xc }
            }
            ;

            // xc より小さい実数解
            var x1 = SolveNegative();
            var p  = a * x1 + b;
            var q  = p * x1 + c;

            return(QuadraticEquation0.Solve(a, p, q).Prepend(x1).ToArray());

            double SolveNegative()
            {
                var x0 = -1D;

                while (f(xc + x0) > 0)
                {
                    x0 *= 2;
                }
                return(NewtonMethod.Solve(f, f1, xc + x0));
            }
        }
    }
Exemple #5
0
        public static double[] Solve(double c, double d)
        {
            if (d < 0)
            {
                return(Solve(c, -d).Reverse().Select(x => - x).ToArray());
            }
            // 自明解
            if (d == 0 && c >= 0)
            {
                return new[] { 0D }
            }
            ;

            // 負の実数解
            var x1 = SolveNegative();
            // f(x) = (x - x_1) (x^2 + x_1 x + x_1^2 + c)
            var det = -3 * x1 * x1 - 4 * c;

            if (det < 0)
            {
                return new[] { x1 }
            }
            ;
            if (det == 0)
            {
                return new[] { x1, -x1 / 2 }
            }
            ;
            return(new[] { x1, (-x1 - Sqrt(det)) / 2, (-x1 + Sqrt(det)) / 2 });

            double SolveNegative()
            {
                var f = CubicEquation1.CreateFunction(c, d);

                var f1 = CubicEquation1.CreateDerivative(c);
                var x0 = -1D;

                while (f(x0) > 0)
                {
                    x0 *= 2;
                }
                return(NewtonMethod.Solve(f, f1, x0));
            }
        }
    }
}
Exemple #6
0
        // f(x) = x^2 + c = 0
        public static double[] Solve(double c)
        {
            if (c > 0)
            {
                return(new double[0]);
            }
            if (c == 0)
            {
                return new[] { 0D }
            }
            ;

            var f  = CreateFunction(c);
            var f1 = CreateDerivative();
            var x0 = Math.Max(-c, 1);
            var x1 = NewtonMethod.Solve(f, f1, x0);

            return(new[] { -x1, x1 });
        }
    }