14 if (variables.empty())
return false;
15 for (std::size_t index = 0; index < variables.size(); ++index) {
16 if (variables[index].empty())
return false;
17 for (std::size_t previous = 0; previous < index; ++previous) {
18 if (variables[index] == variables[previous])
return false;
25 const std::shared_ptr<SymbolicExpr>& expression,
26 const std::vector<std::string>& variables) {
27 if (!expression || !
detail::node(expression))
return false;
28 for (
const auto&
variable : variables) {
38 const std::vector<std::vector<std::shared_ptr<SymbolicExpr>>>& matrix,
39 const std::vector<std::shared_ptr<SymbolicExpr>>& variables) {
40 auto reconstructed = SymbolicExpr::number(0);
41 for (std::size_t row = 0; row < matrix.size(); ++row) {
42 for (std::size_t column = 0; column < matrix.size(); ++column) {
43 if (
detail::node(matrix[row][column])->is_zero())
continue;
44 auto term = SymbolicExpr::multiply(
46 SymbolicExpr::multiply(variables[row], variables[column]));
47 reconstructed = SymbolicExpr::add(reconstructed, term);
54 std::vector<std::vector<std::shared_ptr<SymbolicExpr>>>;
57 const std::vector<std::string>& names) {
58 std::vector<std::shared_ptr<SymbolicExpr>> variables;
59 variables.reserve(names.size());
60 for (
const auto&
name : names) {
61 variables.push_back(SymbolicExpr::variable(
name));
67 const std::shared_ptr<SymbolicExpr>& expanded,
71 (
context).limits().max_ast_nodes,
"transform");
72 const auto half = SymbolicExpr::number(Rational(1, 2));
75 std::vector<std::shared_ptr<SymbolicExpr>>(variables.size()));
76 for (std::size_t row = 0; row < variables.size(); ++row) {
78 if (!first_derivative) {
81 for (std::size_t column = 0; column < variables.size(); ++column) {
82 auto second_derivative =
84 if (!second_derivative) {
92 matrix[row][column] = std::move(coefficient);
99 const std::shared_ptr<SymbolicExpr>& expanded,
104 (
context).limits().max_ast_nodes,
"transform");
106 auto residual = SymbolicExpr::add(
108 SymbolicExpr::multiply(
109 SymbolicExpr::number(-1), reconstructed));
121 const std::shared_ptr<SymbolicExpr>& expr,
122 const std::vector<std::string>&
vars) {
125 (
context).limits().max_ast_nodes,
"transform");
126 if (!expr || !valid_variables(
vars)) {
135 auto variables = make_variables(
vars);
136 auto matrix = quadratic_coefficients(expanded,
vars,
context);
138 !reconstructs_expression(expanded, *matrix, variables,
context)) {
141 return SymbolicExpr::matrix(*matrix);
virtual bool is_zero() const
SymbolicNodePtr differentiate_node(const SymbolicNodePtr &node, const std::string &variable, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
SymbolicNodePtr expand_node(const SymbolicNodePtr &node, 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)
const std::string & variable
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
bool expression_depends_on_variable(const detail::SymbolicNodePtr &expression, const std::string &variable, detail::RewriteBudget *budget)
std::shared_ptr< SymbolicExpr > quadratic_form_matrix(const std::shared_ptr< SymbolicExpr > &expr, const std::vector< std::string > &vars)
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name