Repository navigation
A constant evaluates to a real number whatever the downcasting says, a complex number with a zero imaginary part is real-valued, and the evaluation cache is stamped rather than cleared - #1371
Merged
Conversation
…a complex number with a zero imaginary part is real-valued, and the evaluation cache is stamped with its epoch rather than cleared With the downcasting off, e and pi evaluated through the conversion from a decimal to a Complex with a zero imaginary part, and the constant is one object whose cached Evaled kept it: after any scope with the downcasting off -- the integrator's sampled checks open one around every candidate -- sgn(e^x - 1) was not real-valued, so its derivative, which is zero, stayed unevaluated for the rest of the process (the hyperbolic sample reported seven right answers with sgn(tanh(c + d x)) in them as errors), and e^x was no longer the exponential of x but a logarithm of the constant and an exponential. The constants are Real.Create of their digits now, a Real in either mode, and IsRealValued takes a complex number whose imaginary part is zero for the real number it is. The downcasting setting does not advance the evaluation epoch: tried, it made every cached evaluation in the process stale at each of the integrator's checks, and the unit suite took four times as long. And the epoch is read before an evaluation and recorded with its result, rather than clearing the lazy slot on a stale read: a precision scope opened inside an evaluation -- the factorial opens one -- advanced the epoch under a computation still running, and a re-entrant read cleared the slot it was filling and read back null. Four suites green. Part of #1367. 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
Oct 9, 2026
Rafael-SOWNet
added a commit
that referenced
this pull request
Oct 9, 2026
* Breaking-changes entries for #1828 to #1832 and #1374 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura * And for #1368, #1611 and #1517, each measured on 2.5.0 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura * And for #1289, #1312, #1315, #1377, #1380 and #1371, each measured on 2.5.0 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura --------- Co-authored-by: Claude Opus 5.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.
Follow-up to #1368, found while running the hyperbolic Rubi sample: seven answers with
sgn(tanh(c + d x))in them — all right — came back as errors because their derivatives could not be evaluated.Cause. With the downcasting off,
eandpievaluated through theEDecimal → Complexconversion to aComplexwith a zero imaginary part (that is the documented contract ofDowncastingEnabled = false: no type reduction at all), and the constant is one object whose cachedEvaledkept it. After any scope with the downcasting off — the integrator's sampled checks open one around every candidate —IsRealValued(e^(2x) − 1)was false, sosgn(...)'stayedderivative(sgn(...), x)for the rest of the process, ande^xwas no longer recognised as the exponential ofxinPow(a logarithm of the constant and an exponential instead).Fix, three parts:
Real.Createof their digits — aRealin either mode (Real.Createwith the downcasting off isnew Real, no rational search), so nothing that is cached on them depends on the setting.IsRealValuedtakes a complex number whose imaginary part is zero for the real number it is (Complex.Create(1.5, 0)with the downcasting off).Evaledcache is an explicit field stamped with the epoch it was computed under and its owner, rather than the lazy slot cleared on a stale read: a precision scope opened inside an evaluation (the factorial opens one) advanced the epoch under a computation still running, and a re-entrant read cleared the slot being filled and read backnull— 54NullReferenceExceptions in the suite once a second setting advanced the epoch. The owner stamp is what the lazy slot carried (a record'swithcopies the field).Tried and rejected: making
DowncastingEnabledadvance the epoch too. It made every cached evaluation in the process stale at each of the integrator's checks; the unit suite went from 6 to 22 minutes. Recorded in the epoch's doc comment.Gate: every row within the band (+0.1% to +1.1% bytes, the same as #1368's run — that PR did not move the baseline). Four suites green (11,350 / 134 / 18 / 41).
Part of #1367.
🤖 Generated with Claude Code
https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura