Esempio n. 1
0
        /// <summary>
        /// solves ax3 + bx2 + cx + d
        /// </summary>
        /// <param name="a">
        /// Coefficient of x^3
        /// </param>
        /// <param name="b">
        /// Coefficient of x^2
        /// </param>
        /// <param name="c">
        /// Coefficient of x
        /// </param>
        /// <param name="d">
        /// Free coefficient
        /// </param>
        /// <returns>
        /// Set of roots
        /// </returns>
        internal static Set SolveCubic(Entity a, Entity b, Entity c, Entity d)
        {
            // en: https://en.wikipedia.org/wiki/Cubic_equation
            // ru: https://ru.wikipedia.org/wiki/%D0%A4%D0%BE%D1%80%D0%BC%D1%83%D0%BB%D0%B0_%D0%9A%D0%B0%D1%80%D0%B4%D0%B0%D0%BD%D0%BE

            // TODO (to remove sympy code!)

            Set res;

            if (TreeAnalyzer.IsZero(d))
            {
                res = SolveQuadratic(a, b, c);
                res.Add(0);
                return(res);
            }

            if (TreeAnalyzer.IsZero(a))
            {
                return(SolveQuadratic(b, c, d));
            }

            res = new Set();

            var coeff = MathS.i * MathS.Sqrt(3) / 2;

            var u1 = new NumberEntity(1);
            var u2 = SySyn.Rational(-1, 2) + coeff;
            var u3 = SySyn.Rational(-1, 2) - coeff;
            var D0 = MathS.Sqr(b) - 3 * a * c;
            var D1 = (2 * MathS.Pow(b, 3) - 9 * a * b * c + 27 * MathS.Sqr(a) * d).InnerSimplify();
            var C  = MathS.Pow((D1 + MathS.Sqrt(MathS.Sqr(D1) - 4 * MathS.Pow(D0, 3))) / 2, Number.CreateRational(1, 3));

            foreach (var uk in new List <Entity> {
                u1, u2, u3
            })
            {
                Entity r;
                if (Const.EvalIfCan(C) == 0 && Const.EvalIfCan(D0) == 0)
                {
                    r = -(b + uk * C) / 3 / a;
                }
                else
                {
                    r = -(b + uk * C + D0 / C / uk) / 3 / a;
                }
                res.Add(r);
            }
            return(res);
        }
Esempio n. 2
0
        /// <summary>
        /// solves ax4 + bx3 + cx2 + dx + e
        /// </summary>
        /// <param name="a">
        /// Coefficient of x^4
        /// </param>
        /// <param name="b">
        /// Coefficient of x^3
        /// </param>
        /// <param name="c">
        /// Coefficient of x^2
        /// </param>
        /// <param name="d">
        /// Coefficient of x
        /// </param>
        /// <param name="e">
        /// Free coefficient
        /// </param>
        /// <returns>
        /// Set of roots
        /// </returns>
        internal static Set SolveQuartic(Entity a, Entity b, Entity c, Entity d, Entity e)
        {
            // en: https://en.wikipedia.org/wiki/Quartic_function
            // ru: https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%A4%D0%B5%D1%80%D1%80%D0%B0%D1%80%D0%B8

            Set res;

            if (TreeAnalyzer.IsZero(e))
            {
                res = SolveCubic(a, b, c, d);
                res.Add(0);
                return(res);
            }

            if (TreeAnalyzer.IsZero(a))
            {
                return(SolveCubic(b, c, d, e));
            }


            res = new Set();

            var alpha = (-3 * MathS.Sqr(b) / (8 * MathS.Sqr(a)) + c / a)
                        .InnerSimplify();
            var beta = (MathS.Pow(b, 3) / (8 * MathS.Pow(a, 3)) - (b * c) / (2 * MathS.Sqr(a)) + d / a)
                       .InnerSimplify();
            var gamma = (-3 * MathS.Pow(b, 4) / (256 * MathS.Pow(a, 4)) + MathS.Sqr(b) * c / (16 * MathS.Pow(a, 3)) - (b * d) / (4 * MathS.Sqr(a)) + e / a)
                        .InnerSimplify();

            if (Const.EvalIfCan(beta) == 0)
            {
                res.FastAddingMode = true;
                for (int s = -1; s <= 1; s += 2)
                {
                    for (int t = -1; t <= 1; t += 2)
                    {
                        var x = -b / 4 * a + s * MathS.Sqrt((-alpha + t * MathS.Sqrt(MathS.Sqr(alpha) - 4 * gamma)) / 2);
                        res.Add(x);
                    }
                }
                res.FastAddingMode = false;
                return(res);
            }


            var oneThird = Number.CreateRational(1, 3);
            var P        = (-MathS.Sqr(alpha) / 12 - gamma)
                           .InnerSimplify();
            var Q = (-MathS.Pow(alpha, 3) / 108 + alpha * gamma / 3 - MathS.Sqr(beta) / 8)
                    .InnerSimplify();
            var R = -Q / 2 + MathS.Sqrt(MathS.Sqr(Q) / 4 + MathS.Pow(P, 3) / 27);
            var U = MathS.Pow(R, oneThird)
                    .InnerSimplify();
            var y = (Number.CreateRational(-5, 6) * alpha + U + (Const.EvalIfCan(U) == 0 ? -MathS.Pow(Q, oneThird) : -P / (3 * U)))
                    .InnerSimplify();
            var W = MathS.Sqrt(alpha + 2 * y)
                    .InnerSimplify();

            // Now we need to permutate all four combinations
            res.FastAddingMode = true;  /* we are sure that there's no such root yet */
            for (int s = -1; s <= 1; s += 2)
            {
                for (int t = -1; t <= 1; t += 2)
                {
                    var x = -b / (4 * a) + (s * W + t * MathS.Sqrt(-(3 * alpha + 2 * y + s * 2 * beta / W))) / 2;
                    res.Add(x);
                }
            }
            res.FastAddingMode = false;
            return(res);
        }
Esempio n. 3
0
 internal static bool EdgeEqual(Edge A, Edge B)
 => Const.EvalIfCan(A.Item1) == Const.EvalIfCan(B.Item1) && A.Item2 == B.Item2 && A.Item3 == B.Item3;