41# ifndef MODULAR_ARITHMETIC_H
42# define MODULAR_ARITHMETIC_H
45# include <type_traits>
67# if defined(__SIZEOF_INT128__)
79 if (
m - a <= a) a = a - (
m - a);
100 if (
m == 1)
return 0;
123 template <
typename T>
124 requires (std::is_integral_v<T>
and std::is_signed_v<T>)
136 y = x1 -
static_cast<T>(a / b) *
y1;
165 <<
"Modular inverse does not exist (" << a <<
" is 0 mod " <<
m <<
")";
189 <<
"Modular inverse does not exist (numbers " << a
190 <<
" and " <<
m <<
" are not coprime)";
195# if defined(__SIZEOF_INT128__)
256 detail::montgomery_ctx_unchecked(
const uint64_t mod)
noexcept;
282 for (
size_t i = 0; i < 6; ++i)
312 <<
"montgomery_ctx: modulus must be > 1";
314 <<
"montgomery_ctx: modulus " <<
mod <<
" must be odd";
315 return detail::montgomery_ctx_unchecked(mod);
323 template <u
int64_t Mod>
327 static_assert(
Mod > 1,
"montgomery_ctx_for_mod: modulus must be > 1");
328 static_assert((
Mod & 1ULL) == 1ULL,
329 "montgomery_ctx_for_mod: modulus must be odd");
330 return detail::montgomery_ctx_unchecked(
Mod);
376 return t64 >= ctx.mod() ?
t64 - ctx.mod() :
t64;
381 return static_cast<uint64_t>(t % ctx.mod());
411 return mont_mul(a % ctx.mod(), ctx.r2(), ctx);
445 result =
mont_mul(result, base, ctx);
469 <<
"crt: arrays must have the same size (got " <<
rem.size()
470 <<
" vs " << mod.size() <<
")";
472 const size_t n =
rem.size();
478 for (
size_t i = 0; i < n; ++i)
481 <<
"crt: all moduli must be > 1 (got " << mod[i] <<
" at index " << i <<
")";
484 <<
"crt: product of moduli overflows uint64_t at index " << i;
489 for (
size_t i = 0; i < n; ++i)
Exception handling system with formatted messages for Aleph-w.
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_invalid_argument_if(C)
Throws std::invalid_argument if condition holds.
Simple dynamic array with automatic resizing and functional operations.
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y1_function > > y1(const __gmp_expr< T, U > &expr)
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_exp_function > > exp(const __gmp_expr< T, U > &expr)
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
uint64_t mod_inv(const uint64_t a, const uint64_t m)
Modular Inverse.
T ext_gcd(T a, T b, T &x, T &y) noexcept
Extended Euclidean Algorithm.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::decay_t< typename HeadC::Item_Type > T
uint64_t mod_exp(uint64_t base, uint64_t exp, const uint64_t m)
Modular exponentiation.
uint64_t mod_mul(uint64_t a, uint64_t b, uint64_t m)
Safe 64-bit modular multiplication.
uint64_t crt(const Array< uint64_t > &rem, const Array< uint64_t > &mod)
Chinese Remainder Theorem (CRT).
double mod(double a, double b)
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)
Dynamic array container with automatic resizing.