12 for (std::size_t i = 0; i < num_vars; ++i) {
13 const int left_value = i < left.size() ? left[i] : 0;
14 const int right_value = i <
right.size() ?
right[i] : 0;
15 result[i] = left_value - right_value;
23 for (std::size_t i = 0; i < num_vars; ++i) {
24 const int left_value = i < left.size() ? left[i] : 0;
25 const int right_value = i <
right.size() ?
right[i] : 0;
26 result[i] = left_value + right_value;
32 FGLMPoly& polynomial,
const FGLMPoly& divisor,
36 leading, divisor_leading, polynomial.num_vars);
37 const Rational coefficient =
38 polynomial.lead_coeff() / divisor.lead_coeff();
39 for (
const auto& [monomial,
value] : divisor.terms) {
42 -(coefficient *
value));
44 polynomial.sort_terms(
order);
45 polynomial.normalize();
49 FGLMPoly& polynomial,
const std::vector<FGLMPoly>&
basis,
51 for (
const auto& divisor :
basis) {
52 if (divisor.is_zero()) {
55 const Monomial divisor_leading = divisor.lead_monomial();
60 polynomial, divisor, divisor_leading, leading,
order);
69 void FGLMPoly::sort_terms(
const MonomialOrder&
order) {
70 std::sort(terms.begin(), terms.end(),
71 [&
order](
const std::pair<Monomial, Rational>&
a,
72 const std::pair<Monomial, Rational>&
b) {
73 return order(a.first, b.first);
77 void FGLMPoly::normalize() {
79 std::vector<std::pair<Monomial, Rational>> cleaned;
80 for (
auto& [m,
c] : terms) {
81 if (
c.is_zero())
continue;
82 if (!cleaned.empty() && cleaned.back().first == m) {
83 cleaned.back().second = cleaned.back().second +
c;
84 if (cleaned.back().second.is_zero()) {
88 cleaned.emplace_back(m,
c);
91 terms = std::move(cleaned);
94 FGLMPoly FGLMPoly::reduce(
const std::vector<FGLMPoly>&
basis,
96 FGLMPoly remainder(num_vars);
97 FGLMPoly polynomial = *
this;
98 polynomial.sort_terms(
order);
99 polynomial.normalize();
101 while (!polynomial.is_zero()) {
102 const Monomial previous_leading = polynomial.lead_monomial();
104 polynomial,
basis, previous_leading,
order)) {
106 previous_leading, polynomial.lead_coeff());
107 polynomial.terms.erase(polynomial.terms.begin());
108 polynomial.normalize();
110 if (!polynomial.is_zero() &&
111 !
order(previous_leading, polynomial.lead_monomial())) {
112 throw std::runtime_error(
113 "FGLM polynomial reduction did not decrease the leading monomial");
116 remainder.sort_terms(
order);
117 remainder.normalize();
121 FGLMPoly FGLMPoly::from_monomial(
const Monomial& m,
size_t num_vars) {
122 FGLMPoly p(num_vars);
128 const std::vector<FGLMPoly>&
basis,
单项式序比较器,支持 Lex、GrevLex、DegLex、DegRevLex
FGLM 算法:零维理想 Gröbner 基在不同单项式序之间的转换.
bool reduce_leading_term(FGLMPoly &polynomial, const std::vector< FGLMPoly > &basis, const Monomial &leading, const MonomialOrder &order)
Monomial add_monomials(const Monomial &left, const Monomial &right, std::size_t num_vars)
void subtract_leading_multiple(FGLMPoly &polynomial, const FGLMPoly &divisor, const Monomial &divisor_leading, const Monomial &leading, const MonomialOrder &order)
Monomial subtract_monomials(const Monomial &left, const Monomial &right, std::size_t num_vars)
std::vector< int > Monomial
单项式类型,以整数向量表示各变量的指数
const std::vector< FGLMPoly > const MonomialOrder & order
@ Rational
Rational numbers
const VectorField const VectorField & c
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::shared_ptr< SymbolicExpr > & a
bool divides_monomial(const Monomial &divisor, const Monomial &target)
判断 divisor 是否整除 target
const std::vector< FGLMPoly > & basis
const std::string const ExprPtr & value
FGLMPoly normal_form(const FGLMPoly &f, const std::vector< FGLMPoly > &basis, const MonomialOrder &order)