Repository navigation
A negative power of the variable is not a polynomial to integration by parts - #1647
Merged
Merged
Conversation
…y parts MathS.TryPolynomial reads x^(-1) as a monomial of degree -1, and two rules differentiated what it read until it reached 0: tabular integration by parts, which allows two thousand rounds, and the loop for a polynomial times an exponential and a sine or a cosine, which allows sixty-four. A negative power never reaches 0, and each derivative was a larger tree than the last, so e^(2x) x^(-1) ran the process out of memory within seconds, where e^(2x)/x is Ei(2x) in milliseconds. The power is no unusual spelling: the integrator writes a quotient that way itself once a constant factor is out. Both rules now take a polynomial none of whose degrees is negative, and so does the check that lets parts go on past a special function, which counts on the degree falling. Past them, by parts takes the power as the factor to differentiate, and the remainder is the quotient the exponential integral rules read: e^(2x) x^(-1), e^(a x) x^(-1), e^x x^(-2), x^(-3) e^x, (x + x^(-1)) e^x and 2^x x^(-1) are answered, each out of memory or past a minute on master, and e^x sin(x) x^(-1) and e^x cos(x) x^(-2) are declined in under half a second. Measured on the Rubi corpus, master at 492afc2 and this change on it, run side by side: family 3 at twenty a file 171 -> 173 of 180, families 1 and 5 to 7 at five a file 438 -> 439 of 499, family 2 544 of 650 on both with four timeouts fewer, family 4 at ten a file 611 of 696, family 8 395 of 420 and the independent suites 1756 of 1814 on both. 0 wrong everywhere. Each problem that moved, run alone in a process of its own: ln(c (a + b x^3)^p)/x^7 is answered in 0.4 s and x^(3/2) (A + B x)/(a + b x + c x^2) in 14 s, where master runs out the budget, the second past three minutes; F^(k sqrt(1 - a x)/sqrt(1 + a x))/(1 - a^2 x^2), for four k, is declined in 5 to 8 s, where master's worker passes 4 GB and is killed. The seventh, (a + b x)^3/((c + d x)^5 ln(e ((a + b x)/(c + d x))^n)), is answered on both in 22 s alone; side by side it was load. The unit tests pass, 14,275, with the GC heap held to 4 GB, and the performance gate passes on 0680a2f0, which is this change but for comments and the changelog: allocation is what the baseline says on all 19 gated benchmarks. ANegativePowerIsNotAPolynomialTest integrates nine such products under a guard and differentiates each answer back on both sides of the pole. Against master, two run out of memory under a 2 GB heap, a third outlasts the guard, and the run aborts. Closes #1646. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 1, 2026
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.
MathS.TryPolynomialreadsx^(-1)as a monomial of degree -1. Two rules differentiated what it read until it reached 0: tabular integration by parts, which allows 2000 rounds, and the loop for a polynomial times an exponential and a sine or a cosine, which allows 64. A negative power never reaches 0, and each derivative was a larger tree than the last. Soe^(2x) x^(-1)ran the process out of memory within seconds, wheree^(2x)/xisEi(2x)in milliseconds. The integrator writes a quotient this way itself once a constant factor is out.Both rules now take only a polynomial with no negative degree, and so does the check that lets parts go on past a special function, which relies on the degree falling. Past them, by parts differentiates the power, and the remainder is the quotient the exponential integral rules read.
The other readers of
TreeAnalyzer.TryGetPolynomialin the library already refuse a negative degree: the sums and series over an index, the image of a polynomial and the Gaussian moments. Those integrator readings that still accept one either feed a gate that now refuses it (the regrouping beforeTrySplit) or take a single step of parts (a logarithm beside a polynomial).Measured
"e^(2*x)*x^(-1)".Integrate("x")OutOfMemoryExceptionunder a 2 GB heap1 / x * e ^ (2 * x) / 2 - -1/2 * (-1 / x * e ^ (2 * x) + 2 * Ei(2 * x)) + C, which isEi(2 * x) + C"e^x*x^(-2)".Integrate("x")integral(e ^ x * x ^ (-2), x)e ^ x * -1 / x - -Ei(x) + C492afc23, one integral per process, killed at 2 GB or 60 s: 11 of 26 integrals ran away (8 out of memory, 3 past 60 s). 23 of the 26 hold a negative power, and the rest are controls. Here all 26 finish.e^(2x) x^(-1),e^(a x) x^(-1),e^x x^(-2),x^(-3) e^x,x^(-2) e^(3x),(x + x^(-1)) e^x,2^x x^(-1), and the same int.e^x sin(x) x^(-1)ande^x cos(x) x^(-2).492afc23and this change on it, run side by side, 0 wrong everywhere:ln(c (a + b x^3)^p)/x^7is answered in 0.4 s, andx^(3/2) (A + B x)/(a + b x + c x^2)in 14 s. Master runs out the budget on both, and on the second it is still running after three minutes.F^(k sqrt(1 - a x)/sqrt(1 + a x))/(1 - a^2 x^2), for fourk, is declined in 5 to 8 s. On master the worker passes 4 GB and is killed. During these runs a guard killed six of master's workers past 4 GB and none of this change's.(a + b x)^3/((c + d x)^5 ln(e ((a + b x)/(c + d x))^n)), is answered on both in 22 s alone. Its side-by-side difference was load.0680a2f0, which is this change but for comments and the changelog. Allocation matches the baseline on all 19 gated benchmarks.ANegativePowerIsNotAPolynomialTestintegrates nine such products under a guard and differentiates each answer back on both sides of the pole. Against master, two run out of memory under a 2 GB heap, a third outlasts the guard, and the run aborts.Closes #1646.
🤖 Generated with Claude Code