19 const std::shared_ptr<SymbolicExpr>& expr,
20 const std::string& var,
25 (
context).limits().max_ast_nodes,
"transform");
29 derivative, operation,
30 "surface derivative is outside the supported domain",
context);
34 "surface derivative is outside the supported domain",
39}
catch (
const std::bad_alloc&) {
41}
catch (
const std::length_error& error) {
43}
catch (
const std::exception& error) {
49 const std::vector<std::shared_ptr<SymbolicExpr>>&
point,
54 (
context).limits().max_ast_nodes,
"transform");
55 std::vector<std::shared_ptr<SymbolicExpr>>
gradient;
57 for (
size_t i = 0; i < surf.
vars.size(); ++i) {
60 auto substituted = derivative.value();
61 for (
size_t j = 0; j < surf.
vars.size(); ++j) {
66 "surface derivative substitution is outside the supported domain",
71 substituted, operation,
72 "surface derivative substitution is outside the supported domain",
context);
74 gradient.push_back(std::move(simplified.value()));
79}
catch (
const std::bad_alloc&) {
81}
catch (
const std::length_error& error) {
83}
catch (
const std::exception& error) {
88 const std::vector<std::shared_ptr<SymbolicExpr>>&
gradient,
90 const std::string& operation,
91 std::vector<double>& values,
92 const std::string& singular_message)
103 "surface gradient nonzero condition cannot be verified",
106 if (scaled.value() == 0.0) {
114 const std::vector<double>& gradient_values,
115 double gradient_scale,
116 const std::vector<double>& point_values,
118 const std::string& operation)
120 double normalized_dot = 0.0;
121 for (
size_t i = 0; i < point_values.size(); ++i) {
122 normalized_dot = std::fma(
123 gradient_values[i] / gradient_scale,
124 point_values[i] / point_scale,
127 const double plane_constant = normalized_dot * point_scale;
128 if (!std::isfinite(plane_constant)) {
131 "tangent plane constant is outside the supported domain",
137 for (
double component : gradient_values) {
139 SymbolicExpr::number(component / gradient_scale));
141 plane.
d = SymbolicExpr::number(plane_constant);
149 const std::vector<std::shared_ptr<SymbolicExpr>>&
point,
151 const std::string operation =
"surface_normal";
154 auto step =
context.consume_steps(surf.
vars.size() * 4 + 4, operation);
159 std::vector<double> gradient_values;
160 auto scaled = surface_gradient_scale_checked(
162 "surface normal is undefined at a singular point");
165 double scaled_norm_sq = 0.0;
166 for (
double component : gradient_values) {
167 const double ratio = component / scaled.value();
168 scaled_norm_sq += ratio * ratio;
170 const double scaled_norm = std::sqrt(scaled_norm_sq);
172 std::vector<std::shared_ptr<SymbolicExpr>> result;
173 result.reserve(gradient_values.size());
174 for (
double component : gradient_values) {
175 result.push_back(SymbolicExpr::number(
176 (component / scaled.value()) / scaled_norm));
183 const std::vector<std::shared_ptr<SymbolicExpr>>&
point) {
191 const std::vector<std::shared_ptr<SymbolicExpr>>&
point,
193 const std::string operation =
"tangent_plane";
198 auto step =
context.consume_steps(surf.
vars.size() * 4 + 4, operation);
207 std::vector<double> gradient_values;
208 auto scaled = surface_gradient_scale_checked(
210 "tangent plane is undefined at a singular point");
215 std::vector<double> point_values;
223 if (point_scale && point_scale.value() != 0.0 &&
225 std::numeric_limits<double>::max() /
226 point_scale.value() /
227 static_cast<double>(
point.size())) {
228 return scaled_tangent_plane(
229 gradient_values, scaled.value(), point_values,
230 point_scale.value(), operation);
238 dot.value(), operation,
239 "tangent plane constant is outside the supported domain",
context);
246 plane.
d = std::move(d.value());
252 const std::vector<std::shared_ptr<SymbolicExpr>>&
point) {
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(std::vector< std::shared_ptr< SymbolicExpr > > value)
VectorExprListResult surface_gradient_at_point_checked(const SurfaceSymbolic &surf, const std::vector< std::shared_ptr< SymbolicExpr > > &point, const std::string &operation, ComputationContext &context)
Result< double > surface_gradient_scale_checked(const std::vector< std::shared_ptr< SymbolicExpr > > &gradient, ComputationContext &context, const std::string &operation, std::vector< double > &values, const std::string &singular_message)
ExpressionResult differentiate_surface_checked(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, const std::string &operation, ComputationContext &context)
PlaneSymbolicResult scaled_tangent_plane(const std::vector< double > &gradient_values, double gradient_scale, const std::vector< double > &point_values, double point_scale, 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
SymbolicNodePtr substitute_node(const SymbolicNodePtr &node, const std::string &variable, const SymbolicNodePtr &replacement, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
Result< double > numeric_vector_scale_checked(const std::vector< std::shared_ptr< SymbolicExpr > > &expressions, ComputationContext &context, const std::string &operation, std::vector< double > *values=nullptr)
ExpressionResult simplify_checked(const std::shared_ptr< SymbolicExpr > &expr, const std::string &operation, const std::string &message, ComputationContext &context)
Result< void > validate_surface_point(const SurfaceSymbolic &surf, const std::vector< std::shared_ptr< SymbolicExpr > > &point, ComputationContext &context, const std::string &operation)
const std::string const LimitExprPtr & point
const PlaneSymbolic & plane
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
Result< PlaneSymbolic > PlaneSymbolicResult
Result< std::shared_ptr< SymbolicExpr > > ExpressionResult
Result of an operation that produces a symbolic expression.
VectorExprListResult surface_normal_checked(const SurfaceSymbolic &surf, const std::vector< std::shared_ptr< SymbolicExpr > > &point, ComputationContext &context)
PlaneSymbolicResult tangent_plane_checked(const SurfaceSymbolic &surf, const std::vector< std::shared_ptr< SymbolicExpr > > &point, ComputationContext &context)
std::vector< std::shared_ptr< SymbolicExpr > > normal
法向量。
Result< std::vector< std::shared_ptr< SymbolicExpr > > > VectorExprListResult
std::shared_ptr< SymbolicExpr > F
曲面方程左端,等于零。
VectorField gradient(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars)
ExpressionResult vector_dot_checked(const std::vector< std::shared_ptr< SymbolicExpr > > &a, const std::vector< std::shared_ptr< SymbolicExpr > > &b, ComputationContext &context)
std::shared_ptr< SymbolicExpr > d
常数项。
std::vector< std::string > vars
坐标变量名 {x,y,z}。
由法向量和常数 d 定义的符号平面 ax + by + cz = d。