28 const std::shared_ptr<SymbolicExpr>& f,
const std::vector<std::string>&
vars,
33 const std::shared_ptr<SymbolicExpr>& H,
34 const std::vector<std::string>&,
35 const std::map<std::string, std::shared_ptr<SymbolicExpr>>& pt,
41 if (!mat_node || mat_node->rows() != n || mat_node->cols() != n) {
45 numeric_H.resize(n * n);
46 for (
size_t i = 0; i < n; ++i) {
47 for (
size_t j = 0; j < n; ++j) {
48 auto elem_node = mat_node->get(i, j);
50 numeric_H[i * n + j] = 0.0;
55 for (
const auto& [var_name, val] : pt) {
67 elem, numeric_H[i * n + j],
context)) {
76 const std::vector<double>& numeric_H,
double tol)
78 double a = numeric_H[0],
b = numeric_H[1];
79 double c = numeric_H[2], d = numeric_H[3];
80 double det =
a * d -
b *
c;
83 if (std::abs(det) < tol) {
86 if (det > 0 && trace > 0) {
89 if (det > 0 && trace < 0) {
96 const std::vector<double>& numeric_H,
size_t n,
double tol)
98 std::vector<std::vector<std::shared_ptr<SymbolicExpr>>> grid(n,
99 std::vector<std::shared_ptr<SymbolicExpr>>(n));
100 for (
size_t i = 0; i < n; ++i) {
101 for (
size_t j = 0; j < n; ++j) {
102 double val = numeric_H[i * n + j];
103 const double rounded = std::round(val);
104 const bool representable_integer =
105 std::isfinite(val) &&
107 static_cast<double>(std::numeric_limits<int>::min()) &&
109 static_cast<double>(std::numeric_limits<int>::max()) &&
110 std::abs(val - rounded) < tol;
111 if (representable_integer) {
113 SymbolicExpr::number(
static_cast<int>(rounded));
115 grid[i][j] = SymbolicExpr::number(val);
119 return SymbolicExpr::matrix(grid);
123 const std::vector<std::shared_ptr<SymbolicExpr>>& eigenvals,
double tol,
127 bool all_positive =
true;
128 bool all_negative =
true;
129 bool has_zero =
false;
131 for (
const auto& ev : eigenvals) {
141 if (std::abs(val) < tol) {
143 all_positive =
false;
144 all_negative =
false;
145 }
else if (val > 0) {
146 all_negative =
false;
148 all_positive =
false;
170 const double tol = 1
e-10;
172 const double value = numeric_H[0];
173 if (std::abs(
value) < tol) {
189 throw eigenvalues.error();
198 const std::shared_ptr<SymbolicExpr>& f,
199 const std::vector<std::string>&
vars,
203 context.limits().max_ast_nodes,
"find_extrema");
204 const std::string operation =
"find_extrema";
220 std::vector<std::shared_ptr<SymbolicExpr>>
gradient;
222 for (
const auto& var :
vars) {
227 gradient.push_back(std::move(partial.value()));
231 if (extrema.empty()) {
234 "extrema solver produced no verifiable critical points in the supported domain",
238 for (
const auto& cp : extrema) {
242 "extrema candidate omits one or more variables",
245 for (
const auto& partial :
gradient) {
249 "extrema candidate does not verify against the gradient",
256 "extrema candidate has no verified classification",
263 }
catch (
const std::bad_alloc&) {
265 "extrema allocation failed",
267 }
catch (
const std::length_error& error) {
269 }
catch (
const std::exception&
e) {
275 const std::shared_ptr<SymbolicExpr>& f,
276 const std::vector<std::string>&
vars)
283 const std::shared_ptr<SymbolicExpr>& f,
const std::vector<std::string>&
vars,
287 if (!f ||
vars.empty()) {
291 size_t n =
vars.size();
294 std::vector<std::shared_ptr<SymbolicExpr>> grad_eqs;
296 for (
const auto& var :
vars) {
301 grad_eqs.push_back(partial);
305 std::vector<std::map<std::string, std::shared_ptr<SymbolicExpr>>> solutions;
307 std::vector<SymbolicExpr> poly_eqs;
309 for (
const auto&
eq : grad_eqs) {
310 if (
eq) poly_eqs.push_back(*
eq);
312 if (poly_eqs.size() == n) {
313 auto checked_solutions =
314 Solver::solve_polynomial_system_checked(poly_eqs,
vars,
context);
315 if (!checked_solutions &&
318 throw checked_solutions.error();
320 const auto poly_solutions = checked_solutions
321 ? std::move(checked_solutions.value())
322 : std::vector<std::map<std::string, SymbolicExpr>>{};
323 for (
const auto& sol : poly_solutions) {
324 std::map<std::string, std::shared_ptr<SymbolicExpr>> pt;
325 for (
const auto& [
name, val] : sol) {
328 solutions.push_back(pt);
333 if (solutions.empty()) {
335 if (!solved.empty()) {
336 std::map<std::string, std::shared_ptr<SymbolicExpr>>
point;
340 solutions.push_back(std::move(
point));
344 if (solutions.empty()) {
352 std::vector<CriticalPoint> result;
353 result.reserve(solutions.size());
355 for (
const auto& sol : solutions) {
360 std::vector<double> numeric_H;
367 result.push_back(std::move(cp));
374 const std::shared_ptr<SymbolicExpr>& f,
const std::vector<std::string>&
vars) {
377 context.limits().max_ast_nodes,
"find_extrema");
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(std::vector< CriticalPoint > 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
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)
std::map< std::string, SymbolicExpr > solve_linear_system_impl(const std::vector< SymbolicExpr > &equations, const std::vector< std::string > &variables, ComputationContext &context)
bool vector_calculus_point_has_vars(const std::map< std::string, std::shared_ptr< SymbolicExpr > > &point, const std::vector< std::string > &vars)
Result< void > vector_calculus_validate_distinct_vars(const std::vector< std::string > &vars, std::size_t expected, ComputationContext &context, const std::string &operation)
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)
VectorCalculusExprResult vector_calculus_differentiate_strict(const std::shared_ptr< SymbolicExpr > &expr, const std::string &variable, const std::string &operation, detail::RewriteBudget &transform_budget)
bool vector_calculus_expr_zero_after_substitution(const std::shared_ptr< SymbolicExpr > &expr, const std::map< std::string, std::shared_ptr< SymbolicExpr > > &point, ComputationContext &context, detail::RewriteBudget &transform_budget)
bool vector_calculus_checked_finite_numeric(const std::shared_ptr< SymbolicExpr > &expr, double &value, ComputationContext &context)
std::shared_ptr< SymbolicExpr > hessian_impl(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, detail::RewriteBudget &transform_budget)
MatrixEigenvalueResult matrix_eigenvalues_checked(const std::shared_ptr< SymbolicExpr > &A, ComputationContext &context)
const std::string const LimitExprPtr & point
const std::string & variable
ExprResult eq(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
static CriticalPointClassification classify_hessian_eigenvalues(const std::vector< std::shared_ptr< SymbolicExpr > > &eigenvals, double tol, ComputationContext &context, detail::RewriteBudget &transform_budget)
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
const VectorField const VectorField & c
static std::shared_ptr< SymbolicExpr > symbolic_hessian(const std::vector< double > &numeric_H, size_t n, double tol)
__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
static CriticalPointClassification vector_calculus_classify_critical_point(const std::vector< double > &numeric_H, size_t n, ComputationContext &context, detail::RewriteBudget &transform_budget)
static CriticalPointClassification classify_hessian_pair(const std::vector< double > &numeric_H, double tol)
CriticalPointClassification
const std::string const ExprPtr & value
static bool vector_calculus_evaluate_hessian_at_point(const std::shared_ptr< SymbolicExpr > &H, const std::vector< std::string > &, const std::map< std::string, std::shared_ptr< SymbolicExpr > > &pt, size_t n, std::vector< double > &numeric_H, ComputationContext &context, detail::RewriteBudget &transform_budget)
ExtremaResult find_extrema_checked(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, ComputationContext &context)
Result< std::vector< CriticalPoint > > ExtremaResult
std::vector< CriticalPoint > find_extrema(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars)
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
VectorField gradient(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars)
static std::vector< CriticalPoint > find_extrema_impl(const std::shared_ptr< SymbolicExpr > &f, const std::vector< std::string > &vars, ComputationContext &context, detail::RewriteBudget &transform_budget)
方程求解策略调度器 solve_dispatch 及相关选项结构体.
多项式方程组求解器 Solver,包含 Gröbner 基、线性系统求解。
CriticalPointClassification classification
std::map< std::string, std::shared_ptr< SymbolicExpr > > point
符号矩阵运算:乘法、行列式、逆、旋转/反射/缩放矩阵、特征值。