LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
vector_calculus_integrals.cpp
浏览该文件的文档.
3#include "integration.hpp"
6#include "solver.hpp"
10
11#include <cmath>
12#include <exception>
13#include <map>
14#include <memory>
15#include <set>
16#include <stdexcept>
17#include <string>
18#include <vector>
19
20namespace LMCAS {
21
22using namespace vector_calculus_detail;
23
25 size_t dim)
26{
27 if (dim == 2) return {"x", "y"};
28 return {"x", "y", "z"};
29}
30
32 const std::shared_ptr<SymbolicExpr>& integrand,
33 const std::string& var,
34 const std::shared_ptr<SymbolicExpr>& a,
35 const std::shared_ptr<SymbolicExpr>& b,
37 detail::RewriteBudget& transform_budget)
38{
39 Integrator integrator;
40 auto integrated = integrator.integrate_def_checked(
41 *integrand, var, *a, *b, context);
42 if (!integrated) {
43 return VectorCalculusExprResult::failure(integrated.error());
44 }
45 SymbolicExpr result = std::move(integrated.value());
46
48 return std::shared_ptr<SymbolicExpr>{};
49 }
50 auto res = LMCAS::detail::make_expression_ptr(result);
51 auto simplified = detail::make_expression_ptr(detail::normalize_node(detail::node(res), transform_budget));
52 if (simplified &&
54 return std::shared_ptr<SymbolicExpr>{};
55 }
56 return simplified ? simplified : res;
57}
58
60 const std::shared_ptr<SymbolicExpr>& integrand,
61 const std::string& var,
62 const std::shared_ptr<SymbolicExpr>& a,
63 const std::shared_ptr<SymbolicExpr>& b,
65 detail::RewriteBudget& transform_budget)
66{
67 double a_val = 0.0;
68 double b_val = 0.0;
71 return std::shared_ptr<SymbolicExpr>{};
72 }
73
74 int n = 1000;
75 double h = (b_val - a_val) / n;
76 if (!std::isfinite(h)) return std::shared_ptr<SymbolicExpr>{};
77 double sum = 0.0;
78
79 for (int i = 0; i <= n; ++i) {
80 auto step_result =
81 context.consume_steps(1, "vector_calculus.numeric_integral");
82 if (!step_result) {
83 return VectorCalculusExprResult::failure(step_result.error());
84 }
85 double xi = a_val + i * h;
86 if (!std::isfinite(xi)) return std::shared_ptr<SymbolicExpr>{};
87 auto xi_expr = SymbolicExpr::number(xi);
88 auto fi = detail::make_expression_ptr(detail::substitute_node(detail::node(integrand), var, detail::node(xi_expr), transform_budget));
89 double fi_val = 0.0;
91 return std::shared_ptr<SymbolicExpr>{};
92 }
93
94 double weight = 1.0;
95 if (i == 0 || i == n) {
96 weight = 1.0;
97 } else if (i % 2 == 1) {
98 weight = 4.0;
99 } else {
100 weight = 2.0;
101 }
102 sum += weight * fi_val;
103 if (!std::isfinite(sum)) return std::shared_ptr<SymbolicExpr>{};
104 }
105 sum *= h / 3.0;
106 if (!std::isfinite(sum)) return std::shared_ptr<SymbolicExpr>{};
107
108 return SymbolicExpr::number(sum);
109}
110
111std::shared_ptr<SymbolicExpr>
113 const std::shared_ptr<SymbolicExpr>& integrand,
114 const std::string& var,
115 const std::shared_ptr<SymbolicExpr>& a,
116 const std::shared_ptr<SymbolicExpr>& b,
118 detail::RewriteBudget& transform_budget)
119{
120 auto symbolic_result = vector_calculus_try_definite(integrand, var, a, b, context, transform_budget);
121 if (symbolic_result && symbolic_result.value()) {
122 return std::move(symbolic_result.value());
123 }
124 if (!symbolic_result) throw symbolic_result.error();
125 auto numerical_result = vector_calculus_numerical_definite(integrand, var, a, b, context, transform_budget);
126 if (!numerical_result) throw numerical_result.error();
127 return std::move(numerical_result.value());
128}
129
131 const std::string& operation,
132 const std::string& message)
133{
135 message, operation);
136}
137
139 const std::shared_ptr<SymbolicExpr>& expr,
140 const std::string& operation,
141 const std::string& message,
142 detail::RewriteBudget& transform_budget)
143{
144 if (!expr || !LMCAS::detail::node(expr)) {
145 return vector_calculus_inconclusive(operation, message);
146 }
147 auto simplified = detail::make_expression_ptr(detail::normalize_node(detail::node(expr), transform_budget));
148 if (!simplified || !LMCAS::detail::node(simplified)) {
149 return vector_calculus_inconclusive(operation, message);
150 }
151 return VectorCalculusExprResult::success(std::move(simplified));
152}
153
155 const std::shared_ptr<SymbolicExpr>& expr,
156 const std::string& var,
157 const std::string& operation,
158 detail::RewriteBudget& transform_budget)
159{
160 if (!expr || !LMCAS::detail::node(expr)) {
162 operation, "expression derivative is outside the supported domain");
163 }
164 try {
165 auto derivative = detail::make_expression_ptr(detail::differentiate_node(detail::node(expr), var, transform_budget));
166 return vector_calculus_simplify_strict(derivative, operation,
167 "expression derivative is outside the supported domain", transform_budget);
168 } catch (const CasError& error) {
171 }
173 operation, "expression derivative is outside the supported domain");
174 }
175}
176
178 const std::shared_ptr<SymbolicExpr>& expr,
179 const std::vector<std::string>& coord_vars,
180 const VectorField& values,
181 const std::string& operation,
182 detail::RewriteBudget& transform_budget)
183{
184 if (!expr || !LMCAS::detail::node(expr) || coord_vars.size() != values.size()) {
186 operation, "coordinate substitution is outside the supported domain");
187 }
188 auto substituted = expr;
189 for (size_t i = 0; i < coord_vars.size(); ++i) {
190 if (!values[i] || !LMCAS::detail::node(values[i])) {
192 operation, "coordinate substitution is outside the supported domain");
193 }
194 substituted = detail::make_expression_ptr(detail::substitute_node(detail::node(substituted), coord_vars[i], detail::node(values[i]), transform_budget));
195 if (!substituted || !LMCAS::detail::node(substituted)) {
197 operation, "coordinate substitution is outside the supported domain");
198 }
199 }
200 return vector_calculus_simplify_strict(substituted, operation,
201 "coordinate substitution is outside the supported domain", transform_budget);
202}
203
205 const std::shared_ptr<SymbolicExpr>& integrand,
206 const std::string& var,
207 const std::shared_ptr<SymbolicExpr>& a,
208 const std::shared_ptr<SymbolicExpr>& b,
210 const std::string& operation,
211 detail::RewriteBudget& transform_budget)
212{
213 auto result = vector_calculus_try_definite(integrand, var, a, b, context, transform_budget);
214 if (!result) return result;
215 if (!result.value() || !LMCAS::detail::node(result.value())) {
217 operation,
218 "integral could not be evaluated exactly in the supported domain");
219 }
220 return result;
221}
222
224 const std::shared_ptr<SymbolicExpr>& integrand,
225 const std::vector<IntegrationStep>& steps,
227 const std::string& operation,
228 detail::RewriteBudget& transform_budget)
229{
230 if (!integrand || !LMCAS::detail::node(integrand)) {
232 operation, "integrand construction is outside the supported domain");
233 }
234 Integrator integrator;
235 auto integrated = integrate_multiple_checked(*integrand, steps, integrator, context);
236 if (!integrated) return VectorCalculusExprResult::failure(integrated.error());
237 auto result = LMCAS::detail::make_expression_ptr(integrated.value());
238 return vector_calculus_simplify_strict(result, operation,
239 "integral result simplification is outside the supported domain", transform_budget);
240}
241
244 const std::string& u,
245 const std::string& v,
246 const std::string& operation,
247 detail::RewriteBudget& transform_budget)
248{
249 VectorField r_u;
250 VectorField r_v;
251 r_u.reserve(3);
252 r_v.reserve(3);
253 for (size_t i = 0; i < 3; ++i) {
254 auto du = vector_calculus_differentiate_strict(parametrization[i], u, operation, transform_budget);
255 if (!du) return Result<VectorField>::failure(du.error());
256 auto dv = vector_calculus_differentiate_strict(parametrization[i], v, operation, transform_budget);
257 if (!dv) return Result<VectorField>::failure(dv.error());
258 r_u.push_back(std::move(du.value()));
259 r_v.push_back(std::move(dv.value()));
260 }
261
262 VectorField cross;
263 cross.reserve(3);
264 for (std::size_t index = 0; index < 3; ++index) {
265 auto component = vector_calculus_cross_component(
266 r_u, r_v, index);
267 auto checked = vector_calculus_simplify_strict(component, operation,
268 "surface normal construction is outside the supported domain", transform_budget);
269 if (!checked) {
270 return Result<VectorField>::failure(checked.error());
271 }
272 cross.push_back(std::move(checked.value()));
273 }
274 return Result<VectorField>::success(std::move(cross));
275}
276
279 const std::shared_ptr<SymbolicExpr>& f, const VectorField& parametrization,
280 const std::string& t, const std::shared_ptr<SymbolicExpr>& a,
281 const std::shared_ptr<SymbolicExpr>& b,
283 const std::string& operation,
284 detail::RewriteBudget& transform_budget)
285{
286 const auto coord_vars = vector_calculus_coord_vars(parametrization.size());
287 auto f_composed = vector_calculus_substitute_coords_strict(f, coord_vars, parametrization, operation, transform_budget);
288 if (!f_composed) {
289 return f_composed;
290 }
291
292 std::shared_ptr<SymbolicExpr> speed_sq;
293 for (const auto& component : parametrization) {
294 auto derivative = vector_calculus_differentiate_strict(component, t, operation, transform_budget);
295 if (!derivative) {
296 return derivative;
297 }
298 auto sq = SymbolicExpr::power(derivative.value(), SymbolicExpr::number(2));
299 auto sq_checked = vector_calculus_simplify_strict(sq, operation, "curve speed construction is outside the supported domain", transform_budget);
300 if (!sq_checked) {
301 return sq_checked;
302 }
303 speed_sq = speed_sq ? SymbolicExpr::add(speed_sq, sq_checked.value())
304 : sq_checked.value();
305 auto speed_sq_checked = vector_calculus_simplify_strict(speed_sq, operation, "curve speed construction is outside the supported domain", transform_budget);
306 if (!speed_sq_checked) {
307 return speed_sq_checked;
308 }
309 speed_sq = std::move(speed_sq_checked.value());
310 }
311
312 auto speed = SymbolicExpr::sqrt(speed_sq);
313 auto speed_checked = vector_calculus_simplify_strict(speed, operation, "curve speed construction is outside the supported domain", transform_budget);
314 if (!speed_checked) {
315 return speed_checked;
316 }
317
318 auto integrand = SymbolicExpr::multiply(f_composed.value(), speed_checked.value());
319 auto integrand_checked = vector_calculus_simplify_strict(integrand, operation, "curve integrand construction is outside the supported domain", transform_budget);
320 if (!integrand_checked) {
321 return integrand_checked;
322 }
323
324 return vector_calculus_definite_integral_strict(integrand_checked.value(), t, a, b, context, operation, transform_budget);
325}
326
329 const VectorField& F, const VectorField& parametrization,
330 const std::string& t, const std::shared_ptr<SymbolicExpr>& a,
331 const std::shared_ptr<SymbolicExpr>& b,
333 const std::string& operation,
334 detail::RewriteBudget& transform_budget)
335{
336 const auto coord_vars = vector_calculus_coord_vars(parametrization.size());
337 std::shared_ptr<SymbolicExpr> dot_product;
338 for (size_t i = 0; i < F.size(); ++i) {
339 auto Fi_composed = vector_calculus_substitute_coords_strict(F[i], coord_vars, parametrization, operation, transform_budget);
340 if (!Fi_composed) return Fi_composed;
341
342 auto ri_prime = vector_calculus_differentiate_strict(parametrization[i], t, operation, transform_budget);
343 if (!ri_prime) return ri_prime;
344
345 auto term = SymbolicExpr::multiply(Fi_composed.value(), ri_prime.value());
346 auto term_checked = vector_calculus_simplify_strict(term, operation, "curve integrand construction is outside the supported domain", transform_budget);
347 if (!term_checked) return term_checked;
348
349 dot_product = dot_product ? SymbolicExpr::add(dot_product, term_checked.value())
350 : term_checked.value();
351 auto dot_checked = vector_calculus_simplify_strict(dot_product, operation, "curve integrand construction is outside the supported domain", transform_budget);
352 if (!dot_checked) return dot_checked;
353 dot_product = std::move(dot_checked.value());
354 }
355
356 return vector_calculus_definite_integral_strict(dot_product, t, a, b, context, operation, transform_budget);
357}
358
361 const std::shared_ptr<SymbolicExpr>& f, const VectorField& parametrization,
362 const std::string& u, const std::string& v,
363 const std::shared_ptr<SymbolicExpr>& u_lower, const std::shared_ptr<SymbolicExpr>& u_upper,
364 const std::shared_ptr<SymbolicExpr>& v_lower, const std::shared_ptr<SymbolicExpr>& v_upper,
366 const std::string& operation,
367 detail::RewriteBudget& transform_budget)
368{
369 const std::vector<std::string> coord_vars = {"x", "y", "z"};
370 auto f_composed = vector_calculus_substitute_coords_strict(f, coord_vars, parametrization, operation, transform_budget);
371 if (!f_composed) return f_composed;
372
373 auto cross = vector_calculus_cross_product_partials_strict(parametrization, u, v, operation, transform_budget);
374 if (!cross) return VectorCalculusExprResult::failure(cross.error());
375
376 std::shared_ptr<SymbolicExpr> mag_sq;
377 for (const auto& component : cross.value()) {
378 auto sq = SymbolicExpr::power(component, SymbolicExpr::number(2));
379 auto sq_checked = vector_calculus_simplify_strict(sq, operation, "surface magnitude construction is outside the supported domain", transform_budget);
380 if (!sq_checked) return sq_checked;
381 mag_sq = mag_sq ? SymbolicExpr::add(mag_sq, sq_checked.value())
382 : sq_checked.value();
383 auto mag_sq_checked = vector_calculus_simplify_strict(mag_sq, operation, "surface magnitude construction is outside the supported domain", transform_budget);
384 if (!mag_sq_checked) return mag_sq_checked;
385 mag_sq = std::move(mag_sq_checked.value());
386 }
387
388 auto magnitude = SymbolicExpr::sqrt(mag_sq);
389 auto magnitude_checked = vector_calculus_simplify_strict(magnitude, operation, "surface magnitude construction is outside the supported domain", transform_budget);
390 if (!magnitude_checked) return magnitude_checked;
391
392 auto integrand = SymbolicExpr::multiply(f_composed.value(), magnitude_checked.value());
393 auto integrand_checked = vector_calculus_simplify_strict(integrand, operation, "surface integrand construction is outside the supported domain", transform_budget);
394 if (!integrand_checked) return integrand_checked;
395
396 std::vector<IntegrationStep> steps;
397 steps.push_back({v, v_lower, v_upper});
398 steps.push_back({u, u_lower, u_upper});
399 return vector_calculus_multiple_integral_strict(integrand_checked.value(), steps, context, operation, transform_budget);
400}
401
403 const VectorField& field,
404 const std::vector<std::string>& coordinates,
406 const VectorField& normal,
407 const std::string& message,
408 const std::string& operation,
409 detail::RewriteBudget& transform_budget) {
410 std::shared_ptr<SymbolicExpr> dot_product;
411 for (std::size_t i = 0; i < 3; ++i) {
412 auto composed = vector_calculus_substitute_coords_strict(field[i], coordinates, parametrization, operation, transform_budget);
413 if (!composed) {
414 return composed;
415 }
416 auto term = SymbolicExpr::multiply(
417 composed.value(), normal[i]);
418 auto term_checked = vector_calculus_simplify_strict(term, operation, message, transform_budget);
419 if (!term_checked) {
420 return term_checked;
421 }
423 ? SymbolicExpr::add(dot_product, term_checked.value())
424 : term_checked.value();
425 auto dot_checked = vector_calculus_simplify_strict(dot_product, operation, message, transform_budget);
426 if (!dot_checked) {
427 return dot_checked;
428 }
429 dot_product = std::move(dot_checked.value());
430 }
432}
433
436 const VectorField& F, const VectorField& parametrization,
437 const std::string& u, const std::string& v,
438 const std::shared_ptr<SymbolicExpr>& u_lower, const std::shared_ptr<SymbolicExpr>& u_upper,
439 const std::shared_ptr<SymbolicExpr>& v_lower, const std::shared_ptr<SymbolicExpr>& v_upper,
441 const std::string& operation,
442 detail::RewriteBudget& transform_budget)
443{
444 const std::vector<std::string> coord_vars = {"x", "y", "z"};
445 auto cross = vector_calculus_cross_product_partials_strict(parametrization, u, v, operation, transform_budget);
446 if (!cross) return VectorCalculusExprResult::failure(cross.error());
447
449 "surface integrand construction is outside the supported domain",
450 operation, transform_budget);
451 if (!dot_product) return dot_product;
452
453 std::vector<IntegrationStep> steps;
454 steps.push_back({v, v_lower, v_upper});
455 steps.push_back({u, u_lower, u_upper});
456 return vector_calculus_multiple_integral_strict(dot_product.value(), steps, context, operation, transform_budget);
457}
458
460 const std::shared_ptr<SymbolicExpr>& P,
461 const std::shared_ptr<SymbolicExpr>& Q,
462 const std::vector<std::string>& vars,
463 const std::pair<std::shared_ptr<SymbolicExpr>, std::shared_ptr<SymbolicExpr>>& x_bounds,
464 const std::pair<std::shared_ptr<SymbolicExpr>, std::shared_ptr<SymbolicExpr>>& y_bounds,
466 const std::string& operation,
467 detail::RewriteBudget& transform_budget)
468{
469 auto dQ_dx = vector_calculus_differentiate_strict(Q, vars[0], operation, transform_budget);
470 if (!dQ_dx) return dQ_dx;
471 auto dP_dy = vector_calculus_differentiate_strict(P, vars[1], operation, transform_budget);
472 if (!dP_dy) return dP_dy;
473
474 auto integrand = SymbolicExpr::add(
475 dQ_dx.value(),
476 SymbolicExpr::multiply(SymbolicExpr::number(-1), dP_dy.value()));
477 auto integrand_checked = vector_calculus_simplify_strict(integrand, operation, "Green's theorem integrand is outside the supported domain", transform_budget);
478 if (!integrand_checked) return integrand_checked;
479
480 std::vector<IntegrationStep> steps;
481 steps.push_back({vars[1], y_bounds.first, y_bounds.second});
482 steps.push_back({vars[0], x_bounds.first, x_bounds.second});
483 return vector_calculus_multiple_integral_strict(integrand_checked.value(), steps, context, operation, transform_budget);
484}
485
487 const std::shared_ptr<SymbolicExpr>& integrand,
488 const std::string& variable,
490 detail::RewriteBudget& transform_budget) {
491 auto candidate = detail::make_expression_ptr(detail::substitute_node(detail::node(integrand), variable, detail::node(SymbolicExpr::number(0)), transform_budget));
492 candidate = candidate ? detail::make_expression_ptr(detail::normalize_node(detail::node(candidate), transform_budget)) : nullptr;
493 if (!candidate || expression_depends_on_variable(detail::node(candidate), variable)) {
494 return VectorCalculusExprResult::success(integrand);
495 }
496
497 EqvOptions trig_options;
498 trig_options.profile = EqvProfile::TrigBasic;
499 auto identity = check_equivalent(
500 integrand, candidate, context, trig_options);
501 if (!identity) {
502 return VectorCalculusExprResult::failure(identity.error());
503 }
504 if (!std::holds_alternative<ProvedZeroResidual>(
505 identity.value())) {
506 return VectorCalculusExprResult::success(integrand);
507 }
508 return VectorCalculusExprResult::success(std::move(candidate));
509}
510
513 const std::string& t,
514 const std::shared_ptr<SymbolicExpr>& a,
515 const std::shared_ptr<SymbolicExpr>& b,
517 const std::string& operation,
518 detail::RewriteBudget& transform_budget)
519{
520 auto dx_dt = vector_calculus_differentiate_strict(parametrization[0], t, operation, transform_budget);
521 if (!dx_dt) return dx_dt;
522 auto dy_dt = vector_calculus_differentiate_strict(parametrization[1], t, operation, transform_budget);
523 if (!dy_dt) return dy_dt;
524
525 auto term1 = SymbolicExpr::multiply(parametrization[0], dy_dt.value());
526 auto term2 = SymbolicExpr::multiply(parametrization[1], dx_dt.value());
527 auto integrand = SymbolicExpr::add(
528 term1,
529 SymbolicExpr::multiply(SymbolicExpr::number(-1), term2));
530 auto integrand_checked = vector_calculus_simplify_strict(integrand, operation, "Green's area integrand is outside the supported domain", transform_budget);
531 if (!integrand_checked) return integrand_checked;
532 integrand_checked = vector_calculus_constant_integrand(integrand_checked.value(), t, context, transform_budget);
533 if (!integrand_checked) return integrand_checked;
534
535 auto integral = vector_calculus_definite_integral_strict(integrand_checked.value(), t, a, b, context, operation, transform_budget);
536 if (!integral) return integral;
537
540 auto area = SymbolicExpr::multiply(half, integral.value());
541 return vector_calculus_simplify_strict(area, operation, "Green's area result is outside the supported domain", transform_budget);
542}
543
545 const VectorField& F,
546 const std::vector<std::string>& vars,
547 const std::pair<std::shared_ptr<SymbolicExpr>, std::shared_ptr<SymbolicExpr>>& x_bounds,
548 const std::pair<std::shared_ptr<SymbolicExpr>, std::shared_ptr<SymbolicExpr>>& y_bounds,
549 const std::pair<std::shared_ptr<SymbolicExpr>, std::shared_ptr<SymbolicExpr>>& z_bounds,
551 const std::string& operation,
552 detail::RewriteBudget& transform_budget)
553{
554 std::shared_ptr<SymbolicExpr> div_F;
555 for (size_t i = 0; i < 3; ++i) {
556 auto partial = vector_calculus_differentiate_strict(F[i], vars[i], operation, transform_budget);
557 if (!partial) return partial;
558 div_F = div_F ? SymbolicExpr::add(div_F, partial.value()) : partial.value();
559 auto div_checked = vector_calculus_simplify_strict(div_F, operation, "divergence theorem integrand is outside the supported domain", transform_budget);
560 if (!div_checked) return div_checked;
561 div_F = std::move(div_checked.value());
562 }
563
564 std::vector<IntegrationStep> steps;
565 steps.push_back({vars[2], z_bounds.first, z_bounds.second});
566 steps.push_back({vars[1], y_bounds.first, y_bounds.second});
567 steps.push_back({vars[0], x_bounds.first, x_bounds.second});
568 return vector_calculus_multiple_integral_strict(div_F, steps, context, operation, transform_budget);
569}
570
572 const VectorField& F,
573 const std::vector<std::string>& vars,
574 const std::string& operation,
575 detail::RewriteBudget& transform_budget)
576{
577 auto dFz_dy = vector_calculus_differentiate_strict(F[2], vars[1], operation, transform_budget);
578 if (!dFz_dy) {
579 return Result<VectorField>::failure(dFz_dy.error());
580 }
581 auto dFy_dz = vector_calculus_differentiate_strict(F[1], vars[2], operation, transform_budget);
582 if (!dFy_dz) {
583 return Result<VectorField>::failure(dFy_dz.error());
584 }
585 auto dFx_dz = vector_calculus_differentiate_strict(F[0], vars[2], operation, transform_budget);
586 if (!dFx_dz) {
587 return Result<VectorField>::failure(dFx_dz.error());
588 }
589 auto dFz_dx = vector_calculus_differentiate_strict(F[2], vars[0], operation, transform_budget);
590 if (!dFz_dx) {
591 return Result<VectorField>::failure(dFz_dx.error());
592 }
593 auto dFy_dx = vector_calculus_differentiate_strict(F[1], vars[0], operation, transform_budget);
594 if (!dFy_dx) {
595 return Result<VectorField>::failure(dFy_dx.error());
596 }
597 auto dFx_dy = vector_calculus_differentiate_strict(F[0], vars[1], operation, transform_budget);
598 if (!dFx_dy) {
599 return Result<VectorField>::failure(dFx_dy.error());
600 }
601
602 auto cx = SymbolicExpr::add(
603 dFz_dy.value(),
604 SymbolicExpr::multiply(SymbolicExpr::number(-1), dFy_dz.value()));
605 auto cx_checked = vector_calculus_simplify_strict(cx, operation, "curl construction is outside the supported domain", transform_budget);
606 if (!cx_checked) {
607 return Result<VectorField>::failure(cx_checked.error());
608 }
609
610 auto cy = SymbolicExpr::add(
611 dFx_dz.value(),
612 SymbolicExpr::multiply(SymbolicExpr::number(-1), dFz_dx.value()));
613 auto cy_checked = vector_calculus_simplify_strict(cy, operation, "curl construction is outside the supported domain", transform_budget);
614 if (!cy_checked) {
615 return Result<VectorField>::failure(cy_checked.error());
616 }
617
618 auto cz = SymbolicExpr::add(
619 dFy_dx.value(),
620 SymbolicExpr::multiply(SymbolicExpr::number(-1), dFx_dy.value()));
621 auto cz_checked = vector_calculus_simplify_strict(cz, operation, "curl construction is outside the supported domain", transform_budget);
622 if (!cz_checked) {
623 return Result<VectorField>::failure(cz_checked.error());
624 }
625
627 VectorField{std::move(cx_checked.value()),
628 std::move(cy_checked.value()),
629 std::move(cz_checked.value())});
630}
631
633 const VectorField& F,
634 const std::vector<std::string>& vars,
636 const std::string& u,
637 const std::string& v,
638 const std::pair<std::shared_ptr<SymbolicExpr>, std::shared_ptr<SymbolicExpr>>& u_bounds,
639 const std::pair<std::shared_ptr<SymbolicExpr>, std::shared_ptr<SymbolicExpr>>& v_bounds,
641 const std::string& operation,
642 detail::RewriteBudget& transform_budget)
643{
644 auto curl_F = vector_calculus_curl_strict(F, vars, operation, transform_budget);
645 if (!curl_F) return VectorCalculusExprResult::failure(curl_F.error());
646
647 auto cross = vector_calculus_cross_product_partials_strict(parametrization, u, v, operation, transform_budget);
648 if (!cross) return VectorCalculusExprResult::failure(cross.error());
649
651 "Stokes theorem integrand is outside the supported domain",
652 operation, transform_budget);
653 if (!dot_product) return dot_product;
654
655 std::vector<IntegrationStep> steps;
656 steps.push_back({v, v_bounds.first, v_bounds.second});
657 steps.push_back({u, u_bounds.first, u_bounds.second});
658 return vector_calculus_multiple_integral_strict(dot_product.value(), steps, context, operation, transform_budget);
659}
660
661
662}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(std::shared_ptr< SymbolicExpr > value)
Symbolic integration APIs.
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)
SymbolicNodePtr substitute_node(const SymbolicNodePtr &node, const std::string &variable, const SymbolicNodePtr &replacement, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
VectorCalculusExprResult surface_integral_scalar_strict(const std::shared_ptr< SymbolicExpr > &function, 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, detail::RewriteBudget &transform_budget)
VectorCalculusExprResult vector_calculus_differentiate_strict(const std::shared_ptr< SymbolicExpr > &expr, const std::string &variable, const std::string &operation, detail::RewriteBudget &transform_budget)
std::vector< std::string > vector_calculus_coord_vars(std::size_t dimension)
VectorCalculusExprResult surface_integral_vector_strict(const VectorField &field, 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, detail::RewriteBudget &transform_budget)
VectorCalculusExprResult curve_integral_scalar_strict(const std::shared_ptr< SymbolicExpr > &function, const VectorField &parametrization, const std::string &parameter, const std::shared_ptr< SymbolicExpr > &lower, const std::shared_ptr< SymbolicExpr > &upper, ComputationContext &context, const std::string &operation, detail::RewriteBudget &transform_budget)
VectorCalculusExprResult greens_theorem_area_strict(const VectorField &parametrization, const std::string &parameter, const std::shared_ptr< SymbolicExpr > &lower, const std::shared_ptr< SymbolicExpr > &upper, ComputationContext &context, const std::string &operation, detail::RewriteBudget &transform_budget)
std::shared_ptr< SymbolicExpr > vector_calculus_cross_component(const VectorField &left, const VectorField &right, std::size_t index)
VectorCalculusExprResult vector_calculus_simplify_strict(const std::shared_ptr< SymbolicExpr > &expr, const std::string &operation, const std::string &message, detail::RewriteBudget &transform_budget)
std::shared_ptr< SymbolicExpr > vector_calculus_integrate_with_fallback(const std::shared_ptr< SymbolicExpr > &integrand, const std::string &variable, const std::shared_ptr< SymbolicExpr > &lower, const std::shared_ptr< SymbolicExpr > &upper, ComputationContext &context, detail::RewriteBudget &transform_budget)
VectorCalculusExprResult stokes_theorem_strict(const VectorField &field, const std::vector< std::string > &variables, const VectorField &parametrization, const std::string &u, const std::string &v, const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > &u_bounds, const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > &v_bounds, ComputationContext &context, const std::string &operation, detail::RewriteBudget &transform_budget)
bool vector_calculus_checked_finite_numeric(const std::shared_ptr< SymbolicExpr > &expr, double &value, ComputationContext &context)
VectorCalculusExprResult greens_theorem_strict(const std::shared_ptr< SymbolicExpr > &p, const std::shared_ptr< SymbolicExpr > &q, const std::vector< std::string > &variables, const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > &x_bounds, const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > &y_bounds, ComputationContext &context, const std::string &operation, detail::RewriteBudget &transform_budget)
VectorCalculusExprResult curve_integral_vector_strict(const VectorField &field, const VectorField &parametrization, const std::string &parameter, const std::shared_ptr< SymbolicExpr > &lower, const std::shared_ptr< SymbolicExpr > &upper, ComputationContext &context, const std::string &operation, detail::RewriteBudget &transform_budget)
VectorCalculusExprResult divergence_theorem_strict(const VectorField &field, const std::vector< std::string > &variables, const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > &x_bounds, const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > &y_bounds, const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > &z_bounds, ComputationContext &context, const std::string &operation, detail::RewriteBudget &transform_budget)
static VectorCalculusExprResult vector_calculus_try_definite(const std::shared_ptr< SymbolicExpr > &integrand, const std::string &var, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context, detail::RewriteBudget &transform_budget)
const std::string & variable
__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
ResidualCheckResult check_equivalent(const ExprPtr &left, const ExprPtr &right, ComputationContext &context, const LMCAS::EqvOptions &options)
bool contains_unevaluated_integral(const std::shared_ptr< const SymbolicNode > &node)
static VectorCalculusExprResult vector_calculus_constant_integrand(const std::shared_ptr< SymbolicExpr > &integrand, const std::string &variable, ComputationContext &context, detail::RewriteBudget &transform_budget)
static VectorCalculusExprResult vector_calculus_definite_integral_strict(const std::shared_ptr< SymbolicExpr > &integrand, const std::string &var, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context, const std::string &operation, detail::RewriteBudget &transform_budget)
bool expression_depends_on_variable(const detail::SymbolicNodePtr &expression, const std::string &variable, detail::RewriteBudget *budget)
__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
static Result< VectorField > vector_calculus_cross_product_partials_strict(const VectorField &parametrization, const std::string &u, const std::string &v, const std::string &operation, detail::RewriteBudget &transform_budget)
const MultiPoly & b
__attribute__((visibility("default"))) std const std::vector< std::string > const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > & z_bounds
__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"))) std const std::vector< std::string > const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > & x_bounds
__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
向量场由标量表达式组成。
__attribute__((visibility("default"))) MatrixRankResult matrix_rank_checked(const std __attribute__((visibility("default"))) MatrixRankResult matrix_rank_checked(const std __attribute__((visibility("default"))) ExpressionResult matrix_rref_checked(const std __attribute__((visibility("default"))) ExpressionResult matrix_rref_checked(const std __attribute__((visibility("default"))) MatrixNullspaceResult matrix_nullspace_checked(const std __attribute__((visibility("default"))) MatrixNullspaceResult matrix_nullspace_checked(const std __attribute__((visibility("default"))) MatrixLinearSolveResult matrix_solve_linear_checked(const std __attribute__((visibility("default"))) MatrixLinearSolveResult matrix_solve_linear_checked(const std int dim
static Result< VectorField > vector_calculus_curl_strict(const VectorField &F, const std::vector< std::string > &vars, const std::string &operation, detail::RewriteBudget &transform_budget)
__attribute__((visibility("default"))) std const std::vector< std::string > const VectorField const std::string const std::string const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > & u_bounds
__attribute__((visibility("default"))) std const std::vector< std::string > const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > & y_bounds
static VectorCalculusExprResult vector_calculus_multiple_integral_strict(const std::shared_ptr< SymbolicExpr > &integrand, const std::vector< IntegrationStep > &steps, ComputationContext &context, const std::string &operation, 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 & parametrization
Result< SymbolicExpr > integrate_multiple_checked(const SymbolicExpr &integrand, const std::vector< IntegrationStep > &steps, Integrator &integrator, ComputationContext &context)
Result< std::shared_ptr< SymbolicExpr > > VectorCalculusExprResult
static VectorCalculusExprResult vector_calculus_inconclusive(const std::string &operation, const std::string &message)
static VectorCalculusExprResult vector_calculus_surface_dot_strict(const VectorField &field, const std::vector< std::string > &coordinates, const VectorField &parametrization, const VectorField &normal, const std::string &message, const std::string &operation, detail::RewriteBudget &transform_budget)
__attribute__((visibility("default"))) std const std::vector< std::string > const VectorField const std::string const std::string const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > const std::pair< std::shared_ptr< SymbolicExpr >, std::shared_ptr< SymbolicExpr > > & v_bounds
static VectorCalculusExprResult vector_calculus_numerical_definite(const std::shared_ptr< SymbolicExpr > &integrand, const std::string &var, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context, detail::RewriteBudget &transform_budget)
__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
static VectorCalculusExprResult vector_calculus_substitute_coords_strict(const std::shared_ptr< SymbolicExpr > &expr, const std::vector< std::string > &coord_vars, const VectorField &values, const std::string &operation, 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 & t
const std::vector< IntegrationStep > Integrator & integrator
VectorCalculusExprResult dot_product(const VectorField &a, const VectorField &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 & u
多项式方程组求解器 Solver,包含 Gröbner 基、线性系统求解。
内部 AST 定义。