diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index 937b3f87c..46d4dba8a 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -439,9 +439,22 @@ answered without one now ([#718](https://github.com/asc-community/AngouriMath/is | Input | Was (2.5.0) | Now | |---|---|---| -| `"sec(x)^3*sqrt(a + i*a*tan(x))".ToEntity().Integrate("x")` | `integral(...)` | powers of `sqrt(a - i a tan(x))` times a factor constant wherever it is continuous, 495 characters | -| `"sec(x)^5/(a + i*a*tan(x))^(3/2)".ToEntity().Integrate("x")` | `integral(...)` | the same, 399 characters | -| `"cos(x)^9*(a + i*a*tan(x))^(7/2)".ToEntity().Integrate("x")` | `integral(...)`; on the unreleased master, an answer provided `1 + i tan(x) >= 0` | 1,067 characters, unconditional | +| `"sec(x)^3*sqrt(a + i*a*tan(x))".ToEntity().Integrate("x")` | `integral(...)` | powers of `sqrt(a - i a tan(x))` times a factor constant wherever it is continuous, 285 characters | +| `"sec(x)^5/(a + i*a*tan(x))^(3/2)".ToEntity().Integrate("x")` | `integral(...)` | the same, 225 characters | +| `"cos(x)^9*(a + i*a*tan(x))^(7/2)".ToEntity().Integrate("x")` | `integral(...)`; on the unreleased master, an answer provided `1 + i tan(x) >= 0` | 768 characters, unconditional | + +### A symbolic power of `a + i a tan` is gathered with the secant's in the sum + +**Answers where there were none.** `(k sec(x))^(4 - 2 n) (a + i a tan(x))^n` was declined. In +`u = a + i a tan(z)` it is `u^n (u/a)^(1 - n) ((2 a - u)/a)^(1 - n)`, whose first two factors are one +power of `u/a`, and written apart no rule read them. They are gathered now, `u^n` being `a^n (u/a)^n` up +to a factor constant on the path; the answers to the rest of Rubi's 4.3.1.2 integrated in `u` come out +shorter by a third or more ([#718](https://github.com/asc-community/AngouriMath/issues/718)). + +| Input | Was (2.5.0) | Now | +|---|---|---| +| `"(k*sec(x))^(4 - 2*n)*(a + i*a*tan(x))^n".ToEntity().Integrate("x")` | `integral(...)` | 466 characters | +| `"(k*sec(x))^(2*n)*(a + i*a*tan(x))^(3 - n)".ToEntity().Integrate("x")` | `integral(...)` | 675 characters | ### A quotient in `x^2` over a power of a linear in `x^2` and a biquadratic is split in `x^2` diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs index 887db8f3d..f632213fd 100644 --- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs +++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs @@ -27124,8 +27124,13 @@ static Entity SumOfThePowers(Entity first, Entity second) } var u = Variable.CreateUnique(expr, "u_tan"); var half = ((secantPower - 2) / 2).InnerSimplified; - Entity squared = MathS.Pow(u / a, half) * MathS.Pow((2 * a - u) / a, half); - var inU = MathS.Pow(u, sumPower) * squared; + // u^n is A^n (u/A)^n up to a factor constant along the path, which the quotient below + // takes care of, and gathered with the secant's (u/A)^r one power: with a symbol for the + // powers, `u^(2 - n) (u/A)^(n - 1)` is (u/A)^1, and written apart it was read by no rule. + var gathered = (sumPower + half).InnerSimplified; + if (gathered is not Number && gathered.Complexity <= 40) + gathered = gathered.Simplify(); + var inU = MathS.Pow(u / a, gathered) * MathS.Pow((2 * a - u) / a, half); if (Integration.ComputeAsAQuestionOfItsOwn(inU, u, integrateByParts) is not { } inUAnswer || inUAnswer.Nodes.Any(node => node == MathS.NaN)) return null; diff --git a/Sources/Tests/UnitTests/Calculus/SecantBesideAnImaginaryTangentSumIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/SecantBesideAnImaginaryTangentSumIntegralTest.cs index a44ddde99..070ff65c5 100644 --- a/Sources/Tests/UnitTests/Calculus/SecantBesideAnImaginaryTangentSumIntegralTest.cs +++ b/Sources/Tests/UnitTests/Calculus/SecantBesideAnImaginaryTangentSumIntegralTest.cs @@ -31,13 +31,15 @@ public sealed class SecantBesideAnImaginaryTangentSumIntegralTest [InlineData("sec(x)^7/(a + i*a*tan(x))^4")] [InlineData("sec(x)^9/(a + i*a*tan(x))^8")] [InlineData("(k*sec(x))^3/(a - i*a*tan(x))^2")] + [InlineData("(m*sec(x))^(4 - 2*n)*(a + i*a*tan(x))^n")] + [InlineData("(m*sec(x))^(2*n)*(a + i*a*tan(x))^(3 - n)")] public void InTheSum(string integrand) { var integral = integrand.ToEntity().Integrate("x"); var text = integral.Stringize(); Assert.DoesNotContain("integral(", text); Assert.True(text.Length < 5000, $"{text.Length} characters of answer for {integrand}"); - Entity Pinned(Entity e) => e.Substitute("a", 1.3).Substitute("k", 0.7).Substitute("m", 1.1); + Entity Pinned(Entity e) => e.Substitute("a", 1.3).Substitute("k", 0.7).Substitute("m", 1.1).Substitute("n", 2.3); var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x"); var original = Pinned(integrand.ToEntity()); var compared = 0;