27 const std::vector<std::string>& fields_,
28 const std::string& expr)
34 GiNaC::symtab table = reader.get_syms();
38 for(
auto& field : fields_) {
39 syms.push_back(GiNaC::ex_to<GiNaC::symbol>(table.at(field)));
44 std::stringstream log_str;
45 log_str <<
"Input potential: " <<
v;
54 for (
const auto& sym:
syms) {
55 GiNaC::ex deriv =
v.diff(sym);
58 std::vector<GiNaC::ex> row_partials;
60 for (
const auto& col_sym: syms) {
61 GiNaC::ex deriv2 =
v.diff(sym).diff(col_sym);
62 row_partials.push_back(deriv2);
70 const Eigen::VectorXd& translation)
72 const std::size_t n_coords = translation.size();
73 if (n_coords !=
syms.size()) {
75 "Algebraic_potential::translate_origin: " 76 "dimensions of translation do not match number of fields");
81 for (std::size_t i = 0; i < n_coords; ++i) {
82 l.append(
syms[i] ==
syms[i] + translation[i]);
91 std::stringstream log_str;
92 log_str <<
"Potential after translation: " <<
v;
97 Eigen::MatrixXd cob_matrix_t = cob_matrix.transpose();
98 int n_coords =
syms.size();
101 GiNaC::exmap substitutions;
103 for (
int old_field_ix = 0; old_field_ix < n_coords; ++old_field_ix) {
108 for (
int new_field_ix = 0; new_field_ix < n_coords; ++new_field_ix) {
109 double coeff = cob_matrix(new_field_ix, old_field_ix);
110 rhs += coeff *
syms[new_field_ix];
114 substitutions[
syms[old_field_ix]] = rhs;
117 std::stringstream subs_str;
118 subs_str <<
"Subs: " << substitutions;
122 v =
v.subs(substitutions);
127 std::stringstream expr_str;
128 expr_str <<
"Potential after translation: " <<
v;
136 std::stringstream expr_str;
137 expr_str <<
"Potential after adding constant term: " <<
v;
144 const GiNaC::ex& expr,
const Eigen::VectorXd& coords)
const 146 const std::size_t n_coords = coords.size();
147 if (n_coords !=
syms.size()) {
149 "Algebraic_potential::eval: " 150 "number of values does not match number of coordinates");
155 for (std::size_t i = 0; i < n_coords; ++i) {
156 l.append(
syms[i] == coords(i));
160 GiNaC::ex result = GiNaC::evalf(expr.subs(l));
162 return GiNaC::ex_to<GiNaC::numeric>(result).to_double();
virtual void add_constant_term(double) override
Add a constant offset to the potential.
virtual void apply_basis_change(const Eigen::MatrixXd &) override
Apply a change of basis matrix.
virtual double partial(const Eigen::VectorXd &coords, int i) const override
Partial derivative WRT coordinate i at a point.
void log_message(Log_level level, const std::string &msg) const
GiNaC::ex v
GiNaC expression to hold potential.
std::vector< GiNaC::symbol > syms
GiNaC symbols matched to fields vec.
Algebraic_potential(const std::vector< std::string > &fields, const std::string &expr)
Construct from list of fields and GiNaC potential string.
std::vector< std::vector< GiNaC::ex > > second_partials
Second partials.
virtual double operator()(const Eigen::VectorXd &coords) const override
Evaluate potential at point.
double eval(const GiNaC::ex &, const Eigen::VectorXd &) const
virtual void translate_origin(const Eigen::VectorXd &) override
Shift the location of the origin by a specified vector.
std::vector< GiNaC::ex > first_partials
First partials.
Exception indicating general setup error.
logging::Basic_logger logger