@@ -19988,6 +19988,83 @@ Piecewise piecewise when piecewise.Cases.Any() => piecewise.Cases.First().Expres
1998819988 return null;
1998919989 }
1999019990
19991+ /// <summary>
19992+ /// A linear below the cube root of a quadratic, <c>1/((d + e x) (a + b x + c x^2)^(1/3))</c>,
19993+ /// in closed form where the shifted quadratic <c>a' + c y^2</c>, <c>y = x + b/(2 c)</c>, and
19994+ /// the linear <c>d' + e y</c> satisfy <c>c d'^2 = 3 a' e^2</c> or <c>c d'^2 = -9 a' e^2</c>.
19995+ /// </summary>
19996+ /// <remarks>
19997+ /// With <c>q^3 = 6 c^2 e^2/d'^2</c> and <c>R = (a + b x + c x^2)^(1/3)</c> the integral is
19998+ /// <c>-sqrt(3) c e/(d'^2 q^2) arctan(1/sqrt(3) + 2 c (d' - e y)/(sqrt(3) d' q R))
19999+ /// - 3 c e/(2 d'^2 q^2) ln(d + e x) + 3 c e/(2 d'^2 q^2) ln(c d' - c e y - d' q R)</c>, Rubi's
20000+ /// 1.2.1.2 rule. Where <c>c d'^2 = -9 a' e^2</c>, with <c>t = e y/d'</c>, <c>u = 1 - 3 t</c>
20001+ /// and <c>k^3 = a'</c>, it is <c>(-3/8 ln(2 R + k u) + 1/4 ln(d + e x) + 1/8 ln(u)
20002+ /// - sqrt(3)/4 arctan(sqrt(3) k u/(4 R - k u)))/(e k)</c>: on the curve
20003+ /// <c>w^3 = 1 - 9 t^2</c> the tangent at each point over <c>t = -1</c> meets it again at
20004+ /// <c>(1/3, 0)</c>, so <c>w + r (1 - 3 t)/2</c> for the cube roots of unity <c>r</c> are the
20005+ /// functions whose logarithms carry the residues. Otherwise the integral is elliptic. The
20006+ /// answer is differentiated back.
20007+ /// https://github.com/asc-community/AngouriMath/issues/718
20008+ /// </remarks>
20009+ internal static Entity? SolveALinearBelowACubeRootOfAQuadraticInClosedForm(Entity expr, Entity.Variable x)
20010+ {
20011+ var (numerator, denominator) = Functions.SingleQuotient.Of(expr);
20012+ if (numerator.ContainsNode(x))
20013+ return null;
20014+ Entity? linear = null, quadratic = null;
20015+ foreach (var factor in Mulf.LinearChildren(denominator))
20016+ {
20017+ if (!factor.ContainsNode(x))
20018+ numerator /= factor;
20019+ else if (quadratic is null && factor is Powf(var @base, Number.Rational power) && power == Number.Rational.Create(1, 3))
20020+ quadratic = @base;
20021+ else if (linear is null && TreeAnalyzer.TryGetPolyLinear(factor, x, out _, out _))
20022+ linear = factor;
20023+ else
20024+ return null;
20025+ }
20026+ if (linear is null || quadratic is null
20027+ || !TreeAnalyzer.TryGetPolyLinear(linear, x, out var e, out var d)
20028+ || !TreeAnalyzer.TryGetPolynomial(quadratic, x, out var read)
20029+ || read.Keys.Any(key => key.Sign < 0 || key.CompareTo(EInteger.FromInt32(2)) > 0)
20030+ || !read.TryGetValue(EInteger.FromInt32(2), out var c) || VanishesIdentically(c.Expand()))
20031+ return null;
20032+ var a = read.TryGetValue(EInteger.Zero, out var a0) ? a0 : Number.Integer.Zero;
20033+ var b = read.TryGetValue(EInteger.One, out var b0) ? b0 : Number.Integer.Zero;
20034+ var shift = (b / (2 * c)).InnerSimplified;
20035+ var dShifted = (d - e * shift).InnerSimplified;
20036+ var aShifted = (a - b * b / (4 * c)).InnerSimplified;
20037+ if (VanishesIdentically(dShifted.Expand()) || VanishesIdentically(e.Expand()))
20038+ return null;
20039+ var three = Number.Integer.Create(3);
20040+ var root3 = MathS.Sqrt(three);
20041+ if (VanishesIdentically((c * dShifted * dShifted + 9 * aShifted * e * e).Expand().InnerSimplified.Expand()))
20042+ {
20043+ var k = MathS.Pow(aShifted, Number.Rational.Create(1, 3));
20044+ var cubeRoot = MathS.Pow(quadratic, Number.Rational.Create(1, 3));
20045+ var u = 1 - 3 * e * (x + shift) / dShifted;
20046+ var closed = numerator / (e * k) * (
20047+ -Number.Rational.Create(3, 8) * MathS.Ln(2 * cubeRoot + k * u)
20048+ + Number.Rational.Create(1, 4) * MathS.Ln(linear)
20049+ + Number.Rational.Create(1, 8) * MathS.Ln(u)
20050+ - root3 / 4 * MathS.Arctan(root3 * k * u / (4 * cubeRoot - k * u)));
20051+ closed = closed.InnerSimplified;
20052+ return Functions.PartialFractions.DerivativeHoldsAtSampledPoints(closed, expr, x) ? closed : null;
20053+ }
20054+ if (!VanishesIdentically((c * dShifted * dShifted - 3 * aShifted * e * e).Expand().InnerSimplified.Expand()))
20055+ return null;
20056+ var q = MathS.Pow(6 * c * c * e * e / (dShifted * dShifted), Number.Rational.Create(1, 3));
20057+ var r = MathS.Pow(quadratic, Number.Rational.Create(1, 3));
20058+ var y = x + shift;
20059+ var scale = c * e / (dShifted * dShifted * q * q);
20060+ var answer = numerator * (
20061+ -root3 * scale * MathS.Arctan(1 / root3 + 2 * c * (dShifted - e * y) / (root3 * dShifted * q * r))
20062+ - three / 2 * scale * MathS.Ln(linear)
20063+ + three / 2 * scale * MathS.Ln(c * dShifted - c * e * y - dShifted * q * r));
20064+ answer = answer.InnerSimplified;
20065+ return Functions.PartialFractions.DerivativeHoldsAtSampledPoints(answer, expr, x) ? answer : null;
20066+ }
20067+
1999120068 /// <summary>
1999220069 /// A power of a linear that is not whole, times a linear, over a whole power of a quadratic,
1999320070 /// with the power of the quadratic lowered one at a time:
0 commit comments