Skip to content

An antiderivative built through an even root says where the root is real - #1431

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
radical-substitution-condition
Sep 21, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
radical-substitution-condition

Conversation

@Rafael-SOWNet

@Rafael-SOWNet Rafael-SOWNet commented Sep 21, 2026 •

Copy link
Copy Markdown
Member

Found by the Rubi family-7 run on #1430's merge commit: x*sqrt(c-a*c*x)/e^(3*atanh(a*x)) (7.3.6) came back wrong — d/dx 14% off the integrand at x = 0.59, a = 3.1, c = 0.7. Not a defect of the new rule: e^(3 atanh(a x)) now folds to (2/(1 - a x) - 1)^(3/2) (exact), which made the row reachable for the linear-radical substitution u = sqrt(c - a c x), and that route was already wrong on the same shape (sqrt(c-a*c*x)*(2/(1-a*x)-1)^(-3/2) on master, WRONG 2/6).

The cause. For an even q the substitution takes a power of u out of the radicals — (2c/u^2 - 1)^(-3/2) as u^3/(2c - u^2)^(3/2) — on the strength of u being a non-negative real (FactorANonnegativeVariableOutOfRadicals), which it is only where the radical is real. Above a x = 1 the root is imaginary, the identity does not hold, and the integrand is still real there: sqrt(negative) · (negative)^(-3/2) is i · i · (…). So the answer built for a real u is not the antiderivative on that region, and nothing said so. The general substitution's even-root branch (SolveBySubstitution, "an even root is not negative") made the same assumption.

The fix. An answer that used the step carries the condition it used: provided a x + b >= 0 (the linear-radical route, unless the caller knows u non-negative, as u = e^(k x) is), provided radicand >= 0 (the general route). Beyond it the answer is NaN — no claim — and inside it is unchanged. An answer the step did not touch (x/sqrt(1 + x), 1/(sqrt(x) - x^(-1/3))) is as it was. 1/sqrt(x + x^(3/2)) now reads 2 * sqrt(1 + sqrt(x)) / (1/2) + C provided x >= 0.

LinearRadicalSubstitutionIntegralTest.TheEvenRootStepSaysWhereItHolds pins both: the condition on the answer, the derivative matching inside it at three points, the integrand real at x = 0.59 and the answer's derivative NaN there. Full suite 12007 passed, 0 failed. BREAKING-CHANGES.md entry measured on a v2.5.0 build (both rows were unevaluated there).

The harness side is in the workspace: intbench now skips a sample point where a condition the answer states (anywhere in its tree, since C is added outside the provided) is decidedly False, instead of stripping the condition and comparing — an answer claims nothing there. On that harness: 1774 suite 1706/1774, 0 wrong, 0 timeout (unchanged), family 7 153/270, 0 wrong (152 with the wrong row before), family 6 315/417, 0 wrong (unchanged).

Part of #718.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

The linear-radical substitution u = (a x + b)^(1/q) and the general substitution for an
even root both take a power of u out of a radical on the strength of u being a
non-negative real, which it is only where the radical is. Beyond the radicand's zero u
is imaginary and the integrand can still be real: Rubi's x sqrt(c - a c x)/e^(3 atanh(a x))
above a x = 1 is the product of two imaginary factors, and the answer built for a real u
was 14% off its derivative there and shipped as an answer (family 7, one wrong after
#1430 made the row reachable). An answer that used the step now carries
provided a x + b >= 0: NaN beyond it, which is no claim, and unchanged where it holds.
An answer the step did not touch is as it was.

#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 c11661b into master Sep 21, 2026
31 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the radical-substitution-condition branch September 21, 2026 00:57
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