15# include <gtest/gtest.h>
42 for (
size_t exp = 0;
exp <= degree; ++
exp)
67 const auto value = std::numeric_limits<long long>::min();
68 const auto expected =
static_cast<uint64_t>(std::numeric_limits<long long>::max()) + 1ULL;
519 std::mt19937
rng(0xA13F2026u);
520 std::uniform_int_distribution<int>
scalar_dist(-3, 3);
521 std::uniform_int_distribution<int>
x_dist(-2, 2);
523 for (
size_t i = 0; i < 100; ++i)
529 const double x =
static_cast<double>(
x_dist(
rng));
744 terms.append({2, 3.0});
797 pts.append(std::make_pair(1.0, 3.0));
811 pts.append(std::make_pair(1.0, 1.0));
812 pts.append(std::make_pair(2.0, 4.0));
833 pts.append(std::make_pair(1.0, 5.0));
852 FAIL() <<
"unexpected exponent " <<
exp;
875 auto coeffs = p.coefficients();
900 std::string s = p.
to_str();
902 EXPECT_NE(s.find(
"2x"), std::string::npos);
903 EXPECT_NE(s.find(
"3"), std::string::npos);
909 std::ostringstream
oss;
931 terms.
append({1000, 1.0});
940 const double value = p.
eval(1.5);
1050 for (
double x = -2.0; x <= 3.0; x += 0.5)
1051 EXPECT_NEAR(p.horner_eval(x), p.sparse_eval(x), 1e-12);
1085 while (
it_r.has_curr())
1109 EXPECT_NEAR(p.definite_integral(0.0, 3.0), 12.0, 1e-12);
1116 EXPECT_NEAR(p.definite_integral(0.0, 1.0), 1.0/3.0, 1e-12);
1123 EXPECT_NEAR(p.definite_integral(-1.0, 1.0), 0.0, 1e-12);
1205 int lc_b = b.leading_coeff();
1206 size_t delta = a.degree() - b.degree() + 1;
1208 for (
size_t i = 0; i < delta; ++i)
1280 for (
double x = -3.0; x <= 3.0; x += 0.7)
1299 for (
double x = -3.0; x <= 3.0; x += 0.7)
1374 terms.
append(std::make_pair(
size_t(0), 1.0));
1375 terms.
append(std::make_pair(
size_t(5), 1.0));
1490 EXPECT_EQ(p.count_real_roots(-10.0, 10.0), 2u);
1491 EXPECT_EQ(p.count_real_roots(0.0, 10.0), 1u);
1492 EXPECT_EQ(p.count_real_roots(2.0, 10.0), 0u);
1508 EXPECT_EQ(p.count_real_roots(10.0, -10.0), 2u);
1515 EXPECT_EQ(p.count_all_real_roots(), 4u);
1530 EXPECT_EQ(p.count_all_real_roots(), 0u);
1556 EXPECT_THROW(p.bisect_root(1.0, 2.0), std::domain_error);
1562 EXPECT_NEAR(p.bisect_root(10.0, 0.0), 2.0, 1e-10);
1648 for (
size_t i = 0; i <
term.multiplicity; ++i)
1649 block *=
term.factor;
1965 for (
const auto &factor :
factors)
2029 for (
const auto &factor :
lifted)
2068 for (
const auto &factor :
lifted)
2147 if (
term.multiplicity != 1)
2172 if (
term.multiplicity != 1)
2197 if (
term.multiplicity != 1)
2217 if ((
term.factor.degree() == 3
and term.multiplicity == 1)
or
2218 (
term.factor.degree() == 1
and term.multiplicity == 3))
2256 if (
term.multiplicity != 1)
2285 if (
term.multiplicity != 1)
2312 if (
term.multiplicity != 1)
Simple dynamic array with automatic resizing and functional operations.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
Univariate polynomial over a generic coefficient ring.
Gen_Polynomial nth_derivative(size_t n) const
-th derivative .
DynList< Gen_Polynomial > sturm_chain() const
Sturm sequence of this polynomial.
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.
size_t num_terms() const noexcept
Number of non-zero terms.
DynList< size_t > exponents() const
All exponents with non-zero coefficients (sorted ascending).
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.
Coefficient eval(const Coefficient &x) const
Evaluate with adaptive strategy.
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.
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.
Gen_Polynomial pow(size_t n) const
Exponentiation by repeated squaring.
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.
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 .
bool is_zero() const noexcept
True if this is the zero polynomial.
size_t count_all_real_roots() const
Total number of distinct real roots.
static Gen_Polynomial _integer_exact_quot(const Gen_Polynomial &a, const Gen_Polynomial &b)
Integer-safe exact quotient using pseudo-division.
Coefficient bisect_root(Coefficient a, Coefficient b, Coefficient tol=Coefficient(1e-12), size_t max_iter=200) const
Find a root by bisection in .
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 Gen_Polynomial lcm(const Gen_Polynomial &a, const Gen_Polynomial &b)
Least common multiple.
Array< Coefficient > to_dense() const
Dense coefficient vector.
Gen_Polynomial shift_up(size_t k) const
Multiply by (shift exponents up).
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 .
std::pair< Gen_Polynomial, Gen_Polynomial > pseudo_divmod(const Gen_Polynomial &d) const
Pseudo-division for non-field coefficient types.
Gen_Polynomial integral(const Coefficient &C=Coefficient{}) const
Formal indefinite integral with constant of integration.
static Gen_Polynomial x_to(size_t n)
The monomial .
Coefficient leading_coeff() const noexcept
Leading coefficient (of the highest-degree term).
Gen_Polynomial to_monic() const
Make monic: divide by leading coefficient.
Coefficient newton_root(Coefficient x0, Coefficient tol=Coefficient(1e-12), size_t max_iter=100) const
Find a root by Newton-Raphson iteration.
void set_coeff(size_t exp, const Coefficient &c)
Set coefficient at exponent; removes entry if zero.
Gen_Polynomial reverse() const
Reciprocal polynomial: .
Coefficient get_coeff(size_t exp) const noexcept
Coefficient accessor (read-only at exponent).
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_exp_function > > exp(const __gmp_expr< T, U > &expr)
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_remainder_function > > remainder(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
__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)
Gen_Polynomial< long long > IntPoly
uint64_t abs_to_u64(Int value) noexcept
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
void reverse(Itor beg, Itor end)
Reverse elements in a range.
Itor2 copy(Itor1 sourceBeg, const Itor1 &sourceEnd, Itor2 destBeg)
Copy elements from one range to another.
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_Polynomial< double > Polynomial
Polynomial with double coefficients.
T product(const Container &container, const T &init=T{1})
Compute product of all elements.
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
double mod(double a, double b)
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)
Univariate polynomial ring arithmetic over generic coefficients.