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
|
|
@ -13,6 +13,7 @@
|
|||
#define LIBDPF_INCLUDE_DPF_MODINT_HPP__
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
|
|
@ -32,6 +33,7 @@ namespace dpf
|
|||
{
|
||||
|
||||
/// @brief represents an unsigned integer modulo `2^Nbits` for small values of `Nbits`
|
||||
/// @tparam Nbits width in bits
|
||||
template <std::size_t Nbits>
|
||||
class modint
|
||||
{
|
||||
|
|
@ -40,6 +42,7 @@ class modint
|
|||
using integral_type = dpf::utils::nonvoid_integral_type_from_bitlength_t<Nbits>;
|
||||
|
||||
static constexpr std::size_t num_bits = Nbits;
|
||||
static constexpr bool dpf_modint = true;
|
||||
|
||||
/// @brief construct the `modint`
|
||||
/// @{
|
||||
|
|
@ -78,6 +81,7 @@ class modint
|
|||
/// @}
|
||||
|
||||
/// @brief assign the `modint`
|
||||
/// @return `*this`
|
||||
/// @{
|
||||
|
||||
/// @brief value assignment
|
||||
|
|
@ -110,10 +114,11 @@ class modint
|
|||
~modint() = default;
|
||||
|
||||
/// @brief addition operator
|
||||
/// @param rhs the other addend
|
||||
/// @return the sum
|
||||
/// @{
|
||||
|
||||
/// @details Performs addition with an `integral_type`.
|
||||
/// @param rhs the other addend
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -123,7 +128,6 @@ class modint
|
|||
}
|
||||
|
||||
/// @details Performs addition with another `modint`.
|
||||
/// @param rhs the other addend
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -135,10 +139,11 @@ class modint
|
|||
/// @}
|
||||
|
||||
/// @brief addition-assignment operator
|
||||
/// @param rhs the other addend
|
||||
/// @return `*this`
|
||||
/// @{
|
||||
|
||||
/// @details Adds an `integral_type` to this `modint`.
|
||||
/// @param rhs the other addend
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint & operator+=(integral_type rhs) noexcept
|
||||
|
|
@ -148,7 +153,6 @@ class modint
|
|||
}
|
||||
|
||||
/// @details Adds another `modint` to this one.
|
||||
/// @param rhs the other addend
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint & operator+=(modint rhs) noexcept
|
||||
|
|
@ -164,6 +168,7 @@ class modint
|
|||
/// @brief pre-increment operator
|
||||
/// @details Increments this `modint` and returns a reference to the
|
||||
/// result.
|
||||
/// @return `*this`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint & operator++() noexcept
|
||||
|
|
@ -174,6 +179,7 @@ class modint
|
|||
/// @brief post-increment operator
|
||||
/// @details Creates a copy of this `modint`, and then increments this
|
||||
/// `modint` and returns the copy from before the increment.
|
||||
/// @return `*this`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint operator++(int) noexcept
|
||||
|
|
@ -189,6 +195,7 @@ class modint
|
|||
/// @details Returns the additive inverse modulo `2^Nbits` (two's
|
||||
/// complement on the underlying word). Required by
|
||||
/// `grotto::for_each_offset`, which computes `-offset`.
|
||||
/// @return unary negation
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -198,10 +205,11 @@ class modint
|
|||
}
|
||||
|
||||
/// @brief subtraction operator
|
||||
/// @param rhs the subtrahend
|
||||
/// @return the difference
|
||||
/// @{
|
||||
|
||||
/// @details Performs subtraction by an `integral_type`.
|
||||
/// @param rhs the subtrahend
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -211,7 +219,6 @@ class modint
|
|||
}
|
||||
|
||||
/// @details Performs subtraction by another `modint`.
|
||||
/// @param rhs the subtrahend
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -223,10 +230,11 @@ class modint
|
|||
/// @}
|
||||
|
||||
/// @brief subtraction-assignment operator
|
||||
/// @param rhs the subtrahend
|
||||
/// @return `*this`
|
||||
/// @{
|
||||
|
||||
/// @details Subtracts an `integral_type` from this `modint`.
|
||||
/// @param rhs the subtrahend
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint & operator-=(integral_type rhs) noexcept
|
||||
|
|
@ -236,7 +244,6 @@ class modint
|
|||
}
|
||||
|
||||
/// @details Subtracts another `modint` from this one.
|
||||
/// @param rhs the subtrahend
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint & operator-=(modint rhs) noexcept
|
||||
|
|
@ -252,6 +259,7 @@ class modint
|
|||
/// @brief pre-decrement operator
|
||||
/// @details Decrements this `modint` and returns a reference to the
|
||||
/// result.
|
||||
/// @return `*this`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint & operator--() noexcept
|
||||
|
|
@ -262,6 +270,7 @@ class modint
|
|||
/// @brief post-decrement operator
|
||||
/// @details Creates a copy of this `modint`, and then decrements this
|
||||
/// `modint` and returns the copy from before the decrement.
|
||||
/// @return `*this`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint operator--(int) noexcept
|
||||
|
|
@ -278,6 +287,7 @@ class modint
|
|||
/// one by `shift_amount` bits to the left. The value of `a<<b`
|
||||
/// is therefore a `modint` congruent to `a * 2^b` modulo `2^Nbits`.
|
||||
/// @param shift_amount the number of bits to shift by
|
||||
/// @return bitwise-left-shift operator
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -295,6 +305,7 @@ class modint
|
|||
/// and returns a reference to the result. Upon invoking `a<<=b`,
|
||||
/// `a` is congruent to `a * 2^b` modulo `2^Nbits`.
|
||||
/// @param shift_amount the number of bits to shift by
|
||||
/// @return `*this`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint & operator<<=(std::size_t shift_amount) noexcept
|
||||
|
|
@ -311,6 +322,7 @@ class modint
|
|||
/// one by `shift_amount` bits to the right. The value of `a>>b`
|
||||
/// is therefore a `modint` equal to the integer part of `a/2^b`.
|
||||
/// @param shift_amount the number of bits to shift by
|
||||
/// @return bitwise-right-shift operator
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -338,6 +350,8 @@ class modint
|
|||
}
|
||||
|
||||
/// @brief Integer division of the reduced values.
|
||||
/// @param rhs the right-hand operand
|
||||
/// @return Integer division of the reduced values
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -364,10 +378,11 @@ class modint
|
|||
}
|
||||
|
||||
/// @brief multiplication operator
|
||||
/// @param rhs the other multiplicand
|
||||
/// @return the product
|
||||
/// @{
|
||||
|
||||
/// @brief Multiplies this `modint` with an `integral_type`.
|
||||
/// @param rhs the other multiplicand
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -377,7 +392,6 @@ class modint
|
|||
}
|
||||
|
||||
/// @brief Multiplies another `modint` with this one.
|
||||
/// @param rhs the other multiplicand
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -389,10 +403,11 @@ class modint
|
|||
/// @}
|
||||
|
||||
/// @brief multiplication-assignment operator
|
||||
/// @param rhs the other multiplicand
|
||||
/// @return `*this`
|
||||
/// @{
|
||||
|
||||
/// @details Multiplies an `integral_type` into this `modint`.
|
||||
/// @param rhs the other multiplicand
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint & operator*=(integral_type rhs) noexcept
|
||||
|
|
@ -402,7 +417,6 @@ class modint
|
|||
}
|
||||
|
||||
/// @details Multiplies another `modint` into this one.
|
||||
/// @param rhs the other multiplicand
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
constexpr modint & operator*=(modint rhs) noexcept
|
||||
|
|
@ -532,6 +546,7 @@ class modint
|
|||
}
|
||||
|
||||
/// @brief convert this `modint` to the equivalent `integeral_type`
|
||||
/// @return the returned `operator`
|
||||
HEDLEY_PURE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -572,7 +587,44 @@ class modint
|
|||
operator<<(std::basic_ostream<CharT, Traits> & os,
|
||||
const modint & i)
|
||||
{
|
||||
return os << i.reduced_value();
|
||||
const auto raw = i.reduced_value();
|
||||
using word = std::remove_cv_t<std::decay_t<decltype(raw)>>;
|
||||
if constexpr (std::is_same_v<word, unsigned __int128>
|
||||
|| std::is_same_v<word, __int128>)
|
||||
{
|
||||
if (raw == 0)
|
||||
return os << CharT('0');
|
||||
CharT buf[40];
|
||||
int n = 0;
|
||||
auto v = raw;
|
||||
while (v != 0)
|
||||
{
|
||||
buf[n++] = static_cast<CharT>('0' + static_cast<int>(v % 10));
|
||||
v /= 10;
|
||||
}
|
||||
while (n > 0)
|
||||
os << buf[--n];
|
||||
return os;
|
||||
}
|
||||
else if constexpr (std::is_integral_v<word>)
|
||||
return os << raw;
|
||||
else
|
||||
{
|
||||
unsigned char bytes[sizeof(word)];
|
||||
std::memcpy(bytes, &raw, sizeof(word));
|
||||
os << "0x";
|
||||
bool started = false;
|
||||
constexpr char hex[] = "0123456789abcdef";
|
||||
for (int b = static_cast<int>(sizeof(word)) - 1; b >= 0; --b)
|
||||
{
|
||||
if (!started && bytes[static_cast<std::size_t>(b)] == 0 && b != 0)
|
||||
continue;
|
||||
started = true;
|
||||
const auto byte = bytes[static_cast<std::size_t>(b)];
|
||||
os << hex[byte >> 4] << hex[byte & 0x0f];
|
||||
}
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharT,
|
||||
|
|
@ -615,8 +667,10 @@ class modint
|
|||
};
|
||||
|
||||
/// @brief Multiplies a `modint<Nbits>` with an `modint::integral_type`.
|
||||
/// @tparam Nbits width in bits
|
||||
/// @param lhs the `integral_type` multiplicand
|
||||
/// @param rhs the `modint` multiplicand
|
||||
/// @return Multiplies a `modint<Nbits>` with an `modint::integral_type`
|
||||
template <std::size_t Nbits>
|
||||
HEDLEY_CONST
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -628,9 +682,13 @@ constexpr modint<Nbits> operator*(typename modint<Nbits>::integral_type lhs,
|
|||
}
|
||||
|
||||
/// @brief Compare two `modint<Nbits>`s as if they were regular integers
|
||||
/// @tparam Nbits width in bits
|
||||
/// @param lhs the left-hand operand
|
||||
/// @param rhs the right-hand operand
|
||||
/// @{
|
||||
|
||||
/// @brief less-than operator
|
||||
/// @return `true` when `lhs < rhs`
|
||||
template <std::size_t Nbits>
|
||||
HEDLEY_CONST
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -642,6 +700,7 @@ constexpr bool operator<(modint<Nbits> lhs, modint<Nbits> rhs) noexcept
|
|||
}
|
||||
|
||||
/// @brief less-than-or-equal-to operator
|
||||
/// @return `true` when `lhs <= rhs`
|
||||
template <std::size_t Nbits>
|
||||
HEDLEY_CONST
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -653,6 +712,7 @@ constexpr bool operator<=(modint<Nbits> lhs, modint<Nbits> rhs) noexcept
|
|||
}
|
||||
|
||||
/// @brief greater-than operator
|
||||
/// @return `true` when `lhs > rhs`
|
||||
template <std::size_t Nbits>
|
||||
HEDLEY_CONST
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -664,6 +724,7 @@ constexpr bool operator>(modint<Nbits> lhs, modint<Nbits> rhs) noexcept
|
|||
}
|
||||
|
||||
/// @brief greater-than-or-equal-to operator
|
||||
/// @return `true` when `lhs >= rhs`
|
||||
template <std::size_t Nbits>
|
||||
HEDLEY_CONST
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -675,6 +736,7 @@ constexpr bool operator>=(modint<Nbits> lhs, modint<Nbits> rhs) noexcept
|
|||
}
|
||||
|
||||
/// @brief equality operator
|
||||
/// @return `true` when `lhs == rhs`
|
||||
template <std::size_t Nbits>
|
||||
HEDLEY_CONST
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -686,6 +748,7 @@ constexpr bool operator==(modint<Nbits> lhs, modint<Nbits> rhs) noexcept
|
|||
}
|
||||
|
||||
/// @brief inequality operator
|
||||
/// @return `true` when `lhs != rhs`
|
||||
template <std::size_t Nbits>
|
||||
HEDLEY_CONST
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -1358,6 +1421,7 @@ namespace std
|
|||
/// @{
|
||||
|
||||
/// @details specializes `std::numeric_limits` for `dpf::modint<Nbits>`
|
||||
/// @tparam Nbits width in bits
|
||||
template<std::size_t Nbits>
|
||||
class numeric_limits<dpf::modint<Nbits>>
|
||||
{
|
||||
|
|
@ -1409,18 +1473,21 @@ class numeric_limits<dpf::modint<Nbits>>
|
|||
};
|
||||
|
||||
/// @details specializes `std::numeric_limits` for `dpf::modint<Nbits> const`
|
||||
/// @tparam Nbits width in bits
|
||||
template<std::size_t Nbits>
|
||||
class numeric_limits<dpf::modint<Nbits> const>
|
||||
: public numeric_limits<dpf::modint<Nbits>> {};
|
||||
|
||||
/// @details specializes `std::numeric_limits` for
|
||||
/// `dpf::modint<Nbits> volatile`
|
||||
/// @brief `dpf::modint<Nbits> volatile`
|
||||
/// @tparam Nbits width in bits
|
||||
template<std::size_t Nbits>
|
||||
class numeric_limits<dpf::modint<Nbits> volatile>
|
||||
: public numeric_limits<dpf::modint<Nbits>> {};
|
||||
|
||||
/// @details specializes `std::numeric_limits` for
|
||||
/// `dpf::modint<Nbits> const volatile`
|
||||
/// @brief `dpf::modint<Nbits> const volatile`
|
||||
/// @tparam Nbits width in bits
|
||||
template<std::size_t Nbits>
|
||||
class numeric_limits<dpf::modint<Nbits> const volatile>
|
||||
: public numeric_limits<dpf::modint<Nbits>> {};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue