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