Repository navigation
The special functions compile, in double precision - #1613
Merged
Merged
Conversation
erf, erfc, erfi, Ei, li, Si, Ci, Shi and Chi had no compiled form. So Compile and Compile<TIn, TOut> threw UncompilableNodeException on them, and Solve's numerical search, which compiles, declined any equation with one in it. The interpreter's kernels work in arbitrary precision and take 0.7 to 5.5 ms a call at 20 digits. Newton's method makes about 3,000 calls an equation, so it cannot use them. SpecialFunctions gives each a double-precision routine, and both compilers call it: through new opcodes under Compile, and through definitions for Complex and double under Compile<TIn, TOut>, where an integer or a float is widened to double first, as for the trigonometry. - The error functions come from the Faddeeva function, by Weideman's rational approximation with 40 terms, and from erf's Taylor series near the origin. - Ei is summed as its series where the terms cancel little, is E1's continued fraction elsewhere out to |z| = 40, and is its asymptotic series beyond. - li, Si, Ci, Shi and Chi follow from Ei and from their own series, by the relations the kernels state. Each keeps the kernel's branch cuts and its values on the axes. Over doubles, a value off the real line is NaN, as Math.Sqrt of a negative number is. Measured against the kernels at 30 digits on about ten thousand points, through the compiled delegates: the integrals agree to within 6e-14 of the value, and the error functions to within 3e-13, which is the rounding of z^2 in e^(-z^2) at large |z|. They take 0.5 to 2.4 us a call. Solve answers erf(x) = x/2 + 1/7 with its three real roots, each checked against mpmath, and more off the real line. An equation that isolates a special function, erf(x) = 1/2, is still left unsolved: the solver finds no inverse to write, and so never reaches the search. Part of #1607. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The routines are the compilers' today, and the numerical evaluation's fast tier is where they are to be shared next, as asked on #1607: the interval evaluation reads no special function, so an integrator check with erf or Ei in it falls back to the decimal evaluation. Nothing but the namespace and the file's place changes. Part of #1607. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rafael-SOWNet
force-pushed
the
the-special-functions-compile
branch
from
September 30, 2026 08:31
1428d1b to
19678c9
Compare
Rafael-SOWNet
added a commit
that referenced
this pull request
Sep 30, 2026
The interval evaluation, the fast tier the integrator's checks run on (#1497), read no special function. A check with erf, Ei or Si in it was undecided there and went on to the decimal evaluation, which calls the arbitrary-precision kernels at 40 and then 80 digits. It now takes the double-precision routines in AngouriMath.Numerics, as suggested on #1607. Each value is enclosed as its routine's value at the rectangle's middle, widened by the routine's error and by how far the function can move across the rectangle. The routines agree with the kernels to within 3e-13 of the value, measured and not proved, and are allowed 1e-10 of it, and 1e-10 more near a zero. The movement is the largest the derivative is on the rectangle times its half diagonal; the derivatives are elementary, so the intervals bound them themselves. A rectangle that straddles a cut of Ei, li, Ci or Chi, or where the value or the derivative overflows a double, has no enclosure and stays undecided, as before. A real value stays real where the function is. Every enclosure was checked against the kernels at 30 digits on #1613's grid, about 17,800 per function, each point as an exact double and nudged by a relative 1e-20: no kernel value falls outside its enclosure. IntervalEvaluationTest gains 17 special-function rows. Over Rubi's problems in families 0-7 whose antiderivative uses one of the nine functions, 2,354 in all, master solves 1975 and this 1976, with 0 wrong and 0 errors on both. The one move, 6.1.3:32 (sinh(a + b x^2)^3/x^3, answered in Chi and Shi), is a timeout on master. Run on its own it takes 27 to 29 s on both builds, so the change does not bring it inside the budget by itself. Part of #1607. Co-Authored-By: Claude Opus 5.5 <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.
erf,erfc,erfi,Ei,li,Si,Ci,ShiandChihad no compiled form. SoCompileandCompile<TIn, TOut>threwUncompilableNodeExceptionon them, andSolve's numerical search, which compiles, declined any equation with one in it (#1605). The interpreter's kernels are arbitrary-precision and take 0.7 to 5.5 ms a call at 20 digits. Newton's method makes about 3,000 calls an equation, so they cannot back a compiled form: #1607, suggested on #1605.SpecialFunctions, inAngouriMath.Numericsbeside the interval evaluation (moved there in the second commit, as suggested on #1607), gives each a double-precision routine, which both compilers call:erf's Taylor series near the origin.Ei: its series where the terms cancel little (|z| - Re z <= 3, or|z| <= 2),E1's continued fraction elsewhere out to|z| = 40, and its asymptotic series beyond.li,Si,Ci,Shi,Chi: fromEiand from their own series, by the relations the kernels state.Each keeps the kernel's branch cuts and the kernel's values on the axes. An imaginary part of either sign of zero is read as the axis, as the kernels read it. Under
Compile<TIn, TOut>the definitions are forComplexanddouble, and an integer or a float is widened to double first, as for the trigonometric functions. Over doubles, a value off the real line is NaN, asMath.Sqrtof a negative number is.Solvenow answerserf(x) = x/2 + 1/7with its three real roots, each checked against mpmath, and more off the real line. An equation that isolates a special function, such aserf(x) = 1/2, is still left unsolved: the solver finds no inverse to write, so it never reaches the search.binomial(x, 3/2) = x/2replaceserfas the test's example of what the search still declines.Measured
[-14, 14]^2, both axes out to 40 and in to1e-4, either side of the negative real axis at1e-9and1e-3, and circles out to radius 300.z^2in theire^(-z^2)at large|z|.[-10, 10]^2, against the kernels' 0.7 to 5.5 ms.SpecialFunctionCompilationTest: 57 points through both compilers against the interpreter to 1e-12; real values and NaN over doubles; and five infinite values, whose exact part a complex halving had made NaN.NewtonFallbackTest:erf(x) = x/2 + 1/7andSi(x) = x/2 + 1/7are searched, each with its three real roots from mpmath, and every root it returns is checked.SolveNtstill throws for what doesn't compile.BREAKING-CHANGES.md: the three entries that added the functions gain a row each, since 2.5.0 had none of them. The floors, the rounding and the extremes compile, and Solve's numerical search declines what it cannot represent #1605's entry namesbinomialin place oferf.Part of #1607.
x!,gammaandphiunderCompile<TIn, TOut>are the other half, next.🤖 Generated with Claude Code