From a0c1e98ec04d9c228305b42ff17d5f805b4cba86 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Sat, 3 Oct 2026 17:44:44 +0000 Subject: [PATCH] A symbolic exponent that is -1 as a value is integrated to the logarithm x^(-1 - 3n) (a + b x^n)^3 expanded leaves x^(-1 - 3n + 3n) for its last term, which is x^(-1) for every n, and InnerSimplified keeps -3n + 3n as two terms. The power rule read the exponent as written and divided by its zero, so the whole answer had no value anywhere; x^(-n/n) came back NaN. It asks whether the exponent plus one vanishes as a value now, and gives the logarithm where it does. Part of #718. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura --- BREAKING-CHANGES.md | 18 ++++++++++++++++++ .../Integration/IndefiniteIntegralSolver.cs | 10 ++++++++++ .../Calculus/ExpandedSquareNaNTest.cs | 19 ++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index e9ae2c6a1..dc8cbe1c9 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -533,6 +533,24 @@ Each of these was checked by differentiating it back with the parameters pinned four points. The Rubi sample is unchanged at 231 of 463 with no wrong answers, so nothing that already had an antiderivative moves. +### `NaN` a fourth time, from an exponent that is `-1` only as a value + +**A wrong answer.** `x^(-1 - 3n) (a + b x^n)^3` came back as a sum whose last term was `x^0/0`, so +that it had no value anywhere, and `x^(-n/n)` as `NaN + C`. Expanded, the integrand's last term is +`x^(-1 - 3n + 3n)`, which is `x^(-1)` for every `n`; `InnerSimplified` keeps `-3n + 3n` as two +terms, and the power rule, which reads `-1` once the exponent is a number (the entry above), read +this one as written and divided by its zero. It asks whether the exponent plus one vanishes as a +value now, and gives the logarithm where it does. A symbolic exponent that is `-1` for one value +only is the power rule's as before. Rubi's 1.1.3.2 has four of these +([#718](https://github.com/asc-community/AngouriMath/issues/718)). + +| Input | Was (2.5.0) | Now | +|---|---|---| +| `"x^(-1 - 3*n)*(a + b*x^n)^3".ToEntity().Integrate("x")` | three powers and `x^0/0`, no value anywhere | the three powers and `b^3 ln(x)` | +| `"x^(-1 - 3*n + 3*n)".ToEntity().Integrate("x")` | `x^(-1 - 3n + 3n + 1)/(-1 - 3n + 3n + 1)`, no value anywhere | `ln(x)` | +| `"x^(-n/n)".ToEntity().Integrate("x")` | `NaN` | `ln(x)` | +| `"1/(a*(b*x^m)^n)^(1/(m*n))".ToEntity().Integrate("x")` | `integral(...)` | `(a b^n)^(-1/(m n)) ln(x)`, provided `b > 0` and `a b^n > 0` | + ### `NaN` a third time, from a quadratic with a coefficient off the real line The integrals of `1/sqrt(Q)`, `1/Q` and `1/Q^n` over a quadratic `Q` choose their form by the sign diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs index 9965d1608..6e98dd0f2 100644 --- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs +++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs @@ -2486,6 +2486,14 @@ over is Entity.Powf(var @base, var power) ? /// whether an undecidable n is that one; what it fixes is an exponent that /// is decidable and was read as though it were not. /// + /// + /// Decidable includes a symbol that cancels: x^(-1 - 3n + 3n) is x^(-1) for + /// every n, and is what expanding x^(-1 - 3n) (a + b x^n)^3 leaves for its + /// last term, but keeps -3n + 3n as two terms, + /// so the exponent plus one is asked whether it vanishes as a value. Read as written it + /// was x^0/0 again, and the whole answer had no value anywhere; Rubi's 1.1.3.2 + /// has four such and 1/(a (b x^m)^n)^(1/(m n)), which is x^(-m n/(m n)). + /// /// private static Entity IntegrateAPowerOfTheVariable(Entity @base, Entity power, Entity.Variable x) { @@ -2493,6 +2501,8 @@ private static Entity IntegrateAPowerOfTheVariable(Entity @base, Entity power, E if (exponent == -1) return IntegralPatterns.AntiderivativeLog(@base); var raised = (exponent + 1).InnerSimplified; + if (raised.Vars.Any() && VanishesIdentically(raised)) + return IntegralPatterns.AntiderivativeLog(@base); return MathS.Pow(x, raised) / raised; } diff --git a/Sources/Tests/UnitTests/Calculus/ExpandedSquareNaNTest.cs b/Sources/Tests/UnitTests/Calculus/ExpandedSquareNaNTest.cs index dc73e37c9..2b6487ac2 100644 --- a/Sources/Tests/UnitTests/Calculus/ExpandedSquareNaNTest.cs +++ b/Sources/Tests/UnitTests/Calculus/ExpandedSquareNaNTest.cs @@ -48,7 +48,8 @@ public sealed class ExpandedSquareNaNTest /// private static Entity Pin(Entity expr) => expr .Substitute("a", 2).Substitute("b", 3) - .Substitute("c", 2).Substitute("d", 3).Substitute("e", 5); + .Substitute("c", 2).Substitute("d", 3).Substitute("e", 5) + .Substitute("m", 1.7).Substitute("n", 2.9); private static void DifferentiatesBack(string integrand) { @@ -123,6 +124,22 @@ private static void DifferentiatesBack(string integrand) [InlineData("x^(-2)")] [InlineData("x^(-7)")] [InlineData("x^(1/2)")] + [InlineData("x^n")] + [InlineData("x^(n - 1)")] public void ThePowerRuleIsUnchanged(string integrand) => DifferentiatesBack(integrand); + + /// + /// A symbolic exponent that is -1 as a value, which the power rule read as written: + /// x^(-1 - 3n + 3n) is what expanding x^(-1 - 3n) (a + b x^n)^3 leaves for its + /// last term, and came out as x^0/0, so the whole answer had no value anywhere. + /// Rubi's 1.1.3.2. + /// + [Theory] + [InlineData("x^(-1 - 3*n)*(a + b*x^n)^3")] + [InlineData("x^(-1 - 7*n)*(a + b*x^n)^8")] + [InlineData("1/(a*(b*x^m)^n)^(1/(m*n))")] + [InlineData("x^(-1 - 3*n + 3*n)")] + [InlineData("x^(-n/n)")] + public void AnExponentThatIsMinusOneAsAValue(string integrand) => DifferentiatesBack(integrand); } }