LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
root_of_utils.cpp
浏览该文件的文档.
1
#include "
internal/expression_transform.hpp
"
2
#include "
root_of_utils.hpp
"
3
#include "
solve_polynomial.hpp
"
4
#include "
internal/symbolic_ast.hpp
"
5
#include "
internal/exact_root.hpp
"
6
7
namespace
LMCAS
{
8
9
10
11
12
13
14
static
std::vector<std::shared_ptr<SymbolicExpr>>
solve_closed_form_from_poly
(
15
const
Polynomial<SymbolicPolyCoeff>
& poly,
16
const
std::string& var,
ComputationContext
&
context
)
17
{
18
19
detail::RewriteBudget
transform_budget(
context
, (
context
).limits().max_recursion_depth,
20
(
context
).limits().max_ast_nodes,
"transform"
);
21
int
deg = poly.
degree
();
22
if
(deg <= 0)
return
{};
23
24
auto
get_coeff
= [&](
int
d) -> std::shared_ptr<SymbolicExpr> {
25
if
(d < 0 || d > deg)
return
SymbolicExpr::number(0);
26
return
poly.
coeffs
[d].val ? poly.
coeffs
[d].val : SymbolicExpr::number(0);
27
};
28
29
if
(deg == 1) {
30
31
auto
a
=
get_coeff
(1);
32
auto
b
=
get_coeff
(0);
33
auto
neg_b = SymbolicExpr::multiply(
b
, SymbolicExpr::number(-1));
34
return
{
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(SymbolicExpr::divide(neg_b,
a
)), transform_budget)) };
35
}
else
if
(deg == 2) {
36
auto
a
=
get_coeff
(2);
37
auto
b
=
get_coeff
(1);
38
auto
c
=
get_coeff
(0);
39
40
auto
b2 = SymbolicExpr::power(
b
, SymbolicExpr::number(2));
41
auto
four_ac = SymbolicExpr::multiply(SymbolicExpr::number(4), SymbolicExpr::multiply(
a
,
c
));
42
auto
delta = SymbolicExpr::add(b2, SymbolicExpr::multiply(four_ac, SymbolicExpr::number(-1)));
43
auto
sqrt_delta = SymbolicExpr::sqrt(delta);
44
auto
neg_b = SymbolicExpr::multiply(
b
, SymbolicExpr::number(-1));
45
auto
two_a = SymbolicExpr::multiply(SymbolicExpr::number(2),
a
);
46
47
auto
x1 =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(SymbolicExpr::divide(SymbolicExpr::add(neg_b, sqrt_delta), two_a)), transform_budget));
48
auto
x2 =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(SymbolicExpr::divide(SymbolicExpr::add(neg_b, SymbolicExpr::multiply(sqrt_delta, SymbolicExpr::number(-1))), two_a)), transform_budget));
49
return
{ x1, x2 };
50
}
else
if
(deg == 3) {
51
auto
a
=
get_coeff
(3);
52
auto
b
=
get_coeff
(2);
53
auto
c
=
get_coeff
(1);
54
auto
d =
get_coeff
(0);
55
return
solve_cubic
(
a
,
b
,
c
, d, var);
56
}
else
if
(deg == 4) {
57
auto
a
=
get_coeff
(4);
58
auto
b
=
get_coeff
(3);
59
auto
c
=
get_coeff
(2);
60
auto
d =
get_coeff
(1);
61
auto
e
=
get_coeff
(0);
62
return
solve_quartic
(
a
,
b
,
c
, d,
e
, var);
63
}
64
65
return
{};
66
}
67
68
69
70
71
std::shared_ptr<SymbolicExpr>
rootof_simplify
(
72
const
std::shared_ptr<SymbolicExpr>& rootof_expr)
73
{
74
ComputationContext
context
;
75
if
(!rootof_expr || !
LMCAS::detail::node
(rootof_expr))
return
rootof_expr;
76
77
auto
root = std::dynamic_pointer_cast<const RootOfNode>(
78
LMCAS::detail::node
(rootof_expr));
79
if
(!root)
return
rootof_expr;
80
81
const
std::string& var = root->variable();
82
const
int
k =
static_cast<
int
>
(root->index());
83
std::vector<SymbolicPolyCoeff> coefficients;
84
coefficients.reserve(root->exact_id().polynomial.coeffs.size());
85
for
(
const
auto
& coefficient : root->exact_id().polynomial.coeffs) {
86
coefficients.emplace_back(SymbolicExpr::number(coefficient));
87
}
88
Polynomial<SymbolicPolyCoeff>
sym_poly(coefficients, var);
89
90
int
degree = sym_poly.
degree
();
91
if
(degree <= 0)
return
rootof_expr;
92
93
if
(k < 0 || k >= degree) {
94
return
rootof_expr;
95
}
96
97
if
(degree == 1) {
98
auto
roots
=
solve_closed_form_from_poly
(sym_poly, var,
context
);
99
return
roots
.size() == 1 ?
roots
.front() : rootof_expr;
100
}
101
if
(degree == 2) {
102
auto
roots
=
solve_closed_form_from_poly
(sym_poly, var,
context
);
103
if
(
roots
.size() != 2)
return
rootof_expr;
104
return
roots
[
static_cast<
std::size_t
>
(1 - k)];
105
}
106
107
return
rootof_expr;
108
}
109
110
}
LMCAS::ComputationContext
定义
computation_context.hpp:99
LMCAS::Polynomial
一元多项式模板类
定义
polynomial.hpp:52
LMCAS::Polynomial::coeffs
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
定义
polynomial.hpp:55
LMCAS::Polynomial::degree
int degree() const
获取多项式的次数
定义
polynomial.hpp:100
LMCAS::detail::RewriteBudget
定义
rewrite_budget.hpp:15
exact_root.hpp
expression_transform.hpp
LMCAS::detail::make_expression_ptr
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
定义
base.hpp:111
LMCAS::detail::node
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
定义
base.hpp:91
LMCAS::detail::normalize_node
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
定义
symbolic_core.cpp:201
LMCAS
定义
assumption.hpp:11
LMCAS::rootof_simplify
std::shared_ptr< SymbolicExpr > rootof_simplify(const std::shared_ptr< SymbolicExpr > &rootof_expr)
定义
root_of_utils.cpp:71
LMCAS::e
ExprResult e()
定义
expr_values.cpp:112
LMCAS::context
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
定义
exact_factorization.hpp:65
LMCAS::solve_quartic
std::vector< std::shared_ptr< SymbolicExpr > > solve_quartic(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::shared_ptr< SymbolicExpr > &d, const std::shared_ptr< SymbolicExpr > &e, const std::string &variable)
定义
solve_polynomial_quartic.cpp:48
LMCAS::c
const VectorField const VectorField & c
定义
vector_calculus_vectors.hpp:60
LMCAS::solve_closed_form_from_poly
static std::vector< std::shared_ptr< SymbolicExpr > > solve_closed_form_from_poly(const Polynomial< SymbolicPolyCoeff > &poly, const std::string &var, ComputationContext &context)
定义
root_of_utils.cpp:14
LMCAS::b
const MultiPoly & b
定义
multivariate_factor.hpp:92
LMCAS::a
__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
定义
vector_calculus_curves.hpp:50
LMCAS::get_coeff
std::shared_ptr< SymbolicExpr > get_coeff(const Polynomial< SymbolicPolyCoeff > &p, int deg)
定义
solve_visitor.cpp:41
LMCAS::roots
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
定义
expr_solving.cpp:80
LMCAS::solve_cubic
std::vector< std::shared_ptr< SymbolicExpr > > solve_cubic(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::shared_ptr< SymbolicExpr > &d, const std::string &variable)
定义
solve_polynomial_cubic.cpp:211
root_of_utils.hpp
RootOf 恒等关系、求值及代数闭式化简。
solve_polynomial.hpp
symbolic_ast.hpp
内部 AST 定义。
src
root_of_utils.cpp
生成于
, 为 LMCAS使用
1.18.0