LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
solver_groebner_builder.cpp
浏览该文件的文档.
1
#include "
internal/solver_groebner_builder.hpp
"
2
#include <algorithm>
3
#include <cmath>
4
#include <limits>
5
#include <optional>
6
7
namespace
LMCAS::groebner_detail
{
8
namespace
{
9
std::optional<BigInt>
integer_exponent
(
const
PowerNode
& node) {
10
if
(!node.exponent()->is_number()) {
11
return
std::nullopt;
12
}
13
auto
number = std::dynamic_pointer_cast<const NumberNode>(node.exponent());
14
if
(!number) {
15
return
std::nullopt;
16
}
17
const
auto
&
value
= number->value();
18
if
(std::holds_alternative<BigInt>(
value
)) {
19
return
std::get<BigInt>(
value
);
20
}
21
if
(std::holds_alternative<Rational>(
value
)) {
22
const
auto
&
rational
= std::get<Rational>(
value
);
23
if
(
rational
.is_integer()) {
24
return
rational
.to_bigint();
25
}
26
}
27
return
std::nullopt;
28
}
29
30
bool
power_degrees_fit
(
const
Poly
& base,
int
exponent
) {
31
for
(
const
auto
& [monomial, coefficient] : base.
terms
) {
32
(void)coefficient;
33
for
(
int
degree : monomial) {
34
if
(degree > std::numeric_limits<int>::max() /
exponent
)
return
false
;
35
}
36
}
37
return
true
;
38
}
39
}
40
41
PolyBuilder::PolyBuilder
(
const
std::vector<std::string>&
v
,
PolyContext
& ctx,
bool
strict)
42
:
SymbolicVisitor
(&ctx.budget),
vars
(
v
),
ext_vars
(ctx.
ext_vars
),
43
transcendental_map
(ctx.
transcendental_map
),
aux_to_node
(&ctx.
aux_to_node
),
44
result
(ctx.
ext_vars
.size()),
strict_mode
(strict) {}
45
46
void
PolyBuilder::visit
(
const
NumberNode
& node) {
47
result
=
Poly
(
ext_vars
.size());
48
49
if
(std::holds_alternative<Rational>(node.value())) {
50
result
.
add_term
(std::vector<int>(
ext_vars
.size(), 0), std::get<Rational>(node.value()));
51
}
else
if
(std::holds_alternative<BigInt>(node.value())) {
52
result
.
add_term
(std::vector<int>(
ext_vars
.size(), 0), Rational(std::get<BigInt>(node.value())));
53
}
54
}
55
56
void
PolyBuilder::visit
(
const
VariableNode
& node) {
57
result
=
Poly
(
ext_vars
.size());
58
59
auto
it = node.is_constant() ?
ext_vars
.end() :
60
std::find(
ext_vars
.begin(),
ext_vars
.end(), node.name());
61
if
(it !=
ext_vars
.end()) {
62
Monomial
m(
ext_vars
.size(), 0);
63
m[std::distance(
ext_vars
.begin(), it)] = 1;
64
result
.
add_term
(m, Rational(1));
65
}
else
{
66
67
if
(
strict_mode
) {
68
failed
=
true
;
69
return
;
70
}
71
size_t
idx =
get_or_create_aux_var
(
LMCAS::detail::make_node<VariableNode>
(node.name(), node.is_constant()));
72
73
result
=
Poly
(
ext_vars
.size());
74
Monomial
m(
ext_vars
.size(), 0);
75
m[idx] = 1;
76
result
.
add_term
(m, Rational(1));
77
}
78
}
79
80
void
PolyBuilder::visit
(
const
AddNode
& node) {
81
Poly
sum(
ext_vars
.size());
82
for
(
auto
&
op
: node.operands()) {
83
PolyBuilder
b
(
vars
,
ext_vars
,
transcendental_map
,
aux_to_node
,
84
*
rewrite_budget
(),
strict_mode
);
85
op
->accept(
b
);
86
if
(
b
.failed) {
failed
=
true
;
return
; }
87
88
Poly
b_res =
b
.get_result();
89
align_variables
(sum, b_res);
90
sum =
add_poly
(sum, b_res);
91
}
92
result
= sum;
93
}
94
95
void
PolyBuilder::visit
(
const
MultiplyNode
& node) {
96
Poly
prod(
ext_vars
.size());
97
prod.
add_term
(std::vector<int>(
ext_vars
.size(), 0), Rational(1));
98
99
for
(
auto
&
op
: node.operands()) {
100
PolyBuilder
b
(
vars
,
ext_vars
,
transcendental_map
,
aux_to_node
,
101
*
rewrite_budget
(),
strict_mode
);
102
op
->accept(
b
);
103
if
(
b
.failed) {
failed
=
true
;
return
; }
104
Poly
b_res =
b
.get_result();
105
106
align_variables
(prod, b_res);
107
prod =
mul_poly
(prod, b_res);
108
}
109
result
= prod;
110
}
111
112
void
PolyBuilder::visit
(
const
PowerNode
& node) {
113
PolyBuilder
builder(
vars
,
ext_vars
,
transcendental_map
,
aux_to_node
,
114
*
rewrite_budget
(),
strict_mode
);
115
node.base()->accept(builder);
116
if
(builder.
failed
) {
117
failed
=
true
;
118
return
;
119
}
120
Poly
base = builder.
get_result
();
121
auto
exponent
= integer_exponent(node);
122
if
(!
exponent
|| *
exponent
> BigInt(std::numeric_limits<int>::max()) ||
123
*
exponent
< 0) {
124
if
(
strict_mode
) {
125
failed
=
true
;
126
return
;
127
}
128
represent_as_aux_or_fail
(
129
LMCAS::detail::make_node<PowerNode>
(node.base(), node.exponent()));
130
return
;
131
}
132
if
(*
exponent
== 0) {
133
result
=
Poly
(
ext_vars
.size());
134
result
.
add_term
(
Monomial
(
ext_vars
.size(), 0), Rational(1));
135
return
;
136
}
137
const
int
count =
static_cast<
int
>
(
exponent
->try_to_int64().
value
());
138
if
(!power_degrees_fit(base, count)) {
139
represent_as_aux_or_fail
(node.clone());
140
return
;
141
}
142
Poly
product(
ext_vars
.size());
143
product.
add_term
(
Monomial
(
ext_vars
.size(), 0), Rational(1));
144
for
(
int
index = 0; index < count; ++index) {
145
extend_variables
(product, base.
num_vars
);
146
product =
mul_poly
(product, base);
147
}
148
result
= product;
149
}
150
}
LMCAS::AddNode
加法节点,表示多个操作数的求和。
定义
arithmetic.hpp:55
LMCAS::MultiplyNode
乘法节点,表示多个操作数的乘积。
定义
arithmetic.hpp:134
LMCAS::NumberNode
定义
numbers.hpp:8
LMCAS::PowerNode
幂运算节点,表示 base^exponent。
定义
arithmetic.hpp:218
LMCAS::VariableNode
变量节点,表示一个符号变量。
定义
arithmetic.hpp:10
LMCAS::detail::SymbolicVisitor::SymbolicVisitor
SymbolicVisitor()=default
LMCAS::detail::SymbolicVisitor::rewrite_budget
RewriteBudget * rewrite_budget() const noexcept
定义
base.hpp:220
LMCAS::groebner_detail::PolyBuilder::ext_vars
std::vector< std::string > & ext_vars
定义
solver_groebner_builder.hpp:11
LMCAS::groebner_detail::PolyBuilder::get_or_create_aux_var
size_t get_or_create_aux_var(const std::shared_ptr< const SymbolicNode > &node)
定义
solver_groebner_conversion.cpp:7
LMCAS::groebner_detail::PolyBuilder::vars
std::vector< std::string > vars
定义
solver_groebner_builder.hpp:9
LMCAS::groebner_detail::PolyBuilder::failed
bool failed
定义
solver_groebner_builder.hpp:41
LMCAS::groebner_detail::PolyBuilder::get_result
Poly get_result() const
定义
solver_groebner_builder.hpp:40
LMCAS::groebner_detail::PolyBuilder::PolyBuilder
PolyBuilder(const std::vector< std::string > &v, PolyContext &ctx, bool strict=false)
定义
solver_groebner_builder.cpp:41
LMCAS::groebner_detail::PolyBuilder::transcendental_map
std::unordered_map< std::string, size_t > & transcendental_map
定义
solver_groebner_builder.hpp:13
LMCAS::groebner_detail::PolyBuilder::aux_to_node
std::unordered_map< size_t, std::shared_ptr< const SymbolicNode > > * aux_to_node
定义
solver_groebner_builder.hpp:15
LMCAS::groebner_detail::PolyBuilder::visit
void visit(const NumberNode &node) override
定义
solver_groebner_builder.cpp:46
LMCAS::groebner_detail::PolyBuilder::result
Poly result
定义
solver_groebner_builder.hpp:16
LMCAS::groebner_detail::PolyBuilder::represent_as_aux_or_fail
void represent_as_aux_or_fail(const std::shared_ptr< const SymbolicNode > &node)
定义
solver_groebner_conversion.cpp:28
LMCAS::groebner_detail::PolyBuilder::strict_mode
bool strict_mode
定义
solver_groebner_builder.hpp:17
LMCAS::detail::make_node
std::shared_ptr< const Node > make_node(Args &&... args)
定义
base.hpp:123
LMCAS::groebner_detail::anonymous_namespace{solver_groebner_builder.cpp}::integer_exponent
std::optional< BigInt > integer_exponent(const PowerNode &node)
定义
solver_groebner_builder.cpp:9
LMCAS::groebner_detail::anonymous_namespace{solver_groebner_builder.cpp}::power_degrees_fit
bool power_degrees_fit(const Poly &base, int exponent)
定义
solver_groebner_builder.cpp:30
LMCAS::groebner_detail
定义
solver_groebner_builder.hpp:6
LMCAS::groebner_detail::mul_poly
Poly mul_poly(const Poly &a, const Poly &b)
定义
solver_groebner_poly.cpp:99
LMCAS::groebner_detail::extend_variables
void extend_variables(Poly &polynomial, size_t count)
定义
solver_groebner_poly.cpp:207
LMCAS::groebner_detail::align_variables
void align_variables(Poly &a, Poly &b)
定义
solver_groebner_poly.cpp:218
LMCAS::groebner_detail::add_poly
Poly add_poly(const Poly &a, const Poly &b)
定义
solver_groebner_poly.cpp:72
LMCAS::groebner_detail::Monomial
std::vector< int > Monomial
定义
solver_groebner_internal.hpp:16
LMCAS::v
__attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult surface_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::string & v
定义
vector_calculus_surfaces.hpp:59
LMCAS::b
const MultiPoly & b
定义
multivariate_factor.hpp:92
LMCAS::op
const ExprPtr RelationOp op
定义
expr.hpp:151
LMCAS::exponent
const ExprPtr & exponent
定义
expr.hpp:215
LMCAS::value
const std::string const ExprPtr & value
定义
expr.hpp:293
LMCAS::rational
ExprResult rational(const Rational &value)
定义
expr_values.cpp:82
solver_groebner_builder.hpp
LMCAS::groebner_detail::PolyContext
定义
solver_groebner_internal.hpp:42
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::Poly
Poly()
定义
solver_groebner_internal.hpp:33
LMCAS::groebner_detail::Poly::add_term
void add_term(const Monomial &monomial, const Rational &coefficient)
定义
solver_groebner_poly.cpp:31
LMCAS::groebner_detail::Poly::num_vars
size_t num_vars
定义
solver_groebner_internal.hpp:30
src
solver_groebner_builder.cpp
生成于
, 为 LMCAS使用
1.18.0