HurwitzZeta and Zeta(s, a) at the engine's precision for real arguments; Part of #340 - #360
Merged
Merged
Conversation
…for real s and a, via a bignum Euler-Maclaurin kernel ported from enumeratio's hurwitz-zeta-big.ts - bigHurwitzZeta/bigZetaGeneralized (numerics/special-functions.ts): real-s, real-a Hurwitz zeta via Euler-Maclaurin in BigDecimal, sized by a doubles-only cancellation plan (hurwitzZetaBigPlan) so Re(s) < 0 raises the working precision instead of cancelling; zetaGeneralized peels |k+a|^-s terms for a <= 0 the same way the double kernel does. - library/arithmetic.ts: evaluateHurwitzZeta/evaluateGeneralizedZeta route through the bignum kernel when bignumPreferred and both operands are real, falling back to the existing double hurwitzZetaComplex kernel otherwise (a complex operand, or precision too extreme for the bignum kernel's working-digit budget). - zeta-values.test.ts: table-driven cases across both heads, positive and non-positive a, and Re(s) << 0, at precision 30 and 50, checked against mpmath. Part of cortex-js#340
…he engine precision) Dual review (Codex + Claude), every value checked against mpmath at the matching precision. Correctness: - The Euler-Maclaurin plan sized an ABSOLUTE error and capped the retry at twice the requested digits, so a tiny result was wrong with every digit shown: HurwitzZeta(200, 10) at precision 50 was 5.5e-201 (true 1.0e-200) and HurwitzZeta(300, 10) was 47% off. The target is now relative to an estimate of the result's magnitude, with up to four passes, and the kernel returns only a result carrying the requested digits. - The cancellation allowance did not subtract the result's own magnitude, so a very negative s exceeded the 1,200-digit budget and fell back to the double kernel, which overflowed: HurwitzZeta(-400.5, 0.3) was +oo and (-1000.5, 0.3) NaN. Both now give the correct 50 digits, and past the kernel's limit the application stays symbolic instead of +oo/NaN. - The planner treated a Pochhammer factor that rounds to zero as a double as exact termination (s = -2 + 1e-30 lost digits from the 30th place); it now reads the exact operand. - An exact rational operand (1/3) was rounded to the engine precision before the guard digits, so the last digit was wrong on the evaluate route; it is passed as a pair and converted inside the guarded precision. The .N() route still pre-rounds operands engine-wide (ROADMAP). - A large negative base point allocated one BigDecimal per unit of |a| with no deadline: Zeta(2, -1e8) tried 1e8 objects. The prefix is streamed with deadline checks and, past 10 000 terms, computed as a Hurwitz difference; Zeta(2, -1000000.5) went from 1.9 s to 3 ms. - An integer s between -100 and 0 answers the exact Bernoulli form, so HurwitzZeta(-2.0, 0.5) is 0 (it was -6.9e-18). Performance: the coefficients reuse the engine's cached Bernoulli table and a running factorial; the first HurwitzZeta(3, 1/3) at precision 1000 went from about 11 s to 0.55 s. Tests and documentation: tests for the tiny, huge, near-integer and 1/3 cases, the fallback, and a machine-precision engine; CHANGELOG under [Unreleased]; the double kernel's small inaccuracies (recorded in ROADMAP) and the external-file reference in a comment replaced by the PR number; the unrelated floorModFloat reformat dropped. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Member
|
Thanks, merged, with a review pass on your branch as `f6075589. The main corrections:
Two open notes in ROADMAP: |
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 #340
HurwitzZeta(s, a)andZeta(s, a)answered at machine precision whateverce.precisionwas. For realsandathey now follow it, through a BigDecimal Euler–Maclaurin kernel in the same idiom asbigZeta. Left of Re(s) = 0 the kernel raises its working precision by the cancellation it expects. Past a 1,200-digit budget it falls back to the double kernel. The exact forms andZeta(s, 1)→bigZetaare unchanged. Complex operands stay at machine precision.Checked against mpmath (dps 90) over s ∈ [−10, 20] and a ∈ (−10, 10], at precision 30 and 50: worst relative error 5e-29 and 9e-49. About 0.6 ms a call at precision 50.