LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
vector_calculus_matrices.cpp
浏览该文件的文档.
4#include <stdexcept>
5
6namespace LMCAS {
7
8using namespace vector_calculus_detail;
9
11 const std::vector<std::shared_ptr<SymbolicExpr>>& functions,
12 const std::vector<std::string>& vars,
14{
15 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
16 context.limits().max_ast_nodes, "jacobian");
17 const std::string operation = "jacobian";
18 auto valid = vector_calculus_validate_functions_vars(functions, vars,
19 context, operation);
20 if (!valid) {
21 return VectorCalculusExprResult::failure(valid.error());
22 }
23 auto step = context.consume_steps(functions.size() * vars.size(), operation);
24 if (!step) {
25 return VectorCalculusExprResult::failure(step.error());
26 }
27 try {
28 return vector_calculus_wrap_expr(jacobian_impl(functions, vars, transform_budget), operation);
29 } catch (const CasError& error) {
31 } catch (const std::bad_alloc&) {
33 "vector calculus allocation failed",
34 operation);
35 } catch (const std::length_error& error) {
36 return VectorCalculusExprResult::failure(CasErrc::ResourceLimit, error.what(), operation);
37 } catch (const std::exception& e) {
39 }
40}
41
43 const std::vector<std::shared_ptr<SymbolicExpr>>& functions,
44 const std::vector<std::string>& vars)
45{
47 return jacobian_checked(functions, vars, context);
48}
49
50std::shared_ptr<SymbolicExpr> vector_calculus_detail::jacobian_impl(
51 const std::vector<std::shared_ptr<SymbolicExpr>>& functions,
52 const std::vector<std::string>& vars,
53 detail::RewriteBudget& transform_budget)
54{
55 size_t m = functions.size();
56 size_t n = vars.size();
57 std::size_t nodes = 1;
58 transform_budget.require_nodes(nodes);
59
60 std::vector<std::vector<std::shared_ptr<SymbolicExpr>>> grid;
61 grid.reserve(m);
62
63 for (size_t i = 0; i < m; ++i) {
64 std::vector<std::shared_ptr<SymbolicExpr>> row;
65 row.reserve(n);
66 for (size_t j = 0; j < n; ++j) {
67 auto partial = detail::make_expression_ptr(detail::differentiate_node(detail::node(functions[i]), vars[j], transform_budget));
68 partial = detail::make_expression_ptr(detail::normalize_node(detail::node(partial), transform_budget));
69 nodes = transform_budget.append_size(
70 nodes, transform_budget.measure(detail::node(partial)));
71 row.push_back(partial);
72 }
73 grid.push_back(std::move(row));
74 }
75
76 return SymbolicExpr::matrix(grid);
77}
78
79
81 const std::shared_ptr<SymbolicExpr>& f,
82 const std::vector<std::string>& vars,
84{
85 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
86 context.limits().max_ast_nodes, "hessian");
87 const std::string operation = "hessian";
88 auto valid = vector_calculus_validate_expr_vars(f, vars, context, operation);
89 if (!valid) {
90 return VectorCalculusExprResult::failure(valid.error());
91 }
92 auto step = context.consume_steps(vars.size() * vars.size(), operation);
93 if (!step) {
94 return VectorCalculusExprResult::failure(step.error());
95 }
96 try {
97 return vector_calculus_wrap_expr(hessian_impl(f, vars, transform_budget), operation);
98 } catch (const CasError& error) {
100 } catch (const std::bad_alloc&) {
102 "vector calculus allocation failed",
103 operation);
104 } catch (const std::length_error& error) {
105 return VectorCalculusExprResult::failure(CasErrc::ResourceLimit, error.what(), operation);
106 } catch (const std::exception& e) {
108 }
109}
110
112 const std::shared_ptr<SymbolicExpr>& f,
113 const std::vector<std::string>& vars)
114{
116 return hessian_checked(f, vars, context);
117}
118
119std::shared_ptr<SymbolicExpr> vector_calculus_detail::hessian_impl(
120 const std::shared_ptr<SymbolicExpr>& f, const std::vector<std::string>& vars,
121 detail::RewriteBudget& transform_budget)
122{
123 size_t n = vars.size();
124 std::size_t nodes = 1;
125 transform_budget.require_nodes(nodes);
126
127 std::vector<std::shared_ptr<SymbolicExpr>> first_partials;
128 first_partials.reserve(n);
129 for (size_t i = 0; i < n; ++i) {
130 first_partials.push_back(detail::make_expression_ptr(detail::differentiate_node(detail::node(f), vars[i], transform_budget)));
131 }
132
133 std::vector<std::vector<std::shared_ptr<SymbolicExpr>>> grid(n,
134 std::vector<std::shared_ptr<SymbolicExpr>>(n));
135
136 for (size_t i = 0; i < n; ++i) {
137 for (size_t j = i; j < n; ++j) {
138 auto second_partial = detail::make_expression_ptr(detail::differentiate_node(detail::node(first_partials[i]), vars[j], transform_budget));
139 second_partial = detail::make_expression_ptr(detail::normalize_node(detail::node(second_partial), transform_budget));
140 const auto partial_nodes = transform_budget.measure(detail::node(second_partial));
141 nodes = transform_budget.append_size(nodes, partial_nodes);
142 if (i != j) nodes = transform_budget.append_size(nodes, partial_nodes);
143 grid[i][j] = second_partial;
144 if (i != j) {
145 grid[j][i] = second_partial;
146 }
147 }
148 }
149
150 return SymbolicExpr::matrix(grid);
151}
152
153
154std::shared_ptr<SymbolicExpr> jacobian(
155 const std::vector<std::shared_ptr<SymbolicExpr>>& functions,
156 const std::vector<std::string>& vars)
157{
159 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
160 context.limits().max_ast_nodes, "jacobian");
161 return jacobian_impl(functions, vars, transform_budget);
162}
163
164std::shared_ptr<SymbolicExpr> hessian(
165 const std::shared_ptr<SymbolicExpr>& f, const std::vector<std::string>& vars)
166{
168 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
169 context.limits().max_ast_nodes, "hessian");
170 return hessian_impl(f, vars, transform_budget);
171}
172
173}
static Result failure(CasErrc code, std::string message, std::string operation={})
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
void require_nodes(std::size_t nodes) const
std::size_t append_size(std::size_t current, std::size_t child)
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
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
Result< void > vector_calculus_validate_expr_vars(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, ComputationContext &context, const std::string &operation)
std::shared_ptr< SymbolicExpr > jacobian_impl(const std::vector< std::shared_ptr< SymbolicExpr > > &functions, const std::vector< std::string > &vars, detail::RewriteBudget &transform_budget)
Result< void > vector_calculus_validate_functions_vars(const std::vector< std::shared_ptr< SymbolicExpr > > &functions, const std::vector< std::string > &vars, ComputationContext &context, const std::string &operation)
VectorCalculusExprResult vector_calculus_wrap_expr(std::shared_ptr< SymbolicExpr > expr, const std::string &operation)
std::shared_ptr< SymbolicExpr > hessian_impl(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, detail::RewriteBudget &transform_budget)
std::shared_ptr< SymbolicExpr > hessian(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars)
ExprResult e()
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
__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
std::shared_ptr< SymbolicExpr > jacobian(const std::vector< std::shared_ptr< SymbolicExpr > > &functions, const std::vector< std::string > &vars)
VectorCalculusExprResult hessian_checked(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, ComputationContext &context)
VectorCalculusExprResult jacobian_checked(const std::vector< std::shared_ptr< SymbolicExpr > > &functions, const std::vector< std::string > &vars, ComputationContext &context)
Result< std::shared_ptr< SymbolicExpr > > VectorCalculusExprResult