LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
expr_elementary.cpp
浏览该文件的文档.
1#include "expr.hpp"
5#include <cmath>
6#include <exception>
7#include <memory>
8#include <string>
9#include <utility>
10#include <vector>
11
12namespace LMCAS {
13
14using namespace expr_detail::expr_common;
15
17 auto exponent = rational(Rational(1, 2));
18 if (!exponent) { return exponent; }
19 return quantity_power(expression, exponent.value(), context);
20}
21
22ExprResult sqrt(const ExprPtr& expression) {
24 return sqrt(expression, context);
25}
26
28 const ExprPtr& exponent,
30 return quantity_power(base, exponent, context);
31}
32
33ExprResult pow(const ExprPtr& base, const ExprPtr& exponent) {
35 return pow(base, exponent, context);
36}
37
39 auto valid = require_dimensionless(expression, "sin");
40 if (!valid) { return valid; }
41 return make_unary_math_expr(expression, context, "sin",
42 SymbolicExpr::sin);
43}
44
45ExprResult sin(const ExprPtr& expression) {
47 return sin(expression, context);
48}
49
51 auto valid = require_dimensionless(expression, "cos");
52 if (!valid) { return valid; }
53 return make_unary_math_expr(expression, context, "cos",
54 SymbolicExpr::cos);
55}
56
57ExprResult cos(const ExprPtr& expression) {
59 return cos(expression, context);
60}
61
63 auto valid = require_dimensionless(expression, "tan");
64 if (!valid) { return valid; }
65 return make_unary_math_expr(expression, context, "tan",
66 SymbolicExpr::tan);
67}
68
69ExprResult tan(const ExprPtr& expression) {
71 return tan(expression, context);
72}
73
75 auto valid = require_dimensionless(expression, "asin");
76 if (!valid) { return valid; }
77 return make_unary_function_expr(expression, context, "asin",
79}
80
81ExprResult asin(const ExprPtr& expression) {
83 return asin(expression, context);
84}
85
87 auto valid = require_dimensionless(expression, "acos");
88 if (!valid) { return valid; }
89 return make_unary_function_expr(expression, context, "acos",
91}
92
93ExprResult acos(const ExprPtr& expression) {
95 return acos(expression, context);
96}
97
99 auto valid = require_dimensionless(expression, "atan");
100 if (!valid) { return valid; }
101 return make_unary_function_expr(expression, context, "atan",
103}
104
105ExprResult atan(const ExprPtr& expression) {
107 return atan(expression, context);
108}
109
111 auto valid = require_dimensionless(expression, "exp");
112 if (!valid) { return valid; }
113 return make_unary_math_expr(expression, context, "exp",
114 SymbolicExpr::exp);
115}
116
117ExprResult exp(const ExprPtr& expression) {
119 return exp(expression, context);
120}
121
123 auto valid = require_dimensionless(expression, "log");
124 if (!valid) { return valid; }
125 return make_unary_math_expr(expression, context, "log",
126 SymbolicExpr::ln);
127}
128
129ExprResult log(const ExprPtr& expression) {
131 return log(expression, context);
132}
133
135 auto valid = require_dimensionless(expression, "log10");
136 if (!valid) { return valid; }
137 auto step = context.consume_steps(1, kMathOperation);
138 if (!step) { return ExprResult::failure(step.error()); }
139 if (!expression || !LMCAS::detail::node(expression)) {
141 "log10 argument cannot be null",
143 }
144 try {
145 auto numerator = SymbolicExpr::ln(expression);
146 auto denominator = SymbolicExpr::ln(SymbolicExpr::number(10));
147 auto result = SymbolicExpr::divide(numerator, denominator);
148 if (!result || !LMCAS::detail::node(result)) {
150 "log10 expression construction failed",
152 }
153 return ExprResult::success(std::move(result));
154 } catch (const std::bad_alloc&) {
156 "log10 expression allocation failed",
158 } catch (const std::exception& error) {
161 }
162}
163
164ExprResult log10(const ExprPtr& expression) {
166 return log10(expression, context);
167}
168
170 return make_unary_function_expr(expression, context, "floor",
172}
173
174ExprResult floor(const ExprPtr& expression) {
176 return floor(expression, context);
177}
178
180 return make_unary_function_expr(expression, context, "ceil",
182}
183
184ExprResult ceil(const ExprPtr& expression) {
186 return ceil(expression, context);
187}
188
190 return make_unary_function_expr(expression, context, "round",
192}
193
194ExprResult round(const ExprPtr& expression) {
196 return round(expression, context);
197}
198
199ExprResult clamp(const ExprPtr& expression,
200 const ExprPtr& lower,
201 const ExprPtr& upper,
203 auto step = context.consume_steps(1, kMathOperation);
204 if (!step) { return ExprResult::failure(step.error()); }
205 if (!expression || !LMCAS::detail::node(expression) ||
209 "clamp arguments cannot be null",
211 }
212 try {
215 std::vector<std::shared_ptr<const SymbolicNode>>{
219 std::vector<std::shared_ptr<const SymbolicNode>>{
220 std::move(max_node), LMCAS::detail::node(upper)});
221 return ExprResult::success(
222 LMCAS::detail::make_expression_ptr(std::move(min_node)));
223 } catch (const std::bad_alloc&) {
225 "clamp expression allocation failed",
227 } catch (const std::exception& error) {
230 }
231}
232
233ExprResult clamp(const ExprPtr& expression,
234 const ExprPtr& lower,
235 const ExprPtr& upper) {
237 return clamp(expression, lower, upper, context);
238}
239
240}
@ Max
最大值 max(a, b)。
@ Min
最小值 min(a, b)。
@ Round
四舍五入 round(x)。
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(ExprPtr value)
复变函数分析:留数计算,柯西积分公式,解析延拓.
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const Node > make_node(Args &&... args)
ExprResult make_unary_function_expr(const ExprPtr &expression, ComputationContext &context, const char *function_name, FunctionNode::FuncType type)
ExprResult require_dimensionless(const ExprPtr &expression, const char *function_name)
ExprResult expression_failure(CasErrc code, std::string message, const char *operation)
ExprResult make_unary_math_expr(const ExprPtr &expression, ComputationContext &context, const char *function_name, ExprPtr(*factory)(ExprPtr))
constexpr const char * kMathOperation
ExprResult pow(const ExprPtr &base, const ExprPtr &exponent, ComputationContext &context)
ExprResult exp(const ExprPtr &expression, ComputationContext &context)
ExprResult log10(const ExprPtr &expression, ComputationContext &context)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
ExprResult ceil(const ExprPtr &expression, ComputationContext &context)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult acos(const ExprPtr &expression, ComputationContext &context)
const ExprPtr & lower
Result< ExprPtr > ExprResult
ExprResult atan(const ExprPtr &expression, ComputationContext &context)
ExprResult clamp(const ExprPtr &expression, const ExprPtr &lower, const ExprPtr &upper, ComputationContext &context)
ExprResult asin(const ExprPtr &expression, ComputationContext &context)
ExprResult sin(const ExprPtr &expression, ComputationContext &context)
ExprResult tan(const ExprPtr &expression, ComputationContext &context)
const ExprPtr & exponent
ExprResult cos(const ExprPtr &expression, ComputationContext &context)
std::shared_ptr< SymbolicExpr > ExprPtr
QuantityResult quantity_power(const std::shared_ptr< SymbolicExpr > &base, const std::shared_ptr< SymbolicExpr > &exponent, ComputationContext &context)
ExprResult sqrt(const ExprPtr &expression, ComputationContext &context)
ExprResult log(const ExprPtr &expression, ComputationContext &context)
ExprResult floor(const ExprPtr &expression, ComputationContext &context)
const ExprPtr & denominator
ExprResult rational(const Rational &value)
ExprResult round(const ExprPtr &expression, ComputationContext &context)
内部 AST 定义。