An exponential times a rational function by Liouville's ansatz, the Hermite reduction first for a repeated factor, and a cache that had been remembering a scoped decline - #1287
Merged
Conversation
…ermite reduction first for a repeated factor, and a cache that had been remembering a scoped decline `e^x x/(1 + x)^2` is `(e^x/(1 + x))'`. `e^(x^2)(1 + 2x^2)` is `(x e^(x^2))'`. `(4x^5 - 1)/(1 + x + x^5)^2` is `(-x/(1 + x + x^5))'`. None had an antiderivative: the first two are not a polynomial times an exponential, which is the shape by parts reads, and the third has a denominator nothing factors. ## The ansatz Liouville's theorem says the elementary antiderivative of `e^h R`, with `h` and `R` rational, is `e^h` times a rational function where it exists at all. So the rule writes `F = e^h N/D`, with `D` read off the denominator of `R` -- every written power lowered by one, then the denominator itself, and every level of a single written power, since with an exponential in front the antiderivative's denominator need not be one below the integrand's (`e^(1/x)(1 + x)/x^4` has `x^2` under it) -- and `N` a polynomial of unknown coefficients. `F' = e^h R` is then a polynomial identity linear in those coefficients, solved by the elimination the symbolic partial-fraction split uses and **checked at sampled points with every symbol pinned before anything is returned**. An ansatz that finds no `N` has, by Liouville, shown there is no elementary antiderivative of that shape: `e^x/x`, `e^(x^2)` and `e^x/(1 + x)` are declined in a millisecond each, and a test pins that they stay declined. A sum whose terms share one exponential is read whole: `e^(x^2) + 2x^2 e^(x^2)` is `(x e^(x^2))'`, and neither term is elementary on its own, so splitting it first -- which linearity does -- loses it. The identity is built **one column at a time** as a numeric polynomial rather than once with the unknowns in it. With fourteen unknowns over a degree-eleven denominator the single symbolic expansion did not return; the fourteen numeric ones take a moment. ## The Hermite reduction, and first With no exponential the same ansatz is the rational part of the Hermite reduction, and the full form is taken: `R = (N/D)' + M/D_1`, with `D_1` the product of the distinct factors and `M` a second unknown polynomial, so that a logarithmic part beside the rational one does not defeat it. `(1 + x^2 + x^4)/((1 + x^2)(4 + x^2)^2)` has both. What is left, `M/D_1`, is a proper fraction over a squarefree denominator, and it is handed to the splits and not to the whole integrator: handing it to the whole integrator sent one such remainder through every substitution and by-parts attempt there is, thirty seconds to decline what the splits decline in milliseconds. A denominator with a written repeated factor takes this **first**, ahead of the coprime split and the root peeling. `(1 + x^2)/(x (1 + x^3)^2)` reached the same answer through those after seventeen seconds of peeling and re-factoring; this way it is under a tenth of one. `x^7`, `(x^3 + 2)^2` and `(1 + x^4)^3` are the same story. ## Integration by parts with neither factor worth differentiating The classic "neither is a polynomial, try both orderings" case of by parts ran on any product. Once the Hermite reduction answered `∫u` for a small rational piece of a radical trigonometric integrand, by parts carried on with `v' ∫u`, three hundred nodes of mixed arguments against forty, and every substitution below was tried on it: thirty seconds to decline where it had taken a tenth of one. The case now runs only with a factor worth differentiating -- a logarithm or an inverse function, whose derivative is algebraic, or an exponential, whose integral is itself and which the cyclic cases need. Measured on the Rubi sample with the restriction and without: the same answers, eight seconds less. ## The cache That restriction surfaced a defect that by parts had been hiding. Five rules answer only the question asked (#1265) and decline the same integrand one level down, and the integrator's cache held such a `null` without the scope it was made in. `cos(x)^(-3)`, tried inside the search for `1/cos(x)^3` and declined there by the scoped secant reduction, was then declined *from the cache* in two milliseconds when asked for directly -- unseen until now because by parts used to answer it at depth two regardless. The key carries the scope; a lookup takes a decline only from its own scope and an answer from either, since an antiderivative that was found is right wherever it is asked for. A test asks the two integrals in that order. ## Measured Every answer differentiated back, with parameters pinned. Rubi corpus, 463-problem sample, against the master it was cut from (#1286), both timed on the same evening: master 300/463, 0 wrong, 0 timeouts, 102 s with this 312/463, 0 wrong, 0 timeouts, 76 s Twelve more and nothing lost: `e^x x/(1 + x)^2`, `e^(x^2)(1 + 2x^2)` twice and once as a sum (Moses), `e^(1/x)(1 + x)/x^4` (Hearn), Hebisch's `e^(1/(x^2 - 1))` times a rational function, `(4x^5 - 1)/(1 + x + x^5)^2` (Apostol), Stewart's `(1 + x^2 + x^4)/((1 + x^2)(4 + x^2)^2)`, Timofeev's `x^5/(1 + x^4)^3` and `(1 + x^2)/(x (1 + x^3)^2)`, and two the reduction reached on its own: `ln(x)/(1 + ln(x))^2` and `(3x - 1)^(4/3)/x^2`. The sum of per-problem time over the sample is 100 s to 75 s. Two pinned declines moved as their tests said they would: `BinomialDenominatorIntegralTest` had `1/(x^3 + 2)^2` as outside the binomial rule's shape, and it is the reduction's first and then the rule's; `ExpandedPowerIntegralTest` had `(a - b x^2)^3/x^7` as unreached, and `x^7` is a power of a linear. 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
added a commit
that referenced
this pull request
Sep 11, 2026
…top-level sum asked at the top, and a bare inverse function by parts (#1288) `sqrt(1 + x^3)/x` had no antiderivative. `x^2 sqrt(1 + x^3)` and `x^5 sqrt(1 + x^3)` did, by the same substitution, and the rule for it (#1275) stopped where Chebyshev's first case does. ## The second case, with a rational function left over Under `u = (a + b x^n)^(1/q)`, with `s = (m + 1)/n`: int x^m (a + b x^n)^(p/q) dx = (q/(n b^s)) int u^(p+q-1) (u^q - a)^(s-1) du which is a polynomial in `u` when `s >= 1` -- what the rule expanded -- and a **rational function** of `u` when `s <= 0`, which it read as "not a polynomial" and declined. `sqrt(1 + x^3)/x` is `(2/3) int u^2/(u^2 - 1) du`; `1/(x sqrt(1 - x^3))` is `(2/3) int 1/(u^2 - 1) du`. The rational integrator answers those, and the rule now hands them to it. ## The third case, through the reciprocal Where `s + p/q` is whole instead, `x = 1/y` turns `x^m (a + b x^n)^(p/q) dx` into `-y^m' (b + a y^n)^(p/q) dy` with `m' = -m - 2 - n p/q`, a whole number, and `(m' + 1)/n = -(s + p/q)`, whole -- the second case in `y`, with `a` and `b` exchanged, and `y = 1/x` put back afterwards. `x^6 (3 + 4x^4)^(1/4)` is `-9 int u^4/(u^4 - 4)^3 du` that way, which is the Hermite reduction's (#1287) and the binomial rule's. Chebyshev proved there is no fourth case, so a binomial differential outside these two is declined for a reason. ## A term of a top-level sum is asked at the top `(x^3 - 1)/(2 + x^3)^(1/3)` is two binomial differentials, and was declined although each term alone is answered. Linearity splits the integrand before anything else, and every term it produced sat one level down -- where the five rules scoped to the question asked (#1265, #1280) decline. A term of a top-level sum is strictly smaller than the sum and is not a continuation of any rule's search, which is what the scope was measured to stop; it is asked at the top now. Only from the top: one level down the terms stay one level down, as before. `sec(x)^3 + x` is the same story with the secant reduction. ## A bare inverse function, by parts against 1 `arctan(x sqrt(1 - x^2))` had no antiderivative. It is one step of parts against `1` -- `x f(g) - int x g' f'(g) dx`, with an algebraic remainder -- and that step was never taken: the by-parts rule runs on a product, a single node is not one, and a linear argument is the table's. The remainder is answered where the radical rules reach it, which is three of Charlwood's and Bondarenko's `ln(1/x^4 + x^4)`; the rest of that family wants an Euler substitution the library does not have, and declines in about a second, which a test pins. Asked, not volunteered, like the regrouping beside it. ## Measured Every answer differentiated back. Rubi corpus, 463-problem sample, against #1287's branch it was cut from, both timed on the same evening: #1287 312/463, 0 wrong, 0 timeouts, 76 s with this 325/463, 0 wrong, 0 timeouts, 80 s Thirteen more and nothing lost: `arctan(x sqrt(1 - x^2))`, `arctan(x sqrt(1 + x^2))` (Charlwood) and `ln(1/x^4 + x^4)` (Bondarenko) by parts against 1; and by the binomial rule `sqrt(1 + x^3)/x` (Charlwood), `1/(x sqrt(1 - x^3))` and `sqrt(1 + x^8)/(x (1 + x^8))` (Bronstein), `x^6 (3 + 4x^4)^(1/4)` and `(x^3 - 1)/(2 + x^3)^(1/3)` (Timofeev), and five of Welz's: `(1 - x^3)^(1/3)/x`, `(1 - x^3)^(2/3)/x`, `1/(x (1 - x^2)^(1/3))`, `1/(x (1 - x^2)^(2/3))`, `1/(x (1 - x^3)^(1/3))`. The sum of per-problem time over the sample is 75 s to 79 s, which is the answers. `BinomialDifferentialTest.OutsideTheFirstCase` had `1/(x (1 + x^3)^(1/3))` as a case that may be declined; it is the second case with `s = 0` and moved to the answered theory, with the three that Chebyshev says have no antiderivative kept where they were. 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
e^x x/(1 + x)^2is(e^x/(1 + x))'.e^(x^2)(1 + 2x^2)is(x e^(x^2))'.(4x^5 - 1)/(1 + x + x^5)^2is(-x/(1 + x + x^5))'. None had an antiderivative:the first two are not a polynomial times an exponential, which is the shape by parts
reads, and the third has a denominator nothing factors.
The ansatz
Liouville's theorem says the elementary antiderivative of
e^h R, withhandRrational, is
e^htimes a rational function where it exists at all. So the rulewrites
F = e^h N/D, withDread off the denominator ofR-- every written powerlowered by one, then the denominator itself, and every level of a single written
power, since with an exponential in front the antiderivative's denominator need not
be one below the integrand's (
e^(1/x)(1 + x)/x^4hasx^2under it) -- andNapolynomial of unknown coefficients.
F' = e^h Ris then a polynomial identity linearin those coefficients, solved by the elimination the symbolic partial-fraction split
uses and checked at sampled points with every symbol pinned before anything is
returned. An ansatz that finds no
Nhas, by Liouville, shown there is noelementary antiderivative of that shape:
e^x/x,e^(x^2)ande^x/(1 + x)aredeclined in a millisecond each, and a test pins that they stay declined.
A sum whose terms share one exponential is read whole:
e^(x^2) + 2x^2 e^(x^2)is(x e^(x^2))', and neither term is elementary on its own, so splitting it first --which linearity does -- loses it.
The identity is built one column at a time as a numeric polynomial rather than
once with the unknowns in it. With fourteen unknowns over a degree-eleven denominator
the single symbolic expansion did not return; the fourteen numeric ones take a moment.
The Hermite reduction, and first
With no exponential the same ansatz is the rational part of the Hermite reduction,
and the full form is taken:
R = (N/D)' + M/D_1, withD_1the product of thedistinct factors and
Ma second unknown polynomial, so that a logarithmic partbeside the rational one does not defeat it.
(1 + x^2 + x^4)/((1 + x^2)(4 + x^2)^2)has both. What is left,
M/D_1, is a proper fraction over a squarefree denominator,and it is handed to the splits and not to the whole integrator: handing it to the
whole integrator sent one such remainder through every substitution and by-parts
attempt there is, thirty seconds to decline what the splits decline in milliseconds.
A denominator with a written repeated factor takes this first, ahead of the
coprime split and the root peeling.
(1 + x^2)/(x (1 + x^3)^2)reached the sameanswer through those after seventeen seconds of peeling and re-factoring; this way
it is under a tenth of one.
x^7,(x^3 + 2)^2and(1 + x^4)^3are the same story.Integration by parts with neither factor worth differentiating
The classic "neither is a polynomial, try both orderings" case of by parts ran on any
product. Once the Hermite reduction answered
∫ufor a small rational piece of aradical trigonometric integrand, by parts carried on with
v' ∫u, three hundrednodes of mixed arguments against forty, and every substitution below was tried on it:
thirty seconds to decline where it had taken a tenth of one. The case now runs only
with a factor worth differentiating -- a logarithm or an inverse function, whose
derivative is algebraic, or an exponential, whose integral is itself and which the
cyclic cases need. Measured on the Rubi sample with the restriction and without: the
same answers, eight seconds less.
The cache
That restriction surfaced a defect that by parts had been hiding. Five rules answer
only the question asked (#1265) and decline the same integrand one level down, and
the integrator's cache held such a
nullwithout the scope it was made in.cos(x)^(-3), tried inside the search for1/cos(x)^3and declined there by thescoped secant reduction, was then declined from the cache in two milliseconds when
asked for directly -- unseen until now because by parts used to answer it at depth
two regardless. The key carries the scope; a lookup takes a decline only from its own
scope and an answer from either, since an antiderivative that was found is right
wherever it is asked for. A test asks the two integrals in that order.
Measured
Every answer differentiated back, with parameters pinned.
Rubi corpus, 463-problem sample, against the master it was cut from (#1286), both
timed on the same evening:
Twelve more and nothing lost:
e^x x/(1 + x)^2,e^(x^2)(1 + 2x^2)twice and once asa sum (Moses),
e^(1/x)(1 + x)/x^4(Hearn), Hebisch'se^(1/(x^2 - 1))times arational function,
(4x^5 - 1)/(1 + x + x^5)^2(Apostol), Stewart's(1 + x^2 + x^4)/((1 + x^2)(4 + x^2)^2), Timofeev'sx^5/(1 + x^4)^3and(1 + x^2)/(x (1 + x^3)^2), and two the reduction reached on its own:ln(x)/(1 + ln(x))^2and(3x - 1)^(4/3)/x^2. The sum of per-problem time over thesample is 100 s to 75 s.
Two pinned declines moved as their tests said they would:
BinomialDenominatorIntegralTesthad1/(x^3 + 2)^2as outside the binomial rule'sshape, and it is the reduction's first and then the rule's;
ExpandedPowerIntegralTesthad(a - b x^2)^3/x^7as unreached, andx^7is a powerof a linear.
The five test suites are green.
Part of #718.
🤖 Generated with Claude Code
https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura