LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
vector_calculus_support.cpp
浏览该文件的文档.
5#include "solver.hpp"
7
8#include <cmath>
9#include <exception>
10#include <map>
11#include <memory>
12#include <set>
13#include <stdexcept>
14#include <string>
15#include <vector>
16
18
20 const std::shared_ptr<SymbolicExpr>& expr,
21 double& value,
23{
24 if (!expr) return false;
25 auto numeric = detail::try_finite_numeric(*expr, context);
26 if (!numeric) return false;
27 value = *numeric;
28 return true;
29}
30
31
33 const std::shared_ptr<SymbolicExpr>& f,
34 const std::vector<std::string>& vars,
36 const std::string& operation)
37{
38 auto step = context.consume_steps(1, operation);
39 if (!step) return step;
40 if (!f || !LMCAS::detail::node(f)) {
42 "expression cannot be null", operation);
43 }
44 if (vars.empty()) {
46 "variable list cannot be empty", operation);
47 }
48 for (const auto& var : vars) {
49 if (var.empty()) {
51 "variable name cannot be empty",
52 operation);
53 }
54 }
55 return Result<void>::success();
56}
57
59 const VectorField& field,
60 const std::vector<std::string>& vars,
62 const std::string& operation)
63{
64 auto step = context.consume_steps(1, operation);
65 if (!step) return step;
66 if (field.empty()) {
68 "vector field cannot be empty", operation);
69 }
70 if (field.size() != vars.size()) {
72 "vector field and variables must have the same dimension",
73 operation);
74 }
75 for (const auto& var : vars) {
76 if (var.empty()) {
78 "variable name cannot be empty",
79 operation);
80 }
81 }
82 for (const auto& component : field) {
83 if (!component || !LMCAS::detail::node(component)) {
85 "vector field components cannot be null",
86 operation);
87 }
88 }
89 return Result<void>::success();
90}
91
93 const std::vector<std::shared_ptr<SymbolicExpr>>& functions,
94 const std::vector<std::string>& vars,
96 const std::string& operation)
97{
98 auto step = context.consume_steps(1, operation);
99 if (!step) return step;
100 if (functions.empty()) {
102 "function list cannot be empty",
103 operation);
104 }
105 if (vars.empty()) {
107 "variable list cannot be empty",
108 operation);
109 }
110 for (const auto& var : vars) {
111 if (var.empty()) {
113 "variable name cannot be empty",
114 operation);
115 }
116 }
117 for (const auto& function : functions) {
120 "function expressions cannot be null",
121 operation);
122 }
123 }
124 return Result<void>::success();
125}
126
129 const std::string& t,
130 const std::shared_ptr<SymbolicExpr>& a,
131 const std::shared_ptr<SymbolicExpr>& b,
133 const std::string& operation)
134{
135 auto step = context.consume_steps(1, operation);
136 if (!step) return step;
137 if (parametrization.size() != 2 && parametrization.size() != 3) {
139 "curve parametrization must be two- or three-dimensional",
140 operation);
141 }
142 if (t.empty()) {
144 "parameter variable name cannot be empty",
145 operation);
146 }
147 if (!a || !LMCAS::detail::node(a) || !b || !LMCAS::detail::node(b)) {
149 "curve integral bounds cannot be null",
150 operation);
151 }
152 for (const auto& component : parametrization) {
153 if (!component || !LMCAS::detail::node(component)) {
155 "curve parametrization components cannot be null",
156 operation);
157 }
158 }
159 return Result<void>::success();
160}
161
163 const std::shared_ptr<SymbolicExpr>& f,
165 const std::string& t,
166 const std::shared_ptr<SymbolicExpr>& a,
167 const std::shared_ptr<SymbolicExpr>& b,
169 const std::string& operation)
170{
171 auto step = context.consume_steps(1, operation);
172 if (!step) return step;
173 if (!f || !LMCAS::detail::node(f)) {
175 "scalar field cannot be null",
176 operation);
177 }
179 parametrization, t, a, b, context, operation);
180}
181
183 const VectorField& F,
185 const std::string& t,
186 const std::shared_ptr<SymbolicExpr>& a,
187 const std::shared_ptr<SymbolicExpr>& b,
189 const std::string& operation)
190{
191 auto step = context.consume_steps(1, operation);
192 if (!step) return step;
193 if (F.empty()) {
195 "vector field cannot be empty",
196 operation);
197 }
198 if (F.size() != parametrization.size()) {
200 "vector field and parametrization must have the same dimension",
201 operation);
202 }
203 for (const auto& component : F) {
204 if (!component || !LMCAS::detail::node(component)) {
206 "vector field components cannot be null",
207 operation);
208 }
209 }
211 parametrization, t, a, b, context, operation);
212}
213
215 const std::shared_ptr<SymbolicExpr>& u_lower,
216 const std::shared_ptr<SymbolicExpr>& u_upper,
217 const std::shared_ptr<SymbolicExpr>& v_lower,
218 const std::shared_ptr<SymbolicExpr>& v_upper,
219 const std::string& operation)
220{
221 for (const auto* bound : {&u_lower, &u_upper, &v_lower, &v_upper}) {
222 if (!*bound || !LMCAS::detail::node(*bound)) {
224 "surface integral bounds cannot be null",
225 operation);
226 }
227 }
228 return Result<void>::success();
229}
230
233 const std::string& u,
234 const std::string& v,
235 const std::shared_ptr<SymbolicExpr>& u_lower,
236 const std::shared_ptr<SymbolicExpr>& u_upper,
237 const std::shared_ptr<SymbolicExpr>& v_lower,
238 const std::shared_ptr<SymbolicExpr>& v_upper,
240 const std::string& operation)
241{
242 auto step = context.consume_steps(1, operation);
243 if (!step) {
244 return step;
245 }
246 if (parametrization.size() != 3) {
248 "surface parametrization must be three-dimensional",
249 operation);
250 }
251 if (u.empty() || v.empty()) {
253 "surface parameter variable names cannot be empty",
254 operation);
255 }
256 if (u == v) {
258 "surface parameter variables must be distinct",
259 operation);
260 }
262 u_lower, u_upper, v_lower, v_upper, operation);
263 if (!bounds) {
264 return bounds;
265 }
266 for (const auto& component : parametrization) {
267 if (!component || !LMCAS::detail::node(component)) {
269 "surface parametrization components cannot be null",
270 operation);
271 }
272 }
273 return Result<void>::success();
274}
275
277 const std::shared_ptr<SymbolicExpr>& f,
279 const std::string& u,
280 const std::string& v,
281 const std::shared_ptr<SymbolicExpr>& u_lower,
282 const std::shared_ptr<SymbolicExpr>& u_upper,
283 const std::shared_ptr<SymbolicExpr>& v_lower,
284 const std::shared_ptr<SymbolicExpr>& v_upper,
286 const std::string& operation)
287{
288 auto step = context.consume_steps(1, operation);
289 if (!step) return step;
290 if (!f || !LMCAS::detail::node(f)) {
292 "scalar field cannot be null",
293 operation);
294 }
297 context, operation);
298}
299
301 const VectorField& F,
303 const std::string& u,
304 const std::string& v,
305 const std::shared_ptr<SymbolicExpr>& u_lower,
306 const std::shared_ptr<SymbolicExpr>& u_upper,
307 const std::shared_ptr<SymbolicExpr>& v_lower,
308 const std::shared_ptr<SymbolicExpr>& v_upper,
310 const std::string& operation)
311{
312 auto step = context.consume_steps(1, operation);
313 if (!step) return step;
314 if (F.size() != 3) {
316 "surface vector field must have three components",
317 operation);
318 }
319 for (const auto& component : F) {
320 if (!component || !LMCAS::detail::node(component)) {
322 "surface vector field components cannot be null",
323 operation);
324 }
325 }
328 context, operation);
329}
330
332 const std::pair<std::shared_ptr<SymbolicExpr>, std::shared_ptr<SymbolicExpr>>& bounds,
334 const std::string& operation,
335 const std::string& label)
336{
337 auto step = context.consume_steps(1, operation);
338 if (!step) return step;
339 if (!bounds.first || !LMCAS::detail::node(bounds.first) || !bounds.second || !LMCAS::detail::node(bounds.second)) {
341 label + " bounds cannot be null",
342 operation);
343 }
344 return Result<void>::success();
345}
346
348 const std::vector<std::string>& vars,
349 std::size_t expected,
351 const std::string& operation)
352{
353 auto step = context.consume_steps(1, operation);
354 if (!step) return step;
355 if (vars.size() != expected) {
357 "variable list has the wrong dimension",
358 operation);
359 }
360 std::set<std::string> seen;
361 for (const auto& var : vars) {
362 if (var.empty()) {
364 "variable name cannot be empty",
365 operation);
366 }
367 if (!seen.insert(var).second) {
369 "variable names must be distinct",
370 operation);
371 }
372 }
373 return Result<void>::success();
374}
375
377 const std::shared_ptr<SymbolicExpr>& expr,
378 const std::map<std::string, std::shared_ptr<SymbolicExpr>>& point,
380 detail::RewriteBudget& transform_budget)
381{
382 if (!expr || !LMCAS::detail::node(expr)) {
383 return false;
384 }
385 auto substituted = expr;
386 for (const auto& [var, value] : point) {
387 if (!value || !LMCAS::detail::node(value)) {
388 return false;
389 }
390 substituted = detail::make_expression_ptr(detail::substitute_node(detail::node(substituted), var, detail::node(value), transform_budget));
391 if (!substituted || !LMCAS::detail::node(substituted)) {
392 return false;
393 }
394 }
395 substituted = detail::make_expression_ptr(detail::normalize_node(detail::node(substituted), transform_budget));
396 if (!substituted || !LMCAS::detail::node(substituted)) {
397 return false;
398 }
399 if (substituted->is_zero()) {
400 return true;
401 }
402 double value = 0.0;
404 std::abs(value) < 1e-8;
405}
406
408 const std::map<std::string, std::shared_ptr<SymbolicExpr>>& point,
409 const std::vector<std::string>& vars)
410{
411 for (const auto& var : vars) {
412 auto it = point.find(var);
413 if (it == point.end() || !it->second || !LMCAS::detail::node(it->second)) {
414 return false;
415 }
416 }
417 return true;
418}
419
421 std::shared_ptr<SymbolicExpr> expr,
422 const std::string& operation)
423{
424 if (!expr || !LMCAS::detail::node(expr)) {
427 "vector calculus construction produced a null expression",
428 operation);
429 }
430 return VectorCalculusExprResult::success(std::move(expr));
431}
432
434 VectorField field,
435 const std::string& operation)
436{
437 for (const auto& component : field) {
438 if (!component || !LMCAS::detail::node(component)) {
441 "vector calculus construction produced a null component",
442 operation);
443 }
444 }
445 return VectorCalculusFieldResult::success(std::move(field));
446}
447
448}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::optional< double > try_finite_numeric(const SymbolicExpr &expression, ComputationContext &context)
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
SymbolicNodePtr substitute_node(const SymbolicNodePtr &node, const std::string &variable, const SymbolicNodePtr &replacement, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
Result< void > vector_calculus_validate_curve_scalar_inputs(const std::shared_ptr< SymbolicExpr > &f, const VectorField &parametrization, const std::string &t, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context, const std::string &operation)
bool vector_calculus_point_has_vars(const std::map< std::string, std::shared_ptr< SymbolicExpr > > &point, const std::vector< std::string > &vars)
Result< void > vector_calculus_validate_distinct_vars(const std::vector< std::string > &vars, std::size_t expected, ComputationContext &context, const std::string &operation)
Result< void > vector_calculus_validate_surface_parametrization(const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, ComputationContext &context, const std::string &operation)
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)
Result< void > vector_calculus_validate_surface_vector_inputs(const VectorField &F, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, ComputationContext &context, const std::string &operation)
bool vector_calculus_expr_zero_after_substitution(const std::shared_ptr< SymbolicExpr > &expr, const std::map< std::string, std::shared_ptr< SymbolicExpr > > &point, ComputationContext &context, detail::RewriteBudget &transform_budget)
Result< void > vector_calculus_validate_surface_scalar_inputs(const std::shared_ptr< SymbolicExpr > &f, const VectorField &parametrization, const std::string &u, const std::string &v, const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, ComputationContext &context, const std::string &operation)
static Result< void > vector_calculus_validate_surface_bounds(const std::shared_ptr< SymbolicExpr > &u_lower, const std::shared_ptr< SymbolicExpr > &u_upper, const std::shared_ptr< SymbolicExpr > &v_lower, const std::shared_ptr< SymbolicExpr > &v_upper, const std::string &operation)
Result< void > vector_calculus_validate_curve_parametrization(const VectorField &parametrization, const std::string &t, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context, const std::string &operation)
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)
bool vector_calculus_checked_finite_numeric(const std::shared_ptr< SymbolicExpr > &expr, double &value, ComputationContext &context)
Result< void > vector_calculus_validate_curve_vector_inputs(const VectorField &F, const VectorField &parametrization, const std::string &t, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context, const std::string &operation)
VectorCalculusFieldResult vector_calculus_wrap_field(VectorField field, const std::string &operation)
Result< void > vector_calculus_validate_bound_pair(const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > &bounds, ComputationContext &context, const std::string &operation, const std::string &label)
VectorCalculusExprResult vector_calculus_wrap_expr(std::shared_ptr< SymbolicExpr > expr, const std::string &operation)
Result< void > vector_calculus_validate_field_vars(const VectorField &field, const std::vector< std::string > &vars, ComputationContext &context, const std::string &operation)
const std::string const LimitExprPtr & point
ExprResult e()
__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
__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
__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 const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > & v_lower
__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 const std::shared_ptr< SymbolicExpr > & u_lower
const MultiPoly & b
__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 const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > & v_upper
__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
__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 & parametrization
Result< std::shared_ptr< SymbolicExpr > > VectorCalculusExprResult
const std::string const ExprPtr & value
__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 const std::shared_ptr< SymbolicExpr > const std::shared_ptr< SymbolicExpr > & u_upper
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)
__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 & t
__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 & u
多项式方程组求解器 Solver,包含 Gröbner 基、线性系统求解。
内部 AST 定义。