Document the new DPF surfaces in one command set, and test the field, half-tree, and multipoint edges.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
0d8a5a8131
commit
0dff6df8ed
250 changed files with 12199 additions and 1981 deletions
|
|
@ -25,7 +25,7 @@
|
|||
namespace grotto
|
||||
{
|
||||
|
||||
/// Appendix D gadgets whose polynomial degree is 0 and whose max error is 0.
|
||||
/// @brief Appendix D gadgets whose polynomial degree is 0 and whose max error is 0.
|
||||
enum class exact_constant
|
||||
{
|
||||
signum,
|
||||
|
|
@ -36,7 +36,7 @@ enum class exact_constant
|
|||
zero,
|
||||
nonzero,
|
||||
ilogb,
|
||||
/// `ceil(log2(|x|))`. Exact powers of two agree with `ilogb`; every other
|
||||
/// @brief `ceil(log2(|x|))`. Exact powers of two agree with `ilogb`; every other
|
||||
/// positive magnitude is one larger. Zero uses the same `-64` sentinel.
|
||||
ceil_ilogb,
|
||||
ilog10,
|
||||
|
|
@ -51,20 +51,21 @@ struct constant_lut
|
|||
|
||||
using raw_type = Raw;
|
||||
|
||||
/// Signed piece starts. `bounds.front()` is `numeric_limits<Raw>::min()`,
|
||||
/// @brief Signed piece starts. `bounds.front()` is `numeric_limits<Raw>::min()`,
|
||||
/// and the starts are strictly increasing.
|
||||
std::vector<Raw> bounds;
|
||||
|
||||
/// `values[i]` is the function on `[bounds[i], next)`, where `next` is
|
||||
/// @brief `values[i]` is the function on `[bounds[i], next)`, where `next` is
|
||||
/// `bounds[i + 1]` or one past `numeric_limits<Raw>::max()` for the last piece.
|
||||
std::vector<std::int64_t> values;
|
||||
|
||||
HEDLEY_NO_THROW
|
||||
std::size_t linear_parts() const noexcept { return values.size(); }
|
||||
|
||||
/// Pieces after joining the first and last when they carry the same value.
|
||||
/// Those two meet across the signed wrap, which is how the paper counts
|
||||
/// @brief Pieces after joining the first and last when they carry the same value.
|
||||
/// @details Those two meet across the signed wrap, which is how the paper counts
|
||||
/// parts for `zero` and `nonzero` (2, not 3).
|
||||
/// @return Pieces after joining the first and last when they carry the same value
|
||||
HEDLEY_NO_THROW
|
||||
std::size_t wrapped_parts() const noexcept
|
||||
{
|
||||
|
|
@ -115,7 +116,7 @@ constexpr bool shift_fits(u128 value, unsigned shift) noexcept
|
|||
return shift < 128 && value <= (~u128{0} >> shift);
|
||||
}
|
||||
|
||||
/// 10^0 .. 10^19. Every ilog10 projection reads this one table.
|
||||
/// @brief 10^0 .. 10^19. Every ilog10 projection reads this one table.
|
||||
inline constexpr std::uint64_t pow10[] = {
|
||||
1ull,
|
||||
10ull,
|
||||
|
|
@ -159,7 +160,10 @@ inline bool magnitude_ge_pow10(u128 mag, int k, unsigned fractional_bits) noexce
|
|||
return mag * scale >= (u128{1} << fractional_bits);
|
||||
}
|
||||
|
||||
/// Smallest positive magnitude whose base-10 log is at least `k`.
|
||||
/// @brief Smallest positive magnitude whose base-10 log is at least `k`.
|
||||
/// @param k the `k`
|
||||
/// @param fractional_bits the number of fractional bits
|
||||
/// @return Smallest positive magnitude whose base-10 log is at least `k`
|
||||
HEDLEY_NO_THROW
|
||||
inline u128 first_magnitude_at_least_pow10(int k, unsigned fractional_bits) noexcept
|
||||
{
|
||||
|
|
@ -315,8 +319,8 @@ void push_pow2_cuts(std::vector<Raw> & cuts)
|
|||
detail::push_both_signs<Raw>(detail::u128{1} << k, cuts);
|
||||
}
|
||||
|
||||
/// floor(log2(|raw|)) - F, with -64 on the |x| <= 2^{-64} class (including 0).
|
||||
/// One exponent program; fractional precision only shifts the stored exponent.
|
||||
/// @brief floor(log2(|raw|)) - F, with -64 on the |x| <= 2^{-64} class (including 0).
|
||||
/// @details One exponent program; fractional precision only shifts the stored exponent.
|
||||
template <>
|
||||
struct exact_lut<exact_constant::ilogb>
|
||||
{
|
||||
|
|
@ -347,7 +351,7 @@ struct exact_lut<exact_constant::ilogb>
|
|||
}
|
||||
};
|
||||
|
||||
/// ceil(log2(|x|)). Same powers-of-two cuts as `ilogb`; exact powers keep the
|
||||
/// @brief ceil(log2(|x|)). Same powers-of-two cuts as `ilogb`; exact powers keep the
|
||||
/// floor exponent and every other magnitude steps up by one.
|
||||
template <>
|
||||
struct exact_lut<exact_constant::ceil_ilogb>
|
||||
|
|
@ -387,7 +391,7 @@ struct exact_lut<exact_constant::ceil_ilogb>
|
|||
}
|
||||
};
|
||||
|
||||
/// floor(log10(|x|)), with -19 on |x| <= 10^{-19}. Thresholds come from `pow10`.
|
||||
/// @brief floor(log10(|x|)), with -19 on |x| <= 10^{-19}. Thresholds come from `pow10`.
|
||||
template <>
|
||||
struct exact_lut<exact_constant::ilog10>
|
||||
{
|
||||
|
|
@ -424,8 +428,8 @@ struct exact_lut<exact_constant::ilog10>
|
|||
}
|
||||
};
|
||||
|
||||
/// 64-bit leading-zero count of trunc(x). Negatives are 0; a zero integer part is 64.
|
||||
/// Exponent k of the integer part maps to 63-k after a shift of `fractional_bits`.
|
||||
/// @brief 64-bit leading-zero count of trunc(x). Negatives are 0; a zero integer part is 64.
|
||||
/// @details Exponent k of the integer part maps to 63-k after a shift of `fractional_bits`.
|
||||
template <>
|
||||
struct exact_lut<exact_constant::clz>
|
||||
{
|
||||
|
|
@ -461,8 +465,8 @@ struct exact_lut<exact_constant::clz>
|
|||
}
|
||||
};
|
||||
|
||||
/// 64-bit redundant sign bits of trunc(x) toward zero.
|
||||
/// Positive q uses 62-floor(log2(q)); negative q uses 62-floor(log2(q-1)).
|
||||
/// @brief 64-bit redundant sign bits of trunc(x) toward zero.
|
||||
/// @details Positive q uses 62-floor(log2(q)); negative q uses 62-floor(log2(q-1)).
|
||||
template <>
|
||||
struct exact_lut<exact_constant::clrsb>
|
||||
{
|
||||
|
|
@ -564,7 +568,7 @@ constant_lut<Raw> make_exact_constant_lut(exact_constant which, unsigned fractio
|
|||
throw std::invalid_argument("unknown exact constant");
|
||||
}
|
||||
|
||||
/// Comparison against a public threshold. Two pieces; the cut sits on `bound`
|
||||
/// @brief Comparison against a public threshold. Two pieces; the cut sits on `bound`
|
||||
/// (`lt` / `geq`) or just after it (`leq` / `gt`).
|
||||
enum class threshold_cmp
|
||||
{
|
||||
|
|
@ -600,7 +604,12 @@ constant_lut<Raw> make_threshold_lut(Raw bound, threshold_cmp kind)
|
|||
[=](Raw raw) { return evaluate_threshold(raw, bound, kind); });
|
||||
}
|
||||
|
||||
/// `1` on the inclusive clip window `[low, high]`, `0` outside it.
|
||||
/// @brief `1` on the inclusive clip window `[low, high]`, `0` outside it.
|
||||
/// @tparam Raw underlying representation
|
||||
/// @param low the lower endpoint
|
||||
/// @param high the upper endpoint
|
||||
/// @return `1` on the inclusive clip window `[low, high]`, `0` outside it
|
||||
/// @throws std::invalid_argument if `low > high`
|
||||
template <typename Raw>
|
||||
constant_lut<Raw> make_interval_lut(Raw low, Raw high)
|
||||
{
|
||||
|
|
@ -614,13 +623,20 @@ constant_lut<Raw> make_interval_lut(Raw low, Raw high)
|
|||
[=](Raw raw) { return raw >= low && raw <= high ? std::int64_t{1} : std::int64_t{0}; });
|
||||
}
|
||||
|
||||
/// `floor(min(max(raw, low), high) / modulus)`, division toward -infinity.
|
||||
/// @brief `floor(min(max(raw, low), high) / modulus)`, division toward -infinity.
|
||||
///
|
||||
/// `modulus`, `low`, and `high` are in the same raw units as the domain, so
|
||||
/// one program covers every fractional precision: a mathematical step `M`
|
||||
/// with `F` fractional bits is the raw modulus `M << F`. The paper's
|
||||
/// `quot(M, T1, T2)` is this function. Piece count is about `(high-low)/modulus`;
|
||||
/// the build rejects windows that would need more than 2^16 pieces.
|
||||
/// @tparam Raw underlying representation
|
||||
/// @param raw the underlying integer
|
||||
/// @param modulus the public modulus
|
||||
/// @param low the lower endpoint
|
||||
/// @param high the upper endpoint
|
||||
/// @return `floor(min(max(raw, low), high) / modulus)`, division toward -infinity
|
||||
/// @throws std::invalid_argument if `modulus must be positive`
|
||||
template <typename Raw>
|
||||
std::int64_t evaluate_clipped_quotient(Raw raw, Raw modulus, Raw low, Raw high)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue