|
Uni20
Asynchronous tensor and runtime library.
|
This plan covers the general-purpose real math surface for mpreal and the matching uni20::math interface. It is broader than Bethe's immediate needs. The implementation status below records the elementary-functions change and the subsequent native and MPFR extensions. Availability depends on the configured scalar types and, for some native functions, platform providers.
The current contracts live in scalar math dispatch, arbitrary-precision reals and scalar policy. Complex MPC coverage is a separate extension: a real MPFR routine does not establish a complex branch convention or implementation.
uni20::math, with the existing isolated ADL boundary. Do not add subsystem-specific lookup wrappers.double.Precision on elementary functions converts the inputs first, then evaluates. This is the existing contract, not a promise to round the original rational expression only once. Basic arithmetic has its own stronger mixed-rational rounding contract; arithmetic utilities, including fused operations, round the result from the original operands.expm1 and log1p.Status: implemented by the elementary-functions change, with the existing MPFR 4.1 minimum. This slice has no new MPFR-version requirement.
| Family | New mpreal overloads, with and without trailing Precision |
|---|---|
| Exponentials and logarithms | exp2, expm1, log2, log10, log1p |
| Roots | cbrt |
| Inverse trigonometry | asin, acos |
| Hyperbolic functions | sinh, cosh, tanh, asinh, acosh, atanh |
Expose all of these through uni20::math. Also expose existing scalar tan, atan, atan2 and hypot there. Existing abs, sqrt, pow, exp, log, sin and cos remain part of the surface.
Exact behavior includes rational cube roots, rational powers of two and integer base-two/base-ten logarithms of rational powers of the base, plus the zero/one identities documented in mpreal.md. Other inputs need working precision. Finite-precision evaluation uses MPFR round-to-nearest, ties-to-even on the stored input, after any explicitly requested input conversion.
Validation includes cancellation at tiny positive and negative arguments, precision retention across the shared scalar matrix, accuracy improvement at higher precision, exact roots/powers/logarithms, explicit precision, exceptional values and signed zero. MPFR-disabled native builds remain supported.
Status: implemented. This slice raises the MPFR minimum to 4.2 for signed integer roots and the later extension routines. The original elementary PR retains its 4.1 minimum. Shared numerical probes cover float32/64/80/128 and MPFR at 128/256 bits, including boundary semantics and accuracy improvement.
| Group | Implemented surface | Contract |
|---|---|---|
| Integer powers and roots | pown, rootn | Signed exponent/order types; zero and negative orders; rational perfect roots; native and float128 algorithms without narrowing |
| Rounding | floor, ceil, trunc, round, round_even | Preserve exact rational semantics, ties and signed zero; avoid ambient rounding mode |
| Stable arithmetic | fma, copysign, fdim, fmin, fmax | Fused rounding with mixed rational inputs; sign/comparison operands; NaN rules |
| Remainders | fmod, remainder, remquo | Truncating versus nearest-even quotient; negative inputs and quotient-bit contract |
| Decomposition/scaling | modf, frexp, ldexp, scalbn, ilogb | Named result values; exponent width and special-value behavior |
| Paired functions | sincos, sinhcosh | Named owning results, consistent component precision, paired provider calls |
| Adjacent values | nextafter, next_up, next_down | A finite representable grid; direction need not have matching precision; signed-zero, infinity and exponent-limit rules |
| Classification | isfinite, isnan, isinf, signbit through uni20::math | Bool results need a dispatch policy separate from precision-preserving numerical results |
ceil and ldexp now support MPFR in the generic facade. Classification continues to support the existing root-level scalar interfaces as well.
The owning results are frexp_result{fraction, exponent}, modf_result{fraction, integer}, remquo_result{remainder, quotient}, sincos_result{sin, cos} and sinhcosh_result{sinh, cosh}. Exponents and integer orders use a signed 64-bit domain with checked integer inputs. ilogb rejects zero/nonfinite values. remquo reports signed low three quotient bits.
Exact rational operations do not detour through floating point. A trailing finite precision on arithmetic utilities rounds the result from the original inputs, including non-dyadic rational operands to fma. Paired trig/hyperbolic functions follow the component elementary input-conversion contract. This distinction is documented in mpreal.
There is no next rational number. Adjacent-value APIs take their grid from the first operand or an explicit precision, which first rounds that operand. Sign sources and unrounded directions may differ in precision. Equal zeros return the direction's sign. MPFR has no subnormals; its current exponent limits define the neighbors of zero and infinity. Native formats retain their own limits.
Status: implemented for mpreal, with exact-state, domain and numerical precision tests. See MPFR special functions for the contracts. The families below also have native float32/64/80/128 algorithms or precision-preserving platform adapters. Log-Gamma and Bessel availability still depends on the configured provider. Native evaluation never adapts through MPFR, and a missing platform overload remains constrained out. Shared precision tests distinguish unavailable provider combinations from supported operations. The batch documents record validation evidence; implementation alone does not establish full configuration validation or merge completion.
Native lgamma, lgamma_sign, bessel_j and bessel_y now have per-type platform adapters, using reentrant log-Gamma and checked Bessel order lowering. Native beta uses advertised standard-library functions for float/double/long double, with native Beta restricted to positive arguments. Binary128 Beta now uses a native Gamma-ratio implementation; binary128 Ei uses native series, continued fractions and asymptotics. Native zeta also covers binary128 through Euler–Maclaurin evaluation and reflection. The Beta investigation documents the fallback's accuracy and range contract separately from retained providers. See native special functions. Publication, review and merge progress are tracked in issue #67. Native arithmetic adds neither Boost nor an MPFR runtime dependency.
| Family | Target surface |
|---|---|
| Gamma | tgamma, lgamma, signed log-Gamma, digamma, beta, upper incomplete Gamma |
| Error and zeta | erf, erfc, zeta |
| Exponential integral and dilogarithm | Ei, real-part Li2 |
| Other provider functions | Integer-order Bessel J_n and Y_n, Airy Ai, agm |
| Constants | Explicit-precision pi (existing), log(2), Euler's constant, Catalan's constant |
| Optional convenience | Integer-argument factorial |
Use lgamma for log(abs(Gamma(x))); expose the Gamma sign independently rather than changing that meaning for negative Gamma. Name and document the upper incomplete Gamma explicitly. A real-part dilogarithm is not a complex dilogarithm API. Document provider limitations and behavior at domain boundaries; wrapping a provider is not a guarantee over a wider domain.
For mpreal, constants use precision-aware descriptors: pi, log_two, euler_gamma and catalan. They require finite precision and remain separate from exact rationals. All four names also supply native constexpr values, including configured binary128. Pi, log(2) and Euler gamma use typed std::numbers constants; Catalan is assembled from an independently checked binary prefix. factorial(n,p) explicitly selects exact or finite arithmetic; its integer-source checks and exact-storage costs are documented.
Native math::agm(a,b) is also implemented for matching native real types through scaled iteration; see native AGM.
The typed uni20::factorial<Real>(n[,p]) factory supports native formats and explicit-precision mpreal; see native factorial.
Native digamma also covers all configured real formats; see the algorithm and acceptance criteria.
Native math::dilog_real(x) covers the whole real line at all configured precisions; see real dilogarithm for reductions and acceptance criteria. Native Ei also supplies binary128 and the other configured precisions through Uni20 algorithms. This replaces standard Ei after accuracy and performance comparisons exposed substantial GCC13 errors; the algorithm document records the cost and range behavior. Native zeta similarly replaces standard evaluation after comparison, with exact phase reduction and scaled reflection. Native upper incomplete Gamma supplies all configured precisions using scaled series and fractions, with extra native words for range decisions and large-parameter cancellation. Native Airy Ai now covers the full real axis, with guarded central evaluation, original-input negative phase reduction and positive subnormal rounding. Full GCC Debug, native-only GCC Release and Clang Debug configurations passed; the algorithm document records their coverage and platform limits.
Beta, zeta and Ei now have reusable native implementations, including binary128. When a suitable provider is unavailable, design the native algorithm for reuse across float32/64/80/128 through the existing typed adapter boundary. Keep the public uni20::math calls unchanged and retain MPFR's own scalar implementations.
Sharing an algorithm does not require identical approximation coefficients, iteration counts or evaluation paths at every precision. Construct constants and coefficients without first rounding to double; choose approximation order, termination criteria and scaling from the supported type's precision and range. Allow precision-specific implementations where they improve accuracy or speed. Each function needs explicit domain and exceptional-value contracts, including behavior near poles, zeros, cancellation and overflow/underflow boundaries.
Start with the missing binary128 implementation, validate the shared algorithm at every intended native precision, then compare accuracy and performance with the existing providers before changing provider selection. Use the shared precision matrix and independent higher-precision MPFR references; MPFR remains a test oracle, not a runtime dependency of native evaluation. This comparison has justified replacing standard Ei and zeta. Native zeta no longer shares the upstream signgam limitation. Beta's standard providers remain selected where available; its native fallback supplies binary128 and missing-provider configurations, with the tradeoff recorded in the Beta document.
Status: implemented for mpreal using MPFR 4.2 routines. The seven pi-scaled forward/inverse trigonometric functions also support native float32/64/80/128, using detected libc families or same-precision portable implementations. See native pi-scaled functions. Native exp10, exp2m1, exp10m1, log2p1 and log10p1 also have per-type provider selection and portable implementations; see native exponential/logarithmic extensions. Native compound uses a detected typed provider or scaled, guarded integer exponentiation; see native compound. Native reciprocal functions also preserve all configured native formats, with scaled hyperbolic tails; see native reciprocals and Catalan.
exp10.sinpi, cospi, tanpi, and pi-scaled inverse trigonometric functions.log2p1, log10p1, exp2m1, exp10m1, and compound for (1+x)^n.sec, csc, cot, sech, csch, coth.These routines fit the MPFR 4.2 minimum introduced by stage 2. Native calls use the implementations or detected providers described above, independently of whether MPFR is enabled. Multiplying a rounded pi into the argument is not an adequate replacement for a pi-scaled function's argument reduction contract. Likewise, do not replace the small-argument functions with cancellation-prone compositions. compound rounds the result from the original input, matching the arithmetic-utility contract; the other extensions use explicit input conversion when a precision override is supplied.
Each PR must include:
EXPECT_NEAR conversion to double for extended-precision claims.Track completed stages here, and keep current behavior in the canonical guides. Deferred signatures and semantics remain proposals until their implementing PR. The plan does not add scalar serialization, tensor-wide precision storage, CUDA MPFR execution, or new linear-algebra providers.
complex<mpreal> now supplies sinh, cosh and principal acosh, including explicit-precision overloads. Other complex hyperbolic operations are not implied by their real MPFR availability. Core tests use the shared precision contexts at 80/160/256 bits, independent real-component identities, exact input rejection/conversion and both signed-zero sides of the inverse cut.