Skip to content

The exponential substitution reads a fractional slope, and takes the sign of its base from the radicals - #1290

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
exponential-rational-slopes
Sep 11, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
exponential-rational-slopes

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

e^(x/2)/sqrt(e^x - 1) had no antiderivative. It is 2/sqrt(u^2 - 1) under
u = e^(x/2), and the exponential substitution refused the half: a slope had to be a
whole number. The base is now e^(k x) with k the greatest common divisor of the
slopes as rationals -- numerators' gcd over denominators' lcm -- so every exponential
in the integrand is a whole power of it, and e^(x/2) beside e^x is u beside
u^2.

The sign of k is chosen for the radicals. sqrt(1 + e^(-x))/sinh(x) under u = e^x
is a root of 1 + 1/u, a quotient, which nothing rationalises; under u = e^(-x) it is
sqrt(1 + u), a root of something linear, which the linear-radical substitution
answers. So where every exponential under a root has a negative slope the base is
e^(-k x); u is positive either way, being an exponential, and nothing about the
substitution changes but the spelling of what comes out.

Measured

Every answer differentiated back.

Rubi corpus, 463-problem sample, against the master it was cut from (#1288), timed on
the same evening:

master      325/463, 0 wrong, 0 timeouts, 80 s
with this   328/463, 0 wrong, 0 timeouts, 81 s

Three more, nothing lost: Timofeev's e^(x/2)/sqrt(e^x - 1), and Bondarenko's
sqrt(1 + e^(-x))/(e^x - e^(-x)) and sqrt(1 + e^(-x))/sinh(x). sqrt(1 + tanh(4x)),
the fourth of that family, becomes sqrt(2u^2/(u^2 + 1)) and wants sqrt(u^2) = u
for a u the rule knows to be positive; that is a rewrite this rule could make and
the simplifier rightly will not, and it is not here yet.

The five test suites are green.

Part of #718.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

…sign of its base from the radicals

`e^(x/2)/sqrt(e^x - 1)` had no antiderivative. It is `2/sqrt(u^2 - 1)` under
`u = e^(x/2)`, and the exponential substitution refused the half: a slope had to be a
whole number. The base is now `e^(k x)` with `k` the greatest common divisor of the
slopes as rationals -- numerators' gcd over denominators' lcm -- so every exponential
in the integrand is a whole power of it, and `e^(x/2)` beside `e^x` is `u` beside
`u^2`.

The sign of `k` is chosen for the radicals. `sqrt(1 + e^(-x))/sinh(x)` under `u = e^x`
is a root of `1 + 1/u`, a quotient, which nothing rationalises; under `u = e^(-x)` it is
`sqrt(1 + u)`, a root of something linear, which the linear-radical substitution
answers. So where every exponential under a root has a negative slope the base is
`e^(-k x)`; `u` is positive either way, being an exponential, and nothing about the
substitution changes but the spelling of what comes out.

## Measured

Every answer differentiated back.

Rubi corpus, 463-problem sample, against the master it was cut from (#1288), timed on
the same evening:

    master      325/463, 0 wrong, 0 timeouts, 80 s
    with this   328/463, 0 wrong, 0 timeouts, 81 s

Three more, nothing lost: Timofeev's `e^(x/2)/sqrt(e^x - 1)`, and Bondarenko's
`sqrt(1 + e^(-x))/(e^x - e^(-x))` and `sqrt(1 + e^(-x))/sinh(x)`. `sqrt(1 + tanh(4x))`,
the fourth of that family, becomes `sqrt(2u^2/(u^2 + 1))` and wants `sqrt(u^2) = u`
for a `u` the rule knows to be positive; that is a rewrite this rule could make and
the simplifier rightly will not, and it is not here yet.

The five test suites are green.

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 670c864 into master Sep 11, 2026
31 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the exponential-rational-slopes branch September 11, 2026 19:51
Rafael-SOWNet added a commit that referenced this pull request Sep 11, 2026
…them, and the closed exponential-trigonometric rule reads a power (#1291)

`e^(arcsin(x)) x^3/sqrt(1 - x^2)` had no antiderivative. Under `x = sin(u)` it is
`e^u sin(u)^3`; `x arcsec(x)/sqrt(x^2 - 1)` is `u sec(u)^2` under `x = sec(u)`. The
general substitution does not find either, because it substitutes for a subtree and
asks what is left, and what is left beside `arcsin(x)` is `x` itself -- which only the
inverse substitution removes, the same reason the logarithm has one. The radical goes
by construction: `sqrt(1 - x^2)` is `cos(u)` on the branch the arcsine is defined on,
where substituting and simplifying would leave `sqrt(1 - sin(u)^2)`, which the
simplifier is right not to call `cos(u)`. Admitted only where there is a radical to
remove or an exponential of the inverse to turn into `e^u`; `x arcsin(x)` stays by
parts', and its answer stays in `x`.

Three things the substituted integrand needed, each a gap in its own right:

- The closed rule for `P(x) e^(ax) trig(bx)` read one bare sine or cosine, so
  `e^u sin(u)^3` and `e^u/sec(u)` fell out. A power of the sine or the cosine, or a
  product of the two, is a sum of sines and cosines of multiples of the argument --
  `sin^3 u = (3 sin u - sin 3u)/4` -- and each term is the shape the rule closes, so it
  runs once per term and the answers add. A secant or cosecant under the bar is read
  as a cosine or sine above it.

- By parts read a product and not a quotient with a polynomial over the bar:
  `x/cos(x)^2` reached nothing where `x sec(x)^2` is one step. The polynomial factors
  of the numerator are gathered against the rest of the quotient, at the top only,
  and not over an algebraic function, which is the rational integrator's or Euler's.
  And the polynomial step hands its `dv` to the closed `sin^p cos^q` rule directly,
  which is scoped to the top and would otherwise not see it: `u sin(u)^3/cos(u)^2` was
  nine seconds of declining through the half-angle substitution and is half a second.

- `ComputeAsAQuestionOfItsOwn` went back through the entry check, where a depth of zero
  means a fresh question and empties the set of integrals in progress -- so the
  integrand a substitution was rewriting lost its place in the cycle guard. It now
  enters past that check. And the truncation flag that gates caching a decline is
  scoped to the computation it is about, rather than to everything asked after some
  unrelated branch above ran out of depth.

## Measured

Every answer differentiated back at points on the branch the inverse function is
defined on.

Rubi corpus, 463-problem sample, against the master it was rebased onto (#1290), both measured on the same evening:

    master      337/463, 0 wrong, 0 timeouts, 89 s
    with this   343/463, 0 wrong, 0 timeouts, 88 s

Six more, nothing lost: Charlwood's `e^asin(x) x^3/sqrt(1-x^2)`, `x asec(x)/sqrt(x^2-1)`
and `asin(x)/(1+sqrt(1-x^2))`, Timofeev's `(x^2-1)^(3/2) asec(x)^2/x^5`, Bronstein's
`(x - tan(x))/tan(x)^2` and Welz's `x/(a e^(px) + b e^(-px))^2`. Two inputs were
measured slower in the corpus run and turned out to cost the same on master alone --
warm-cache ordering, not this change.

The five test suites are green.

Part of #718.


Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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