LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
calculus_revolution.cpp
浏览该文件的文档.
1#include <stdexcept>
3#include "integration.hpp"
7
8namespace LMCAS {
9
10using namespace calculus_utils_detail;
12 const std::shared_ptr<SymbolicExpr>& integrand,
13 const std::string& var,
14 const std::shared_ptr<SymbolicExpr>& a,
15 const std::shared_ptr<SymbolicExpr>& b,
17try {
18 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
19 (context).limits().max_ast_nodes, "transform");
20 Integrator integrator;
21 auto integrated = integrator.integrate_def_checked(
22 *integrand, var, *a, *b, context);
23 if (!integrated) {
24 return ExpressionResult::failure(integrated.error());
25 }
26 SymbolicExpr result = std::move(integrated.value());
27
29 return std::shared_ptr<SymbolicExpr>{};
30 }
31 auto res = LMCAS::detail::make_expression_ptr(result);
32 auto simplified = detail::make_expression_ptr(detail::normalize_node(detail::node(res), transform_budget));
33 if (simplified &&
35 return std::shared_ptr<SymbolicExpr>{};
36 }
37 return simplified ? simplified : res;
38} catch (const CasError& error) {
39 return ExpressionResult::failure(error);
40} catch (const std::bad_alloc&) {
41 return ExpressionResult::failure(CasErrc::ResourceLimit, "allocation failed", "calculus_utils_try_symbolic_definite");
42} catch (const std::length_error& error) {
43 return ExpressionResult::failure(CasErrc::ResourceLimit, error.what(), "calculus_utils_try_symbolic_definite");
44} catch (const std::exception& error) {
45 return ExpressionResult::failure(CasErrc::InternalInvariant, error.what(), "calculus_utils_try_symbolic_definite");
46}
48 const std::shared_ptr<SymbolicExpr>& f, const std::string& var,
49 const std::shared_ptr<SymbolicExpr>& a, const std::shared_ptr<SymbolicExpr>& b,
51try {
52 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
53 (context).limits().max_ast_nodes, "transform");
54 const std::string operation = "surface_area_revolution_x";
55 auto input = calculus_utils_validate_expr_bounds(f, var, a, b, context, operation);
56 if (!input) {
57 return ExpressionResult::failure(input.error());
58 }
59 auto step = context.consume_steps(8, operation);
60 if (!step) {
61 return ExpressionResult::failure(step.error());
62 }
63
64 try {
65 auto f_prime = detail::make_expression_ptr(detail::differentiate_node(detail::node(f), var, transform_budget));
66 if (!f_prime || !LMCAS::detail::node(f_prime)) {
69 "surface derivative is outside the supported domain",
70 operation);
71 }
72
73 auto f_prime_sq = SymbolicExpr::power(f_prime, SymbolicExpr::number(2));
74 auto one_plus_fp_sq = SymbolicExpr::add(SymbolicExpr::number(1), f_prime_sq);
75 auto arc_factor = SymbolicExpr::sqrt(one_plus_fp_sq);
76 auto abs_f = calculus_utils_make_abs(f);
77 if (!abs_f || !LMCAS::detail::node(abs_f)) {
80 "absolute value node construction failed",
81 operation);
82 }
83 auto integrand = SymbolicExpr::multiply(abs_f, arc_factor);
84
86 integrand, var, a, b, context);
87 if (!integral) {
88 return integral;
89 }
90 if (!integral.value() ||
91 !LMCAS::detail::node(integral.value())) {
94 "surface area integral could not be evaluated exactly",
95 operation);
96 }
97
98 auto two_pi = SymbolicExpr::multiply(
99 SymbolicExpr::number(2), LMCAS::detail::make_expression_ptr(
101 auto result = SymbolicExpr::multiply(
102 two_pi, std::move(integral.value()));
103 auto simplified = detail::make_expression_ptr(detail::normalize_node(detail::node(result), transform_budget));
104 return ExpressionResult::success(simplified ? simplified : result);
105 } catch (const std::bad_alloc&) {
107 "surface area allocation failed",
108 operation);
109 } catch (const std::length_error& error) { return ExpressionResult::failure(CasErrc::ResourceLimit, error.what(), "surface_area_revolution_x"); } catch (const std::exception& e) {
111 e.what(), operation);
112 }
113} catch (const CasError& error) {
114 return ExpressionResult::failure(error);
115} catch (const std::bad_alloc&) {
116 return ExpressionResult::failure(CasErrc::ResourceLimit, "allocation failed", "surface_area_revolution_x");
117} catch (const std::length_error& error) {
118 return ExpressionResult::failure(CasErrc::ResourceLimit, error.what(), "surface_area_revolution_x");
119} catch (const std::exception& error) {
120 return ExpressionResult::failure(CasErrc::InternalInvariant, error.what(), "surface_area_revolution_x");
121}
122
124 const std::shared_ptr<SymbolicExpr>& f, const std::string& var,
125 const std::shared_ptr<SymbolicExpr>& a, const std::shared_ptr<SymbolicExpr>& b)
126{
129}
130
131
133 const std::shared_ptr<SymbolicExpr>& f, const std::string& var,
134 const std::shared_ptr<SymbolicExpr>& a, const std::shared_ptr<SymbolicExpr>& b,
136try {
137 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
138 (context).limits().max_ast_nodes, "transform");
139 const std::string operation = "surface_area_revolution_y";
140 auto input = calculus_utils_validate_expr_bounds(f, var, a, b, context, operation);
141 if (!input) {
142 return ExpressionResult::failure(input.error());
143 }
144 auto step = context.consume_steps(8, operation);
145 if (!step) {
146 return ExpressionResult::failure(step.error());
147 }
148
149 try {
150 auto f_prime = detail::make_expression_ptr(detail::differentiate_node(detail::node(f), var, transform_budget));
151 if (!f_prime || !LMCAS::detail::node(f_prime)) {
154 "surface derivative is outside the supported domain",
155 operation);
156 }
157
158 auto f_prime_sq = SymbolicExpr::power(f_prime, SymbolicExpr::number(2));
159 auto one_plus_fp_sq = SymbolicExpr::add(SymbolicExpr::number(1), f_prime_sq);
160 auto arc_factor = SymbolicExpr::sqrt(one_plus_fp_sq);
161 auto var_expr = SymbolicExpr::variable(var);
162 auto abs_var = calculus_utils_make_abs(var_expr);
163 if (!abs_var || !LMCAS::detail::node(abs_var)) {
166 "absolute value node construction failed",
167 operation);
168 }
169 auto integrand = SymbolicExpr::multiply(abs_var, arc_factor);
170
172 integrand, var, a, b, context);
173 if (!integral) {
174 return integral;
175 }
176 if (!integral.value() ||
177 !LMCAS::detail::node(integral.value())) {
180 "surface area integral could not be evaluated exactly",
181 operation);
182 }
183
184 auto two_pi = SymbolicExpr::multiply(
185 SymbolicExpr::number(2), LMCAS::detail::make_expression_ptr(
187 auto result = SymbolicExpr::multiply(
188 two_pi, std::move(integral.value()));
189 auto simplified = detail::make_expression_ptr(detail::normalize_node(detail::node(result), transform_budget));
190 return ExpressionResult::success(simplified ? simplified : result);
191 } catch (const std::bad_alloc&) {
193 "surface area allocation failed",
194 operation);
195 } catch (const std::length_error& error) { return ExpressionResult::failure(CasErrc::ResourceLimit, error.what(), "surface_area_revolution_y"); } catch (const std::exception& e) {
197 e.what(), operation);
198 }
199} catch (const CasError& error) {
200 return ExpressionResult::failure(error);
201} catch (const std::bad_alloc&) {
202 return ExpressionResult::failure(CasErrc::ResourceLimit, "allocation failed", "surface_area_revolution_y");
203} catch (const std::length_error& error) {
204 return ExpressionResult::failure(CasErrc::ResourceLimit, error.what(), "surface_area_revolution_y");
205} catch (const std::exception& error) {
206 return ExpressionResult::failure(CasErrc::InternalInvariant, error.what(), "surface_area_revolution_y");
207}
208
210 const std::shared_ptr<SymbolicExpr>& f, const std::string& var,
211 const std::shared_ptr<SymbolicExpr>& a, const std::shared_ptr<SymbolicExpr>& b)
212{
215}
216
217}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(std::shared_ptr< SymbolicExpr > value)
Symbolic integration APIs.
std::shared_ptr< SymbolicExpr > calculus_utils_make_abs(const std::shared_ptr< SymbolicExpr > &expr)
Result< void > calculus_utils_validate_expr_bounds(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context, const std::string &operation)
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)
static ExpressionResult calculus_utils_try_symbolic_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)
ExprResult e()
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
bool contains_unevaluated_integral(const std::shared_ptr< const SymbolicNode > &node)
const MultiPoly & b
Result< std::shared_ptr< SymbolicExpr > > ExpressionResult
Result of an operation that produces a symbolic expression.
__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
ExpressionResult surface_area_revolution_y_checked(const std::shared_ptr< SymbolicExpr > &f, const std::string &var, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context)
ExpressionResult surface_area_revolution_x_checked(const std::shared_ptr< SymbolicExpr > &f, const std::string &var, const std::shared_ptr< SymbolicExpr > &a, const std::shared_ptr< SymbolicExpr > &b, ComputationContext &context)
const std::vector< IntegrationStep > Integrator & integrator
内部 AST 定义。