11 const std::shared_ptr<SymbolicExpr>& f,
12 const std::vector<std::string>&
vars,
16 context.limits().max_ast_nodes,
"gradient");
17 const std::string operation =
"gradient";
22 auto step =
context.consume_steps(
vars.size(), operation);
30 }
catch (
const std::bad_alloc&) {
32 "vector calculus allocation failed",
34 }
catch (
const std::length_error& error) {
36 }
catch (
const std::exception&
e) {
42 const std::shared_ptr<SymbolicExpr>& f,
43 const std::vector<std::string>&
vars)
50 const std::vector<std::string>&
vars,
54 throw std::invalid_argument(
"gradient: f must not be null");
58 std::size_t nodes = 0;
59 result.reserve(
vars.size());
60 for (
const auto& var :
vars) {
67 result.push_back(partial);
75 const std::vector<std::string>&
vars,
79 context.limits().max_ast_nodes,
"divergence");
80 const std::string operation =
"divergence";
85 auto step =
context.consume_steps(F.size(), operation);
93 }
catch (
const std::bad_alloc&) {
95 "vector calculus allocation failed",
97 }
catch (
const std::length_error& error) {
99 }
catch (
const std::exception&
e) {
106 const std::vector<std::string>&
vars)
113 const std::vector<std::string>&
vars,
116 if (F.size() !=
vars.size()) {
117 throw std::invalid_argument(
118 "divergence: F and vars must have the same dimension");
121 return SymbolicExpr::number(0);
124 std::shared_ptr<SymbolicExpr> sum =
nullptr;
125 for (
size_t i = 0; i < F.size(); ++i) {
137 sum = SymbolicExpr::add(sum, partial);
143 return SymbolicExpr::number(0);
151 const std::vector<std::string>&
vars,
155 context.limits().max_ast_nodes,
"curl");
156 const std::string operation =
"curl";
161 if (F.size() != 2 && F.size() != 3) {
164 "curl requires a 2D or 3D vector field",
167 auto step =
context.consume_steps(F.size(), operation);
175 }
catch (
const std::bad_alloc&) {
177 "vector calculus allocation failed",
179 }
catch (
const std::length_error& error) {
181 }
catch (
const std::exception&
e) {
188 const std::vector<std::string>&
vars)
195 const std::vector<std::string>&
vars,
198 if (F.size() !=
vars.size()) {
199 throw std::invalid_argument(
200 "curl: F and vars must have the same dimension");
204 if (F.size() == 2 &&
vars.size() == 2) {
208 auto neg_dF1_dx2 = SymbolicExpr::multiply(
209 SymbolicExpr::number(-1), dF1_dx2);
210 auto scalar_curl = SymbolicExpr::add(dF2_dx1, neg_dF1_dx2);
217 if (F.size() != 3 ||
vars.size() != 3) {
218 throw std::invalid_argument(
219 "curl: requires 2D or 3D vector field");
225 auto curl_x = SymbolicExpr::add(
227 SymbolicExpr::multiply(SymbolicExpr::number(-1), dF2_dx3));
233 auto curl_y = SymbolicExpr::add(
235 SymbolicExpr::multiply(SymbolicExpr::number(-1), dF3_dx1));
241 auto curl_z = SymbolicExpr::add(
243 SymbolicExpr::multiply(SymbolicExpr::number(-1), dF1_dx2));
247 std::size_t nodes = 0;
248 for (
const auto& component : result) {
257 const std::shared_ptr<SymbolicExpr>& f,
258 const std::vector<std::string>&
vars,
262 context.limits().max_ast_nodes,
"laplacian");
263 const std::string operation =
"laplacian";
268 auto step =
context.consume_steps(
vars.size() * 2, operation);
276 }
catch (
const std::bad_alloc&) {
278 "vector calculus allocation failed",
280 }
catch (
const std::length_error& error) {
282 }
catch (
const std::exception&
e) {
288 const std::shared_ptr<SymbolicExpr>& f,
289 const std::vector<std::string>&
vars)
296 const std::vector<std::string>&
vars,
300 throw std::invalid_argument(
"laplacian: f must not be null");
303 return SymbolicExpr::number(0);
306 std::shared_ptr<SymbolicExpr> sum =
nullptr;
307 for (
const auto& var :
vars) {
320 sum = SymbolicExpr::add(sum, second);
326 return SymbolicExpr::number(0);
333 const std::vector<std::string>&
vars)
337 context.limits().max_ast_nodes,
"gradient");
342 const std::vector<std::string>&
vars)
346 context.limits().max_ast_nodes,
"divergence");
351 const std::vector<std::string>&
vars)
355 context.limits().max_ast_nodes,
"curl");
359std::shared_ptr<SymbolicExpr>
laplacian(
const std::shared_ptr<SymbolicExpr>& f,
360 const std::vector<std::string>&
vars)
364 context.limits().max_ast_nodes,
"laplacian");
static Result failure(CasErrc code, std::string message, std::string operation={})
std::size_t measure(const std::shared_ptr< const SymbolicNode > &node)
void require_nodes(std::size_t nodes) const
std::size_t append_size(std::size_t current, std::size_t child)
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
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
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)
VectorField gradient_impl(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, detail::RewriteBudget &transform_budget)
std::shared_ptr< SymbolicExpr > divergence_impl(const VectorField &F, const std::vector< std::string > &vars, detail::RewriteBudget &transform_budget)
std::shared_ptr< SymbolicExpr > laplacian_impl(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, detail::RewriteBudget &transform_budget)
VectorCalculusFieldResult vector_calculus_wrap_field(VectorField field, const std::string &operation)
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)
VectorField curl_impl(const VectorField &F, const std::vector< std::string > &vars, detail::RewriteBudget &transform_budget)
VectorCalculusFieldResult curl_checked(const VectorField &F, const std::vector< std::string > &vars, ComputationContext &context)
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
VectorField curl(const VectorField &F, const std::vector< std::string > &vars)
VectorCalculusFieldResult gradient_checked(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, ComputationContext &context)
std::shared_ptr< SymbolicExpr > laplacian(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars)
VectorCalculusExprResult laplacian_checked(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, ComputationContext &context)
std::shared_ptr< SymbolicExpr > divergence(const VectorField &F, const std::vector< std::string > &vars)
std::vector< std::shared_ptr< SymbolicExpr > > VectorField
向量场由标量表达式组成。
VectorCalculusExprResult divergence_checked(const VectorField &F, const std::vector< std::string > &vars, ComputationContext &context)
Result< VectorField > VectorCalculusFieldResult
Result< std::shared_ptr< SymbolicExpr > > VectorCalculusExprResult
VectorField gradient(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars)