Repository navigation
A power of the variable is a substitution even where it is written nowhere (#233) - #1135
Merged
Merged
Conversation
…where
`int x / (x^4 + 1)` came back unevaluated. It wants `u = x^2`, and two separate things stopped it.
Candidates were taken from the subexpressions that occur, and `x^2` occurs nowhere in
`x / (x^4 + 1)`. So it was never offered. And had it been offered, substituting it would have
replaced nothing: `x^4` is not written as `(x^2)^2`, and a substitution matches what is written, so
the integrand would have kept its `x` and the candidate would have been rejected anyway.
`int x^3 / (x^4 + 1)` worked throughout, because its substitution `u = x^4` does occur. That is what
made the gap hard to see from the outside -- one of the pair works and the other does not, for a
reason that is about syntax rather than about integration.
So a power of the variable now offers its divisors as candidates, and substituting a power rewrites
the other powers of the variable into powers of itself, which it can do exactly when its exponent
divides theirs. Nothing is assumed by either: the caller still checks that no `x` survives, so a
candidate that does not clear the variable is rejected as before. `x^2 / (x^4 + 1)` is exactly that
case -- a bare `x` remains, it is still declined, and it stays open on the issue, since it needs the
denominator factored over the reals rather than a substitution.
Newly integrable, each verified by differentiating the answer and comparing with the integrand at
nine sampled points rather than by reading the printed form:
x/(x^4 + 1) arctan(x^2)/2 + C
x/(x^4 - 1) x/(x^4 + 4) x^2/(x^6 + 1)
x/(x^6 + 1) x^3/(x^8 + 1) x^3/(x^12 + 1)
Eleven integrals taking the other paths -- a substitution that does occur, partial fractions, by
parts, a logarithm -- are checked the same way and are unchanged. The full suite is green and takes
the same time it did, so the extra candidates cost nothing measurable.
Part of #233. Three of the five it lists were already answered; `sqrt(tan(x))` and
`x^2 / (x^4 + 1)` remain.
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.
Part of #233.
The gap, which was about syntax rather than about integration
int x / (x^4 + 1)came back unevaluated. It wantsu = x^2, and two separate things stopped it:x^2occurs nowhere inx / (x^4 + 1). So it was never offered.x^4is not written as(x^2)^2, and a substitution matches what is written. The integrand would have kept itsxand the candidate would have been rejected anyway.int x^3 / (x^4 + 1)worked throughout, because its substitutionu = x^4does occur. One of the pair working and the other not, for a reason with nothing to do with integration, is what made this hard to see from the outside.The fix
A power of the variable now offers its divisors as candidates, and substituting a power rewrites the other powers of the variable into powers of itself — which it can do exactly when its exponent divides theirs.
Neither half assumes anything. The caller still checks that no
xsurvives, so a candidate that does not clear the variable is rejected exactly as before.Newly integrable
x/(x^4 + 1)arctan(x^2)/2 + Cx/(x^4 - 1)x/(x^4 + 4)x^2/(x^6 + 1)arctan(x^3)/3 + Cx/(x^6 + 1)x^3/(x^8 + 1)arctan(x^4)/4 + Cx^3/(x^12 + 1)Each verified by differentiating the answer and comparing with the integrand at nine sampled points, not by reading the printed form. These come out with arctangents and radicals whose shape says nothing about whether they are right, and a wrong constant factor still differentiates back to something proportional — so
arctan(x^2)/2is additionally asserted as a form.What it still declines, deliberately
x^2 / (x^4 + 1)underu = x^2leaves a barex, so it is still rejected — that integral needs the denominator factored over the reals (x^4 + 1is irreducible over the rationals; it is(x^2 - sqrt(2)x + 1)(x^2 + sqrt(2)x + 1)), which this does not do. It stays open on the issue, and there is a test asserting it is declined so that a future change has to be deliberate about it.sqrt(tan(x))likewise remains — the issue calls it "very painful, requires different solvers", and it does.Measured
Eleven integrals taking the other paths — a substitution that does occur, partial fractions, by parts, a logarithm — are checked the same way and are unchanged.
Failed: 0, Passed: 9264on net10.0, in 6m38s against ~6m50s before, so the extra candidates cost nothing measurable.Three of the five cases #233 lists were already answered before this:
cos(x^2)*x,sin(x)*e^xand1/(a^2 + x^2), the last as a piecewise on the sign ofa^2. Measured, not assumed — the issue's boxes were all still unticked.🤖 Generated with Claude Code
https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura