57#ifndef TPL_POLYNOMIAL_H
58#define TPL_POLYNOMIAL_H
61#include <initializer_list>
79namespace polynomial_detail {
93 result = result * base;
100template <
typename Int>
101 requires std::is_integral_v<Int>
104 if constexpr (std::is_signed_v<Int>)
106 using Unsigned = std::make_unsigned_t<Int>;
109 return static_cast<uint64_t>(magnitude);
115template <
typename Int>
116 requires std::is_integral_v<Int>
122 if constexpr (std::is_signed_v<Int>)
134template <
typename Int>
135 requires std::is_integral_v<Int>
138 if constexpr (std::is_signed_v<Int>)
165template <
typename Coefficient =
double>
172 using Term = std::pair<size_t, Coefficient>;
184 if constexpr (std::is_floating_point_v<Coefficient>)
185 return Coefficient(128) * std::numeric_limits<Coefficient>::epsilon();
197 if constexpr (std::is_floating_point_v<Coefficient>)
198 return std::abs(c) <=
epsilon();
207 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
209 auto &p = it.get_curr();
230 return p !=
nullptr ? &p->second :
nullptr;
237 return p !=
nullptr ? &p->second :
nullptr;
284 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
286 auto &p = it.get_curr();
287 p.second = p.second * s;
310 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
312 auto &p = it.get_curr();
313 p.second = p.second / s;
329 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
331 const auto &p = it.get_curr();
335 for (
size_t i =
desc_terms.size(); i > 0; --i)
349 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
351 auto &p = it.get_curr();
494 const DynList<std::pair<Coefficient, Coefficient>> &points)
498 const size_t n = points.size();
505 points.for_each([&](
const std::pair<Coefficient, Coefficient> &pt)
512 for (
size_t i = 0; i < n; ++i)
513 for (
size_t j = i + 1; j < n; ++j)
516 for (
size_t order = 1; order < n; ++order)
517 for (
size_t i = n - 1; i >= order; --i)
527 for (
size_t i = 1; i < n; ++i)
556 return coeffs.max().first;
574 return coeffs.size() == 1;
600 return coeffs.max().second;
666 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
668 auto &p = it.get_curr();
729 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
731 auto &p = it.get_curr();
732 result.
coeffs[p.first] = -p.second;
754 for (
auto it = q.
coeffs.get_it(); it.has_curr(); it.next_ne())
756 auto &p = it.get_curr();
794 for (
auto it = q.
coeffs.get_it(); it.has_curr(); it.next_ne())
796 auto &p = it.get_curr();
837 for (
auto it1 =
outer->coeffs.get_it(); it1.has_curr(); it1.next_ne())
839 auto &
t1 = it1.get_curr();
840 for (
auto it2 = inner->
coeffs.get_it(); it2.has_curr(); it2.next_ne())
842 auto &
t2 = it2.get_curr();
862 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
864 auto &p = it.get_curr();
886 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
888 auto &p = it.get_curr();
891 result.
coeffs[p.first] = q;
929 while (
not r.is_zero())
937 <<
"divmod: inexact coefficient division (leading_coeff=" <<
r.leading_coeff()
938 <<
" / divisor_lc=" <<
d_lc <<
" = 0). "
939 <<
"For integral/non-field coefficients, use pseudo_divmod() instead.";
987 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
989 auto &p = it.get_curr();
994 result.
coeffs[p.first - 1] = dc;
1033 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1035 auto &p = it.get_curr();
1056 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1058 auto &p = it.get_curr();
1059 const size_t next_exp = p.first + 1;
1253 while (
not r.is_zero())
1264 r.scale_inplace(
lc_d);
1268 r.add_scaled_shifted(d, -
lc_r,
exp);
1308 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1310 auto &p = it.get_curr();
1311 result.
coeffs[d - p.first] = p.second;
1323 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1325 auto &p = it.get_curr();
1326 result.
coeffs[p.first] = (p.first % 2 == 0) ? p.second : -p.second;
1356 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1358 auto &p = it.get_curr();
1359 result.
coeffs[p.first +
k] = p.second;
1376 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1378 auto &p = it.get_curr();
1380 result.
coeffs[p.first -
k] = p.second;
1395 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1397 auto &p = it.get_curr();
1399 result.
coeffs[p.first] = p.second;
1416 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1418 auto &p = it.get_curr();
1419 result(p.first) = p.second;
1462 const size_t d =
degree();
1464 if constexpr (std::is_floating_point_v<Coefficient>)
1467 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1469 auto &p = it.get_curr();
1481 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1483 auto &p = it.get_curr();
1486 const long double ratio =
1487 std::fabs(
static_cast<long double>(p.second) /
static_cast<long double>(
lc));
1512 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1514 auto &p = it.get_curr();
1516 if constexpr (std::is_floating_point_v<Coefficient>)
1522 if constexpr (std::is_floating_point_v<Coefficient>)
1625 size_t count = sa > sb ? sa - sb : 0;
1676 <<
"bisect_root: f(a) and f(b) must have opposite signs";
1678 for (
size_t i = 0; i <
max_iter; ++i)
1716 for (
size_t i = 0; i <
max_iter; ++i)
1725 if constexpr (std::is_floating_point_v<Coefficient>)
1727 if (std::abs(delta) < tol)
1754 auto it1 =
coeffs.get_it();
1755 auto it2 = q.coeffs.get_it();
1757 while (it1.has_curr()
and it2.has_curr())
1759 auto &lhs = it1.get_curr();
1760 auto &rhs = it2.get_curr();
1762 if (lhs.first == rhs.first)
1771 if (lhs.first < rhs.first)
1784 while (it1.has_curr())
1791 while (it2.has_curr())
1804 return not (*
this == q);
1818 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1820 auto &p = it.get_curr();
1821 op(p.first, p.second);
1829 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1831 auto &p = it.get_curr();
1832 result.
append({p.first, p.second});
1865 std::ostringstream
oss;
1964 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1966 auto &p = it.get_curr();
1967 result = std::gcd(result, p.second);
2003 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
2005 auto &p = it.get_curr();
2006 result.
coeffs.insert(p.first, p.second / c);
2029 requires std::is_integral_v<Coefficient>
2039 while (
not b.is_zero())
2043 b =
rem.is_zero() ?
rem :
rem.primitive_part();
2046 return a.primitive_part();
2078 size_t multiplicity = 1;
2080 while (
not h.is_constant())
2086 if (
not w.is_constant())
2111 requires std::is_integral_v<Coefficient>
2114 if (b.is_constant())
2118 for (
auto it = a.coeffs.get_it(); it.has_curr(); it.next_ne())
2120 auto &p = it.get_curr();
2122 <<
"_integer_exact_quot: inexact constant division for coefficient " << p.second
2123 <<
" and divisor " << d;
2124 r.
coeffs.insert(p.first, p.second / d);
2128 auto [q,
rem] = a.pseudo_divmod(b);
2130 <<
"_integer_exact_quot: divisor does not divide dividend exactly";
2131 return q.is_zero() ? q : q.primitive_part();
2135 requires std::is_integral_v<Coefficient>
2150 requires std::is_integral_v<Coefficient>
2152 if (mod == 0
or mod == 1)
2161 result = (result +
term) % mod;
2169 requires std::is_integral_v<Coefficient>
2172 <<
"divide_by_monic_linear_mod: constant polynomial is not divisible by x - r";
2179 for (
size_t idx =
degree; idx-- > 0;)
2187 <<
"divide_by_monic_linear_mod: x - r does not divide polynomial modulo p";
2198 requires std::is_integral_v<Coefficient>
2228 requires std::is_integral_v<Coefficient>
2233 if (
not r.is_zero())
2238 catch (
const std::domain_error &)
2248 requires std::is_integral_v<Coefficient>
2250 if (f.is_zero()
or f.degree() == 0)
2256 const size_t degree = f.degree();
2287 requires std::is_integral_v<Coefficient>
2289 if (f.is_zero()
or f.degree() == 0)
2323 factor.set_coeff(0, -num);
2324 factor.set_coeff(1,
den);
2345 requires std::is_integral_v<Coefficient>
2347 if (f.is_zero()
or f.degree() < 2)
2358 const double abs_lc = std::abs(
static_cast<double>(f.leading_coeff()));
2360 for (
auto it = f.coeffs.get_it(); it.has_curr(); it.next_ne())
2362 const auto &
term = it.get_curr();
2363 if (
term.first == f.degree())
2365 if (
const double ratio = std::abs(
static_cast<double>(
term.second)) /
abs_lc;
2376 static_cast<int64_t>(std::ceil(2.0 * std::abs(
static_cast<double>(a)) *
root_bound));
2426 requires std::is_integral_v<Coefficient>
2428 if (f.is_zero()
or f.degree() < 3)
2439 const double abs_lc = std::abs(
static_cast<double>(f.leading_coeff()));
2441 for (
auto it = f.coeffs.get_it(); it.has_curr(); it.next_ne())
2443 const auto &
term = it.get_curr();
2444 const double coeff_abs = std::abs(
static_cast<double>(
term.second));
2523 requires std::is_integral_v<Coefficient>
2529 if (f.is_zero()
or f.is_constant())
2550 result.
append(remaining);
2572 const size_t d =
degree();
2577 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
2579 auto &p = it.get_curr();
2585 const auto d_real =
static_cast<double>(d);
2617 requires std::is_integral_v<Coefficient>
2620 ah_domain_error_if(levels == 0) <<
"hensel_lift: levels must be >= 1, got " << levels;
2622 <<
"hensel_lift: levels must be <= 30 to avoid overflow, got " << levels;
2627 const size_t target_steps =
static_cast<size_t>(1) << levels;
2632 <<
"hensel_lift: overflow computing " << name <<
" (" << lhs <<
" * " << rhs <<
")";
2641 <<
"hensel_lift: target modulus " <<
target_u64 <<
" does not fit in coefficient type";
2646 for (
auto it =
factors.get_it(); it.has_curr(); it.next_ne())
2674#if defined(_MSC_VER) or defined(_WIN32)
2694 polynomial_detail::centered_from_mod_u64<Coefficient>(
2772 for (
auto it =
sfd_terms.get_it(); it.has_curr(); it.next_ne())
2779 while (remaining.
degree() > 0)
2789 while (remaining.
degree() > 1)
2799 while (remaining.
degree() > 2)
2825 for (
auto jt =
lifted.get_it();
jt.has_curr();
jt.next_ne())
2864template <
typename C>
2871template <
typename C>
2878template <
typename C>
2885template <
typename C>
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
size_t size_t int32_t value
size_t size_t int32_t * out
Simple dynamic array with automatic resizing and functional operations.
void putn(const size_t n)
Reserve n additional logical slots in the array without value-initializing them.
Doubly-linked list (defined in tpl_dynList.H).
T & append(const T &item)
Generic key-value map implemented on top of a binary search tree.
Univariate polynomial over a generic coefficient ring.
Gen_Polynomial nth_derivative(size_t n) const
-th derivative .
std::pair< size_t, Coefficient > Term
static Gen_Polynomial divide_by_monic_linear_mod(const Gen_Polynomial &f, Coefficient root, Coefficient mod)
Gen_Polynomial(const DynList< std::pair< size_t, Coefficient > > &term_list)
Sparse construction from a list of (exponent, coefficient) pairs.
DynList< Gen_Polynomial > sturm_chain() const
Sturm sequence of this polynomial.
bool is_monic() const noexcept
True if leading coefficient equals 1.
Coefficient horner_eval(const Coefficient &x) const
Evaluate using gap-aware Horner's method.
Gen_Polynomial negate_arg() const
Argument negation: .
static Gen_Polynomial zero()
The zero polynomial.
void for_each_term(Op &&op) const
Iterate over non-zero terms in ascending exponent order.
static Gen_Polynomial one()
The constant polynomial 1.
Coefficient content() const
Content: GCD of all coefficients.
void divide_scalar_inplace(const Coefficient &s)
Divide every coefficient in place by a scalar.
size_t num_terms() const noexcept
Number of non-zero terms.
void add_scaled_shifted(const Gen_Polynomial &src, const Coefficient &scale, size_t shift=0)
Add scale times src shifted by shift to this polynomial.
DynList< size_t > exponents() const
All exponents with non-zero coefficients (sorted ascending).
void add_to_coeff(size_t exp, const Coefficient &delta)
Add a delta to one coefficient, erasing the term if it cancels.
Coefficient * coeff_ptr(size_t exp) noexcept
Pointer to stored coefficient, or null if absent.
Gen_Polynomial operator/(const Coefficient &s) const
Divide by a scalar.
static DynList< Gen_Polynomial > factor_mod_p(const Gen_Polynomial &f, Coefficient p)
Factorization over integers mod p (trial method).
Gen_Polynomial primitive_part() const
Primitive part: polynomial divided by its content.
Coefficient cauchy_bound() const
Cauchy upper bound on absolute value of roots.
Gen_Polynomial & operator-=(const Gen_Polynomial &q)
In-place subtraction.
static bool try_extract_rational_linear_factor(const Gen_Polynomial &f, Gen_Polynomial &factor, Gen_Polynomial "ient)
void remove_zeros()
Remove all entries whose coefficient is (approximately) zero.
Coefficient eval(const Coefficient &x) const
Evaluate with adaptive strategy.
Coefficient coeff_at(size_t exp) const
Read coefficient at exponent (0 if absent).
Gen_Polynomial & operator+=(const Gen_Polynomial &q)
In-place addition.
Gen_Polynomial truncate(size_t n) const
Truncate to degree less than n.
std::string to_str(const std::string &var="x") const
Human-readable string representation.
static Gen_Polynomial from_roots(const DynList< Coefficient > &roots)
Build polynomial from its roots: .
static Gen_Polynomial interpolate(const DynList< std::pair< Coefficient, Coefficient > > &points)
Polynomial interpolation through a set of points.
Gen_Polynomial operator*(const Gen_Polynomial &q) const
Polynomial multiplication.
bool is_constant() const noexcept
True if constant or zero.
size_t count_real_roots(const Coefficient &a, const Coefficient &b) const
Count distinct real roots in via Sturm's theorem.
void scale_inplace(const Coefficient &s)
Multiply every coefficient in place by a scalar.
Gen_Polynomial pow(size_t n) const
Exponentiation by repeated squaring.
Coefficient operator[](size_t exp) const
Coefficient at exponent exp (0 if absent).
DynList< SfdTerm > yun_sfd() const
Yun's square-free decomposition (SFD).
size_t sign_variations() const
Count sign changes in the coefficient sequence.
bool is_monomial() const noexcept
True if exactly one non-zero term.
bool has_term(size_t exp) const noexcept
True if there is a non-zero coefficient at exp.
const Coefficient * coeff_ptr(size_t exp) const noexcept
Pointer to stored coefficient, or null if absent.
static Xgcd_Result xgcd(Gen_Polynomial a, Gen_Polynomial b)
static Gen_Polynomial integer_gcd(Gen_Polynomial a, Gen_Polynomial b)
Polynomial GCD over integers (Euclidean algorithm with primitive parts).
double mignotte_bound() const
Mignotte bound on integer roots.
Gen_Polynomial compose(const Gen_Polynomial &q) const
Composition .
Coefficient sparse_eval(const Coefficient &x) const
Evaluate using sparse evaluation.
static constexpr Coefficient epsilon() noexcept
Tolerance threshold for floating-point zero detection.
Coefficient definite_integral(const Coefficient &a, const Coefficient &b) const
Definite integral .
bool is_zero() const noexcept
True if this is the zero polynomial.
static bool try_exact_candidate_division(const Gen_Polynomial &f, const Gen_Polynomial &candidate, Gen_Polynomial "ient)
Try exact division but treat inexact integral division as a rejected candidate.
Gen_Polynomial operator+(const Gen_Polynomial &q) const
Polynomial addition.
size_t count_all_real_roots() const
Total number of distinct real roots.
static size_t sturm_sign_changes(const DynList< Gen_Polynomial > &chain, const Coefficient &x)
Count sign changes in a Sturm chain at a given point.
static Gen_Polynomial _integer_exact_quot(const Gen_Polynomial &a, const Gen_Polynomial &b)
Integer-safe exact quotient using pseudo-division.
Gen_Polynomial(const DynList< Coefficient > &l)
Dense construction from DynList.
Coefficient bisect_root(Coefficient a, Coefficient b, Coefficient tol=Coefficient(1e-12), size_t max_iter=200) const
Find a root by bisection in .
void for_each_term_desc(Op &&op) const
Iterate over non-zero terms in descending exponent order.
Gen_Polynomial(const Coefficient &c)
Constant polynomial .
size_t degree() const noexcept
Degree of the polynomial.
DynList< SfdTerm > factorize() const
Main factorization over integers.
Gen_Polynomial shift_down(size_t k) const
Divide by (shift exponents down).
static DynList< Gen_Polynomial > hensel_lift(const Gen_Polynomial &f, DynList< Gen_Polynomial > factors, Coefficient p, size_t levels)
Hensel lifting of modular factors.
DynList< std::pair< size_t, Coefficient > > terms_list() const
All non-zero terms as a sorted list of (exponent, coefficient).
std::pair< Gen_Polynomial, Gen_Polynomial > divmod(const Gen_Polynomial &d) const
Polynomial long division: returns (quotient, remainder).
static bool try_extract_primitive_quadratic_factor(const Gen_Polynomial &f, Gen_Polynomial &factor, Gen_Polynomial "ient)
Try to extract an exact primitive quadratic factor over .
Gen_Polynomial & operator/=(const Coefficient &s)
In-place scalar division.
static Gen_Polynomial lcm(const Gen_Polynomial &a, const Gen_Polynomial &b)
Least common multiple.
static uint64_t eval_mod_u64(const Gen_Polynomial &f, uint64_t x, uint64_t mod)
Array< Coefficient > to_dense() const
Dense coefficient vector.
Gen_Polynomial shift_up(size_t k) const
Multiply by (shift exponents up).
DynMapTree< size_t, Coefficient > coeffs
Gen_Polynomial shift(const Coefficient &k) const
Taylor shift: .
static Gen_Polynomial gcd(Gen_Polynomial a, Gen_Polynomial b)
Greatest common divisor (Euclidean algorithm).
Gen_Polynomial square_free() const
Square-free part: .
Gen_Polynomial derivative() const
Formal derivative .
DynList< Coefficient > multi_eval(const DynList< Coefficient > &points) const
Evaluate at multiple points.
std::pair< Gen_Polynomial, Gen_Polynomial > pseudo_divmod(const Gen_Polynomial &d) const
Pseudo-division for non-field coefficient types.
Gen_Polynomial & operator*=(const Gen_Polynomial &q)
In-place multiplication.
Gen_Polynomial integral(const Coefficient &C=Coefficient{}) const
Formal indefinite integral with constant of integration.
Gen_Polynomial operator-() const
Unary negation.
static bool coeff_is_zero(const Coefficient &c) noexcept
Test whether a coefficient is (approximately) zero.
static Gen_Polynomial x_to(size_t n)
The monomial .
static bool try_divide_by_linear_factor(const Gen_Polynomial &f, Coefficient a, Coefficient b, Gen_Polynomial "ient)
bool operator!=(const Gen_Polynomial &q) const noexcept
Inequality comparison.
Gen_Polynomial()=default
Default constructor: the zero polynomial.
Gen_Polynomial multiply_by_monic_linear(const Coefficient &c) const
Specialized multiplication by a monic linear factor .
static bool try_extract_primitive_cubic_factor(const Gen_Polynomial &f, Gen_Polynomial &factor, Gen_Polynomial "ient)
Try to extract an exact primitive cubic factor over .
bool operator==(const Gen_Polynomial &q) const noexcept
Equality comparison.
Coefficient leading_coeff() const noexcept
Leading coefficient (of the highest-degree term).
Gen_Polynomial to_monic() const
Make monic: divide by leading coefficient.
Gen_Polynomial & operator%=(const Gen_Polynomial &d)
In-place polynomial remainder.
Coefficient newton_root(Coefficient x0, Coefficient tol=Coefficient(1e-12), size_t max_iter=100) const
Find a root by Newton-Raphson iteration.
Gen_Polynomial(std::initializer_list< Coefficient > il)
Dense construction from initializer list.
Gen_Polynomial operator%(const Gen_Polynomial &d) const
Polynomial remainder.
Coefficient operator()(const Coefficient &x) const
Syntactic sugar: p(x) calls eval.
static Gen_Polynomial reduce_coeffs_mod(const Gen_Polynomial &f, Coefficient mod)
void set_coeff(size_t exp, const Coefficient &c)
Set coefficient at exponent; removes entry if zero.
Gen_Polynomial reverse() const
Reciprocal polynomial: .
DynList< Coefficient > coefficients() const
All non-zero coefficients in ascending exponent order.
Gen_Polynomial(const Coefficient &c, size_t exp)
Monomial .
static DynList< Coefficient > positive_divisors(Coefficient value)
Coefficient get_coeff(size_t exp) const noexcept
Coefficient accessor (read-only at exponent).
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_exp_function > > exp(const __gmp_expr< T, U > &expr)
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Singly linked list implementations with head-tail access.
Safe modular arithmetic, extended Euclidean algorithm, and Chinese Remainder Theorem.
C power(C base, size_t exp)
Fast exponentiation by squaring.
uint64_t normalize_mod_u64(Int value, const uint64_t modulus) noexcept
uint64_t abs_to_u64(Int value) noexcept
Int centered_from_mod_u64(const uint64_t value, const uint64_t modulus) noexcept
Main namespace for Aleph-w library functions.
Gen_MultiPolynomial< C, M > operator+(const C &s, const Gen_MultiPolynomial< C, M > &p)
Scalar + polynomial (commutative).
uint64_t mod_inv(const uint64_t a, const uint64_t m)
Modular Inverse.
and
Check uniqueness with explicit hash + equality functors.
Gen_MultiPolynomial< C, M > operator-(const C &s, const Gen_MultiPolynomial< C, M > &p)
Scalar - polynomial.
Matrix< Trow, Tcol, NumType > operator*(const NumType &scalar, const Matrix< Trow, Tcol, NumType > &m)
Scalar-matrix multiplication (scalar * matrix).
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.
void next()
Advance all underlying iterators (bounds-checked).
std::ostream & operator<<(std::ostream &osObject, const Field< T > &rightOp)
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Square-free decomposition term: factor and multiplicity.
Extended GCD: computes g, s, t such that .
Gen_Polynomial t
Bezout coefficient for the second argument.
Gen_Polynomial s
Bezout coefficient for the first argument.
Gen_Polynomial g
Greatest common divisor (monic).
Aleph::DynList< T > keys() const
Dynamic array container with automatic resizing.
Dynamic key-value map based on balanced binary search trees.