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);
112 return static_cast<uint64_t>(value);
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;
1254 while (
not r.is_zero())
1265 r.scale_inplace(
lc_d);
1269 r.add_scaled_shifted(d, -
lc_r,
exp);
1309 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1311 auto &p = it.get_curr();
1312 result.
coeffs[d - p.first] = p.second;
1324 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1326 auto &p = it.get_curr();
1327 result.
coeffs[p.first] = (p.first % 2 == 0) ? p.second : -p.second;
1357 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1359 auto &p = it.get_curr();
1360 result.
coeffs[p.first +
k] = p.second;
1377 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1379 auto &p = it.get_curr();
1381 result.
coeffs[p.first -
k] = p.second;
1396 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1398 auto &p = it.get_curr();
1400 result.
coeffs[p.first] = p.second;
1417 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1419 auto &p = it.get_curr();
1420 result(p.first) = p.second;
1463 const size_t d =
degree();
1465 if constexpr (std::is_floating_point_v<Coefficient>)
1468 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1470 auto &p = it.get_curr();
1482 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1484 auto &p = it.get_curr();
1487 const long double ratio
1488 = std::fabs(
static_cast<long double>(p.second) /
static_cast<long double>(
lc));
1513 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1515 auto &p = it.get_curr();
1517 if constexpr (std::is_floating_point_v<Coefficient>)
1523 if constexpr (std::is_floating_point_v<Coefficient>)
1626 size_t count = sa > sb ? sa - sb : 0;
1677 <<
"bisect_root: f(a) and f(b) must have opposite signs";
1679 for (
size_t i = 0; i <
max_iter; ++i)
1717 for (
size_t i = 0; i <
max_iter; ++i)
1726 if constexpr (std::is_floating_point_v<Coefficient>)
1728 if (std::abs(delta) < tol)
1755 auto it1 =
coeffs.get_it();
1756 auto it2 = q.coeffs.get_it();
1758 while (it1.has_curr()
and it2.has_curr())
1760 auto &
lhs = it1.get_curr();
1761 auto &
rhs = it2.get_curr();
1763 if (
lhs.first ==
rhs.first)
1772 if (
lhs.first <
rhs.first)
1785 while (it1.has_curr())
1792 while (it2.has_curr())
1805 return not(*
this == q);
1819 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1821 auto &p = it.get_curr();
1822 op(p.first, p.second);
1830 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1832 auto &p = it.get_curr();
1833 result.
append({p.first, p.second});
1866 std::ostringstream
oss;
1965 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1967 auto &p = it.get_curr();
1968 result = std::gcd(result, p.second);
2004 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
2006 auto &p = it.get_curr();
2007 result.
coeffs.insert(p.first, p.second / c);
2030 requires std::is_integral_v<Coefficient>
2040 while (
not b.is_zero())
2044 b =
rem.is_zero() ?
rem :
rem.primitive_part();
2047 return a.primitive_part();
2079 size_t multiplicity = 1;
2081 while (
not h.is_constant())
2087 if (
not w.is_constant())
2112 requires std::is_integral_v<Coefficient>
2115 if (b.is_constant())
2119 for (
auto it = a.coeffs.get_it(); it.has_curr(); it.next_ne())
2121 auto &p = it.get_curr();
2123 <<
"_integer_exact_quot: inexact constant division for coefficient "
2124 << p.second <<
" and divisor " << d;
2125 r.
coeffs.insert(p.first, p.second / d);
2129 auto [q,
rem] = a.pseudo_divmod(b);
2131 <<
"_integer_exact_quot: divisor does not divide dividend exactly";
2132 return q.is_zero() ? q : q.primitive_part();
2136 requires std::is_integral_v<Coefficient>
2151 requires std::is_integral_v<Coefficient>
2153 if (mod == 0
or mod == 1)
2162 result = (result +
term) % mod;
2170 requires std::is_integral_v<Coefficient>
2173 <<
"divide_by_monic_linear_mod: constant polynomial is not divisible by x - r";
2180 for (
size_t idx =
degree; idx-- > 0;)
2188 <<
"divide_by_monic_linear_mod: x - r does not divide polynomial modulo p";
2199 requires std::is_integral_v<Coefficient>
2229 requires std::is_integral_v<Coefficient>
2234 if (
not r.is_zero())
2239 catch (
const std::domain_error &)
2249 requires std::is_integral_v<Coefficient>
2251 if (f.is_zero()
or f.degree() == 0)
2257 const size_t degree = f.degree();
2288 requires std::is_integral_v<Coefficient>
2290 if (f.is_zero()
or f.degree() == 0)
2324 factor.set_coeff(0, -num);
2325 factor.set_coeff(1,
den);
2346 requires std::is_integral_v<Coefficient>
2348 if (f.is_zero()
or f.degree() < 2)
2359 const double abs_lc = std::abs(
static_cast<double>(f.leading_coeff()));
2361 for (
auto it = f.coeffs.get_it(); it.has_curr(); it.next_ne())
2363 const auto &
term = it.get_curr();
2364 if (
term.first == f.degree())
2366 const double ratio = std::abs(
static_cast<double>(
term.second)) /
abs_lc;
2377 =
static_cast<int64_t>(std::ceil(2.0 * std::abs(
static_cast<double>(a)) *
root_bound));
2427 requires std::is_integral_v<Coefficient>
2429 if (f.is_zero()
or f.degree() < 3)
2440 const double abs_lc = std::abs(
static_cast<double>(f.leading_coeff()));
2442 for (
auto it = f.coeffs.get_it(); it.has_curr(); it.next_ne())
2444 const auto &
term = it.get_curr();
2445 const double coeff_abs = std::abs(
static_cast<double>(
term.second));
2524 requires std::is_integral_v<Coefficient>
2530 if (f.is_zero()
or f.is_constant())
2553 result.
append(remaining);
2575 const size_t d =
degree();
2580 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
2582 auto &p = it.get_curr();
2588 const auto d_real =
static_cast<double>(d);
2620 requires std::is_integral_v<Coefficient>
2624 <<
"hensel_lift: levels must be >= 1, got " << levels;
2626 <<
"hensel_lift: levels must be <= 30 to avoid overflow, got " << levels;
2631 const size_t target_steps =
static_cast<size_t>(1) << levels;
2636 <<
"hensel_lift: overflow computing " << name <<
" (" <<
lhs <<
" * " <<
rhs <<
")";
2645 <<
"hensel_lift: target modulus " <<
target_u64
2646 <<
" does not fit in coefficient type";
2651 for (
auto it =
factors.get_it(); it.has_curr(); it.next_ne())
2688 polynomial_detail::centered_from_mod_u64<Coefficient>(
2766 for (
auto it =
sfd_terms.get_it(); it.has_curr(); it.next_ne())
2773 while (remaining.
degree() > 0)
2783 while (remaining.
degree() > 1)
2793 while (remaining.
degree() > 2)
2819 for (
auto jt =
lifted.get_it();
jt.has_curr();
jt.next_ne())
2858template <
typename C>
2865template <
typename C>
2872template <
typename C>
2879template <
typename C>
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
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.
Dynamic singly linked list with functional programming support.
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.
Gen_Polynomial & operator-=(const Coefficient &c)
In-place subtraction of a scalar constant term.
Gen_Polynomial & operator*=(const Coefficient &s)
In-place scalar multiplication.
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.
Gen_Polynomial operator/(const Gen_Polynomial &d) const
Polynomial quotient.
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.
Gen_Polynomial operator-(const Gen_Polynomial &q) const
Polynomial subtraction.
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).
Gen_Polynomial operator+(const Coefficient &c) const
Add a scalar constant term.
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.
Gen_Polynomial operator*(const Coefficient &s) const
Multiply by a scalar.
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 Coefficient &c)
In-place addition of a scalar constant term.
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 .
Gen_Polynomial & operator/=(const Gen_Polynomial &d)
In-place polynomial quotient.
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)
Gen_Polynomial operator-(const Coefficient &c) const
Subtract a scalar constant term.
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)
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.
and
Check uniqueness with explicit hash + equality functors.
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.
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.
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.