diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index eeb6537f8..205ec5f0b 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -1796,6 +1796,21 @@ closed form now, by the sign of `c` | `"x/((4*c + d*x^3)*sqrt(c + d*x^3))".ToEntity().Integrate("x")` | `integral(...)` | the same in `sqrt(c + d x^3)` and `q = (d/c)^(1/3)`, by the sign of `c` | | `"x/((8 - d*x^3)*sqrt(1 + d*x^3))".ToEntity().Integrate("x")` | `integral(...)` | `(artanh((1 + d^(1/3) x)^2/(3 sqrt(1 + d x^3))) - artanh(sqrt(1 + d x^3)/3))/(18 d^(2/3)) - atan(sqrt(3) (1 + d^(1/3) x)/sqrt(1 + d x^3))/(6 sqrt(3) d^(2/3))`, written with logarithms | +### `x` over a cubic binomial beside the root of another is integrated at its third elementary ratio + +**Answers where there were none.** `x/((b x^3 + 2 a (5 + 3 sqrt(3))) sqrt(a + b x^3))` was declined, with its +seven variants in Rubi's 1.1.3.4, and so were four numeric ones in its Welz problems. +`x/((a + b x^3) sqrt(c + d x^3))` is elementary at a third ratio as well, `a^2 d^2 - 20 a b c d - 8 b^2 c^2 = 0`, where `r = (a d - 10 b c)/(6 b c)` is `sqrt(3)` or `-sqrt(3)`, as two +arctangents and two inverse hyperbolic tangents for each sign of `c r` +([#718](https://github.com/asc-community/AngouriMath/issues/718), PR +[#1862](https://github.com/asc-community/AngouriMath/pull/1862)). + +| Input | Was (2.5.0) | Now | +|---|---|---| +| `"x/((b*x^3 + 2*a*(5 + 3*sqrt(3)))*sqrt(a + b*x^3))".ToEntity().Integrate("x")` | `integral(...)` | 1,663 characters, by the sign of `a` | +| `"x/((b*x^3 + 2*a*(5 - 3*sqrt(3)))*sqrt(a + b*x^3))".ToEntity().Integrate("x")` | `integral(...)` | 1,703 characters, by the sign of `a` | +| `"x/((x^3 + 10 + 6*sqrt(3))*sqrt(1 + x^3))".ToEntity().Integrate("x")` | `integral(...)` | 626 characters | + ### `x^2` over a three-quarter power of a quadratic binomial beside another is integrated where that is elementary **Answers where there were none.** `x^2/((A + B x^2)^(3/4) (C + D x^2))` at `B C - 2 A D = 0`, Rubi's diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs index 7bd633b26..50b8e7d7f 100644 --- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs +++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs @@ -6137,8 +6137,9 @@ Entity OverOnePlus(Entity k) } /// - /// x/((a + b x^3) sqrt(c + d x^3)) at the two ratios where its integral is elementary, - /// Rubi's 1.1.3.4: 4 b c = a d and 8 b c + a d = 0, in closed form. + /// x/((a + b x^3) sqrt(c + d x^3)) at the three ratios where its integral is elementary, + /// Rubi's 1.1.3.4: 4 b c = a d, 8 b c + a d = 0 and + /// a^2 d^2 - 20 a b c d - 8 b^2 c^2 = 0, in closed form. /// /// /// @@ -6160,10 +6161,25 @@ Entity OverOnePlus(Entity k) /// Rubi splits the second into three integrals, a substitution's in x^3, a linear /// over a linear and a quadratic over a quadratic, each elementary, and their sum is the /// form above; asked as three, two come back piecewise in the symbols and their sum holds - /// every combination of the arms. Every condition is decided as a value, and the answer is - /// differentiated back at sampled points before it is returned. + /// every combination of the arms. + /// + /// + /// At the third, r = (a d - 10 b c)/(6 b c) is sqrt(3) or -sqrt(3), the + /// condition's two roots, and with s = sqrt(c r) Rubi's four terms are + /// + /// -q (2 - r)/(sqrt(2) b) (atan(s (1 - r) y/(sqrt(2) c r^2))/(3 r s) + atan(s (1 + r) (1 + q x)/(sqrt(2) y))/(2 r s) + /// + artanh(s (1 - r) (1 + q x)/(sqrt(2) y))/(6 s) + artanh(s (1 + r - 2 q x)/(sqrt(2) y))/(3 s)) + /// + /// Each is atan(s v)/s or artanh(s v)/s, which depends on s^2 alone, so + /// where c r is negative the same terms are written with t = sqrt(-c r), each + /// atan becoming an artanh and each artanh an atan: one real form + /// for each sign, where Rubi has one for each sign of c and a power of r that is + /// complex at r = -sqrt(3). + /// Every condition is decided as a value, and the answer is differentiated back at sampled + /// points before it is returned. /// Welz's x/((4 - x^3) sqrt(1 - x^3)) and x/((8 - d x^3) sqrt(1 + d x^3)) were - /// declined, with the rest of 1.1.3.4 at those ratios. + /// declined, with the rest of 1.1.3.4 at those ratios, and + /// x/((b x^3 + 2 a (5 + 3 sqrt(3))) sqrt(a + b x^3)) with its seven variants after them. /// https://github.com/asc-community/AngouriMath/issues/718 /// /// @@ -6219,6 +6235,28 @@ Entity OverOnePlus(Entity k) - MathS.Hyperbolic.Artanh(sqrtOfThree * s * (1 + q * x) / y) / (6 * sqrtOfThree)) / (MathS.Pow(s, 3) * MathS.Sqr(q)); answer = LowestOverTheSymbols(-d / b) * BySign(c, wherePositive, whereNegative); } + else if (Zero(MathS.Sqr(a * d) - 20 * a * b * c * d - 8 * MathS.Sqr(b * c)) + && ((a * d - 10 * b * c) / (6 * b * c)) is var ratio + && (Zero(ratio - sqrtOfThree) ? sqrtOfThree : Zero(ratio + sqrtOfThree) ? -sqrtOfThree : null) is { } r) + { + // Each term is atan(s v)/s or atanh(s v)/s for s = sqrt(c r), which depends on s^2 + // alone, so the sign of c r picks the real form. + var k = LowestOverTheSymbols(c * r); + var w = 1 + q * x; + Entity Terms(bool positive, Entity s) + => -q * (2 - r) / (Sqr2() * b) * ( + Circular(positive, s * (1 - r) * y / (Sqr2() * c * MathS.Sqr(r))) / (3 * r * s) + + Circular(positive, s * (1 + r) * w / (Sqr2() * y)) / (2 * r * s) + + Hyperbolic(positive, s * (1 - r) * w / (Sqr2() * y)) / (6 * s) + + Hyperbolic(positive, s * (1 + r - 2 * q * x) / (Sqr2() * y)) / (3 * s)); + var sPositive = MathS.Sqrt(k); + var sNegative = MathS.Sqrt(LowestOverTheSymbols(-k)); + // atan(i t v)/(i t) = atanh(t v)/t, and atanh(i t v)/(i t) = atan(t v)/t. + answer = BySign(k, Terms(true, sPositive), Terms(false, sNegative)); + static Entity Sqr2() => MathS.Sqrt(2); + static Entity Circular(bool positive, Entity v) => positive ? MathS.Arctan(v) : MathS.Hyperbolic.Artanh(v); + static Entity Hyperbolic(bool positive, Entity v) => positive ? MathS.Hyperbolic.Artanh(v) : MathS.Arctan(v); + } if (answer is null) return null; answer = (multiple * answer).InnerSimplified; diff --git a/Sources/Tests/UnitTests/Calculus/XOverACubicBinomialBesideTheRootOfAnotherIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/XOverACubicBinomialBesideTheRootOfAnotherIntegralTest.cs index 9204487dd..770219859 100644 --- a/Sources/Tests/UnitTests/Calculus/XOverACubicBinomialBesideTheRootOfAnotherIntegralTest.cs +++ b/Sources/Tests/UnitTests/Calculus/XOverACubicBinomialBesideTheRootOfAnotherIntegralTest.cs @@ -12,9 +12,9 @@ namespace AngouriMath.Tests.Calculus { /// - /// x/((a + b x^3) sqrt(c + d x^3)) at the two ratios where its integral is elementary, - /// Rubi's 1.1.3.4: 4 b c = a d, in closed form by the sign of c, and - /// 8 b c + a d = 0, as three integrals. + /// x/((a + b x^3) sqrt(c + d x^3)) at the three ratios where its integral is elementary, + /// Rubi's 1.1.3.4: 4 b c = a d, in closed form by the sign of c, + /// 8 b c + a d = 0, as three integrals, and a^2 d^2 - 20 a b c d - 8 b^2 c^2 = 0. /// #718 /// /// @@ -37,6 +37,12 @@ public sealed class XOverACubicBinomialBesideTheRootOfAnotherIntegralTest [InlineData("x/((8*c - d*x^3)*sqrt(c + d*x^3))", 1.3)] [InlineData("x/((8*c - d*x^3)*sqrt(c + d*x^3))", -1.3)] [InlineData("3*x/((8 + x^3)*sqrt(-1 + x^3))", 1.3)] + // a^2 d^2 - 20 a b c d - 8 b^2 c^2 = 0, at both of its roots. + [InlineData("x/((d*x^3 + 2*c*(5 + 3*sqrt(3)))*sqrt(c + d*x^3))", 1.3)] + [InlineData("x/((d*x^3 + 2*c*(5 + 3*sqrt(3)))*sqrt(c + d*x^3))", -1.3)] + [InlineData("x/((d*x^3 + 2*c*(5 - 3*sqrt(3)))*sqrt(c + d*x^3))", 1.3)] + [InlineData("x/((d*x^3 + 2*c*(5 - 3*sqrt(3)))*sqrt(c + d*x^3))", -1.3)] + [InlineData("x/((-x^3 + 2*(5 - 3*sqrt(3)))*sqrt(1 - x^3))", 1.3)] public void IsIntegrated(string integrand, double c) { var integral = integrand.ToEntity().Integrate("x");