Record Grotto half-ulp tables and comparison geneval, and factor shared beaver terms before the quotient.

Horner and window evaluation need those tables in the tree. Comparison geneval opens the same value words as a Doerner–Shelat key. A factor common to every polynomial term is multiplied first so that preprocessing stays smaller.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ryan Henry 2026-09-24 15:16:21 -06:00
parent 3f10e05176
commit 875f09fec1
14 changed files with 42668 additions and 184 deletions

View file

@ -5,8 +5,12 @@
/// Chebfun). A requested precision only rounds those coefficients
/// down to `k + 16` fractional bits. `coth` is different: its
/// principal function depends on `k` through
/// `beta = ln(2^{k+1}+1)/2`, so each precision has its own uniform
/// partition. The returned raw value is
/// `beta = ln(2^{k+1}+1)/2`, so each precision has its own
/// partition. `inv` (1/x), `rsqrt` (1/sqrt(x)), and `invsq`
/// (1/x^2) are also per precision: each is a longest-feasible
/// cubic march on the closed principal interval [1/2, 1], with
/// absolute error at most half an ulp at that precision. They do
/// not apply an exponent lift. The returned raw value is
/// `round_half_away(p(x) * 2^k)`. On the closed principal domain,
/// `p` stays within one unit in the last place of that precision.
@ -33,6 +37,9 @@ enum class principal : unsigned
sec,
gsec,
csch,
inv,
rsqrt,
invsq,
};
inline constexpr unsigned principal_precisions[] = {8u, 12u, 16u, 20u, 24u, 28u, 32u};
@ -71,6 +78,7 @@ struct table_ref
};
#include "grotto/principal_tables.inc"
#include "grotto/principal_recip_tables.inc"
struct w256
{
@ -288,6 +296,14 @@ inline const table_ref & table_for(principal which, unsigned fractional_bits)
const unsigned slot = fractional_bits / 4u - 2u;
return *COTH_BY_K[slot];
}
if (which == principal::inv || which == principal::rsqrt || which == principal::invsq)
{
const unsigned slot = fractional_bits / 4u - 2u;
const table_ref * const * bank = which == principal::inv
? INV_BY_K
: which == principal::rsqrt ? RSQRT_BY_K : INVSQ_BY_K;
return *bank[slot];
}
return *SHARED_TABLE[index];
}