CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
BasisFunction.cc
Go to the documentation of this file.
3 
4 namespace CASM {
5 
7  Array<Array< InnerProduct * > > Function::inner_prod_table = Array<Array< InnerProduct * > > ();
8  Array<Array< FunctionOperation * > > Function::operation_table = Array<Array< FunctionOperation * > > ();
9 
10 
11  //*******************************************************************************************
12 
13  Function::Function(const std::vector<std::shared_ptr<BasisSet> > &_args) : func_ID(ID_count++), m_argument(_args) {
14  //Index linear_ind(0);
15  for(Index i = 0; i < m_argument.size(); i++) {
16  for(Index j = 0; j < m_argument[i]->size(); j++) {
17  m_arg2sub.push_back(i);
18  m_arg2fun.push_back(j);
19  }
20  }
21  }
22  //*******************************************************************************************
23 
24  double Function::dot(Function const *RHS) const {
25  return inner_prod_table[this->class_ID()][RHS->class_ID()]->dot(this, RHS);
26  }
27 
28  //*******************************************************************************************
29  void Function::normalize() {
30  double mag(sqrt(this->dot(this)));
31  if(almost_zero(mag)) {
32  return;
33  }
34  m_formula.clear();
35  m_tex_formula.clear();
36  this->scale(1.0 / mag);
37  }
38 
39  //*******************************************************************************************
40 
41  bool Function::shallow_compare(Function const *RHS) const {
42  return (operation_table[this->class_ID()][RHS->class_ID()])->compare(this, RHS);
43  }
44 
45  //*******************************************************************************************
46 
47  bool Function::compare(Function const *RHS) const {
48  if(m_argument.size() != (RHS->m_argument).size())
49  return false;
50 
51  //if operations between this and RHS are undefined, return false
52  if(!operation_table[this->class_ID()][RHS->class_ID()])
53  return false;
54 
55  for(Index i = 0; i < m_argument.size(); i++) {
56  if(!(m_argument[i]->compare(*(RHS->m_argument)[i])))
57  return false;
58  }
59 
60  return shallow_compare(RHS);
61  }
62 
63  //*******************************************************************************************
64 
65  Function *Function::plus(Function const *RHS) const {
66  return operation_table[this->class_ID()][RHS->class_ID()]->add(this, RHS);
67  }
68  //*******************************************************************************************
69 
70  Function *Function::minus(Function const *RHS) const {
71  return operation_table[this->class_ID()][RHS->class_ID()]->subtract(this, RHS);
72  }
73  //*******************************************************************************************
74 
75  Function *Function::poly_quotient(Function const *RHS) const {
76  return operation_table[this->class_ID()][RHS->class_ID()]->poly_quotient(this, RHS);
77  }
78  //*******************************************************************************************
79 
80  Function *Function::poly_remainder(Function const *RHS) const {
81  return operation_table[this->class_ID()][RHS->class_ID()]->poly_remainder(this, RHS);
82  }
83  //*******************************************************************************************
84 
85  Function *Function::multiply(Function const *RHS) const {
86  return (operation_table[this->class_ID()][RHS->class_ID()])->multiply(this, RHS);
87  }
88  //*******************************************************************************************
89 
90  Function *Function::plus_in_place(Function const *RHS) {
91  m_formula.clear();
92  m_tex_formula.clear();
93  refresh_ID();
94  return operation_table[this->class_ID()][RHS->class_ID()]->add_to(this, RHS);
95  }
96  //*******************************************************************************************
97 
98  Function *Function::minus_in_place(Function const *RHS) {
99  m_formula.clear();
100  m_tex_formula.clear();
101  refresh_ID();
102  return operation_table[this->class_ID()][RHS->class_ID()]->subtract_from(this, RHS);
103  }
104 
105  //*******************************************************************************************
106 
107  ReturnArray<SymGroupRepID> Function::_sub_sym_reps() const {
108  Array<SymGroupRepID> t_result(m_argument.size());
109  for(Index i = 0; i < m_argument.size(); i++) {
110  t_result[i] = m_argument[i]->basis_symrep_ID();
111  }
112  return t_result;
113  }
114 
115  //*******************************************************************************************
116 
117  Function const *Function::_argument(Index i) const {
118  return (*m_argument[m_arg2sub[i]])[m_arg2fun[i]];
119  }
120 
121  //*******************************************************************************************
122 
123  double Function::_arg_eval_cache(Index i) const {
124  return m_argument[m_arg2sub[i]]->eval_cache(m_arg2fun[i]);
125  }
126 
127  //*******************************************************************************************
128 
129  double Function::_arg_deval_cache(Index i) const {
130  return m_argument[m_arg2sub[i]]->deval_cache(m_arg2fun[i]);
131  }
132 
133  //*******************************************************************************************
134 
135  int Function::_dependency_layer() const {
136  int tdep = -1;
137  for(Index i = 0; i < m_argument.size(); i++) {
138  tdep = max(tdep, m_argument[i]->dependency_layer());
139  }
140  return ++tdep;
141  }
142  //*******************************************************************************************
143  /*
144  Function *Function::_argument(Index i) {
145  return (*m_argument[m_arg2sub[i]])[m_arg2fun[i]];
146  }
147  */
148  //*******************************************************************************************
149 
150  bool Function::accept(const FunctionVisitor &visitor, BasisSet const *home_basis_ptr) {
151  //bool is_updated(false);
152  //std::cout << "INSIDE BASE Function::accept\n";
153  // shared_basis
154  //for(Index i = 0; i < m_argument.size(); i++)
155  //is_updated = (m_argument[i]->accept(visitor)) || is_updated; // should we add && depends_on to first part?
156 
157  //if(is_updated) {
158  //m_formula.clear();
159  //m_tex_formula.clear();
160  //}
161 
162  return _accept(visitor, home_basis_ptr);// || is_updated;
163  }
164 
165  //*******************************************************************************************
166 
167  void Function::refresh_ID() {
168  func_ID = ID_count++;
169  }
170 
171  //*******************************************************************************************
172 
173  void Function::print(std::ostream &stream)const {
174  if(!m_formula.size()) {
175  this->make_formula();
176  }
177  stream << m_formula;
178  return;
179  }
180  //*******************************************************************************************
181 
182  void Function::print_tex(std::ostream &stream)const {
183  if(!m_formula.size()) {
184  this->make_formula();
185  }
186  stream << m_tex_formula;
187  return;
188  }
189 
190  //*******************************************************************************************
191 
192  Function *Function::sym_copy_coeffs(const SymOp &op, int dependency_level) const {
193  Function *tptr(this->copy());
194  return tptr->apply_sym_coeffs(op, dependency_level);
195  }
196 
197  //*******************************************************************************************
198 
199  int Function::register_remotes(const std::string &dof_name, const Array<DoF::RemoteHandle> &remote_handles) {
200  int t_tot(0);
201  // From now on, this will be handled at BasisSet level
202  //for(Index i = 0; i < m_argument.size(); i++) {
203  //t_tot += m_argument[i]->register_remotes(dof_name, remote_handles);
204  //}
205  return t_tot;
206  }
207 
208  //*******************************************************************************************
209 
210  bool Function::update_dof_IDs(const Array<Index> &before_IDs, const Array<Index> &after_IDs) {
211  //JCT shared_basis
212  /*bool is_updated(false);
213  for(Index i = 0; i < m_argument.size(); i++) {
214  is_updated = ((m_argument[i]->update_dof_IDs(before_IDs, after_IDs)) && depends_on(m_argument[i])) || is_updated;
215  }
216 
217  if(is_updated) {
218  m_formula.clear();
219  m_tex_formula.clear();
220  }
221  */
222  return _update_dof_IDs(before_IDs, after_IDs);
223  }
224 
225  //*******************************************************************************************
226 
227  std::string Function::formula() const {
228  if(!m_formula.size()) {
229  this->make_formula();
230  }
231 
232  return m_formula;
233  }
234 
235  //*******************************************************************************************
236 
237  std::string Function::tex_formula() const {
238  if(!m_formula.size()) {
239  this->make_formula();
240  }
241 
242  return m_tex_formula;
243  }
244 
245  //*******************************************************************************************
246  /*
247  double Function::eval(int var_state) const {
248 
249  std::cerr << "WARNING: You are trying to evaluate a function using integer argument,\n"
250  << " but that option is not available for the function:\n"
251  << " " << (this->formula()) << "\n";
252  return NAN;
253  }
254  */
255  //*******************************************************************************************
256 
257  double Function::eval(const Array<Index> &dof_IDs, const Array<double> &arg_state) const {
258 
259  std::cerr << "WARNING: You are trying to evaluate a function using an Array<double> as argument,"
260  << " but that option is not available for the function:\n"
261  << " " << (this->formula()) << "\n";
262  return NAN;
263  }
264 
265  //*******************************************************************************************
266 
267  double Function::eval(const Array<Index> &dof_IDs, const Array<Index> &var_state) const {
268 
269  std::cerr << "WARNING: You are trying to evaluate a function using an Array<int> as argument,\n"
270  << " but that option is not available for the function:\n"
271  << " " << (this->formula()) << "\n";
272  return NAN;
273  }
274 
275  //*******************************************************************************************
276 
277  // Comparison
278  bool FunctionOperation::compare(Function const *LHS, Function const *RHS) const {
279  // default behavior if Functions are of different types
280  return false;
281  }
282 
283  //*******************************************************************************************
284 
285  // Multiplication (tensor product)
286  Function *FunctionOperation::multiply(Function const *LHS, Function const *RHS) const {
287  std::cerr << "WARNING: Multiplication of type " << LHS->type_name() << " with type " << RHS->type_name() << " is undefined!!!\n";
288  return nullptr;
289  }
290 
291  //*******************************************************************************************
292 
293  Function *FunctionOperation::multiply_by(Function *LHS, Function const *RHS) const {
294  std::cerr << "WARNING: Multiplication of type " << LHS->type_name() << " with type " << RHS->type_name() << " is undefined!!!\n";
295  return nullptr;
296  }
297 
298  //*******************************************************************************************
299 
300  // Addition
301  Function *FunctionOperation::add(Function const *LHS, Function const *RHS) const {
302  std::cerr << "WARNING: Addition of type " << LHS->type_name() << " with type " << RHS->type_name() << " is undefined!!!\n";
303  return nullptr;
304  }
305 
306  //*******************************************************************************************
307 
308  Function *FunctionOperation::add_to(Function *LHS, Function const *RHS) const {
309  std::cerr << "WARNING: Addition of type " << LHS->type_name() << " with type " << RHS->type_name() << " is undefined!!!\n";
310  return nullptr;
311  }
312 
313  //*******************************************************************************************
314 
315  // Subtraction
316  Function *FunctionOperation::subtract(Function const *LHS, Function const *RHS) const {
317  std::cerr << "WARNING: Subtraction of type " << LHS->type_name() << " with type " << RHS->type_name() << " is undefined!!!\n";
318  return nullptr;
319  }
320 
321  //*******************************************************************************************
322 
323  Function *FunctionOperation::subtract_from(Function *LHS, Function const *RHS) const {
324  std::cerr << "WARNING: Subtraction of type " << LHS->type_name() << " with type " << RHS->type_name() << " is undefined!!!\n";
325  return nullptr;
326  }
327 
328  //*******************************************************************************************
329 
330  // Polynomial division
331  Function *FunctionOperation::poly_quotient(Function const *LHS, Function const *RHS) const {
332  std::cerr << "WARNING: Polynomial division of type " << LHS->type_name() << " with type " << RHS->type_name() << " is undefined!!!\n";
333  return nullptr;
334  }
335 
336  //*******************************************************************************************
337 
338  Function *FunctionOperation::poly_remainder(Function const *LHS, Function const *RHS) const {
339  std::cerr << "WARNING: Polynomial division of type " << LHS->type_name() << " with type " << RHS->type_name() << " is undefined!!!\n";
340  return nullptr;
341  }
342 
343  //*******************************************************************************************
344  //** jsonParser stuff - Function
345  //*******************************************************************************************
346 
348 
349  // Not quite sure what to do with all this. For now, just print 'formula'.
350 
351  // static members:
352  //
353  // class Function : public HierarchyID<Function>
354  // static int Nclass;
355  // static int ID_count;
356  // static Array< Array< InnerProduct * > > inner_prod_table;
357  // static Array< Array< TensorProduct * > > tensor_prod_table;
358  // static Array< Array< FunctionDifference * > > difference_table;
359  // static Array< Array< FunctionSum * > > sum_table;
360 
361 
362  // int func_ID;
363  // Array<Function *> m_argument;
364  // mutable std::string m_formula, m_tex_formula;
365 
366  json.put_obj();
367 
368  json["m_formula"] = m_formula;
369 
370  return json;
371  }
372 
373  //*******************************************************************************************
374 
375  /*
376  void Function::from_json(const jsonParser &json) {
377 
378  // no reading functions for now
379 
380  }
381  */
382 
383  //*******************************************************************************************
384 
385  jsonParser &to_json(const Function *func, jsonParser &json) {
386  return func->to_json(json);
387  }
388 
389  // This does not exist: void from_json(Function *func, const jsonParser &json);
390  // Use the json (i.e. json["Function_type"] = "MonomialFunction")
391  // to know which Function's from_json to call
392 
393 
394 }
395 
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Definition: CASM_math.hh:41
bool compare(const T &A, const T &B, double tol)
Floating point comparison with tol, return A < B.
Definition: CASM_math.hh:89
virtual Function * apply_sym_coeffs(const SymOp &op, int dependency_layer=1)
virtual jsonParser & to_json(jsonParser &json) const
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
Main CASM namespace.
Definition: complete.cpp:8
virtual int class_ID() const =0
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
EigenIndex Index
For long integer indexing:
virtual std::string type_name() const =0
static Index ID_count
T max(const T &A, const T &B)
Definition: CASM_math.hh:32
T dot(const Tensor< T > &LHS, const Tensor< T > &RHS)
Definition: Tensor.hh:961
Function * poly_remainder(Function const *RHS) const
jsonParser & put_obj()
Puts new empty JSON object.
Definition: jsonParser.hh:276
static Array< Array< InnerProduct * > > inner_prod_table
ArgumentContainer m_argument
Function * poly_quotient(Function const *RHS) const
static Array< Array< FunctionOperation * > > operation_table
Basic std::vector like container (deprecated)