/// <summary> /// Return real roots of the equation: x^3 + c2 x^2 + c1 x + c0 = 0 /// Double and triple solutions are returned as replicated values. /// Imaginary and non existing solutions are returned as NaNs. /// </summary> public static Triple <double> RealRootsOfNormed( double c2, double c1, double c0) { // ------ eliminate quadric term (x = y - c2/3): x^3 + p x + q = 0 double d = c2 * c2; double p3 = 1 / 3.0 * /* p */ (-1 / 3.0 * d + c1); double q2 = 1 / 2.0 * /* q */ ((2 / 27.0 * d - 1 / 3.0 * c1) * c2 + c0); double p3c = p3 * p3 * p3; double shift = 1 / 3.0 * c2; d = q2 * q2 + p3c; if (d < 0) // casus irreducibilis: three real solutions { double phi = 1 / 3.0 * Fun.Acos(-q2 / Fun.Sqrt(-p3c)); double t = 2 * Fun.Sqrt(-p3); double r0 = t * Fun.Cos(phi) - shift; double r1 = -t *Fun.Cos(phi + Constant.Pi / 3.0) - shift; double r2 = -t *Fun.Cos(phi - Constant.Pi / 3.0) - shift; return(Triple.CreateAscending(r0, r1, r2)); } // else if (Fun.IsTiny(q2)) // one triple root // { // too unlikely for // double r = -1/3.0 * c2; // special handling // return Triple.Create(r, r, r); // to pay off // } d = Fun.Sqrt(d); // one single and one double root double uav = Fun.Cbrt(d - q2) - Fun.Cbrt(d + q2); double s0 = uav - shift, s1 = -0.5 * uav - shift; return(s0 < s1?Triple.Create(s0, s1, s1) : Triple.Create(s1, s1, s0)); }
/// <summary> /// One real root of the equation: x^3 + c2 x^2 + c1 x + c0 = 0. /// </summary> public static double OneRealRootOfNormed( double c2, double c1, double c0 ) { // ------ eliminate quadric term (x = y - c2/3): x^3 + p x + q = 0 double d = c2 * c2; double p3 = 1 / 3.0 * /* p */ (-1 / 3.0 * d + c1); double q2 = 1 / 2.0 * /* q */ ((2 / 27.0 * d - 1 / 3.0 * c1) * c2 + c0); double p3c = p3 * p3 * p3; d = q2 * q2 + p3c; if (d < 0) // -------------- casus irreducibilis: three real roots { return(2 * Fun.Sqrt(-p3) * Fun.Cos(1 / 3.0 * Fun.Acos(-q2 / Fun.Sqrt(-p3c))) - 1 / 3.0 * c2); } d = Fun.Sqrt(d); // one triple root or a single and a double root return(Fun.Cbrt(d - q2) - Fun.Cbrt(d + q2) - 1 / 3.0 * c2); }
/// <summary> /// Return real roots of the equation: x^3 + p x + q = 0 /// Double and triple solutions are returned as replicated values. /// Imaginary and non existing solutions are returned as NaNs. /// </summary> public static Triple <double> RealRootsOfDepressed( double p, double q) { double p3 = 1 / 3.0 * p, q2 = 1 / 2.0 * q; double p3c = p3 * p3 * p3, d = q2 * q2 + p3c; if (d < 0) // ---------- casus irreducibilis: three real solutions { double phi = 1 / 3.0 * Fun.Acos(-q2 / Fun.Sqrt(-p3c)); double t = 2 * Fun.Sqrt(-p3); double r0 = t * Fun.Cos(phi); double r1 = -t *Fun.Cos(phi + Constant.Pi / 3.0); double r2 = -t *Fun.Cos(phi - Constant.Pi / 3.0); return(Triple.CreateAscending(r0, r1, r2)); } d = Fun.Sqrt(d); // one triple root or a single and a double root double s0 = Fun.Cbrt(d - q2) - Fun.Cbrt(d + q2); double s1 = -0.5 * s0; return(s0 < s1?Triple.Create(s0, s1, s1) : Triple.Create(s1, s1, s0)); }