Skip to content

(a + b asech(c x))/(d + e x)^2 is integrated, and a root written apart with |x| no longer needs a parity - #1459

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
asech-over-a-linear
Sep 22, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
asech-over-a-linear

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Rubi's 7.5.1 (a + b asech(c x))/(d + e x)^2 ran for ten minutes without an answer (the numeric asech(2 + 3x)/x^2 next to it is 0.7 s). Traced with the dispatcher instrumented and a managed stack dump mid-runaway: by parts leaves 1/(x^2 (d + e x) sqrt(1/(c x)^2 − 1)), Euler's substitution answers that in 15 ms, and four things stood between the two.

  • A constant over a product is the reciprocal, not the product to the power −1. SolveAsPolynomialTerm's c/g(x) branch handed pe/(x (d + e x) sqrt(…)) on as pe · (x (d + e x) sqrt(…))^(−1), a spelling no radical rule reads (its own comment says so, for the rational rules); it is 1/(…) now, asked as the same question with the constant in front. The 1/g(x) case keeps the power, since 1/g asked again would be the same call.
  • SolveByDistributingWholePowersOfProducts asks its respelling as the same question. (c x)^2 and c^2 x^2 are one integrand, and one level down the remainder sat past SolveByWritingAPowerOfAQuotientApart's "question asked or one below" scope — which is what answers it.
  • sgn(x)^m where the parity extension fails. The quotient-apart route writes sqrt(1/(c x)^2 − 1) as sqrt(1 − c^2 x^2)/(|c| |x|) and answers for x > 0, then extends by parity — and 1/(x^2 (d + e x) sqrt(…)) has none, so the antiderivative it had just found was declined. |x|^m is sgn(x)^m x^m for a whole m, exact on each half-line, and that stands in for the extension now where every power of x taken is whole (a fractional |x|^(1/2) still needs the parity).
  • A root inside a logarithm's argument is left alone. The logarithm is an atom to every rule whatever its argument is written as, and writing asech(c x)'s own root apart re-asked the whole integrand for 1.5 s of nothing.

Measured:

  • (a + b asech(c x))/(d + e x)^2 590 s+ → 1.1 s; (a + b asech(c x))/x^7 9 s timeout → 0.09 s; e^(2 asech(a x))/x^2 unevaluated → 0.07 s; x (a + b asech(c x))/(d + e x^2)^2 2.7 → 1.0 s.
  • Family 7: 206 → 210 of 270, 0 wrong, 0 error, timeouts 34 → 26, wall 1185 → 952 s (gains: 7.5.1:102/177, 7.5.2:102, 7.6.1:126, 7.3.6:797/883).
  • The 1774-problem suite: 1706 → 1707 (Timofeev 944 is answered), 0 wrong, 0 timeout, wall 87 s; per-problem, nothing moved by more than 0.3 s except Timofeev 859, 1 s faster.
  • Full suite 12547 passed, 0 failed; the kernel gate PASSED on all 19 gated benchmarks. BREAKING-CHANGES.md entry with the 2.5.0 column measured on a build of v2.5.0 (all four left unevaluated there).

Tests: four rows in InverseHyperbolicSecantIntegralTest, each differentiated back against the integrand at five real points with a, b, c, d, e pinned.

Part of #718.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

…t with |x| no longer needs a parity

Rubi's 7.5.1 with a symbolic linear below the bar ran for ten minutes without
an answer. Traced, by parts leaves 1/(x^2 (d + e x) sqrt(1/(c x)^2 - 1)), and
four things stood between that and the answer Euler's substitution gives:

- SolveAsPolynomialTerm handed a constant over a product on as the product to
  the power -1, which no radical rule reads; it is the reciprocal now, asked as
  the same question with the constant in front.
- SolveByDistributingWholePowersOfProducts asked its respelling one level down,
  past the rules scoped to the question asked or one below it; (c x)^2 and
  c^2 x^2 are one integrand, and it is the same question.
- SolveByWritingAPowerOfAQuotientApart, having written the root apart with |x|
  for x > 0 and found the antiderivative, declined it because the integrand has
  no parity to extend by; sgn(x)^m stands in for the extension where every
  power of x taken is a whole one, which is exact.
- A root inside a logarithm's argument is left as written: the logarithm is an
  atom to every rule, and writing asech(c x)'s root apart re-asked the whole
  integrand for a second and a half of nothing.

Rubi's family 7: 206 to 210 of 270, 0 wrong, timeouts 34 to 26, wall 1185 to
952 s; the 1774-problem suite 1706 to 1707 (Timofeev 944), 0 wrong, wall 87 s.
Suite 12547 passed; the kernel gate passed on all 19 gated benchmarks.

Part of #718.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
@Rafael-SOWNet
Rafael-SOWNet merged commit 67a89b6 into master Sep 22, 2026
31 of 34 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the asech-over-a-linear branch September 22, 2026 01:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant