Skip to content

Integration and limits with the downcasting off compute as with it on, on exact numbers - #1516

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
downcasting-off-is-exact
Sep 27, 2026
Merged

Rafael-SOWNet merged 1 commit into
masterfrom
downcasting-off-is-exact

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Member

Closes #1490.

With DowncastingEnabled off, integration and limits gave NaN, or left unevaluated, what the default setting answers. There were two causes:

  • The zero test. TreeAnalyzer.IsZero compares against the literal 0, and with the downcasting off a zero is Complex(0, 0), which isn't equal to it. So nothing was zero, and 1/(1 + c^2 x^2) kept its a = 0 case, ln(1)/0.
  • The parse. A whole number parsed with the downcasting off is a decimal Real, so x^2 isn't a whole power to the integrator.

Integration and limits now compute as with the downcasting on, whatever the caller's setting, on the input's decimals read as the exact rationals they are. The answer no longer depends on the setting. The cost, as proposed on the issue, is that decimals come back as rationals: the integral of 0.1 x is x^2/20.

With the downcasting on, nothing changes and nothing is added to the path: the setting is read, and that's all. With it off, the scope is opened once, at the outermost call, since every call inside it finds the downcasting on.

Fixing the zero test alone would have fixed the NaN, but not the rest. The rules still test numbers by type and against literals, and with only the zero test fixed, (d - c^2 d x^2)^(3/2) (a + b arcsin(c x)) gave up after 290 s instead of 7.

with the downcasting off master this PR
(a + b arcsin(c x))/sqrt(d - c^2 d x^2), parsed with it on NaN + C the antiderivative
(d - c^2 d x^2)^(3/2) (a + b arcsin(c x)), parsed with it on unevaluated, after 6.2 s the antiderivative, in 0.13 s
1/sqrt(2 - 2 x^2), parsed with it off unevaluated -arcsin(-x) sqrt(2)/2, up to form
x^2 sin(x), parsed with it off unevaluated the antiderivative
limit(sin(c x)/x, x, 0) NaN c
limit((1 - cos(c x))/x^2, x, 0) NaN c^2/2
0.1 x, parsed with it off 0.1 * x^2 / 2 + C 1/10 * x^2 / 2 + C

Not in this PR

The parse cache is keyed by ExplicitParsingOnly but not by DowncastingEnabled. A string parsed under one setting therefore comes back under the other with the first parse's numbers. That's #1513.

Measured

  • The unit suite passes on net10.0: 12883 passed, 14 skipped, none failed, of 12897.
  • The new tests bind: 8 of the 9 in DowncastingOffCalculusTest fail with the library change reverted. The ninth is 1/sqrt(2 - 2 x^2) parsed with the setting on, which master already answers, and it is there to keep that so.
  • The allocation gate passes on all 19 gated benchmarks. None moves.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

…, on exact numbers

With the downcasting off, a whole number parses as a decimal, so x^2 is not
a whole power to the integrator, and the zero test reads no literal zero as
zero: (a + b arcsin(c x))/sqrt(d - c^2 d x^2) integrated to NaN, and
limit(sin(c x)/x, x, 0) was NaN, where the default setting answers. The
integration and limit transformations now compute with the downcasting on,
whatever the caller's setting, on the input's decimals read as the exact
rationals they are; with it on, nothing changes. The cost is that decimals
come back as rationals: 0.1 x integrates to x^2/20.

Closes #1490.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
@Rafael-SOWNet
Rafael-SOWNet force-pushed the downcasting-off-is-exact branch from 6862967 to 7982a1a Compare September 27, 2026 19:16
@Rafael-SOWNet
Rafael-SOWNet merged commit 97fcdbc into master Sep 27, 2026
31 checks passed
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.

(a + b arcsin(c x))/sqrt(d - c^2 d x^2) integrates to NaN with downcasting off

1 participant