Repository navigation
EllipticF, EllipticE and EllipticPi at the working precision - #557
Open
enumeratio wants to merge 1 commit into
Open
enumeratio wants to merge 1 commit into
enumeratio wants to merge 1 commit into
Conversation
…i(n|m) N() at the precision asked for real operands with Carlson's R_F, R_D and R_J summed by duplication in BigDecimal (DLMF 19.25, 19.36), with a null bignum result that declines instead of falling back to doubles; read exact operands of F and Π to guard digits; add mpmath tables at 30, 50 and 100 digits. Fix cortex-js#550
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.
EllipticF(φ, m),EllipticE(φ, m),EllipticPi(n, φ, m)andEllipticPi(n, m)giveN()at the precision asked for real operands. Fixes #550numerics/elliptic-big.ts:R_F,R_J(andR_D = R_J(x, y, z, z)) by the duplication theorem inBigDecimal(DLMF 19.36(i); the series at order 6 as incarlsonRF/carlsonRJ),R_C(1, 1+e)by series for|e| <= 0.01and by atan/atanh otherwise. The Legendre forms are DLMF 19.25.5, 19.25.9 and 19.25.14, withφ + kπfrom2ktimes the complete integral (EllipticK/EllipticEkernels already there, and the new complete Π).φ - kπfor a largek,π/2 - |r|(socos φcomes fromsin(π/2 - |r|)and keeps its relative accuracy at the double nearestπ/2),1 - m sin²φ(formed asc² + (1-m) sin²φ, so m near 1 loses nothing), the same for1 - n sin²φ, theR_C(1, 1+e)argument near-1, and the sumss·R_F ∓ …·R_D/R_Jand2kC + …. When the loss is more than the 15 guard digits hold it runs again with that many more, up to 400, and past that returnsnull. Every loop has a named cap (CARLSON_MAX_DUPLICATIONS, 1000), and the duplication stops when the spread of the arguments is below10^(-precision/6)of their mean, which puts the truncation error of the order-6 series below a unit in the last place.applyN(boxed-expression/apply.ts): abigFnresult ofnulldeclines (the call stays unevaluated) instead of falling to the machine kernel. A NaN still means "not real here, try the next kernel", which is how the complex-valued cases keep their double complex answer.EllipticFand bothEllipticPiforms are wrapped inguardDigitsN, asEllipticEis, so an exact operand (Pi/3) is read to guard digits underN().EllipticPiwhere1 - n sin²φ < 0(n > 1for the complete form) is the Cauchy principal value, as the machine kernel gives it (EllipticPiwith a complex parameter givesComplexInfinity, andRangepast 2^53 rounds its elements #422: the real part of mpmath's value forn + i0⁺).R_Jforp < 0is DLMF 19.20.14 in terms ofR_Jat a positivep',R_FandR_C; the cancellation of its three terms is measured like the others.Principal value (n > 1): 8 rows (complete and incomplete, amplitudes to 3.2 and 1.5707963267948966, m from -3 to 0.99, n from 1.5 to 100) against the real part of mpmath's
ellippi, at 30, 50 and 100 digits, except two rows where mpmath's own 100-digit (and, for one, 50-digit) value loses digits to cancellation at 30 extra working digits and CE agrees with itself at 50, 100 and 160. Five points (n = 1.5 to 4) were also checked at 40 digits against a principal-value integral withmpmath.quad(the pole subtracted and integrated in closed form), which reproduces the real part ofellippito 40 digits.Accuracy, against mpmath 1.3.0 (40 more working digits, decimal operands, a 15% sample re-checked at 70 and 110 digits),
N()at 30, 50 and 100 digits, 1165 points with a real value (|φ| 1e-5 to 250 and 1.5707963267948966; m from -100 to 50, 1 and 1 - 1e-20; n from -5 to 1 - 1e-20 and 1.5 where1 - n sin²φ > 0):EllipticF(φ, m)EllipticE(φ, m)EllipticPi(n, φ, m)EllipticPi(n, m)The hard regions are in the grid: m = 1 - 1e-20 and m = 1 with φ at the double nearest π/2, n = 1 - 1e-20 for the complete form and 0.999 with φ near π/2 for the incomplete,
|m|up to 1e6 in the tests, φ up to 250 (k = 80 periods). A call takes about 1 ms at 30 digits and 5 ms at 100.Tests:
test/compute-engine/elliptic-incomplete-big.test.tshas 40 mpmath rows at 30/50/100 digits, exact operands at 30 and 50 (they stay symbolic underevaluate()), a float operand underevaluate(), the machine and compiled-JavaScript routes at double precision (rows whose double operand is not the decimal one, near m = 1, are skipped there), the principal-value rows, the complex value of real operands (EllipticF(2, 2)at 30 digits is the double complex value), and the infinite poles. Not run here: the neighbour files that mentionElliptic(listed in the summary).Not touched: the complex results of real operands stay doubles at every precision, as for the other special functions (
docs/plans/2026-09-27-big-decimal-imaginary-part.md, D4); the compiled targets use the machine kernels, unchanged.