LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
solve_polynomial_quadratic.cpp
浏览该文件的文档.
1
#include "
internal/expression_transform.hpp
"
2
#include "
internal/expression_analysis.hpp
"
3
#include "
internal/polynomial_solver_support.hpp
"
4
#include <stdexcept>
5
6
namespace
LMCAS
{
7
using namespace
polynomial_solver_detail
;
8
9
namespace
polynomial_solver_detail
{
10
std::vector<std::shared_ptr<SymbolicExpr>>
solve_quadratic_internal
(
11
const
std::shared_ptr<SymbolicExpr>&
a
,
const
std::shared_ptr<SymbolicExpr>&
b
,
12
const
std::shared_ptr<SymbolicExpr>&
c
,
ComputationContext
&
context
) {
13
detail::RewriteBudget
transform_budget(
context
, (
context
).limits().max_recursion_depth,
14
(
context
).limits().max_ast_nodes,
"transform"
);
15
auto
b2 = SymbolicExpr::power(
b
,
num
(2));
16
auto
four_ac = SymbolicExpr::multiply(
num
(4), SymbolicExpr::multiply(
a
,
c
));
17
auto
delta =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(
sub
(b2, four_ac)), transform_budget));
18
19
auto
neg_b =
negate
(
b
);
20
auto
two_a = SymbolicExpr::multiply(
num
(2),
a
);
21
if
(delta && delta->is_zero()) {
22
return
{
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(SymbolicExpr::divide(neg_b, two_a)), transform_budget)) };
23
}
24
25
auto
sqrt_delta = SymbolicExpr::sqrt(delta);
26
auto
exact_b =
detail::exact_rational_value
(
detail::node
(
b
));
27
auto
exact_delta =
detail::exact_rational_value
(
detail::node
(delta));
28
if
(exact_b && *exact_b != Rational(0) &&
29
exact_delta && *exact_delta > Rational(0)) {
30
auto
numerator = *exact_b < Rational(0)
31
? SymbolicExpr::add(neg_b, sqrt_delta)
32
:
sub
(neg_b, sqrt_delta);
33
auto
x1 =
detail::make_expression_ptr
(
detail::normalize_node
(
34
detail::node
(SymbolicExpr::divide(numerator, two_a)), transform_budget));
35
auto
x2 =
detail::make_expression_ptr
(
detail::normalize_node
(
36
detail::node
(SymbolicExpr::divide(
37
SymbolicExpr::multiply(
num
(2),
c
), numerator)), transform_budget));
38
return
{x1, x2};
39
}
40
auto
x1 =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(SymbolicExpr::divide(SymbolicExpr::add(neg_b, sqrt_delta), two_a)), transform_budget));
41
auto
x2 =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(SymbolicExpr::divide(
sub
(neg_b, sqrt_delta), two_a)), transform_budget));
42
43
return
{ x1, x2 };
44
}
45
}
46
47
std::vector<std::shared_ptr<SymbolicExpr>>
polynomial_solver_detail::solve_biquadratic_impl
(
48
const
std::shared_ptr<SymbolicExpr>&
a
,
49
const
std::shared_ptr<SymbolicExpr>&
b
,
50
const
std::shared_ptr<SymbolicExpr>&
c
,
51
const
std::string&,
ComputationContext
&
context
) {
52
detail::RewriteBudget
transform_budget(
context
, (
context
).limits().max_recursion_depth,
53
(
context
).limits().max_ast_nodes,
"transform"
);
54
auto
a_simplified =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(
a
), transform_budget));
55
if
(a_simplified->get_number_value_is_zero()) {
56
auto
b_simplified =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(
b
), transform_budget));
57
if
(!b_simplified->get_number_value_is_zero()) {
58
return
solve_quadratic_internal
(
b
,
num
(0),
c
,
context
);
59
}
60
61
auto
c_simplified =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(
c
), transform_budget));
62
if
(c_simplified->get_number_value_is_zero()) {
63
throw
std::invalid_argument(
64
"solve_biquadratic: identically zero equation has no finite root list"
);
65
}
66
if
(
is_purely_numeric
(c_simplified)) {
67
return
{};
68
}
69
throw
std::invalid_argument(
70
"solve_biquadratic: equation is independent of the requested variable"
);
71
}
72
73
auto
u_roots =
solve_quadratic_internal
(
a
,
b
,
c
,
context
);
74
75
std::vector<std::shared_ptr<SymbolicExpr>> results;
76
for
(
const
auto
&
u
: u_roots) {
77
auto
pos_root =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(SymbolicExpr::sqrt(
u
)), transform_budget));
78
auto
neg_root =
detail::make_expression_ptr
(
detail::normalize_node
(
detail::node
(
negate
(SymbolicExpr::sqrt(
u
))), transform_budget));
79
results.push_back(pos_root);
80
results.push_back(neg_root);
81
}
82
83
return
results;
84
}
85
86
std::vector<std::shared_ptr<SymbolicExpr>>
solve_biquadratic
(
87
const
std::shared_ptr<SymbolicExpr>&
a
,
88
const
std::shared_ptr<SymbolicExpr>&
b
,
89
const
std::shared_ptr<SymbolicExpr>&
c
,
90
const
std::string&
variable
) {
91
ComputationContext
context
;
92
return
solve_biquadratic_impl
(
a
,
b
,
c
,
variable
,
context
);
93
}
94
95
}
LMCAS::ComputationContext
定义
computation_context.hpp:99
LMCAS::detail::RewriteBudget
定义
rewrite_budget.hpp:15
expression_analysis.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::exact_rational_value
std::optional< Rational > exact_rational_value(const NumberNode &number)
定义
expression_analysis.cpp:243
LMCAS::detail::normalize_node
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
定义
symbolic_core.cpp:201
LMCAS::polynomial_solver_detail
定义
polynomial_solver_support.hpp:5
LMCAS::polynomial_solver_detail::num
std::shared_ptr< SymbolicExpr > num(int value)
定义
solve_polynomial_normalization.cpp:20
LMCAS::polynomial_solver_detail::solve_biquadratic_impl
std::vector< std::shared_ptr< SymbolicExpr > > solve_biquadratic_impl(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::string &variable, ComputationContext &context)
定义
solve_polynomial_quadratic.cpp:47
LMCAS::polynomial_solver_detail::sub
std::shared_ptr< SymbolicExpr > sub(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b)
定义
solve_polynomial_normalization.cpp:16
LMCAS::polynomial_solver_detail::negate
std::shared_ptr< SymbolicExpr > negate(const std::shared_ptr< SymbolicExpr > &expr)
定义
solve_polynomial_normalization.cpp:12
LMCAS::polynomial_solver_detail::is_purely_numeric
bool is_purely_numeric(const std::shared_ptr< SymbolicExpr > &expr)
定义
solve_polynomial_normalization.cpp:8
LMCAS::polynomial_solver_detail::solve_quadratic_internal
std::vector< std::shared_ptr< SymbolicExpr > > solve_quadratic_internal(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, ComputationContext &context)
定义
solve_polynomial_quadratic.cpp:10
LMCAS
定义
assumption.hpp:11
LMCAS::variable
const std::string & variable
定义
expr.hpp:286
LMCAS::context
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
定义
exact_factorization.hpp:65
LMCAS::c
const VectorField const VectorField & c
定义
vector_calculus_vectors.hpp:60
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::solve_biquadratic
std::vector< std::shared_ptr< SymbolicExpr > > solve_biquadratic(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, const std::shared_ptr< SymbolicExpr > &c, const std::string &variable)
定义
solve_polynomial_quadratic.cpp:86
LMCAS::u
__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 & u
定义
vector_calculus_surfaces.hpp:59
polynomial_solver_support.hpp
src
solve_polynomial_quadratic.cpp
生成于
, 为 LMCAS使用
1.18.0