LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
multiple_integral.cpp
浏览该文件的文档.
1#include <stdexcept>
4
5namespace LMCAS {
6
7static bool validate_integration_steps(const std::vector<IntegrationStep>& steps) {
8 if (steps.empty()) return false;
9
10 for (size_t i = 0; i < steps.size(); ++i) {
11 const auto& s = steps[i];
12 if (s.variable.empty()) return false;
13
14 // Bounds must be either both null (indefinite) or both set (definite).
15 const bool has_lower = static_cast<bool>(s.lower);
16 const bool has_upper = static_cast<bool>(s.upper);
17 if (has_lower != has_upper) return false;
18
19 // Reject duplicate variables.
20 for (size_t j = 0; j < i; ++j) {
21 if (steps[j].variable == s.variable) return false;
22 }
23 }
24 return true;
25}
26
28 const SymbolicExpr& integrand,
29 const std::vector<IntegrationStep>& steps,
30 Integrator& integrator,
32 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
33 (context).limits().max_ast_nodes, "transform");
34
37 CasErrc::InvalidArgument, "invalid multiple integration steps",
38 "integrate.multiple");
39 }
40 auto access = context.consume_steps(0, "integrate.multiple");
41 if (!access) return Result<SymbolicExpr>::failure(access.error());
42
43 auto current = LMCAS::detail::make_expression_ptr(integrand);
44
45 for (const auto& step : steps) {
46 auto step_access = context.consume_steps(1, "integrate.multiple");
47 if (!step_access) {
48 return Result<SymbolicExpr>::failure(step_access.error());
49 }
50 if (!current) {
52 CasErrc::InternalInvariant, "multiple integration lost its expression",
53 "integrate.multiple");
54 }
55
56
57 const bool definite = static_cast<bool>(step.lower) && static_cast<bool>(step.upper);
58
59 if (!definite) {
60 auto result = integrator.integrate_checked(*current, step.variable, context);
61 if (!result) return result;
62 current = LMCAS::detail::make_expression_ptr(result.value());
63 } else {
64 auto result = integrator.integrate_def_checked(
65 *current, step.variable, *step.lower, *step.upper, context);
66 if (!result) return result;
67 auto res_ptr = LMCAS::detail::make_expression_ptr(result.value());
68 auto simp = detail::make_expression_ptr(detail::normalize_node(detail::node(res_ptr), transform_budget));
69 current = simp ? simp : res_ptr;
70 }
71 }
72 auto final_access = context.consume_steps(0, "integrate.multiple");
73 if (!final_access) return Result<SymbolicExpr>::failure(final_access.error());
74
75 return Result<SymbolicExpr>::success(*current);
76} catch (const CasError& error) {
78} catch (const std::bad_alloc&) {
79 return Result<SymbolicExpr>::failure(CasErrc::ResourceLimit, "allocation failed", "integrate_multiple_checked");
80} catch (const std::length_error& error) {
81 return Result<SymbolicExpr>::failure(CasErrc::ResourceLimit, error.what(), "integrate_multiple_checked");
82} catch (const std::exception& error) {
83 return Result<SymbolicExpr>::failure(CasErrc::InternalInvariant, error.what(), "integrate_multiple_checked");
84}
85
86} // namespace LMCAS
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
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
const std::string & variable
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
static bool validate_integration_steps(const std::vector< IntegrationStep > &steps)
Result< SymbolicExpr > integrate_multiple_checked(const SymbolicExpr &integrand, const std::vector< IntegrationStep > &steps, Integrator &integrator, ComputationContext &context)
const std::vector< IntegrationStep > Integrator & integrator