LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
calculus_utils.cpp
浏览该文件的文档.
4
6
7Result<void> calculus_utils_validate_expr(const std::shared_ptr<SymbolicExpr>& expr,
8 const std::string& var,
10 const std::string& operation)
11{
12 auto step = context.consume_steps(1, operation);
13 if (!step) {
14 return step;
15 }
16 if (!expr || !LMCAS::detail::node(expr)) {
18 "expression cannot be null", operation);
19 }
20 if (var.empty()) {
22 "variable name cannot be empty", operation);
23 }
24 return Result<void>::success();
25}
26
28 const std::shared_ptr<SymbolicExpr>& first,
29 const std::shared_ptr<SymbolicExpr>& second,
30 const std::string& var,
32 const std::string& operation)
33{
34 auto step = context.consume_steps(1, operation);
35 if (!step) {
36 return step;
37 }
38 if (!first || !LMCAS::detail::node(first) || !second || !LMCAS::detail::node(second)) {
40 "expression cannot be null", operation);
41 }
42 if (var.empty()) {
44 "variable name cannot be empty", operation);
45 }
46 return Result<void>::success();
47}
48
50 const std::shared_ptr<SymbolicExpr>& expr,
51 const std::string& var,
52 const std::shared_ptr<SymbolicExpr>& target,
54 const std::string& operation)
55{
56 auto input = calculus_utils_validate_expr(expr, var, context, operation);
57 if (!input) {
58 return input;
59 }
62 "target expression cannot be null",
63 operation);
64 }
65 return Result<void>::success();
66}
67
69 const std::shared_ptr<SymbolicExpr>& expr,
70 const std::string& var,
71 const std::shared_ptr<SymbolicExpr>& a,
72 const std::shared_ptr<SymbolicExpr>& b,
74 const std::string& operation)
75{
76 auto input = calculus_utils_validate_expr(expr, var, context, operation);
77 if (!input) {
78 return input;
79 }
80 if (!a || !LMCAS::detail::node(a) || !b || !LMCAS::detail::node(b)) {
82 "bounds cannot be null", operation);
83 }
84 return Result<void>::success();
85}
86static bool is_infinity_node(const std::shared_ptr<const SymbolicNode>& node)
87{
88 auto function = std::dynamic_pointer_cast<const FunctionNode>(node);
90}
91
92/**
93 * @internal
94 * @brief 判断表达式是否包含无穷大节点.
95 */
96bool calculus_utils_is_infinity(const std::shared_ptr<SymbolicExpr>& expr)
97{
98 if (!expr || !LMCAS::detail::node(expr)) {
99 return false;
100 }
101
102 if (auto f = std::dynamic_pointer_cast<const FunctionNode>(LMCAS::detail::node(expr))) {
103 return f->type() == FunctionNode::FuncType::Infinity;
104 }
105 if (auto m = std::dynamic_pointer_cast<const MultiplyNode>(LMCAS::detail::node(expr))) {
106 for (auto& op : m->operands()) {
107 if (is_infinity_node(op)) {
108 return true;
109 }
110 }
111 }
112 return false;
113}
114
115/**
116 * @internal
117 * @brief 判断两个表达式是否结构相等.
118 */
119bool calculus_utils_expr_equal(const std::shared_ptr<SymbolicExpr>& a,
120 const std::shared_ptr<SymbolicExpr>& b)
121{
122 const bool a_exists = a && LMCAS::detail::node(a);
123 const bool b_exists = b && LMCAS::detail::node(b);
124 if (!a_exists || !b_exists) {
125 return a_exists == b_exists;
126 }
127 return LMCAS::detail::node(a)->equals(*LMCAS::detail::node(b));
128}
129std::shared_ptr<SymbolicExpr> calculus_utils_make_abs(
130 const std::shared_ptr<SymbolicExpr>& expr)
131{
132 if (!expr || !LMCAS::detail::node(expr)) {
133 return nullptr;
134 }
138 std::vector<std::shared_ptr<const SymbolicNode>>{LMCAS::detail::node(expr)}));
139}
140
141}
142
143namespace LMCAS {
144
145std::shared_ptr<SymbolicExpr> log_differentiate(
146 const std::shared_ptr<SymbolicExpr>& f, const std::string& var)
147{
149 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
150 (context).limits().max_ast_nodes, "transform");
151 if (!f || !LMCAS::detail::node(f)) {
152 return nullptr;
153 }
154
155 /// 计算 ln(f)
156 auto ln_f = SymbolicExpr::ln(f);
157
158 /// 对 ln(f) 求导 - 化简器会自动应用对数规则
159 /// (ln(a*b) = ln(a)+ln(b), ln(a^n) = n*ln(a))
160 auto ln_f_simplified = detail::make_expression_ptr(detail::normalize_node(detail::node(ln_f), transform_budget));
161 auto d_ln_f = detail::make_expression_ptr(detail::differentiate_node(detail::node(ln_f_simplified), var, transform_budget));
162
163 /// 结果 = f * d/dx[ln(f)]
164 auto result = SymbolicExpr::multiply(f, d_ln_f);
165 return detail::make_expression_ptr(detail::normalize_node(detail::node(result), transform_budget));
166}
167
168std::shared_ptr<SymbolicExpr> differential(
169 const std::shared_ptr<SymbolicExpr>& f, const std::string& var)
170{
172 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
173 (context).limits().max_ast_nodes, "transform");
174 if (!f || !LMCAS::detail::node(f)) {
175 return nullptr;
176 }
177
178 /// 微分 df = f'(var) * dx,返回系数 f'(var)
180}
181
182std::vector<std::pair<std::shared_ptr<SymbolicExpr>, std::string>> total_differential(
183 const std::shared_ptr<SymbolicExpr>& f, const std::vector<std::string>& vars)
184{
186 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
187 (context).limits().max_ast_nodes, "transform");
188 std::vector<std::pair<std::shared_ptr<SymbolicExpr>, std::string>> result;
189 if (!f || !LMCAS::detail::node(f)) {
190 return result;
191 }
192
193 result.reserve(vars.size());
194 for (const auto& v : vars) {
195 auto partial = detail::make_expression_ptr(detail::differentiate_node(detail::node(f), v, transform_budget));
196 result.emplace_back(partial, v);
197 }
198 return result;
199}
200
201}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
std::shared_ptr< SymbolicExpr > calculus_utils_make_abs(const std::shared_ptr< SymbolicExpr > &expr)
static bool is_infinity_node(const std::shared_ptr< const SymbolicNode > &node)
Result< void > calculus_utils_validate_two_exprs(const std::shared_ptr< SymbolicExpr > &first, const std::shared_ptr< SymbolicExpr > &second, const std::string &var, ComputationContext &context, const std::string &operation)
Result< void > calculus_utils_validate_expr_target(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, const std::shared_ptr< SymbolicExpr > &target, ComputationContext &context, const std::string &operation)
bool calculus_utils_is_infinity(const std::shared_ptr< SymbolicExpr > &expr)
判断表达式是否包含无穷大节点.
bool calculus_utils_expr_equal(const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b)
判断两个表达式是否结构相等.
Result< void > calculus_utils_validate_expr(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, ComputationContext &context, const std::string &operation)
Result< void > calculus_utils_validate_expr_bounds(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context, const std::string &operation)
SymbolicNodePtr differentiate_node(const SymbolicNodePtr &node, const std::string &variable, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
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)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
std::vector< std::pair< std::shared_ptr< SymbolicExpr >, std::string > > total_differential(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars)
__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
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
std::shared_ptr< SymbolicExpr > differential(const std::shared_ptr< SymbolicExpr > &f, const std::string &var)
__attribute__((visibility("default"))) VectorCalculusFieldResult gradient_checked(const std __attribute__((visibility("default"))) VectorCalculusFieldResult gradient_checked(const std __attribute__((visibility("default"))) VectorField gradient(const std const std::vector< std::string > & vars
const MultiPoly & b
const ExprPtr RelationOp op
__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
const ExprPtr & target
std::shared_ptr< SymbolicExpr > log_differentiate(const std::shared_ptr< SymbolicExpr > &f, const std::string &var)
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)
内部 AST 定义。