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