41#ifndef TPL_MULTI_POLYNOMIAL_H
42#define TPL_MULTI_POLYNOMIAL_H
71namespace multi_poly_detail {
77 for (
size_t i = 0; i < idx.size(); ++i)
85 for (
size_t i = 0; i < idx.size(); ++i)
96 const size_t n = std::max(a.
size(), b.
size());
98 for (
size_t i = 0; i < a.
size(); ++i)
100 for (
size_t i = 0; i < b.
size(); ++i)
108 if (idx.
size() >= target)
111 for (
size_t i = 0; i < idx.
size(); ++i)
155 for (
size_t i = 0; i < n; ++i)
165 const size_t n = sizes.
size();
167 for (
size_t i = n; i > 0; --i)
169 r(i - 1) =
flat % sizes(i - 1);
170 flat /= sizes(i - 1);
179 const size_t n = sizes.
size();
180 for (
size_t i = n; i > 0; --i)
189template <
typename Coefficient>
193 for (
size_t j = 0; j < alpha.
size(); ++j)
202 for (
size_t i = 0; i <
nvars; ++i)
204 const size_t ai = i < alpha.size() ? alpha(i) : 0;
205 const size_t bi = i < beta.size() ? beta(i) : 0;
216 for (
size_t i = 0; i <
nvars; ++i)
217 r(i) = std::max(i < a.
size() ? a(i) : 0, i < b.
size() ? b(i) : 0);
227 for (
size_t i = 0; i <
nvars; ++i)
228 r(i) = (i < beta.
size() ? beta(i) : 0) - (i < alpha.
size() ? alpha(i) : 0);
248 const size_t n = std::max(a.size(), b.size());
249 for (
size_t i = 0; i < n; ++i)
251 const size_t ai = i < a.size() ? a(i) : 0;
252 const size_t bi = i < b.size() ? b(i) : 0;
292 const size_t n = std::max(a.size(), b.size());
293 for (
size_t i = n; i > 0; --i)
295 const size_t ai = i - 1 < a.size() ? a(i - 1) : 0;
296 const size_t bi = i - 1 < b.size() ? b(i - 1) : 0;
321template <
typename Coefficient =
double,
class MonomOrder = Grevlex_Order>
335 requires(
not std::is_integral_v<Coefficient>)
348 for (
size_t i = 0; i <
basis.size(); ++i)
356 const size_t nvars)
noexcept
358 for (
size_t v = 0; v <
nvars; ++v)
360 const size_t av = v < a.size() ? a(v) : 0;
361 const size_t bv = v < b.size() ? b(v) : 0;
362 if (std::min(
av,
bv) != 0)
373 return i < j ? std::make_pair(i, j) : std::make_pair(j, i);
386 if (
lhs.lcm_degree !=
rhs.lcm_degree)
387 return lhs.lcm_degree <
rhs.lcm_degree;
390 if (order(
lhs.lcm,
rhs.lcm))
392 if (order(
rhs.lcm,
lhs.lcm))
488 requires(
not std::is_integral_v<Coefficient>)
492 for (
size_t i = 0; i <
generators.size(); ++i)
516 requires(
not std::is_integral_v<Coefficient>)
524 for (
size_t i = 0; i <
basis.size(); ++i)
531 for (
size_t j = 0; j <
basis.size(); ++j)
548 for (
size_t i = 0; i <
basis.size(); ++i)
563 for (
size_t i = 0; i <
basis.size(); ++i)
576 requires(
not std::is_integral_v<Coefficient>)
582 for (
size_t i = 0; i <
basis.size(); ++i)
584 if (
basis(i).is_zero())
587 for (
size_t j = 0; j <
basis.size(); ++j)
596 for (
size_t j = 0; j <
basis.size(); ++j)
611 for (
size_t j = 0; j <
basis.size(); ++j)
623 for (
size_t j = 0; j <
basis.size(); ++j)
641 for (
size_t i = 0; i <
basis.size(); ++i)
651 requires(
not std::is_integral_v<Coefficient>)
654 for (
size_t i = 0; i <
basis.size(); ++i)
661 if (
basis.size() < 2)
664 for (
size_t i = 0; i <
basis.size(); ++i)
665 for (
size_t j = i + 1; j <
basis.size(); ++j)
692 if constexpr (std::is_floating_point_v<Coefficient>)
693 return Coefficient(128) * std::numeric_limits<Coefficient>::epsilon();
704 if constexpr (std::is_floating_point_v<Coefficient>)
705 return std::abs(c) <=
epsilon();
761 for (
const auto &t :
ts)
833 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
846 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
848 const auto &idx = it.get_curr().first;
849 if (
const size_t e = var < idx.
size() ? idx(var) : 0; e > d)
867 return {
m.first,
m.second};
912 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
914 const auto &p = it.get_curr();
915 op(p.first, p.second);
926 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
928 const auto &p = it.get_curr();
933 op(t.first, t.second);
970 p->second = p->second + delta;
982 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
984 auto &p = it.get_curr();
1011 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1012 it.get_curr().second *= s;
1028 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
1029 it.get_curr().second /= s;
1151 r.coeffs.insert(idx, -c);
1226 r.coeffs.insert(idx,
prod);
1256 r.coeffs.insert(idx, q);
1306 <<
"eval: point has " << pt.
size() <<
" components but polynomial has " <<
nvars_
1314 for (
size_t j = 0; j < idx.
size(); ++j)
1363 return not(*
this == q);
1397 constexpr char abc[] = {
'x',
'y',
'z'};
1398 vn.append(std::string(1,
abc[
vn.size()]));
1401 vn.append(
"x" + std::to_string(
vn.size()));
1403 std::ostringstream
oss;
1410 if constexpr (std::is_floating_point_v<Coefficient>)
1436 oss << (
neg ?
" - " :
" + ");
1450 for (
size_t j = 0; j < idx.
size(); ++j)
1458 oss <<
"^" << idx(j);
1484 <<
"cannot demote from " <<
nvars_ <<
" to " <<
new_nv <<
" variables";
1521 const size_t m = data.
size();
1522 const size_t b =
basis.size();
1531 for (
size_t i = 0; i <
m; ++i)
1533 for (
size_t j = 0; j < b; ++j)
1535 y(i) = data(i).second;
1542 for (
size_t i = 0; i < b; ++i)
1544 for (
size_t j = 0; j < b; ++j)
1547 for (
size_t k = 0;
k <
m; ++
k)
1548 AtA(i)(j) += A(
k)(i) * A(
k)(j);
1552 for (
size_t k = 0;
k <
m; ++
k)
1553 Aty(i) += A(
k)(i) *
y(
k);
1558 for (
size_t col = 0; col < b; ++col)
1563 for (
size_t row = col + 1; row < b; ++row)
1582 for (
size_t row = col + 1; row < b; ++row)
1585 for (
size_t j = col; j < b; ++j)
1586 AtA(row)(j) -= f *
AtA(col)(j);
1587 Aty(row) -= f *
Aty(col);
1592 for (
size_t i = b; i > 0; --i)
1594 c(i - 1) =
Aty(i - 1);
1595 for (
size_t j = i; j < b; ++j)
1596 c(i - 1) -=
AtA(i - 1)(j) * c(j);
1597 c(i - 1) /=
AtA(i - 1)(i - 1);
1602 for (
size_t j = 0; j < b; ++j)
1634 const size_t m = data.
size();
1635 const size_t b =
basis.size();
1640 <<
"fit_weighted: weights.size() " <<
weights.size() <<
" != data.size() " <<
m;
1646 for (
size_t i = 0; i <
m; ++i)
1649 for (
size_t j = 0; j < b; ++j)
1658 for (
size_t i = 0; i < b; ++i)
1660 for (
size_t j = 0; j < b; ++j)
1663 for (
size_t k = 0;
k <
m; ++
k)
1664 AtA(i)(j) += A(
k)(i) * A(
k)(j);
1668 for (
size_t k = 0;
k <
m; ++
k)
1674 for (
size_t col = 0; col < b; ++col)
1679 for (
size_t row = col + 1; row < b; ++row)
1690 <<
"fit_weighted: singular system at column " << col;
1699 for (
size_t row = col + 1; row < b; ++row)
1702 for (
size_t j = col; j < b; ++j)
1703 AtA(row)(j) -= f *
AtA(col)(j);
1704 Aty(row) -= f *
Aty(col);
1709 for (
size_t i = b; i > 0; --i)
1711 c(i - 1) =
Aty(i - 1);
1712 for (
size_t j = i; j < b; ++j)
1713 c(i - 1) -=
AtA(i - 1)(j) * c(j);
1714 c(i - 1) /=
AtA(i - 1)(i - 1);
1719 for (
size_t j = 0; j < b; ++j)
1756 const size_t m = data.
size();
1757 const size_t b =
basis.size();
1766 for (
size_t i = 0; i <
m; ++i)
1768 for (
size_t j = 0; j < b; ++j)
1770 y(i) = data(i).second;
1777 for (
size_t i = 0; i < b; ++i)
1779 for (
size_t j = 0; j < b; ++j)
1782 for (
size_t k = 0;
k <
m; ++
k)
1783 AtA(i)(j) += A(
k)(i) * A(
k)(j);
1787 for (
size_t k = 0;
k <
m; ++
k)
1788 Aty(i) += A(
k)(i) *
y(
k);
1793 double best_gcv = std::numeric_limits<double>::max();
1807 for (
size_t i = 0; i < b; ++i)
1814 for (
size_t col = 0; col < b; ++col)
1819 for (
size_t row = col + 1; row < b; ++row)
1839 for (
size_t row = col + 1; row < b; ++row)
1842 for (
size_t j = col; j < b; ++j)
1843 sys(row)(j) -= f *
sys(col)(j);
1844 rhs(row) -= f *
rhs(col);
1852 for (
size_t i = b; i > 0; --i)
1854 c(i - 1) =
rhs(i - 1);
1855 for (
size_t j = i; j < b; ++j)
1856 c(i - 1) -=
sys(i - 1)(j) * c(j);
1857 c(i - 1) /=
sys(i - 1)(i - 1);
1862 for (
size_t i = 0; i <
m; ++i)
1865 for (
size_t j = 0; j < b; ++j)
1866 pred += A(i)(j) * c(j);
1873 double denominator = 1.0 -
static_cast<double>(b) /
static_cast<double>(
m);
1874 if (denominator < 0.01)
1889 for (
size_t i = 0; i < b; ++i)
1893 for (
size_t col = 0; col < b; ++col)
1897 for (
size_t row = col + 1; row < b; ++row)
1910 for (
size_t row = col + 1; row < b; ++row)
1913 for (
size_t j = col; j < b; ++j)
1919 for (
size_t i = b; i > 0; --i)
1922 for (
size_t j = i; j < b; ++j)
1935 for (
size_t j = 0; j < b; ++j)
1971 const size_t k = alpha(var);
1976 const Coefficient ff = multi_poly_detail::falling_factorial<Coefficient>(
k, n);
2014 for (
size_t i = 0; i < n; ++i)
2017 for (
size_t j = i + 1; j < n; ++j)
2038 <<
"eval_gradient: point size " << pt.
size() <<
" < nvars " <<
nvars_;
2043 result(
k) = g(
k).eval(pt);
2059 <<
"eval_hessian: point size " << pt.
size() <<
" < nvars " <<
nvars_;
2064 for (
size_t i = 0; i < n; ++i)
2065 for (
size_t j = 0; j < n; ++j)
2066 result(i)(j) = H(i)(j).
eval(pt);
2096 <<
"interpolate: grid size " <<
grid.size() <<
" != nvars " <<
nvars;
2101 for (
size_t d = 0; d <
nvars; ++d)
2109 <<
"interpolate: values size " << values.
size() <<
" != total " <<
total;
2112 for (
size_t d = 0; d <
nvars; ++d)
2115 for (
size_t i = 0; i <
nodes.size(); ++i)
2116 for (
size_t j = i + 1; j <
nodes.size(); ++j)
2118 <<
"interpolate: duplicate node at dimension " << d;
2123 for (
size_t f = 0; f <
total; ++f)
2129 const size_t m = sizes(
dim);
2134 for (
size_t d =
dim + 1; d <
nvars; ++d)
2147 for (
size_t d =
nvars; d > 0; --d)
2151 size_t sz = sizes(d - 1);
2159 for (
size_t i = 0; i <
m; ++i)
2163 for (
size_t order = 1; order <
m; ++order)
2164 for (
size_t i =
m; i > order; --i)
2174 for (
size_t i = 1; i <
m; ++i)
2177 result = result +
dd(i) *
basis;
2202 std::ostringstream
oss;
2203 oss << R
"({"nvars":)" << nvars_ << R"(,"terms":[)";
2210 for (
size_t j = 0; j < idx.
size(); ++j)
2216 oss << R
"(],"c":)" << std::setprecision(17) << c << "}";
2243 size_t pos = s.find(
"\"nvars\":");
2251 pos = s.find(
"\"terms\":[");
2255 while (pos < s.size() && s[pos] !=
']')
2258 size_t e_pos = s.find(
"\"e\":[", pos);
2259 if (
e_pos == std::string::npos)
2271 idx(
idx_i++) = std::stoul(token);
2283 pos = s.find(
"},",
e_end);
2284 if (pos == std::string::npos)
2303 out.write(
reinterpret_cast<const char *
>(&
nv),
sizeof(
nv));
2306 out.write(
reinterpret_cast<const char *
>(&
nt),
sizeof(
nt));
2310 for (
size_t j = 0; j <
nvars_; ++j)
2313 out.write(
reinterpret_cast<const char *
>(&
exp),
sizeof(
exp));
2315 const auto c_double =
static_cast<double>(c);
2332 in.read(
reinterpret_cast<char *
>(&
nv),
sizeof(
nv));
2336 in.read(
reinterpret_cast<char *
>(&
nt),
sizeof(
nt));
2340 for (
size_t i = 0; i <
n_terms; ++i)
2343 for (
size_t j = 0; j <
nvars; ++j)
2346 in.read(
reinterpret_cast<char *
>(&
exp),
sizeof(
exp));
2374 const size_t n =
pts.size();
2378 for (
size_t i = 0; i < n; ++i)
2403 const size_t m = data.
size();
2404 const size_t b =
basis.size();
2411 for (
size_t i = 0; i <
m; ++i)
2415 std::vector<Array<size_t>>
basis_vec(b);
2416 for (
size_t i = 0; i < b; ++i)
2424 for (
size_t j = 0; j < b; ++j)
2432 for (
size_t i = 0; i <
m; ++i)
2435 y(i) = data(i).second;
2442 for (
size_t i = 0; i < b; ++i)
2444 for (
size_t j = 0; j < b; ++j)
2447 for (
size_t k = 0;
k <
m; ++
k)
2448 AtA(i)(j) += A(
k)(i) * A(
k)(j);
2452 for (
size_t k = 0;
k <
m; ++
k)
2453 Aty(i) += A(
k)(i) *
y(
k);
2458 for (
size_t col = 0; col < b; ++col)
2462 for (
size_t row = col + 1; row < b; ++row)
2473 <<
"fit_parallel: singular normal equations";
2481 for (
size_t row = col + 1; row < b; ++row)
2484 for (
size_t j = col; j < b; ++j)
2485 AtA(row)(j) -= f *
AtA(col)(j);
2486 Aty(row) -= f *
Aty(col);
2491 for (
size_t i = b; i > 0; --i)
2493 c(i - 1) =
Aty(i - 1);
2494 for (
size_t j = i; j < b; ++j)
2495 c(i - 1) -=
AtA(i - 1)(j) * c(j);
2496 c(i - 1) /=
AtA(i - 1)(i - 1);
2501 for (
size_t j = 0; j < b; ++j)
2537 for (
size_t i = 0; i < s; ++i)
2541 <<
"divmod: divisors[" << i <<
"].nvars (" <<
divisors(i).nvars_ <<
") != this.nvars ("
2556 for (
size_t i = 0; i < s; ++i)
2565 if constexpr (std::is_integral_v<Coefficient>)
2608 requires(
not std::is_integral_v<Coefficient>)
2613 <<
"s_poly: incompatible number of variables (" << f.
nvars_ <<
" vs " << g.nvars_ <<
")";
2615 const size_t nv = f.nvars_;
2616 auto [
lm_f,
lc_f] = f.leading_term();
2617 auto [
lm_g,
lc_g] = g.leading_term();
2629 return t_f * f -
t_g * g;
2659 requires(
not std::is_integral_v<Coefficient>)
2677 size_t iteration = 0;
2680 while (
not P.is_empty())
2684 <<
"groebner_basis: iteration limit (" <<
max_iterations <<
") exceeded";
2712 if (
not r.is_zero())
2718 G.append(std::move(
r));
2721 <<
"groebner_basis: incremental autoreduction collapsed the basis";
2748 requires(
not std::is_integral_v<Coefficient>)
2754 for (
size_t i = 0; i <
G.size(); ++i)
2758 for (
size_t i = 0; i <
G.size(); ++i)
2766 for (
size_t j = 0; j <
G.size(); ++j)
2773 G(i) = std::move(
r);
2779 for (
size_t i = 0; i <
G.size(); ++i)
2817 requires(
not std::is_integral_v<Coefficient>)
2847 for (
size_t i = 0; i < a.
size(); ++i)
2850 for (
size_t j = 0; j < b.
size(); ++j)
2853 size_t nv = a(0).nvars_;
2854 for (
size_t i = 1; i < a.
size(); ++i)
2856 <<
"]: expected " <<
nv <<
", got " << a(i).nvars_;
2858 for (
size_t j = 0; j < b.
size(); ++j)
2860 <<
"]: expected " <<
nv <<
", got " << b(j).nvars_;
2863 for (
size_t i = 0; i < a.
size(); ++i)
2865 for (
size_t j = 0; j < b.
size(); ++j)
2866 result(a.
size() + j) = b(j);
2890 for (
size_t i = 0; i < a.
size(); ++i)
2893 for (
size_t j = 0; j < b.
size(); ++j)
2896 size_t nv = a(0).nvars_;
2897 for (
size_t i = 1; i < a.
size(); ++i)
2899 <<
"]: expected " <<
nv <<
", got " << a(i).nvars_;
2901 for (
size_t j = 0; j < b.
size(); ++j)
2903 <<
"]: expected " <<
nv <<
", got " << b(j).nvars_;
2907 for (
size_t i = 0; i < a.
size(); ++i)
2908 for (
size_t j = 0; j < b.
size(); ++j)
2909 result(
k++) = a(i) * b(j);
2932 for (
size_t i = 0; i <
gens.size(); ++i)
2935 size_t nv =
gens(0).nvars_;
2951 for (
size_t i = 1; i < n; ++i)
2975 requires(
not std::is_integral_v<Coefficient>)
2980 for (
size_t i = 0; i <
I_gens.size(); ++i)
2983 for (
size_t j = 0; j <
J_gens.size(); ++j)
2987 for (
size_t i = 1; i <
I_gens.size(); ++i)
2989 <<
"contains_ideal: nvars mismatch in I[" << i <<
"]: expected " <<
nv <<
", got "
2992 for (
size_t j = 0; j <
J_gens.size(); ++j)
2994 <<
"contains_ideal: nvars mismatch in J[" << j <<
"]: expected " <<
nv <<
", got "
3001 for (
size_t j = 0; j <
J_gens.size(); ++j)
3027 requires(
not std::is_integral_v<Coefficient>)
3032 for (
size_t i = 0; i <
I_gens.size(); ++i)
3035 for (
size_t j = 0; j <
J_gens.size(); ++j)
3039 for (
size_t i = 1; i <
I_gens.size(); ++i)
3041 <<
"ideals_equal: nvars mismatch in I[" << i <<
"]: expected " <<
nv <<
", got "
3044 for (
size_t j = 0; j <
J_gens.size(); ++j)
3046 <<
"ideals_equal: nvars mismatch in J[" << j <<
"]: expected " <<
nv <<
", got "
3071 requires(
not std::is_integral_v<Coefficient>)
3075 for (
size_t i = 0; i <
gens.size(); ++i)
3078 size_t nv =
gens(0).nvars_;
3082 <<
"radical_member: f nvars mismatch: expected " <<
nv <<
", got " << f.nvars_;
3093 for (
size_t i = 0; i <
gens.size(); ++i)
3149 for (
auto it =
coeffs.get_it(); it.has_curr(); it.next_ne())
3151 const auto &p = it.get_curr();
3153 result = std::gcd(result, a);
3196 r.coeffs.insert(idx, -
coeff);
3205 result.
coeffs.insert(idx, q);
3229 <<
"homomorphic_eval: keep_var " <<
keep_var <<
" >= nvars " <<
nvars_;
3231 <<
"homomorphic_eval: eval_pts size " <<
eval_pts.size() <<
" != nvars-1 " << (
nvars_ - 1);
3239 for (
size_t v = 0; v <
nvars_; ++v)
3279 for (
size_t i = 0; i <
vals.size(); ++i)
3280 if (
vals(i) == value)
3297 if (
lhs.main_coeff <
rhs.main_coeff)
3299 if (
rhs.main_coeff <
lhs.main_coeff)
3301 return lhs.constant_term <
rhs.constant_term;
3308 requires std::is_integral_v<Coefficient>
3314 for (
auto it =
factors.get_it(); it.has_curr(); it.next_ne())
3316 const auto &
term = it.get_curr();
3317 if (
term.factor.degree() != 1)
3321 for (
size_t m = 0;
m <
term.multiplicity; ++
m)
3325 if (result.size() > 1)
3334 requires std::is_integral_v<Coefficient>
3338 for (
auto it =
factors.get_it(); it.has_curr(); it.next_ne())
3340 const auto &
term = it.get_curr();
3343 _append_unique(roots, -
term.factor.get_coeff(0));
3351 return var <
main_var ? var : var - 1;
3359 for (
size_t v = 0; v < p.
num_vars(); ++v)
3386 requires std::is_integral_v<Coefficient>
3395 for (
size_t pos = 0; pos <
other_vars.size(); ++pos)
3400 if (coeff_is_zero(
coeff))
3419 requires std::is_integral_v<Coefficient>
3429 for (
size_t v = 0; v < p.num_vars(); ++v)
3438 for (
size_t pos = 0; pos <
other_vars.size(); ++pos)
3456 for (
size_t pos = 0; pos <
other_vars.size(); ++pos)
3504 requires std::is_integral_v<Coefficient>
3513 for (
size_t pos = 0; pos <
other_vars.size(); ++pos)
3517 if (coeff_is_zero(
slopes(pos)))
3541 requires std::is_integral_v<Coefficient>
3563 if (_search_affine_lift_options(
3576 requires std::is_integral_v<Coefficient>
3589 for (
size_t v = 0; v < p.num_vars(); ++v)
3597 for (
size_t pos = 0; pos <
other_vars.size(); ++pos)
3609 for (
size_t i = 0; i <
base_roots.size(); ++i)
3610 if (_search_affine_lift_options(
3620 requires std::is_integral_v<Coefficient>
3632 for (
size_t v = 0; v < p.num_vars(); ++v)
3654 requires std::is_integral_v<Coefficient>
3661 for (
size_t pos = 0; pos <
other_vars.size(); ++pos)
3665 if (node_count == 0)
3674 for (
size_t i = 0; i < node_count; ++i)
3676 grid(pos).append(value);
3677 value = value +
step;
3690 for (
size_t pos =
grid.size(); pos > 0; --pos)
3692 const size_t idx = remaining %
grid(pos - 1).
size();
3693 remaining /=
grid(pos - 1).size();
3694 point(pos - 1) =
grid(pos - 1)(idx);
3706 for (
size_t pos = 0; pos <
other_vars.size(); ++pos)
3714 requires std::is_integral_v<Coefficient>
3719 auto terms = u.factorize();
3720 for (
auto it = terms.get_it(); it.has_curr(); it.next_ne())
3722 const auto &
term = it.get_curr();
3723 for (
size_t m = 0;
m <
term.multiplicity; ++
m)
3734 if (
lhs.degree() !=
rhs.degree())
3735 return lhs.degree() <
rhs.degree();
3761 requires std::is_integral_v<Coefficient>
3768 for (
size_t i = 0; i <
expanded.size(); ++i)
3771 if (factor.is_zero()
or factor.is_constant())
3773 factor = factor.primitive_part();
3774 groups(factor.degree()).append(factor);
3778 for (
size_t degree = 0; degree <
groups.size(); ++degree)
3798 for (
size_t pos = 0; pos <
other_vars.size(); ++pos)
3815 requires std::is_integral_v<Coefficient>
3822 for (
size_t v = 0; v < p.num_vars(); ++v)
3848 for (
size_t degree = 1; degree <
base_groups.size(); ++degree)
3864 for (
size_t exp = 0;
exp <= degree; ++
exp)
3873 if (u.is_zero()
or u.is_constant())
3880 for (
size_t degree = 0; degree <
base_groups.size(); ++degree)
3890 for (
size_t exp = 0;
exp <= degree; ++
exp)
3899 for (
size_t exp = 0;
exp <= degree; ++
exp)
3917 requires std::is_integral_v<Coefficient>
3930 for (
size_t i = 0; i <
candidates.size(); ++i)
3950 requires std::is_integral_v<Coefficient>
3963 for (
auto it =
sfd_terms.get_it(); it.has_curr(); it.next_ne())
3965 const auto &st = it.get_curr();
4017 for (
size_t i = 0; i <
k; ++i)
4025 for (
size_t i = 0; i <
k; ++i)
4038 if (_divides_exactly(f,
cand))
4041 f = _exact_quotient(f,
cand);
4065 if (_divides_exactly(f,
product))
4068 f = _exact_quotient(f,
product);
4122 if (is_zero()
or is_constant())
4142 for (
auto it = tail.
get_it(); it.has_curr(); it.next_ne())
4143 result.
append(it.get_curr());
4155 size_t multiplicity = 1;
4173 for (
auto it = tail.
get_it(); it.has_curr(); it.next_ne())
4174 result.
append(it.get_curr());
4183 size_t min_deg = std::numeric_limits<size_t>::max();
4184 for (
size_t v = 0; v < nvars_; ++v)
4204 for (
size_t v = 0; v < nvars_; ++v)
4217 if (g.is_zero()
or g.is_constant())
4223 for (
size_t v = 0; v < nvars_; ++v)
4234 if (g.is_zero()
or g.is_constant())
4247 for (
auto it =
univ_sfd.get_it(); it.has_curr(); it.next_ne())
4249 const auto &
term = it.get_curr();
4250 for (
size_t m = 0;
m <
term.multiplicity; ++
m)
4266 for (
auto it =
univ_factors.get_it(); it.has_curr(); it.next_ne())
4272 for (
auto it = tail.
get_it(); it.has_curr(); it.next_ne())
4273 result.
append(it.get_curr());
4283 for (
size_t j = 0; j < alpha.
size(); ++j)
4313 template <
typename T>
4317 for (
auto it =
lst.get_it(); it.has_curr(); it.next_ne())
4356 <<
"_exact_quotient: divisor does not divide polynomial exactly";
4376template <
typename C>
4396template <
typename C,
class M>
4401 const size_t m = data.
size();
4408 for (
size_t i = 0; i <
m; ++i)
4409 sum_y += data(i).second;
4410 result.
mean_y =
static_cast<double>(
sum_y) /
static_cast<double>(
m);
4417 for (
size_t i = 0; i <
m; ++i)
4420 C
res = data(i).second -
pred;
4423 const auto dev_y =
static_cast<double>(data(i).second) - result.
mean_y;
4426 const auto res_d =
static_cast<double>(
res);
4433 if (result.
tss > 1e-16)
4439 result.
rmse = std::sqrt(result.
rss /
static_cast<double>(
m));
4453template <
typename C,
class M>
4464template <
typename C,
class M>
4475template <
typename C,
class M>
4486template <
typename C,
class M>
Exception handling system with formatted messages for Aleph-w.
#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.
Parallel functional programming operations using ThreadPool.
High-level sorting functions for Aleph containers.
Simple dynamic array with automatic resizing and functional operations.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
T & append(const T &data)
Append a copy of data
void reserve(size_t cap)
Reserves cap cells into the array.
Dynamic heap of elements of type T ordered by a comparison functor.
T getMin()
Remove the minimum element (according to Compare) and return it.
T & insert(const T &item)
Insert a copy of item into the heap.
Dynamic singly linked list with functional programming support.
T & insert(const T &item)
T & append(const T &item)
Generic key-value map implemented on top of a binary search tree.
bool contains(const Key &key) const noexcept
bool is_empty() const noexcept
Sparse multivariate polynomial.
static bool radical_member(const Gen_MultiPolynomial &f, const Array< Gen_MultiPolynomial > &gens)
Test membership in radical of ideal: f ∈ √I.
void divide_scalar_inplace(const Coefficient &s)
Divide every coefficient by s in place.
static Array< Gen_MultiPolynomial > reduced_groebner_basis(const Array< Gen_MultiPolynomial > &generators)
Reduced Gröbner basis (minimized and normalized).
static bool leading_monomials_coprime(const Array< size_t > &a, const Array< size_t > &b, const size_t nvars) noexcept
static Pair_Key canonical_pair(size_t i, size_t j) noexcept
static Gen_MultiPolynomial fit(const Array< std::pair< Array< Coefficient >, Coefficient > > &data, const size_t nvars, const Array< Array< size_t > > &basis)
Basic least-squares polynomial fitting.
static bool _try_lift_primitive_affine_linear_factor_for_main_var(const Gen_MultiPolynomial &p, size_t main_var, const Array< Coefficient > &base_eval_pts, Gen_MultiPolynomial &factor)
Try to lift a primitive affine linear factor from specialized coefficients.
void for_each_term_desc(Op &&op) const
Visit every non-zero term in descending monomial order.
Gen_MultiPolynomial primitive_part() const
Primitive part: polynomial divided by its content.
Gen_MultiPolynomial reduce_modulo(const Array< Gen_MultiPolynomial > &divisors) const
Polynomial reduction modulo an ideal (one-liner).
Gen_MultiPolynomial partial(size_t var, size_t n=1) const
Partial derivative with respect to a variable.
static bool pair_is_recorded(const Pair_Registry &pairs, size_t i, size_t j)
static Gen_MultiPolynomial fit_ridge(const Array< std::pair< Array< Coefficient >, Coefficient > > &data, size_t nvars, const Array< Array< size_t > > &basis, Coefficient *lambda_used=nullptr, double *gcv_score=nullptr)
Regularized least-squares fitting with automatic GCV-based lambda selection.
std::string to_json() const
Serialize polynomial to JSON string.
static bool redundant_pair_by_chain_criterion(const Pair_Candidate &candidate, const Array< Array< size_t > > &leading_monomials, const Pair_Registry &zero_pairs, const size_t nvars)
Gen_MultiPolynomial & operator/=(const Coefficient &s)
In-place scalar division.
static bool contains_ideal(const Array< Gen_MultiPolynomial > &I_gens, const Array< Gen_MultiPolynomial > &J_gens)
Test whether ideal I contains ideal J: I ⊇ J.
static Array< Gen_MultiPolynomial > autoreduced_generators(const Array< Gen_MultiPolynomial > &generators)
static size_t _eval_index_for_var(size_t main_var, size_t var) noexcept
Return the evaluation-array position corresponding to variable var.
size_t degree_in(size_t var) const noexcept
Degree in a specific variable.
Gen_MultiPolynomial operator+(const Gen_MultiPolynomial &q) const
Polynomial addition.
Gen_MultiPolynomial(const size_t nvars, std::initializer_list< std::pair< Array< size_t >, Coefficient > > ts)
Construct from an initializer list of term pairs.
DynMapTree< Pair_Key, bool > Pair_Registry
DynList< FactorTerm > factorize() const
Main multivariate factorization over the integers.
bool is_constant() const noexcept
True if constant or zero (total degree 0).
static Gen_MultiPolynomial _exact_quotient(const Gen_MultiPolynomial &f, const Gen_MultiPolynomial &divisor)
Compute exact quotient f / divisor over Z[x1,...,xn].
static Gen_MultiPolynomial s_poly(const Gen_MultiPolynomial &f, const Gen_MultiPolynomial &g)
S-polynomial (Sylvester polynomial) of two polynomials.
static Pair_Candidate pop_best_pair(Pair_Queue &queue, Pair_Registry &queued_pairs)
static Array< Coefficient > _build_eval_point(size_t nvars, size_t main_var, const Array< size_t > &other_vars, const Array< Coefficient > &coords)
Build the full homomorphic-evaluation point from active-variable coordinates.
Array< Coefficient > eval_batch(const Array< Array< Coefficient > > &pts) const
Evaluate polynomial at multiple points (with parallelism support).
Gen_MultiPolynomial operator-() const
Unary negation.
void to_binary(std::ostream &out) const
Serialize polynomial to binary stream.
Gen_MultiPolynomial operator-(const Gen_MultiPolynomial &q) const
Polynomial subtraction.
void scale_inplace(const Coefficient &s)
Multiply every coefficient by s in place.
std::string to_str(const DynList< std::string > &names=DynList< std::string >()) const
Human-readable string.
static Pair_Candidate make_pair_candidate(size_t i, size_t j, const Array< Array< size_t > > &leading_monomials, size_t nvars)
void for_each_term(Op &&op) const
Visit every non-zero term in ascending monomial order.
static size_t _list_size(const DynList< T > &lst)
Count elements in a DynList.
static bool _try_extract_interpolated_factor(const Gen_MultiPolynomial &p, Gen_MultiPolynomial &factor)
Try to extract an exact non-linear factor via coefficient interpolation.
static bool _try_lift_affine_linear_factor_for_main_var(const Gen_MultiPolynomial &p, size_t main_var, const Array< Coefficient > &base_eval_pts, Gen_MultiPolynomial &factor)
Try to lift a monic affine linear factor for a fixed main variable.
Gen_MultiPolynomial operator/(const Coefficient &s) const
Divide by a scalar.
Gen_MultiPolynomial operator*(const Gen_MultiPolynomial &q) const
Polynomial multiplication.
Array< Coefficient > eval_gradient(const Array< Coefficient > &pt) const
Evaluate gradient at a point.
static void make_monic_inplace(Gen_MultiPolynomial &p)
static bool contains_equal_polynomial(const Array< Gen_MultiPolynomial > &basis, const Gen_MultiPolynomial &p)
std::pair< Array< size_t >, Coefficient > leading_term() const
Leading term (largest monomial in the ordering).
static Gen_MultiPolynomial interpolate(const Array< Array< Coefficient > > &grid, const Array< Coefficient > &values, size_t nvars)
Multivariate interpolation via Newton divided differences (Chung-Yao).
Gen_MultiPolynomial operator+(const Coefficient &s) const
Add a scalar constant term.
Gen_MultiPolynomial operator-(const Coefficient &s) const
Subtract a scalar constant term.
static Gen_MultiPolynomial monomial(size_t nvars, const Array< size_t > &idx, const Coefficient &c=Coefficient(1))
A single monomial .
static Array< Coefficient > _collect_unique_monic_linear_roots(const Gen_Polynomial< Coefficient > &u)
Collect unique roots of monic linear factors from a univariate factorization.
size_t num_terms() const noexcept
Number of non-zero terms.
bool is_zero() const noexcept
True if this is the zero polynomial.
Gen_MultiPolynomial & operator*=(const Coefficient &s)
In-place scalar multiplication.
Coefficient content() const
Content of a multivariate polynomial: GCD of all coefficients.
Gen_MultiPolynomial(const size_t nvars, const DynList< std::pair< Array< size_t >, Coefficient > > &ts)
Construct from a list of (exponent-vector, coefficient) pairs.
static Gen_MultiPolynomial fit_parallel(const Array< std::pair< Array< Coefficient >, Coefficient > > &data, size_t nvars, const Array< Array< size_t > > &basis)
Parallel least-squares fitting.
std::pair< size_t, size_t > Pair_Key
DynBinHeap< Pair_Candidate, Pair_Candidate_Less > Pair_Queue
static DynList< FactorTerm > _factorize_as_univariate_in_var(const Gen_MultiPolynomial &p, size_t active_var)
Factor a polynomial that is effectively univariate in one variable.
Gen_MultiPolynomial & operator*=(const Gen_MultiPolynomial &q)
In-place polynomial multiplication.
static bool _collect_sorted_primitive_factor_groups(const Gen_Polynomial< Coefficient > &u, size_t max_degree, Array< Array< Gen_Polynomial< Coefficient > > > &groups)
Expand, primitive-normalize, and group factors by degree in a stable order.
static bool _search_affine_lift_options(const Gen_MultiPolynomial &p, size_t main_var, const Array< size_t > &other_vars, const Array< Array< Coefficient > > &root_options, const Array< Coefficient > &base_eval_pts, const Coefficient &base_root, size_t pos, Array< Coefficient > &slopes, Gen_MultiPolynomial &factor)
Recursive search for an affine linear multivariate lift.
static Array< Uni_Linear_Factor_Data > _collect_sorted_primitive_linear_factors(const Gen_Polynomial< Coefficient > &u)
Collect primitive linear factors from a univariate factorization in stable order.
Array< Array< Coefficient > > eval_hessian(const Array< Coefficient > &pt) const
Evaluate Hessian at a point.
static Array< Gen_MultiPolynomial > _interpolated_factors_for_main_var(const Gen_MultiPolynomial &p, size_t main_var, Coefficient grid_start, Coefficient grid_step)
Reconstruct primitive factors by interpolation across specialization grids.
static Array< Gen_MultiPolynomial > ideal_power(const Array< Gen_MultiPolynomial > &gens, size_t n)
Power of an ideal: I^n = I · I · ... · I (n times).
Coefficient leading_coeff() const
Leading coefficient.
Gen_MultiPolynomial promote(size_t new_nv) const
Promote to a polynomial with more variables.
void remove_zeros()
Remove all terms whose coefficient is approximately zero.
Array< Gen_MultiPolynomial > gradient() const
Gradient vector: array of all first-order partial derivatives.
static Gen_MultiPolynomial from_json(const std::string &s)
Deserialize from JSON.
Array< size_t > leading_monomial() const
Leading monomial (exponent vector of the leading term).
static bool coeff_is_zero(const Coefficient &c) noexcept
Test whether a coefficient is (approximately) zero.
Gen_Polynomial< Coefficient > homomorphic_eval(size_t keep_var, const Array< Coefficient > &eval_pts) const
Homomorphic evaluation: reduce to univariate by substitution.
Gen_MultiPolynomial & operator-=(const Coefficient &s)
In-place subtraction of a scalar constant term.
static void enqueue_pair_if_needed(Pair_Queue &queue, Pair_Registry &queued_pairs, const Pair_Candidate &candidate, const Array< Array< size_t > > &leading_monomials, Pair_Registry &zero_pairs, const size_t nvars)
static void _append_unique(Array< Coefficient > &vals, const Coefficient &value)
Append value to vals if it is not already present.
static constexpr Coefficient epsilon() noexcept
Machine epsilon for floating-point coefficients.
static DynList< FactorTerm > factor_recombination(Gen_MultiPolynomial f, const Array< Gen_MultiPolynomial > &candidates)
Factor recombination: find true factors from lifted candidates.
static Gen_MultiPolynomial _build_affine_factor_from_linear_data(size_t nvars, size_t main_var, const Array< size_t > &other_vars, const Array< Coefficient > &base_eval_pts, const Coefficient &main_coeff, const Array< Coefficient > &other_coeffs, const Coefficient &base_constant_term)
Build a primitive affine linear factor from specialized coefficients.
static size_t _count_active_vars(const Gen_MultiPolynomial &p, size_t &last_active_var)
Count active variables (positive degree) and remember the last one seen.
static bool _divides_exactly(const Gen_MultiPolynomial &f, const Gen_MultiPolynomial &divisor)
Test whether divisor divides f exactly over Z[x1,...,xn].
static Gen_MultiPolynomial variable(size_t nvars, const size_t var)
The polynomial (a single variable).
static Array< Gen_MultiPolynomial > groebner_basis(const Array< Gen_MultiPolynomial > &generators)
Gröbner basis computation via Buchberger's algorithm.
static Array< Gen_Polynomial< Coefficient > > _expanded_univariate_factors(const Gen_Polynomial< Coefficient > &u)
Expand a univariate factorization into individual factors.
Gen_MultiPolynomial(const size_t nvars, const Coefficient &c=Coefficient{})
Constant polynomial.
static void rebuild_groebner_pair_state(const Array< Gen_MultiPolynomial > &basis, Array< Array< size_t > > &leading_monomials, Pair_Queue &queue, Pair_Registry &queued_pairs, Pair_Registry &zero_pairs)
Gen_MultiPolynomial operator*(const Coefficient &s) const
Multiply by a scalar.
static Gen_MultiPolynomial _substitute_var(const Gen_MultiPolynomial &p, size_t var, const Coefficient &val)
Substitute a single variable with a scalar value.
Gen_MultiPolynomial & operator-=(const Gen_MultiPolynomial &q)
In-place subtraction.
void add_to_coeff(const Array< size_t > &idx, const Coefficient &delta)
Add delta to the coefficient at idx.
static Gen_MultiPolynomial from_binary(std::istream &in)
Deserialize polynomial from binary stream.
static bool _build_interpolation_grid(const Gen_MultiPolynomial &p, const Array< size_t > &other_vars, Coefficient start, Coefficient step, Array< Array< Coefficient > > &grid, size_t &total_points)
Build a regular interpolation grid for the active non-main variables.
Array< size_t > norm(const Array< size_t > &idx) const
Pad an index to nvars_ trailing zeros.
static bool lcm_pair_less(const Pair_Candidate &lhs, const Pair_Candidate &rhs)
Gen_MultiPolynomial()=default
Default constructor: the zero polynomial with 0 variables.
Gen_MultiPolynomial & operator+=(const Coefficient &s)
In-place addition of a scalar constant term.
Coefficient operator()(const Array< Coefficient > &pt) const
Evaluate at a point (function-call syntax).
static Gen_MultiPolynomial _embed_coeff_poly_as_x_term(const Gen_MultiPolynomial &coeff_poly, size_t nvars, size_t main_var, const Array< size_t > &other_vars, size_t exp)
Embed a coefficient polynomial in the ambient ring and multiply by x_main^exp.
static Gen_MultiPolynomial _embed_univariate(const Gen_Polynomial< Coefficient > &u, size_t nv, const size_t x_var)
Embed a univariate polynomial into the multivariate ring.
static bool _try_extract_affine_linear_factor(const Gen_MultiPolynomial &p, Gen_MultiPolynomial &factor)
Try to extract a monic affine linear factor via multivariate lifting.
Coefficient coeff_at(const Array< size_t > &idx) const
Read coefficient at a multi-index (0 if absent).
static Array< Gen_MultiPolynomial > minimize_groebner_basis(Array< Gen_MultiPolynomial > basis)
bool operator==(const Gen_MultiPolynomial &q) const
Polynomial equality.
static Array< Gen_MultiPolynomial > autoreduce_groebner_basis(Array< Gen_MultiPolynomial > basis)
static Array< Coefficient > _decode_grid_point(const Array< Array< Coefficient > > &grid, size_t flat_index)
Decode a flat tensor-grid index into coordinates (last dimension fastest).
size_t num_vars() const noexcept
Number of variables.
static Array< Gen_MultiPolynomial > ideal_sum(const Array< Gen_MultiPolynomial > &a, const Array< Gen_MultiPolynomial > &b)
Sum of two ideals: I + J = ⟨generators(I) ∪ generators(J)⟩.
Gen_MultiPolynomial pow(size_t n) const
Exponentiation by repeated squaring.
bool operator!=(const Gen_MultiPolynomial &q) const
Polynomial inequality.
static Array< Gen_MultiPolynomial > remove_zero_and_duplicates(const Array< Gen_MultiPolynomial > &basis)
Array< Array< Gen_MultiPolynomial > > hessian() const
Hessian matrix: all second-order partial derivatives.
static bool ideal_member(const Gen_MultiPolynomial &f, const Array< Gen_MultiPolynomial > &generators)
Test membership in an ideal via Gröbner basis.
DynMapTree< Array< size_t >, Coefficient, Avl_Tree, MonomOrder > coeffs
std::pair< Array< Gen_MultiPolynomial >, Gen_MultiPolynomial > divmod(const Array< Gen_MultiPolynomial > &divisors) const
Multivariate division with remainder (Buchberger algorithm).
static Gen_MultiPolynomial _build_affine_factor(size_t nvars, size_t main_var, const Array< size_t > &other_vars, const Array< Coefficient > &base_eval_pts, const Array< Coefficient > &slopes, const Coefficient &base_root)
Build a monic affine linear factor from root data.
static bool pair_is_zero_known(const Pair_Registry &zero_pairs, size_t i, size_t j)
Gen_MultiPolynomial & operator+=(const Gen_MultiPolynomial &q)
In-place addition.
Coefficient eval(const Array< Coefficient > &pt) const
Evaluate at a point.
static Coefficient _eval_monomial(const Array< Coefficient > &pt, const Array< size_t > &alpha)
Evaluate a monomial at a point.
static Array< Gen_MultiPolynomial > ideal_product(const Array< Gen_MultiPolynomial > &a, const Array< Gen_MultiPolynomial > &b)
Product of two ideals: I · J = ⟨a_i · b_j : a_i ∈ I, b_j ∈ J⟩.
Gen_MultiPolynomial(const size_t nvars, const Array< size_t > &idx, const Coefficient &c)
Single-term constructor.
size_t degree() const noexcept
Total degree (maximum sum of exponents over all terms).
DynList< std::pair< Array< size_t >, Coefficient > > terms() const
All terms as a list (ascending order).
static Gen_MultiPolynomial fit_weighted(const Array< std::pair< Array< Coefficient >, Coefficient > > &data, size_t nvars, const Array< Array< size_t > > &basis, const Array< Coefficient > &weights)
Weighted least-squares polynomial fitting.
static bool ideals_equal(const Array< Gen_MultiPolynomial > &I_gens, const Array< Gen_MultiPolynomial > &J_gens)
Test equality of two ideals: I = J.
Univariate polynomial over a generic coefficient ring.
void for_each_term(Op &&op) const
Iterate over non-zero terms in ascending exponent order.
void set_coeff(size_t exp, const Coefficient &c)
Set coefficient at exponent; removes entry if zero.
Coefficient get_coeff(size_t exp) const noexcept
Coefficient accessor (read-only at exponent).
size_t size() const noexcept
Count the number of elements of the list.
Graph implemented with double-linked adjacency lists.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
constexpr bool is_empty() const noexcept
Checks if the graph is empty (has no nodes).
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
constexpr size_t size() const noexcept
Returns the number of entries in the table.
__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_dim_function > > dim(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
__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_unary_expr< __gmp_expr< T, U >, __gmp_gamma_function > > gamma(const __gmp_expr< T, U > &expr)
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
List_Graph< Graph_Node< string >, Graph_Arc< Empty_Class > > G
DynArray< Graph::Node * > nodes
Singly linked list implementations with head-tail access.
Freq_Node * pred
Predecessor node in level-order traversal.
bool divides_index(const Array< size_t > &alpha, const Array< size_t > &beta, size_t nvars) noexcept
Test whether alpha divides beta component-wise (alpha(i) <= beta(i) all i).
Coefficient eval_monomial(const Array< Coefficient > &pt, const Array< size_t > &alpha)
Evaluate monomial at a point (helper for fitting/interpolation).
T falling_factorial(const size_t k, const size_t n)
Falling factorial k(k-1)(k-2)...(k-n+1).
Array< size_t > decrement_index_at(const Array< size_t > &idx, const size_t var, const size_t n=1)
Decrement exponent at a specific variable.
bool is_zero_index(const Array< size_t > &idx) noexcept
Test whether a multi-index is the zero vector.
Array< size_t > flat_to_multi_index(size_t flat, const Array< size_t > &sizes)
Convert flat index to multi-index given sizes per dimension.
T int_power(const T &base, size_t exp)
Integer power by repeated squaring.
Array< size_t > lcm_indices(const Array< size_t > &a, const Array< size_t > &b, const size_t nvars)
Component-wise max = monomial LCM.
size_t multi_to_flat_index(const Array< size_t > &midx, const Array< size_t > &sizes)
Convert multi-index to flat index given sizes per dimension.
size_t total_degree(const Array< size_t > &idx) noexcept
Total degree of a multi-index (sum of exponents).
Array< size_t > add_indices(const Array< size_t > &a, const Array< size_t > &b)
Component-wise addition of two multi-indices.
Array< size_t > sub_indices(const Array< size_t > &beta, const Array< size_t > &alpha, const size_t nvars)
Component-wise subtraction beta - alpha (requires alpha divides beta).
Array< size_t > extend_index(const Array< size_t > &idx, size_t target)
Pad a multi-index with trailing zeros to reach target size.
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).
auto pmaps(ThreadPool &pool, const Container &c, Op op, size_t chunk_size=0)
Parallel map operation.
bool eq(const C1 &c1, const C2 &c2, Eq e=Eq())
Check equality of two containers using a predicate.
DynList< T > intercept(const Container< T > &c1, const Container< T > &c2)
size_t size(Node *root) noexcept
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
DynArray< T > & in_place_sort(DynArray< T > &c, Cmp cmp=Cmp())
Sorts a DynArray in place.
PolyFitAnalysis< C > analyze_fit(const Gen_MultiPolynomial< C, M > &poly, const Array< std::pair< Array< C >, C > > &data)
Compute residual analysis for a polynomial fit.
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).
T product(const Container &container, const T &init=T{1})
Compute product of all elements.
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.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
AVL binary search tree with nodes without virtual destructor.
Factorization term: a factor polynomial with its multiplicity.
Gen_MultiPolynomial factor
bool operator()(const Pair_Candidate &lhs, const Pair_Candidate &rhs) const
Deterministic ordering of primitive univariate factors by normalized signature.
bool operator()(const Gen_Polynomial< Coefficient > &lhs, const Gen_Polynomial< Coefficient > &rhs) const
Deterministic ordering of primitive univariate linear factors.
bool operator()(const Uni_Linear_Factor_Data &lhs, const Uni_Linear_Factor_Data &rhs) const
Primitive linear factor data for a chosen main variable.
Coefficient constant_term
Graded reverse lexicographic monomial order (default).
bool operator()(const Array< size_t > &a, const Array< size_t > &b) const noexcept
Graded lexicographic monomial order.
bool operator()(const Array< size_t > &a, const Array< size_t > &b) const noexcept
Lexicographic monomial order.
bool operator()(const Array< size_t > &a, const Array< size_t > &b) const noexcept
Structure holding residual analysis for polynomial fits.
double rmse
Root mean squared error.
double rss
Residual sum of squares.
double ess
Explained sum of squares.
Array< C > residuals
Per-point residuals.
double r_squared
Coefficient of determination (0–1)
double mean_y
Mean of y values.
double tss
Total sum of squares.
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)
Dynamic array container with automatic resizing.
Dynamic binary heap with node-based storage.
Dynamic key-value map based on balanced binary search trees.
Univariate polynomial ring arithmetic over generic coefficients.