From a5064cc81ebd0a03c6c8a6798425a251ffe3e290 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Thu, 22 Oct 2026 00:56:04 +0000 Subject: [PATCH] Ask the radicand rule's rewriting without the condition its inner simplification writes Rubi's 7.2.5 x/(acosh(x) sqrt(x - 1) sqrt(x + 1)) ran past the budget. SolveByWritingAConstantMultipleOfARadicandOverIt writes the pair of roots as the root of x^2 - 1 that acosh(x) holds, with the constant factor K, and the inner simplification of the rewriting put provided not x - 1 = 0 over the whole of it: the inverse hyperbolic substitution did not read the condition, and the search split the sum and went by parts. The point it excludes is outside the integrand's domain, and the question is now asked bare. (A derivative check on the rule's answer was tried and dropped: it took three of Rubi's 5.1.4 arcsine rows, answered in 0.2 to 1.4 s, past the budget.) Part of #233. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura --- BREAKING-CHANGES.md | 12 +++++ .../Integration/IndefiniteIntegralSolver.cs | 7 ++- ...ingAskedWithoutItsConditionIntegralTest.cs | 44 +++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 Sources/Tests/UnitTests/Calculus/TheRadicandRewritingAskedWithoutItsConditionIntegralTest.cs diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md index 33abc4553..3adcb9293 100644 --- a/BREAKING-CHANGES.md +++ b/BREAKING-CHANGES.md @@ -542,6 +542,18 @@ becomes a polynomial in `u` times exponentials and trigonometric functions, and | `"(a+b*atan(c*x))^2/(1+i*c*x)^4".ToEntity().Integrate("x")` | `integral(...)` | 731 characters | | `"(a+b*atan(c*x))^3/(d+i*c*d*x)^4".ToEntity().Integrate("x")` | `integral(...)` | 1,202 characters | +### Two roots of linears written as an inverse hyperbolic cosine's radicand are asked without a condition + +**Answers where there were none.** Rubi's 7.2.5 `x/(acosh(x) sqrt(x - 1) sqrt(x + 1))` ran past the budget. The pair of roots +is written as the root of `x^2 - 1` that `acosh(x)` holds, with the factor `K` that is constant where it is defined. +The inner simplification then wrote the rewritten question with `provided not x - 1 = 0` over the whole of it, and +nothing below read that. The point it excludes is outside the integrand's domain, and the question is now asked +without it ([#233](https://github.com/asc-community/AngouriMath/issues/233)). + +| Input | Was (2.5.0) | Now | +|---|---|---| +| `"x/(acosh(x)*sqrt(-1+x)*sqrt(1+x))".ToEntity().Integrate("x")` | `integral(...)` | 93 characters, `K Chi(acosh(x))` | + ### An arcoth of a linear is integrated as its artanh plus a constant **Answers where there were none.** `acoth(x)^2/(1 - x^2)^2`, Rubi's 7.4.1, was declined, where diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs index 743b3329e..a70cb8786 100644 --- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs +++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs @@ -43437,7 +43437,12 @@ Entity WithTheExponentials(Entity e, Entity? one) (rewritten, root) = (paired, pairRoot); if (rewritten == expr) return null; - var simplified = rewritten.InnerSimplified; + // Without a condition over the whole of it, which the inner simplification writes where a + // linear stands on both sides of the bar and nothing below reads: Rubi's 7.2.5 + // `x/(acosh(x) sqrt(x - 1) sqrt(x + 1))` became `x/(K sqrt(x^2 - 1) acosh(x)) provided not + // x - 1 = 0`, and ran past the budget, where without the condition it is a `Chi`. The point + // it excludes is outside the integrand's domain. + var simplified = Functions.PartialFractions.Bare(rewritten.InnerSimplified); if (simplified == expr || simplified == expr.InnerSimplified) return null; if (Integration.ComputeAsTheSameQuestion(simplified, x, integrateByParts) is not { } answer) diff --git a/Sources/Tests/UnitTests/Calculus/TheRadicandRewritingAskedWithoutItsConditionIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/TheRadicandRewritingAskedWithoutItsConditionIntegralTest.cs new file mode 100644 index 000000000..e3f5f19e8 --- /dev/null +++ b/Sources/Tests/UnitTests/Calculus/TheRadicandRewritingAskedWithoutItsConditionIntegralTest.cs @@ -0,0 +1,44 @@ +// +// Copyright (c) 2019-2026 Angouri. +// AngouriMath is licensed under MIT. +// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md. +// Website: https://am.angouri.org. +// + +using System; +using AngouriMath.Extensions; +using Xunit; + +namespace AngouriMath.Tests.Calculus +{ + /// + /// Two roots of linears written as the radicand an inverse hyperbolic cosine holds, asked without + /// the condition the inner simplification writes over the rewriting: Rubi's 7.2.5 + /// x/(acosh(x) sqrt(x - 1) sqrt(x + 1)) was asked as ... provided not x - 1 = 0 and ran + /// past the budget, where it is a hyperbolic cosine integral. + /// #233 + /// + [Trait("Area", "Calculus")] + public sealed class TheRadicandRewritingAskedWithoutItsConditionIntegralTest + { + [Theory] + [InlineData("x/(acosh(x)*sqrt(-1 + x)*sqrt(1 + x))")] + [InlineData("x^2/(acosh(x)*sqrt(-1 + x)*sqrt(1 + x))")] + public void IsAnswered(string integrand) + { + var integral = integrand.ToEntity().Integrate("x"); + var text = integral.Stringize(); + Assert.DoesNotContain("integral(", text); + var derivative = integral.Substitute("C", 0).Differentiate("x"); + var original = integrand.ToEntity(); + foreach (var at in new[] { 1.2, 1.7, 2.3, 3.1, 4.4 }) + { + var want = original.Substitute("x", at).EvalNumerical(); + var got = derivative.Substitute("x", at).EvalNumerical(); + Assert.True(Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart) + < 1e-9 * Math.Max(1, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart)), + $"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}"); + } + } + } +}