LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
solver_groebner_poly.cpp
浏览该文件的文档.
2#include <algorithm>
3
5
6 bool MonomialLess::operator()(const Monomial& a, const Monomial& b) const {
7
8 for (size_t i = 0; i < a.size(); ++i) {
9 if (a[i] != b[i]) {
10 return a[i] > b[i];
11 }
12 }
13 return false;
14 }
15
17 if (terms.empty()) return std::vector<int>(num_vars, 0);
18 return terms.begin()->first;
19 }
20
21 Rational Poly::lead_coeff() const {
22 if (terms.empty()) return Rational(0);
23 return terms.begin()->second;
24 }
25
27 if (terms.empty()) return {Rational(0), std::vector<int>(num_vars, 0)};
28 return {terms.begin()->second, terms.begin()->first};
29 }
30
31 void Poly::add_term(const Monomial& m, const Rational& c) {
32 if (c == Rational(0)) return;
33 auto it = terms.find(m);
34 if (it != terms.end()) {
35
36 Rational new_c = it->second + c;
37 if (new_c == Rational(0)) {
38 terms.erase(it);
39 } else {
40 it->second = new_c;
41 }
42 } else {
43 terms[m] = c;
44 }
45 }
46
48 Monomial res(a.size());
49 for (size_t i = 0; i < a.size(); ++i) res[i] = a[i] + b[i];
50 return res;
51 }
52
54 Monomial res(a.size());
55 for (size_t i = 0; i < a.size(); ++i) res[i] = std::max(a[i], b[i]);
56 return res;
57 }
58
59 bool divides_mono(const Monomial& a, const Monomial& b) {
60 for (size_t i = 0; i < a.size(); ++i) {
61 if (a[i] > b[i]) return false;
62 }
63 return true;
64 }
65
66 Monomial div_mono(const Monomial& num, const Monomial& den) {
67 Monomial res(num.size());
68 for (size_t i = 0; i < num.size(); ++i) res[i] = num[i] - den[i];
69 return res;
70 }
71
72 Poly add_poly(const Poly& a, const Poly& b) {
73 Poly res = a;
74 for (auto const& [m, c] : b.terms) {
75 res.add_term(m, c);
76 }
77 return res;
78 }
79
80 Poly sub_poly(const Poly& a, const Poly& b) {
81 Poly res = a;
82 for (auto const& [m, c] : b.terms) {
83
84 Rational c_neg = c * Rational(-1);
85 res.add_term(m, c_neg);
86 }
87 return res;
88 }
89
90 Poly mul_poly_term(const Poly& p, const Term& t) {
91 Poly res(p.num_vars);
92 if (t.coeff == Rational(0)) return res;
93 for (auto const& [m, c] : p.terms) {
94 res.add_term(mul_mono(m, t.mono), c * t.coeff);
95 }
96 return res;
97 }
98
99 Poly mul_poly(const Poly& a, const Poly& b) {
100 Poly res(a.num_vars);
101 for (auto const& [ma, ca] : a.terms) {
102 for (auto const& [mb, cb] : b.terms) {
103 res.add_term(mul_mono(ma, mb), ca * cb);
104 }
105 }
106 return res;
107 }
108
109 Poly reduce(Poly p, const std::vector<Poly>& G) {
110 Poly r(p.num_vars);
111
112 while (!p.is_zero()) {
113 bool reduced = false;
114 Monomial p_lm = p.lead_monomial();
115
116 for (const auto& g : G) {
117 if (divides_mono(g.lead_monomial(), p_lm)) {
118
119 Term factor;
120 factor.coeff = p.lead_coeff() / g.lead_coeff();
121 factor.mono = div_mono(p_lm, g.lead_monomial());
122
123 Poly term_g = mul_poly_term(g, factor);
124 p = sub_poly(p, term_g);
125 reduced = true;
126 break;
127 }
128 }
129
130 if (!reduced) {
131 Term lt = p.lead_term();
132 r.add_term(lt.mono, lt.coeff);
133
134 p.terms.erase(p.terms.begin());
135 }
136 }
137 return r;
138 }
139
140 Poly s_poly(const Poly& f, const Poly& g) {
142
143 Term t1;
144 t1.mono = div_mono(L, f.lead_monomial());
145 t1.coeff = Rational(1) / f.lead_coeff();
146
147 Term t2;
148 t2.mono = div_mono(L, g.lead_monomial());
149 t2.coeff = Rational(1) / g.lead_coeff();
150
151 return sub_poly(mul_poly_term(f, t1), mul_poly_term(g, t2));
152 }
153
154 bool coprime_leading_monomials(const Poly& f, const Poly& g) {
155 if (f.is_zero() || g.is_zero()) {
156 return false;
157 }
158 const Monomial& lm_f = f.lead_monomial();
159 const Monomial& lm_g = g.lead_monomial();
160 for (size_t i = 0; i < lm_f.size() && i < lm_g.size(); ++i) {
161 if (lm_f[i] > 0 && lm_g[i] > 0) {
162 return false;
163 }
164 }
165 return true;
166 }
167
168 bool chain_criterion(const std::vector<Poly>& G, size_t i, size_t j,
169 const std::set<std::pair<size_t,size_t>>& processed_pairs) {
170 Monomial L = lcm_mono(G[i].lead_monomial(), G[j].lead_monomial());
171 for (size_t k = 0; k < G.size(); ++k) {
172 if (k == i || k == j) {
173 continue;
174 }
175 if (G[k].is_zero()) {
176 continue;
177 }
178 if (divides_mono(G[k].lead_monomial(), L)) {
179 auto pair_ik = (i < k) ? std::make_pair(i, k) : std::make_pair(k, i);
180 auto pair_kj = (k < j) ? std::make_pair(k, j) : std::make_pair(j, k);
181 if (processed_pairs.count(pair_ik) && processed_pairs.count(pair_kj)) {
182 return true;
183 }
184 }
185 }
186 return false;
187 }
188
189 int compute_spoly_sugar(const Poly& f, const Poly& g) {
191
192 int deg_L = 0;
193 for (int e : L) deg_L += e;
194
195 int deg_lm_f = 0;
196 for (int e : f.lead_monomial()) deg_lm_f += e;
197
198 int deg_lm_g = 0;
199 for (int e : g.lead_monomial()) deg_lm_g += e;
200
201 int sugar_f = f.sugar + deg_L - deg_lm_f;
202 int sugar_g = g.sugar + deg_L - deg_lm_g;
203
204 return std::max(sugar_f, sugar_g);
205 }
206
207void extend_variables(Poly& polynomial, size_t count) {
208 if (polynomial.num_vars >= count) return;
209 Poly extended(count);
210 for (const auto& [monomial, coefficient] : polynomial.terms) {
211 Monomial resized = monomial;
212 resized.resize(count, 0);
213 extended.add_term(resized, coefficient);
214 }
215 polynomial = std::move(extended);
216}
217
219 if (a.num_vars < b.num_vars) {
220 extend_variables(a, b.num_vars);
221 } else if (b.num_vars < a.num_vars) {
222 extend_variables(b, a.num_vars);
223 }
224}
225}
Monomial div_mono(const Monomial &numerator, const Monomial &denominator)
Poly mul_poly(const Poly &a, const Poly &b)
bool chain_criterion(const std::vector< Poly > &basis, size_t i, size_t j, const std::set< std::pair< size_t, size_t > > &processed_pairs)
bool coprime_leading_monomials(const Poly &f, const Poly &g)
void extend_variables(Poly &polynomial, size_t count)
Poly s_poly(const Poly &f, const Poly &g)
Poly reduce(Poly polynomial, const std::vector< Poly > &basis)
int compute_spoly_sugar(const Poly &f, const Poly &g)
Monomial mul_mono(const Monomial &a, const Monomial &b)
void align_variables(Poly &a, Poly &b)
bool divides_mono(const Monomial &a, const Monomial &b)
Monomial lcm_mono(const Monomial &a, const Monomial &b)
Poly sub_poly(const Poly &a, const Poly &b)
Poly mul_poly_term(const Poly &polynomial, const Term &term)
Poly add_poly(const Poly &a, const Poly &b)
std::shared_ptr< SymbolicExpr > num(int value)
ExprResult e()
__attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std std::shared_ptr< SymbolicExpr > r
const VectorField const VectorField & c
const MultiPoly & b
__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
ExprResult lt(const ExprPtr &lhs, const ExprPtr &rhs)
__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 & t
bool operator()(const Monomial &a, const Monomial &b) const
void add_term(const Monomial &monomial, const Rational &coefficient)