CASM  1.1.0
A Clusters Approach to Statistical Mechanics
BasisFunction.hh
Go to the documentation of this file.
1 #ifndef BASISFUNCTION_HH
2 #define BASISFUNCTION_HH
3 
4 #include <iostream>
5 #include <map>
6 #include <memory>
7 #include <sstream>
8 #include <vector>
9 
10 #include "casm/basis_set/DoF.hh"
11 #include "casm/container/Array.hh"
12 #include "casm/external/Eigen/Dense"
14 #include "casm/misc/HierarchyID.hh"
15 
16 //#include "../container/SparseTensor.cc"
17 //#include "../container/Tensor.cc"
18 //#include "../basis_set/DoF.cc"
19 //#include "../symmetry/SymOp.hh"
20 //#include "../symmetry/SymGroup.hh"
21 //#include "../misc/HierarchyID.cc"
22 
23 namespace CASM {
24 
25 class Function;
26 class FunctionVisitor;
27 class FunctionOperation;
28 class InnerProduct;
29 class Variable;
30 class BasisSet;
31 class SymOp;
32 template <typename T>
34 
35 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41 class Function : public HierarchyID<Function> {
42  protected:
43  typedef std::vector<std::shared_ptr<BasisSet> > ArgumentContainer;
44 
45  public:
46  Function(const Function &RHS) = default;
47  Function(const ArgumentContainer &_args);
48 
50 
51  // WARNING: If you write a destructor for a Function-derived class,
52  // it should internally call Function::~Function()
53  virtual ~Function(){};
54  void refresh_ID();
55  Index ID() const { return func_ID; }
56 
57  Index num_args() const { return m_arg2sub.size(); }
58 
59  void set_identifier(char _key, std::string const &_value);
60 
61  std::string identifier(char _key) const;
62 
63  std::string formula() const;
64  std::string tex_formula() const;
65 
66  void print(std::ostream &stream) const;
67  void print_tex(std::ostream &stream) const;
68 
69  void set_formula(const std::string &new_formula) {
70  m_formula = new_formula;
71  m_tex_formula = new_formula;
72  }
73  void set_tex_formula(const std::string &new_formula) {
74  m_tex_formula = new_formula;
75  }
76  void clear_formula() {
77  m_formula.clear();
78  m_tex_formula.clear();
79  // for(Index i = 0; i < m_argument.size(); i++)
80  // m_argument[i]->clear_formulae();
81  }
82 
83  virtual std::string type_name() const = 0;
84 
85  // virtual void make_formula(double prefactor)const =0;
86  virtual Function *copy() const = 0;
87  virtual void make_formula() const = 0;
88  virtual bool is_zero() const = 0;
89 
90  // very basic dependency check -- only compares pointer values for now and
91  // checks that coefficient is nonzero
92  virtual bool depends_on(const Function *test_func) const {
93  return this == test_func;
94  }
95 
96  // for derived accept method, always do:
97  // accept(const FunctionVisitor &visitor){Function::accept(visitor);
98  // visitor->visit(*this);}
99  bool accept(const FunctionVisitor &visitor,
100  BasisSet const *home_basis_ptr = nullptr);
101  bool accept(const FunctionVisitor &visitor,
102  BasisSet const *home_basis_ptr = nullptr) const;
103 
104  virtual void small_to_zero(double tol = TOL) = 0;
105  virtual Index num_terms() const = 0;
106  virtual double leading_coefficient() const = 0;
107  virtual double leading_coefficient(Index &index) const = 0;
108  virtual double get_coefficient(Index i) const = 0;
109  virtual int class_ID() const = 0;
110  virtual void scale(double scale_factor) = 0;
111  virtual SparseTensor<double> const *get_coeffs() const { return nullptr; }
112 
113  virtual Eigen::VectorXd const *get_eigen_coeffs() const { return nullptr; }
114 
115  virtual double remote_eval() const = 0;
116  virtual double remote_deval(const DoF::RemoteHandle &dvar) const = 0;
117 
118  virtual double cache_eval() const = 0;
119  virtual double cache_deval(const DoF::RemoteHandle &dvar) const = 0;
120 
121  virtual int register_remotes(
122  const std::vector<DoF::RemoteHandle> &remote_handles);
123 
124  bool update_dof_IDs(const std::vector<Index> &before_IDs,
125  const std::vector<Index> &after_IDs);
126 
127  virtual std::set<Index> dof_IDs() const = 0;
128 
129  virtual Function *apply_sym_coeffs(const SymOp &op,
130  int dependency_layer = 1) {
131  if (_dependency_layer() == dependency_layer) return _apply_sym(op);
132 
133  // for(Index i = 0; i < m_argument.size(); ++i)
134  // m_argument[i]->apply_sym(op, dependency_layer);
135 
136  return this;
137  }
138 
139  Function *sym_copy_coeffs(const SymOp &op, int dependency_layer = 1) const;
140 
141  void normalize();
142 
143  double dot(Function const *RHS) const;
144 
145  // shallow comparison assumes that m_argument is equivalent to RHS.m_argument
146  bool shallow_compare(Function const *RHS) const;
147 
148  // 'deep' comparison also checks that m_argument is equivalent to
149  // RHS.m_argument
150  bool compare(Function const *RHS) const;
151 
152  Function *minus(Function const *RHS) const;
153  Function *plus(Function const *RHS) const;
154  Function *multiply(Function const *RHS) const;
155  Function *poly_quotient(Function const *RHS) const;
156  Function *poly_remainder(Function const *RHS) const;
157  Function *minus_in_place(Function const *RHS);
158  Function *plus_in_place(Function const *RHS);
159 
161  void set_arguments(const ArgumentContainer &new_arg) { m_argument = new_arg; }
162 
167  void set_arguments(const ArgumentContainer &new_arg,
168  std::vector<Index> const &compatibility_map);
169 
170  const ArgumentContainer &argument_bases() const { return m_argument; }
171 
172  virtual jsonParser &to_json(jsonParser &json) const;
173 
174  protected:
175  // static members hold tables of objects that define DerivedA--DerivedB
176  // operations
179 
180  // Function::extend_hierarchy() is called at first object initialization of a
181  // new derived type
182  static void extend_hierarchy() {
183  for (Index i = 0; i < inner_prod_table.size(); i++) {
184  operation_table[i].push_back(nullptr);
185  inner_prod_table[i].push_back(nullptr);
186  }
187 
188  inner_prod_table.push_back(
189  Array<InnerProduct *>(inner_prod_table.size() + 1, nullptr));
190  operation_table.push_back(
191  Array<FunctionOperation *>(operation_table.size() + 1, nullptr));
192  }
193 
195 
197 
211  // std::string m_label_format;
212 
213  // double scale_val;
214 
215  // arg2sub tells which subspace each argument belongs to
216  // in example above for polynomials of {x, y, v, w}
217  // arg2sub will be {0,0,1,1}
220 
221  mutable std::string m_formula, m_tex_formula;
222 
224 
225  virtual void _set_arguments(const ArgumentContainer &new_arg,
226  std::vector<Index> const &compatibility_map) {
227  set_arguments(new_arg);
228  }
229 
230  Function const *_argument(Index i) const;
231 
232  double _arg_eval_cache(Index i) const;
233 
234  double _arg_deval_cache(Index i) const;
235 
236  // Function *_argument(Index i);
237 
238  // dependency layer is number of functional layers between the degree of
239  // freedom and the current layer Consider the function H(G(F(x))), where 'x'
240  // is a degree of freedom.
241  // 'x' has dependency layer = 0
242  // F(x) has dependency layer = 1
243  // G(F) has dependency layer = 2
244  // H(G) has dependency layer = 3
245  // G(F) * F(x) has dependency layer = 3 // because it is a
246  // function K(G,F)
247  int _dependency_layer() const;
248 
249  virtual Function *_apply_sym(const SymOp &op) = 0;
250 
251  virtual bool _accept(const FunctionVisitor &visitor,
252  BasisSet const *home_basis_ptr = nullptr) = 0;
253 
254  virtual bool _accept(const FunctionVisitor &visitor,
255  BasisSet const *home_basis_ptr = nullptr) const = 0;
256 
257  virtual bool _update_dof_IDs(const std::vector<Index> &before_IDs,
258  const std::vector<Index> &after_IDs) {
259  // default action: do nothing, report that function does not change (via
260  // 'return false');
261  return false;
262  }
263 
264  private:
265  friend class HierarchyID<Function>;
266  static Index ID_count;
267 
268  std::map<char, std::string> m_identifiers;
269 };
270 
271 jsonParser &to_json(const Function *func, jsonParser &json);
272 
273 // This does not exist: void from_json(Function *func, const jsonParser &json);
274 // Use the json (i.e. json["Function_type"] = "PolynomialFunction")
275 // to know which Function's from_json to call
276 
277 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278 
279 // InnerProduct is separate from FunctionOperation (for now)
280 // Because InnerProduct behavior may be different for two Functions of the same
281 // Derived type
283  public:
284  virtual double dot(Function const *LHS, Function const *RHS) const = 0;
285 };
286 
287 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
288 
290  public:
291  // Comparison
292  virtual bool compare(Function const *LHS, Function const *RHS) const;
293 
294  // Multiplication (tensor product)
295  virtual Function *multiply(Function const *LHS, Function const *RHS) const;
296  virtual Function *multiply_by(Function *LHS, Function const *RHS) const;
297 
298  // Addition
299  virtual Function *add(Function const *LHS, Function const *RHS) const;
300  virtual Function *add_to(Function *LHS, Function const *RHS) const;
301 
302  // Subtraction
303  virtual Function *subtract(Function const *LHS, Function const *RHS) const;
304  virtual Function *subtract_from(Function *LHS, Function const *RHS) const;
305 
306  // Polynomial division
307  virtual Function *poly_quotient(Function const *LHS,
308  Function const *RHS) const;
309  virtual Function *poly_remainder(Function const *LHS,
310  Function const *RHS) const;
311 };
312 
313 } // namespace CASM
314 #endif
Basic std::vector like container (deprecated)
Definition: Array.hh:45
Index size() const
Definition: Array.hh:131
Function * plus_in_place(Function const *RHS)
Index ID() const
virtual double leading_coefficient() const =0
virtual void make_formula() const =0
virtual bool is_zero() const =0
virtual SparseTensor< double > const * get_coeffs() const
std::string identifier(char _key) const
void set_tex_formula(const std::string &new_formula)
std::string formula() const
virtual Eigen::VectorXd const * get_eigen_coeffs() const
Function * poly_remainder(Function const *RHS) const
virtual ~Function()
virtual double cache_eval() const =0
virtual void _set_arguments(const ArgumentContainer &new_arg, std::vector< Index > const &compatibility_map)
virtual void scale(double scale_factor)=0
std::string m_tex_formula
Function * minus_in_place(Function const *RHS)
virtual Function * copy() const =0
std::map< char, std::string > m_identifiers
ReturnArray< SymGroupRepID > _sub_sym_reps() const
virtual double leading_coefficient(Index &index) const =0
virtual double remote_eval() const =0
virtual int register_remotes(const std::vector< DoF::RemoteHandle > &remote_handles)
virtual Index num_terms() const =0
virtual Function * _apply_sym(const SymOp &op)=0
Function(const ArgumentContainer &_args)
virtual std::string type_name() const =0
static Index ID_count
ArgumentContainer m_argument
void clear_formula()
bool shallow_compare(Function const *RHS) const
static void extend_hierarchy()
bool accept(const FunctionVisitor &visitor, BasisSet const *home_basis_ptr=nullptr)
virtual bool _accept(const FunctionVisitor &visitor, BasisSet const *home_basis_ptr=nullptr) const =0
std::string m_formula
virtual jsonParser & to_json(jsonParser &json) const
virtual std::set< Index > dof_IDs() const =0
bool compare(Function const *RHS) const
virtual bool _accept(const FunctionVisitor &visitor, BasisSet const *home_basis_ptr=nullptr)=0
virtual Function * apply_sym_coeffs(const SymOp &op, int dependency_layer=1)
double _arg_eval_cache(Index i) const
virtual double get_coefficient(Index i) const =0
Function * minus(Function const *RHS) const
std::vector< std::shared_ptr< BasisSet > > ArgumentContainer
static Array< Array< InnerProduct * > > inner_prod_table
const ArgumentContainer & argument_bases() const
void set_identifier(char _key, std::string const &_value)
void print(std::ostream &stream) const
void set_formula(const std::string &new_formula)
void print_tex(std::ostream &stream) const
Function const * _argument(Index i) const
virtual double remote_deval(const DoF::RemoteHandle &dvar) const =0
Array< Index > m_arg2fun
bool update_dof_IDs(const std::vector< Index > &before_IDs, const std::vector< Index > &after_IDs)
Function * plus(Function const *RHS) const
Index num_args() const
Function * poly_quotient(Function const *RHS) const
double _arg_deval_cache(Index i) const
int _dependency_layer() const
double dot(Function const *RHS) const
std::string tex_formula() const
virtual int class_ID() const =0
virtual bool _update_dof_IDs(const std::vector< Index > &before_IDs, const std::vector< Index > &after_IDs)
static Array< Array< FunctionOperation * > > operation_table
Function * sym_copy_coeffs(const SymOp &op, int dependency_layer=1) const
virtual void small_to_zero(double tol=TOL)=0
virtual bool depends_on(const Function *test_func) const
Function(const Function &RHS)=default
void set_arguments(const ArgumentContainer &new_arg)
change arguments of this function
Array< Index > m_arg2sub
virtual double cache_deval(const DoF::RemoteHandle &dvar) const =0
Function * multiply(Function const *RHS) const
virtual Function * subtract(Function const *LHS, Function const *RHS) const
virtual Function * poly_quotient(Function const *LHS, Function const *RHS) const
virtual bool compare(Function const *LHS, Function const *RHS) const
virtual Function * add_to(Function *LHS, Function const *RHS) const
virtual Function * poly_remainder(Function const *LHS, Function const *RHS) const
virtual Function * multiply(Function const *LHS, Function const *RHS) const
virtual Function * subtract_from(Function *LHS, Function const *RHS) const
virtual Function * add(Function const *LHS, Function const *RHS) const
virtual Function * multiply_by(Function *LHS, Function const *RHS) const
virtual double dot(Function const *LHS, Function const *RHS) const =0
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
Main CASM namespace.
Definition: APICommand.hh:8
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
const double TOL
Definition: definitions.hh:30
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Eigen::VectorXd VectorXd