LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
vector_calculus_algebra.cpp
浏览该文件的文档.
5
6
7namespace LMCAS {
8
9using namespace vector_calculus_detail;
10
12{
13 if (a.size() != b.size()) {
16 "vectors must have the same dimension",
17 "dot_product");
18 }
19 std::shared_ptr<SymbolicExpr> sum = SymbolicExpr::number(0);
20 for (size_t i = 0; i < a.size(); ++i) {
21 if (!a[i] || !b[i]) continue;
22 sum = SymbolicExpr::add(sum, SymbolicExpr::multiply(a[i], b[i]));
23 }
25}
26
27std::shared_ptr<SymbolicExpr>
29 const VectorField& left, const VectorField& right, std::size_t index) {
30 static constexpr std::size_t first[] = {1, 2, 0};
31 static constexpr std::size_t second[] = {2, 0, 1};
32 return SymbolicExpr::add(
33 SymbolicExpr::multiply(left[first[index]], right[second[index]]),
34 SymbolicExpr::multiply(
35 SymbolicExpr::number(-1),
36 SymbolicExpr::multiply(
37 left[second[index]], right[first[index]])));
38}
39
41 const VectorField& a, const VectorField& b, detail::RewriteBudget& transform_budget) {
42 if (a.size() != 3 || b.size() != 3) {
45 "vectors must be three-dimensional",
46 "cross_product");
47 }
48 VectorField result;
49 result.reserve(3);
50 for (std::size_t index = 0; index < 3; ++index) {
51 result.push_back(
53 }
54 return VectorCalculusFieldResult::success(std::move(result));
55}
56
58{
59 if (a.size() != b.size()) {
62 "vectors must have the same dimension",
63 "vector_project");
64 }
65 auto bb_result = dot_product_impl(b, b, transform_budget);
66 if (!bb_result) return VectorCalculusFieldResult::failure(bb_result.error());
67 auto bb = bb_result.value();
68 if (LMCAS::detail::node(bb) && LMCAS::detail::node(bb)->is_zero()) {
70 VectorField(a.size(), SymbolicExpr::number(0)));
71 }
72 auto ab_result = dot_product_impl(a, b, transform_budget);
73 if (!ab_result) return VectorCalculusFieldResult::failure(ab_result.error());
74 auto ab = ab_result.value();
75 auto coeff = SymbolicExpr::divide(ab, bb);
76 VectorField result;
77 result.reserve(b.size());
78 for (const auto& comp : b) {
79 result.push_back(detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::multiply(coeff, comp)), transform_budget)));
80 }
81 return VectorCalculusFieldResult::success(std::move(result));
82}
83
85{
86 auto bb_result = dot_product_impl(b, b, transform_budget);
87 if (!bb_result) return bb_result;
88 auto bb = bb_result.value();
89 if (LMCAS::detail::node(bb) && LMCAS::detail::node(bb)->is_zero()) {
91 }
92 auto ab_result = dot_product_impl(a, b, transform_budget);
93 if (!ab_result) return ab_result;
95 detail::make_expression_ptr(detail::normalize_node(detail::node(SymbolicExpr::divide(ab_result.value(), SymbolicExpr::sqrt(bb))), transform_budget)));
96}
97
99{
100 auto aa_result = dot_product_impl(a, a, transform_budget);
101 if (!aa_result) {
102 return aa_result;
103 }
104 auto bb_result = dot_product_impl(b, b, transform_budget);
105 if (!bb_result) {
106 return bb_result;
107 }
108 auto aa = aa_result.value();
109 auto bb = bb_result.value();
110 if ((LMCAS::detail::node(aa) && LMCAS::detail::node(aa)->is_zero()) ||
111 (LMCAS::detail::node(bb) && LMCAS::detail::node(bb)->is_zero())) {
112 return VectorCalculusExprResult::success(nullptr);
113 }
114 auto ab_result = dot_product_impl(a, b, transform_budget);
115 if (!ab_result) {
116 return ab_result;
117 }
118 auto denom = SymbolicExpr::multiply(SymbolicExpr::sqrt(aa), SymbolicExpr::sqrt(bb));
119 auto cos_theta = SymbolicExpr::divide(ab_result.value(), denom);
122 std::vector<std::shared_ptr<const SymbolicNode>>{LMCAS::detail::node(cos_theta)});
125}
126
128 const VectorField& a, const VectorField& b, const VectorField& c, detail::RewriteBudget& transform_budget)
129{
130 auto cross = cross_product_impl(b, c, transform_budget);
131 if (!cross) return VectorCalculusExprResult::failure(cross.error());
132 return dot_product_impl(a, cross.value(), transform_budget);
133}
134
135
138 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
139 context.limits().max_ast_nodes, "dot_product");
140 return dot_product_impl(a, b, transform_budget);
141} catch (const CasError& error) {
143} catch (const std::bad_alloc&) {
145 "vector calculus allocation failed", "dot_product");
146} catch (const std::length_error& error) {
147 return VectorCalculusExprResult::failure(CasErrc::ResourceLimit, error.what(), "dot_product");
148} catch (const std::exception& error) {
149 return VectorCalculusExprResult::failure(CasErrc::InternalInvariant, error.what(), "dot_product");
150}
151
153 const VectorField& a, const VectorField& b) try {
155 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
156 context.limits().max_ast_nodes, "cross_product");
157 return cross_product_impl(a, b, transform_budget);
158} catch (const CasError& error) {
160} catch (const std::bad_alloc&) {
162 "vector calculus allocation failed", "cross_product");
163} catch (const std::length_error& error) {
164 return VectorCalculusFieldResult::failure(CasErrc::ResourceLimit, error.what(), "cross_product");
165} catch (const std::exception& error) {
166 return VectorCalculusFieldResult::failure(CasErrc::InternalInvariant, error.what(), "cross_product");
167}
168
171 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
172 context.limits().max_ast_nodes, "vector_project");
173 return vector_project_impl(a, b, transform_budget);
174} catch (const CasError& error) {
176} catch (const std::bad_alloc&) {
178 "vector calculus allocation failed", "vector_project");
179} catch (const std::length_error& error) {
180 return VectorCalculusFieldResult::failure(CasErrc::ResourceLimit, error.what(), "vector_project");
181} catch (const std::exception& error) {
182 return VectorCalculusFieldResult::failure(CasErrc::InternalInvariant, error.what(), "vector_project");
183}
184
187 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
188 context.limits().max_ast_nodes, "scalar_project");
189 return scalar_project_impl(a, b, transform_budget);
190} catch (const CasError& error) {
192} catch (const std::bad_alloc&) {
194 "vector calculus allocation failed", "scalar_project");
195} catch (const std::length_error& error) {
196 return VectorCalculusExprResult::failure(CasErrc::ResourceLimit, error.what(), "scalar_project");
197} catch (const std::exception& error) {
198 return VectorCalculusExprResult::failure(CasErrc::InternalInvariant, error.what(), "scalar_project");
199}
200
203 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
204 context.limits().max_ast_nodes, "vector_angle_symbolic");
205 return vector_angle_symbolic_impl(a, b, transform_budget);
206} catch (const CasError& error) {
208} catch (const std::bad_alloc&) {
210 "vector calculus allocation failed", "vector_angle_symbolic");
211} catch (const std::length_error& error) {
212 return VectorCalculusExprResult::failure(CasErrc::ResourceLimit, error.what(), "vector_angle_symbolic");
213} catch (const std::exception& error) {
214 return VectorCalculusExprResult::failure(CasErrc::InternalInvariant, error.what(), "vector_angle_symbolic");
215}
216
218 const VectorField& a, const VectorField& b, const VectorField& c) try {
220 detail::RewriteBudget transform_budget(context, context.limits().max_recursion_depth,
221 context.limits().max_ast_nodes, "mixed_product");
222 return mixed_product_impl(a, b, c, transform_budget);
223} catch (const CasError& error) {
225} catch (const std::bad_alloc&) {
227 "vector calculus allocation failed", "mixed_product");
228} catch (const std::length_error& error) {
229 return VectorCalculusExprResult::failure(CasErrc::ResourceLimit, error.what(), "mixed_product");
230} catch (const std::exception& error) {
231 return VectorCalculusExprResult::failure(CasErrc::InternalInvariant, error.what(), "mixed_product");
232}
233
234}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(std::shared_ptr< SymbolicExpr > 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)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
std::shared_ptr< SymbolicExpr > vector_calculus_cross_component(const VectorField &left, const VectorField &right, std::size_t index)
static VectorCalculusFieldResult cross_product_impl(const VectorField &a, const VectorField &b, detail::RewriteBudget &transform_budget)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
static VectorCalculusExprResult scalar_project_impl(const VectorField &a, const VectorField &b, detail::RewriteBudget &transform_budget)
const VectorField const VectorField & c
const MultiPoly & b
static VectorCalculusExprResult mixed_product_impl(const VectorField &a, const VectorField &b, const VectorField &c, detail::RewriteBudget &transform_budget)
__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
std::vector< std::shared_ptr< SymbolicExpr > > VectorField
向量场由标量表达式组成。
Result< VectorField > VectorCalculusFieldResult
VectorCalculusExprResult vector_angle_symbolic(const VectorField &a, const VectorField &b)
VectorCalculusExprResult scalar_project(const VectorField &a, const VectorField &b)
VectorCalculusFieldResult vector_project(const VectorField &a, const VectorField &b)
static VectorCalculusFieldResult vector_project_impl(const VectorField &a, const VectorField &b, detail::RewriteBudget &transform_budget)
Result< std::shared_ptr< SymbolicExpr > > VectorCalculusExprResult
VectorCalculusExprResult mixed_product(const VectorField &a, const VectorField &b, const VectorField &c)
const ExprPtr & right
VectorCalculusFieldResult cross_product(const VectorField &a, const VectorField &b)
static VectorCalculusExprResult dot_product_impl(const VectorField &a, const VectorField &b, detail::RewriteBudget &transform_budget)
VectorCalculusExprResult dot_product(const VectorField &a, const VectorField &b)
static VectorCalculusExprResult vector_angle_symbolic_impl(const VectorField &a, const VectorField &b, detail::RewriteBudget &transform_budget)
内部 AST 定义。