From 5e6b0e4a6f747b50024f0eed8b3d5ac1956ed2fd Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Fri, 16 Oct 2026 12:15:08 +0000 Subject: [PATCH 1/2] Answer a difference of two cubes where the sampled check cannot tell With a negative second cube the real cube root makes all three quadratics complex at the pinned values, the intervals settle too few points, and 8 x^2/(8 a x^3 - b (x^2 + 1)^3) -- which 1/(a - b cosh(x)^3) is under u = e^x -- was refused where its + b twin was answered. The answer is now refused only where it differs. Rubi's 6.2.7 1/(a - b cosh(x)^3) was declined. Part of https://github.com/asc-community/AngouriMath/issues/718 Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura --- .../Integration/IndefiniteIntegralSolver.cs | 6 +++++- .../Calculus/ASumOfTwoCubesIntegralTest.cs | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs index 5a0a8ccab..2542f1d97 100644 --- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs +++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs @@ -19674,7 +19674,11 @@ Piecewise piecewise when piecewise.Cases.Any() => piecewise.Cases.First().Expres foreach (var unity in unities) answer = answer + unity * each.Substitute(namedB, unity * root).Substitute(namedS, shift); answer = (constant / (3 * d6 * MathS.Pow(root, Number.Integer.Create(2))) * answer).InnerSimplified; - return Functions.PartialFractions.DerivativeHoldsAtSampledPoints(answer, expr, x) ? answer : null; + // Refused where it differs, not where it cannot be told: with `q < 0` the real cube root + // makes all three quadratics' coefficients complex at the pinned values, the intervals + // settle too few points, and `8 x^2/(8 a x^3 - b (x^2 + 1)^3)` -- `1/(a - b cosh(x)^3)` + // under `u = e^x` -- was declined where its `+ b` twin was answered. + return Functions.PartialFractions.DerivativeDiffersWhereReal(answer, expr, x) ? null : answer; } /// diff --git a/Sources/Tests/UnitTests/Calculus/ASumOfTwoCubesIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/ASumOfTwoCubesIntegralTest.cs index 4ef667494..5254c2e04 100644 --- a/Sources/Tests/UnitTests/Calculus/ASumOfTwoCubesIntegralTest.cs +++ b/Sources/Tests/UnitTests/Calculus/ASumOfTwoCubesIntegralTest.cs @@ -55,5 +55,18 @@ public void IsAnsweredAndDifferentiatesBack(string integrand) DifferentiatesBack(integrand, ("a", 2), ("b", 3), ("c", 5)); DifferentiatesBack(integrand, ("a", -1), ("b", 2), ("c", -3)); } + + // A difference of two cubes, the second cube's coefficient negative: `1/(a - b cosh(x)^3)` is + // `8 u^2/(8 a u^3 - b (u^2 + 1)^3)` under `u = e^x`. The real cube root makes all three + // quadratics complex at sampled values, and the answer was refused for want of points. + [Theory] + [InlineData("8*x^2/(8*a*x^3-b*(x^2+1)^3)")] + [InlineData("1/(a-b*cosh(x)^3)")] + [InlineData("x/(27*a^3+27*a^2*b*x^2-27*a^2*c*x^3+9*a*b^2*x^4+b^3*x^6)")] + public void ADifferenceIsAnsweredAndDifferentiatesBack(string integrand) + { + DifferentiatesBack(integrand, ("a", 2), ("b", 3), ("c", 5)); + DifferentiatesBack(integrand, ("a", -1), ("b", 2), ("c", -3)); + } } } From 50c0536c8ce826ae9bc4a1be436db6f8b999e4f8 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Fri, 16 Oct 2026 14:26:31 +0000 Subject: [PATCH 2/2] Record the difference of two cubes in the breaking changes Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura --- BREAKING-CHANGES.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index a34469655..767f6bc37 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -396,6 +396,19 @@ in Rubi's 1.1.3.4 come out shorter as well, and those that took two seconds take | `"1/(x^8*(a + b*x^3)*(c + d*x^3))".ToEntity().Integrate("x")` | `integral(...)` | 1,217 characters | | `"1/(x^6*(a + b*x^4)*(c + d*x^4))".ToEntity().Integrate("x")` | `integral(...)` | 795 characters | +### A difference of two cubes is split over the cube roots of unity where its answer cannot be sampled + +**Answers where there were none.** `1/(a - b cosh(x)^3)` was declined, which Rubi's 6.2.7 has. Under `u = e^x` it is +`8 u^2/(8 a u^3 - b (u^2 + 1)^3)`, a difference of two cubes, which the rule for a sum of two cubes split correctly and +then refused: with the second cube negative, the real cube root makes all three quadratics complex at the sampled +values, and too few points could be compared. The answer is now refused only where it differs +([#718](https://github.com/asc-community/AngouriMath/issues/718)). + +| Input | Was (2.5.0) | Now | +|---|---|---| +| `"1/(a-b*cosh(x)^3)".ToEntity().Integrate("x")` | `integral(...)` | 666 characters | +| `"8*x^2/(8*a*x^3-b*(x^2+1)^3)".ToEntity().Integrate("x")` | `integral(...)` | 654 characters | + ### A negative power of an inverse function of `c + d x^2` is integrated in sine and cosine integrals **Answers where there were none.** `1/(a + b acos(1 + d x^2))` was declined, and so were seventeen more of Rubi's