Exemplo n.º 1
0
    // 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) });
    }
}
Exemplo n.º 2
0
        public static double[] Solve(double c, double d)
        {
            if (d < 0)
            {
                return(Solve(c, -d).Reverse().Select(x => - x).ToArray());
            }

            // 最小の実数解
            var x1 = d == 0 && c >= 0 ? 0 : 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 }
            }
            ;
            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));
            }
        }
    }
Exemplo n.º 3
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 }
        }
        ;
        if (yc == 0 && f1(xc) == 0)
        {
            return new[] { xc, xc, 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));
        }
    }
}