LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
numeric_evaluation.cpp
浏览该文件的文档.
1
#include "
internal/numeric_evaluation_support.hpp
"
2
#include "
internal/squared_norm.hpp
"
3
#include <cmath>
4
#include <limits>
5
6
namespace
LMCAS
{
7
namespace
{
8
9
constexpr
const
char
*
kOperation
=
"evaluate_numeric"
;
10
11
class
RecursionScope
{
12
public
:
13
explicit
RecursionScope
(
ComputationContext
&
context
) :
context_
(
context
) {}
14
~RecursionScope
() {
context_
.leave_recursion(); }
15
16
private
:
17
ComputationContext
&
context_
;
18
};
19
20
}
21
22
namespace
detail
{
23
24
Result<ApproxReal>
numeric_failure
(
CasErrc
code, std::string message) {
25
return
Result<ApproxReal>::failure
(code, std::move(message), kOperation);
26
}
27
28
Result<ApproxReal>
numeric_approximation
(
double
value
) {
29
if
(!std::isfinite(
value
)) {
30
return
numeric_failure
(
CasErrc::NumericFailure
,
"numeric evaluation produced a nonfinite result"
);
31
}
32
return
Result<ApproxReal>::success
(
33
ApproxReal
{
value
, std::numeric_limits<double>::infinity(),
NumericStatus::Finite
});
34
}
35
36
Result<ApproxReal>
NumericEvaluator::evaluate
(
const
std::shared_ptr<const SymbolicNode>&
node
) {
37
auto
entered =
context_
.
enter_recursion
(kOperation);
38
if
(!entered) {
39
return
Result<ApproxReal>::failure
(entered.error());
40
}
41
RecursionScope scope(
context_
);
42
if
(!
node
) {
43
return
numeric_failure
(
CasErrc::InvalidArgument
,
"expression contains a null node"
);
44
}
45
if
(
const
auto
*
value
=
dynamic_cast<
const
NumberNode
*
>
(
node
.get())) {
46
return
number
(*
value
);
47
}
48
if
(
const
auto
*
value
=
dynamic_cast<
const
VariableNode
*
>
(
node
.get())) {
49
return
variable
(*
value
);
50
}
51
if
(
const
auto
*
value
=
dynamic_cast<
const
AddNode
*
>
(
node
.get())) {
52
return
sum
(*
value
);
53
}
54
if
(
const
auto
*
value
=
dynamic_cast<
const
MultiplyNode
*
>
(
node
.get())) {
55
return
product
(*
value
);
56
}
57
const
auto
squares =
squared_norm_terms
(*
node
);
58
if
(squares[0]) {
59
return
norm
(squares);
60
}
61
if
(
const
auto
*
value
=
dynamic_cast<
const
PowerNode
*
>
(
node
.get())) {
62
return
power
(*
value
);
63
}
64
if
(
dynamic_cast<
const
RootOfNode
*
>
(
node
.get())) {
65
return
root
(
node
);
66
}
67
if
(
const
auto
*
value
=
dynamic_cast<
const
FunctionNode
*
>
(
node
.get())) {
68
return
function
(*
value
);
69
}
70
return
numeric_failure
(
CasErrc::UnsupportedExpression
,
71
"expression node is not real-numerically evaluable"
);
72
}
73
74
Result<ApproxReal>
NumericEvaluator::function
(
const
FunctionNode
&
node
) {
75
if
(
node
.type() ==
FunctionNode::FuncType::Infinity
&&
node
.arguments().empty()) {
76
return
Result<ApproxReal>::success
(
ApproxReal
{
77
std::numeric_limits<double>::infinity(), 0.0,
NumericStatus::PositiveInfinity
});
78
}
79
if
(
node
.type() ==
FunctionNode::FuncType::Atan2
) {
80
return
atan2
(
node
);
81
}
82
if
(
node
.type() ==
FunctionNode::FuncType::Max
||
node
.type() ==
FunctionNode::FuncType::Min
) {
83
return
extremum
(
node
);
84
}
85
if
(
node
.type() ==
FunctionNode::FuncType::Log
&&
86
node
.arguments().size() == 2) {
87
auto
value
=
evaluate
(
node
.arguments()[0]);
88
if
(!
value
) {
89
return
value
;
90
}
91
auto
base =
evaluate
(
node
.arguments()[1]);
92
if
(!base) {
93
return
base;
94
}
95
const
double
numeric_value =
value
.value().value;
96
const
double
numeric_base = base.value().value;
97
if
(!(numeric_value > 0.0)) {
98
return
numeric_failure
(
99
CasErrc::DomainError
,
100
"logarithm requires a positive real argument"
);
101
}
102
if
(!(numeric_base > 0.0) || numeric_base == 1.0) {
103
return
numeric_failure
(
104
CasErrc::DomainError
,
105
"logarithm base must be positive and not equal to one"
);
106
}
107
return
numeric_approximation
(
108
std::log(numeric_value) / std::log(numeric_base));
109
}
110
if
(
node
.arguments().size() != 1) {
111
return
numeric_failure
(
CasErrc::UnsupportedExpression
,
112
"function is not supported by real numeric evaluation"
);
113
}
114
if
(
node
.type() ==
FunctionNode::FuncType::Sqrt
) {
115
if
(
const
auto
*
value
=
dynamic_cast<
const
NumberNode
*
>
(
node
.arguments()[0].get())) {
116
return
square_root
(*
value
);
117
}
118
}
119
auto
argument =
evaluate
(
node
.arguments()[0]);
120
if
(!argument) {
121
return
argument;
122
}
123
return
evaluate_unary_numeric
(
node
.type(), argument.value().value);
124
}
125
126
}
127
128
Result<ApproxReal>
evaluate_numeric
(
const
SymbolicExpr& expression,
129
const
NumericBindings
&
bindings
,
130
ComputationContext
&
context
)
try
{
131
if
(!
detail::node
(expression)) {
132
return
Result<ApproxReal>::failure
(
CasErrc::InvalidArgument
,
133
"cannot evaluate an empty expression"
, kOperation);
134
}
135
detail::NumericEvaluator
evaluator(
bindings
,
context
);
136
return
evaluator.
evaluate
(
detail::node
(expression));
137
}
138
catch
(
const
CasError& error) {
139
return
Result<ApproxReal>::failure
(error);
140
}
catch
(
const
std::bad_alloc&) {
141
return
Result<ApproxReal>::failure
(
142
CasErrc::ResourceLimit
,
"numeric evaluation allocation failed"
, kOperation);
143
}
catch
(
const
std::length_error& error) {
144
return
Result<ApproxReal>::failure
(
CasErrc::ResourceLimit
, error.what(), kOperation);
145
}
catch
(
const
std::exception& error) {
146
return
Result<ApproxReal>::failure
(
CasErrc::InternalInvariant
, error.what(), kOperation);
147
}
148
149
}
LMCAS::AddNode
加法节点,表示多个操作数的求和。
定义
arithmetic.hpp:55
LMCAS::ComputationContext
定义
computation_context.hpp:99
LMCAS::ComputationContext::enter_recursion
Result< void > enter_recursion(const std::string &operation={})
定义
computation_context.hpp:125
LMCAS::FunctionNode
函数节点,表示数学函数调用(三角函数、对数、特殊函数等)。
定义
functions.hpp:10
LMCAS::FunctionNode::FuncType::Atan2
@ Atan2
双参数反正切。
定义
functions.hpp:19
LMCAS::FunctionNode::FuncType::Max
@ Max
最大值 max(a, b)。
定义
functions.hpp:26
LMCAS::FunctionNode::FuncType::Min
@ Min
最小值 min(a, b)。
定义
functions.hpp:27
LMCAS::FunctionNode::FuncType::Sqrt
@ Sqrt
对数、绝对值、平方根。
定义
functions.hpp:16
LMCAS::FunctionNode::FuncType::Log
@ Log
定义
functions.hpp:16
LMCAS::FunctionNode::FuncType::Infinity
@ Infinity
无穷大。
定义
functions.hpp:20
LMCAS::MultiplyNode
乘法节点,表示多个操作数的乘积。
定义
arithmetic.hpp:134
LMCAS::NumberNode
定义
numbers.hpp:8
LMCAS::PowerNode
幂运算节点,表示 base^exponent。
定义
arithmetic.hpp:218
LMCAS::Result
定义
result.hpp:39
LMCAS::Result::failure
static Result failure(CasErrc code, std::string message, std::string operation={})
定义
result.hpp:52
LMCAS::Result::success
static Result success(T value)
定义
result.hpp:48
LMCAS::RootOfNode
定义
special_forms.hpp:76
LMCAS::VariableNode
变量节点,表示一个符号变量。
定义
arithmetic.hpp:10
LMCAS::anonymous_namespace{numeric_evaluation.cpp}::RecursionScope::context_
ComputationContext & context_
定义
numeric_evaluation.cpp:17
LMCAS::anonymous_namespace{numeric_evaluation.cpp}::RecursionScope::~RecursionScope
~RecursionScope()
定义
numeric_evaluation.cpp:14
LMCAS::anonymous_namespace{numeric_evaluation.cpp}::RecursionScope::RecursionScope
RecursionScope(ComputationContext &context)
定义
numeric_evaluation.cpp:13
LMCAS::detail::NumericEvaluator
定义
numeric_evaluation_support.hpp:13
LMCAS::detail::NumericEvaluator::variable
Result< ApproxReal > variable(const VariableNode &node)
定义
numeric_evaluation_nodes.cpp:26
LMCAS::detail::NumericEvaluator::sum
Result< ApproxReal > sum(const AddNode &node)
定义
numeric_evaluation_nodes.cpp:48
LMCAS::detail::NumericEvaluator::norm
Result< ApproxReal > norm(const std::array< const PowerNode *, 2 > &squares)
定义
numeric_evaluation_nodes.cpp:159
LMCAS::detail::NumericEvaluator::number
Result< ApproxReal > number(const NumberNode &node)
定义
numeric_evaluation_nodes.cpp:8
LMCAS::detail::NumericEvaluator::function
Result< ApproxReal > function(const FunctionNode &node)
定义
numeric_evaluation.cpp:74
LMCAS::detail::NumericEvaluator::extremum
Result< ApproxReal > extremum(const FunctionNode &node)
定义
numeric_evaluation_nodes.cpp:142
LMCAS::detail::NumericEvaluator::root
Result< ApproxReal > root(const std::shared_ptr< const SymbolicNode > &node)
定义
numeric_evaluation_nodes.cpp:168
LMCAS::detail::NumericEvaluator::atan2
Result< ApproxReal > atan2(const FunctionNode &node)
定义
numeric_evaluation_nodes.cpp:131
LMCAS::detail::NumericEvaluator::square_root
Result< ApproxReal > square_root(const NumberNode &node)
定义
numeric_evaluation_power.cpp:31
LMCAS::detail::NumericEvaluator::evaluate
Result< ApproxReal > evaluate(const std::shared_ptr< const SymbolicNode > &node)
定义
numeric_evaluation.cpp:36
LMCAS::detail::NumericEvaluator::context_
ComputationContext & context_
定义
numeric_evaluation_support.hpp:22
LMCAS::detail::NumericEvaluator::power
Result< ApproxReal > power(const PowerNode &node)
定义
numeric_evaluation_power.cpp:71
LMCAS::detail::NumericEvaluator::product
Result< ApproxReal > product(const MultiplyNode &node)
定义
numeric_evaluation_nodes.cpp:67
LMCAS::anonymous_namespace{numeric_evaluation.cpp}::kOperation
constexpr const char * kOperation
定义
numeric_evaluation.cpp:9
LMCAS::detail
多元 Hensel 提升(单变量步)
定义
assumption_context.hpp:31
LMCAS::detail::node
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
定义
base.hpp:91
LMCAS::detail::numeric_failure
Result< ApproxReal > numeric_failure(CasErrc code, std::string message)
定义
numeric_evaluation.cpp:24
LMCAS::detail::evaluate_unary_numeric
Result< ApproxReal > evaluate_unary_numeric(FunctionNode::FuncType type, double value)
定义
numeric_evaluation_functions.cpp:166
LMCAS::detail::squared_norm_terms
std::array< const PowerNode *, 2 > squared_norm_terms(const SymbolicNode &root)
Recognize real-numeric norm forms without evaluating their squares.
定义
squared_norm.cpp:45
LMCAS::detail::numeric_approximation
Result< ApproxReal > numeric_approximation(double value)
定义
numeric_evaluation.cpp:28
LMCAS
定义
assumption.hpp:11
LMCAS::context
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
定义
exact_factorization.hpp:65
LMCAS::CasErrc
CasErrc
定义
result.hpp:12
LMCAS::CasErrc::InvalidArgument
@ InvalidArgument
定义
result.hpp:13
LMCAS::CasErrc::UnsupportedExpression
@ UnsupportedExpression
定义
result.hpp:23
LMCAS::CasErrc::InternalInvariant
@ InternalInvariant
定义
result.hpp:28
LMCAS::CasErrc::ResourceLimit
@ ResourceLimit
定义
result.hpp:25
LMCAS::CasErrc::NumericFailure
@ NumericFailure
定义
result.hpp:27
LMCAS::CasErrc::DomainError
@ DomainError
定义
result.hpp:16
LMCAS::NumericStatus::Finite
@ Finite
定义
numeric_value.hpp:5
LMCAS::NumericStatus::PositiveInfinity
@ PositiveInfinity
定义
numeric_value.hpp:5
LMCAS::bindings
const std::vector< Binding > & bindings
定义
expr.hpp:310
LMCAS::value
const std::string const ExprPtr & value
定义
expr.hpp:293
LMCAS::evaluate_numeric
Result< ApproxReal > evaluate_numeric(const SymbolicExpr &expression, const NumericBindings &bindings={})
定义
numeric_evaluation.hpp:44
LMCAS::NumericBindings
std::unordered_map< std::string, double > NumericBindings
定义
numeric_evaluation.hpp:14
numeric_evaluation_support.hpp
squared_norm.hpp
LMCAS::ApproxReal
定义
numeric_value.hpp:7
src
numeric_evaluation.cpp
生成于
, 为 LMCAS使用
1.18.0