LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
solver_groebner_basis.cpp
浏览该文件的文档.
1
#include "
internal/solver_groebner_internal.hpp
"
2
#include <algorithm>
3
#include <functional>
4
#include <queue>
5
6
namespace
LMCAS::groebner_detail
{
7
namespace
{
8
using
PairQueue
= std::priority_queue<SugarPair, std::vector<SugarPair>, std::greater<SugarPair>>;
9
10
void
initialize_sugar
(std::vector<Poly>&
basis
) {
11
for
(
auto
& polynomial :
basis
) {
12
if
(polynomial.is_zero())
continue
;
13
int
maximum = 0;
14
for
(
const
auto
& [monomial, coefficient] : polynomial.terms) {
15
(void)coefficient;
16
int
degree = 0;
17
for
(
int
exponent
: monomial) degree +=
exponent
;
18
maximum = std::max(maximum, degree);
19
}
20
polynomial.sugar = maximum;
21
}
22
}
23
24
PairQueue
initial_pairs
(
const
std::vector<Poly>&
basis
) {
25
PairQueue
pairs;
26
for
(
size_t
i = 0; i <
basis
.size(); ++i) {
27
for
(
size_t
j = i + 1; j <
basis
.size(); ++j) {
28
pairs.push({i, j,
compute_spoly_sugar
(
basis
[i],
basis
[j])});
29
}
30
}
31
return
pairs;
32
}
33
34
std::vector<Poly>
minimal_basis
(
const
std::vector<Poly>&
basis
) {
35
std::vector<bool> marked(
basis
.size(),
false
);
36
for
(
size_t
i = 0; i <
basis
.size(); ++i) {
37
if
(marked[i])
continue
;
38
for
(
size_t
j = 0; j <
basis
.size(); ++j) {
39
if
(i == j || marked[j])
continue
;
40
if
(
divides_mono
(
basis
[j].lead_monomial(),
basis
[i].lead_monomial())) {
41
marked[i] =
true
;
42
break
;
43
}
44
}
45
}
46
std::vector<Poly> minimal;
47
for
(
size_t
i = 0; i <
basis
.size(); ++i) {
48
if
(!marked[i]) minimal.push_back(
basis
[i]);
49
}
50
return
minimal;
51
}
52
53
void
make_monic
(
Poly
& polynomial) {
54
Rational leading = polynomial.
lead_coeff
();
55
if
(leading == Rational(0) || leading == Rational(1))
return
;
56
Rational inverse = Rational(1) / leading;
57
Poly
monic(polynomial.
num_vars
);
58
for
(
const
auto
& [monomial, coefficient] : polynomial.
terms
) {
59
monic.add_term(monomial, coefficient * inverse);
60
}
61
polynomial = std::move(monic);
62
}
63
}
64
65
void
buchberger
(std::vector<Poly>&
basis
,
size_t
num_vars) {
66
initialize_sugar(
basis
);
67
auto
pairs = initial_pairs(
basis
);
68
std::set<std::pair<size_t, size_t>> processed_pairs;
69
while
(!pairs.empty()) {
70
auto
[i, j, sugar_degree] = pairs.top();
71
pairs.pop();
72
auto
canonical_pair = i < j ? std::make_pair(i, j) : std::make_pair(j, i);
73
processed_pairs.insert(canonical_pair);
74
if
(
coprime_leading_monomials
(
basis
[i],
basis
[j]))
continue
;
75
if
(
chain_criterion
(
basis
, i, j, processed_pairs))
continue
;
76
Poly
polynomial =
s_poly
(
basis
[i],
basis
[j]);
77
extend_variables
(polynomial, num_vars);
78
Poly
remainder =
reduce
(polynomial,
basis
);
79
if
(remainder.
is_zero
())
continue
;
80
remainder.
sugar
= sugar_degree;
81
size_t
new_index =
basis
.size();
82
basis
.push_back(remainder);
83
for
(
size_t
k = 0; k < new_index; ++k) {
84
pairs.push({k, new_index,
compute_spoly_sugar
(
basis
[k],
basis
[new_index])});
85
}
86
}
87
}
88
89
void
reduce_basis
(std::vector<Poly>&
basis
) {
90
auto
minimal = minimal_basis(
basis
);
91
for
(
size_t
i = 0; i < minimal.size(); ++i) {
92
std::vector<Poly> others;
93
for
(
size_t
j = 0; j < minimal.size(); ++j) {
94
if
(j != i) others.push_back(minimal[j]);
95
}
96
minimal[i] =
reduce
(minimal[i], others);
97
}
98
std::vector<Poly> reduced;
99
for
(
const
auto
& polynomial : minimal) {
100
if
(!polynomial.is_zero()) reduced.push_back(polynomial);
101
}
102
for
(
auto
& polynomial : reduced) make_monic(polynomial);
103
basis
= std::move(reduced);
104
}
105
}
LMCAS::groebner_detail::anonymous_namespace{solver_groebner_basis.cpp}::initialize_sugar
void initialize_sugar(std::vector< Poly > &basis)
定义
solver_groebner_basis.cpp:10
LMCAS::groebner_detail::anonymous_namespace{solver_groebner_basis.cpp}::make_monic
void make_monic(Poly &polynomial)
定义
solver_groebner_basis.cpp:53
LMCAS::groebner_detail::anonymous_namespace{solver_groebner_basis.cpp}::initial_pairs
PairQueue initial_pairs(const std::vector< Poly > &basis)
定义
solver_groebner_basis.cpp:24
LMCAS::groebner_detail::anonymous_namespace{solver_groebner_basis.cpp}::minimal_basis
std::vector< Poly > minimal_basis(const std::vector< Poly > &basis)
定义
solver_groebner_basis.cpp:34
LMCAS::groebner_detail::anonymous_namespace{solver_groebner_basis.cpp}::PairQueue
std::priority_queue< SugarPair, std::vector< SugarPair >, std::greater< SugarPair > > PairQueue
定义
solver_groebner_basis.cpp:8
LMCAS::groebner_detail
定义
solver_groebner_builder.hpp:6
LMCAS::groebner_detail::chain_criterion
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)
定义
solver_groebner_poly.cpp:168
LMCAS::groebner_detail::coprime_leading_monomials
bool coprime_leading_monomials(const Poly &f, const Poly &g)
定义
solver_groebner_poly.cpp:154
LMCAS::groebner_detail::extend_variables
void extend_variables(Poly &polynomial, size_t count)
定义
solver_groebner_poly.cpp:207
LMCAS::groebner_detail::s_poly
Poly s_poly(const Poly &f, const Poly &g)
定义
solver_groebner_poly.cpp:140
LMCAS::groebner_detail::reduce
Poly reduce(Poly polynomial, const std::vector< Poly > &basis)
定义
solver_groebner_poly.cpp:109
LMCAS::groebner_detail::compute_spoly_sugar
int compute_spoly_sugar(const Poly &f, const Poly &g)
定义
solver_groebner_poly.cpp:189
LMCAS::groebner_detail::reduce_basis
void reduce_basis(std::vector< Poly > &basis)
定义
solver_groebner_basis.cpp:89
LMCAS::groebner_detail::divides_mono
bool divides_mono(const Monomial &a, const Monomial &b)
定义
solver_groebner_poly.cpp:59
LMCAS::groebner_detail::buchberger
void buchberger(std::vector< Poly > &basis, size_t num_vars)
定义
solver_groebner_basis.cpp:65
LMCAS::exponent
const ExprPtr & exponent
定义
expr.hpp:215
LMCAS::basis
const std::vector< FGLMPoly > & basis
定义
fglm.hpp:102
solver_groebner_internal.hpp
LMCAS::groebner_detail::Poly
定义
solver_groebner_internal.hpp:28
LMCAS::groebner_detail::Poly::terms
PolyTerms terms
定义
solver_groebner_internal.hpp:29
LMCAS::groebner_detail::Poly::lead_coeff
Rational lead_coeff() const
定义
solver_groebner_poly.cpp:21
LMCAS::groebner_detail::Poly::sugar
int sugar
定义
solver_groebner_internal.hpp:31
LMCAS::groebner_detail::Poly::num_vars
size_t num_vars
定义
solver_groebner_internal.hpp:30
LMCAS::groebner_detail::Poly::is_zero
bool is_zero() const
定义
solver_groebner_internal.hpp:35
src
solver_groebner_basis.cpp
生成于
, 为 LMCAS使用
1.18.0