CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
Variable.cc
Go to the documentation of this file.
2 
3 #include <memory>
4 
6 
7 #include "casm/symmetry/SymOp.hh"
11 
12 namespace CASM {
13 
14  //*******************************************************************************************
15 
19 
20  }
21  /*
22  template< class Base >
23  template< class Derived >
24  int HierarchyID<Derived>::new_class_ID(const DerivedID<Derived, Base> &_ID){
25  static int Nclass=0;
26  Base::extend_hierarchy();
27  Derived::fill_dispatch_table();
28  return Nclass++;
29  }
30  */
31 
32 
33  //*******************************************************************************************
34 
35  Variable::Variable(const Variable &old_var) :
36  m_var_compon(old_var.var_compon()),
37  m_sym_rep_ID(old_var.sym_rep_ID()),
38  m_coeffs(old_var.coeffs()) {
39 
40  }
41  //*******************************************************************************************
42 
43  Variable::Variable(const Array<ContinuousDoF> &_var_compon, int var_ind, SymGroupRepID _sym_rep_ID) :
44  m_var_compon(_var_compon),
45  m_sym_rep_ID(_sym_rep_ID),
46  m_coeffs(_var_compon.size()) {
47 
48  m_coeffs.setZero();
49  m_coeffs[var_ind] = 1.0;
50  }
51 
52  //*******************************************************************************************
53 
54  Variable::Variable(const Array<ContinuousDoF> &_var_compon, const Eigen::VectorXd &_coeffs, SymGroupRepID _sym_rep_ID) :
55  m_var_compon(_var_compon),
56  m_sym_rep_ID(_sym_rep_ID),
57  m_coeffs(_coeffs) {
58 
59  }
60 
61  //*******************************************************************************************
62 
63  bool Variable::_accept(const FunctionVisitor &visitor, BasisSet const *home_basis_ptr/*=NULL*/) {
64  return visitor.visit(*this, home_basis_ptr);
65  }
66 
67  //*******************************************************************************************
68  bool Variable::is_zero() const {
69  //Could check to see if arguments are zero. For now, assume this is done at time of construction
70  for(EigenIndex i = 0; i < m_coeffs.size(); i++) {
71  if(!almost_zero(m_coeffs[i])) {
72  return false;
73  }
74  }
75  return true;
76  }
77 
78  //*******************************************************************************************
79 
81  for(EigenIndex i = 0; i < m_coeffs.size(); i++) {
82  if(almost_zero(m_coeffs[i], tol)) {
83  m_coeffs[i] = 0.0;
84  }
85  }
86  }
87 
88  //*******************************************************************************************
89 
91  Index np(0);
92 
93  for(Index i = 0; i < m_var_compon.size(); i++) {
94  if(!almost_zero(m_coeffs[i])) {
95  np++;
96  }
97  }
98 
99  return np;
100 
101  }
102 
103  //*******************************************************************************************
104 
106  for(Index i = 0; i < m_var_compon.size(); i++) {
107  if(!almost_zero(m_coeffs[i])) {
108  return m_coeffs[i];
109  }
110  }
111  return 0.0;
112  }
113 
114  //*******************************************************************************************
115 
116  double Variable::leading_coefficient(Index &index) const {
117  for(index = 0; index < m_var_compon.size(); index++) {
118  if(!almost_zero(m_coeffs[index])) {
119  return m_coeffs[index];
120  }
121  }
122  return 0.0;
123  }
124 
125  //*******************************************************************************************
126 
128  if(EigenIndex(i) < m_coeffs.size())
129  return m_coeffs[i];
130  return 0.0;
131  }
132 
133  //*******************************************************************************************
134 
135  void Variable::make_formula() const {
136  m_formula.clear();
137  m_tex_formula.clear();
138 
139  std::stringstream tformula, ttex;
140  Array<int> var_ind;
141  for(Index i = 0; i < m_var_compon.size(); i++) {
142  if(!almost_zero(m_coeffs[i])) {
143  var_ind.push_back(i);
144  }
145  }
146 
147  if(!var_ind.size()) {
148  m_formula = "0";
149  m_tex_formula = "0";
150  return;
151  }
152 
153  double var_scale(m_coeffs[var_ind[0]]);
154  if(almost_zero(var_scale + 1)) {
155  ttex << '-';
156  }
157  else if(!almost_zero(var_scale - 1)) {
158  ttex << irrational_to_tex_string(var_scale, 10 * m_coeffs.size() * m_coeffs.size());
159  }
160 
161  if(var_ind.size() > 1) {
162  tformula << "(";
163  ttex << "(";
164  }
165 
166  for(Index i = 0; i < var_ind.size(); i++) {
167  if(i > 0 && m_coeffs[var_ind[i]] > 0) {
168  tformula << '+';
169  }
170  if(almost_zero(m_coeffs[var_ind[i]] + 1)) {
171  tformula << '-';
172  }
173  if(!almost_zero(std::abs(m_coeffs[var_ind[i]]) - 1)) {
174  tformula << m_coeffs[var_ind[i]];
175  tformula << '*';
176  }
177 
178  if(i > 0 && m_coeffs[var_ind[i]] / var_scale > 0) {
179  ttex << '+';
180  }
181  if(almost_zero(m_coeffs[var_ind[i]] / var_scale + 1)) {
182  ttex << '-';
183  }
184  if(!almost_zero(std::abs(m_coeffs[var_ind[i]] / var_scale) - 1)) {
185  ttex << irrational_to_tex_string(m_coeffs[var_ind[i]] / var_scale, 10 * m_coeffs.size() * m_coeffs.size()) << ' ';
186  }
187 
188  tformula << m_var_compon[var_ind[i]].type_name() << '[' << m_var_compon[var_ind[i]].ID() << ']';
189  ttex << m_var_compon[var_ind[i]].type_name() << '_' << m_var_compon[var_ind[i]].ID();
190  }
191  if(var_ind.size() > 1) {
192  tformula << ")";
193  ttex << ')';
194  }
195  m_tex_formula = ttex.str();
196  m_formula = tformula.str();
197  return;
198  }
199 
200  //*******************************************************************************************
202  m_formula.clear();
203  refresh_ID();
204  Eigen::MatrixXd const *tmat;
205  tmat = op.get_matrix_rep(m_sym_rep_ID);
206  if(tmat) {
207  m_coeffs = (*tmat) * m_coeffs;
208  }
209  else {
210  std::cerr << "WARNING: Attempting to reference invalid symmetry matrix (From rep_ID " << m_sym_rep_ID << ") in Variable::apply_sym! Continuing...\n";
211  }
212  return this;
213  }
214 
215  //*******************************************************************************************
216  int Variable::register_remotes(const std::string &dof_name, const Array<DoF::RemoteHandle> &remote_handles) {
217  int t_tot(0);
218  for(Index i = 0; i < m_var_compon.size(); i++) {
219  if(m_var_compon[i].type_name() == dof_name) {
220  if(!valid_index(m_var_compon[i].ID()) || m_var_compon[i].ID() >= remote_handles.size()) {
221  std::cerr << "CRITICAL ERROR: In Variable::register_remotes(), m_var_compon[" << i << "].ID() = " << m_var_compon[i].ID() << " is out of bounds.\n"
222  << " Exiting...\n";
223  exit(1);
224  }
225  m_var_compon[i].register_remote(remote_handles[m_var_compon[i].ID()]);
226  t_tot++;
227  }
228  }
229  return t_tot;
230  }
231 
232  //*******************************************************************************************
233 
234  bool Variable::_update_dof_IDs(const Array<Index> &before_IDs, const Array<Index> &after_IDs) {
235 
236  Index ID_ind;
237  bool is_updated(false);
238 
239  for(Index i = 0; i < m_var_compon.size(); i++) {
240  // IMPORTANT: Do before_IDs.find(), NOT m_var_compon.find() (if such a thing existed)
241  ID_ind = before_IDs.find(m_var_compon[i].ID());
242  // Only set ID if DoF doesn't have an ID lock
243  if(ID_ind < after_IDs.size() && !m_var_compon[i].is_locked()) {
244  m_var_compon[i].set_ID(after_IDs[ID_ind]);
245  // The new ID only changes the formula if the corresponding coeff is nonzero
246  if(!almost_zero(m_coeffs[i]))
247  is_updated = true;
248  }
249  }
250  if(is_updated) {
251  m_formula.clear();
252  m_tex_formula.clear();
253  }
254  return is_updated;
255  }
256 
257  //*******************************************************************************************
258 
259  bool Variable::compare(const Variable *RHS)const {
260 
261  if(m_var_compon.size() != RHS->m_var_compon.size())
262  return false;
263 
264  for(Index i = 0; i < m_var_compon.size(); i++) {
265  if(!m_var_compon[i].compare((RHS->m_var_compon)[i], false))
266  return false;
267  }
268 
269  return almost_equal(m_coeffs, RHS->m_coeffs);
270 
271  }
272 
273  //*******************************************************************************************
274 
275  void Variable::scale(double scale_factor) {
276  m_tex_formula.clear();
277  m_formula.clear();
278  refresh_ID();
279  m_coeffs *= scale_factor;
280  }
281 
282  //*******************************************************************************************
283 
284  double Variable::remote_eval() const {
285  double t_eval(0.0);
286  for(Index i = 0; i < m_var_compon.size(); i++)
287  t_eval += m_coeffs[i] * m_var_compon[i].remote_value();
288 
289  return t_eval;
290  }
291 
292  //*******************************************************************************************
293 
294  double Variable::remote_deval(const DoF::RemoteHandle &dvar) const {
295  for(Index i = 0; i < m_var_compon.size(); i++) {
296  if(dvar.d_ptr() && dvar.d_ptr() == m_var_compon[i].remote_ptr()) {
297  //std::cout << "derivative hit: " << m_coeffs[i] << '*' << m_var_compon[i].type_name() << '[' << m_var_compon[i].ID() << "]\n";
298  return m_coeffs[i];
299  }
300  }
301  return 0.0;
302  }
303 
304  //*******************************************************************************************
305 
307  m_coeffs -= RHS->coeffs();
308  return this;
309  }
310 
311  //*******************************************************************************************
312 
314  m_coeffs += RHS->coeffs();
315  return this;
316  }
317 
318  //*******************************************************************************************
319  double BasicVarVarScalarProd::dot(Function const *LHS, Function const *RHS) const {
320  Variable const *VLHS(static_cast<Variable const *>(LHS)),
321  *VRHS(static_cast<Variable const *>(RHS));
322  return (VLHS->coeffs()).dot(VRHS->coeffs());
323  }
324 
325  //*******************************************************************************************
326  bool VarVarOperation::compare(const Function *LHS, const Function *RHS) const {
327  return static_cast<const Variable *>(LHS)->compare(static_cast<const Variable *>(RHS));
328  }
329 
330  //*******************************************************************************************
332  std::cerr << "WARNING: In-place multiplication of one Variable with another is not defined!!\n"
333  << " Exiting...\n";
334  exit(1);
335  return NULL;
336 
337  }
338 
339  //*******************************************************************************************
340 
341  Function *VarVarOperation::multiply(Function const *LHS, Function const *RHS) const {
342 
343  Variable const *VLHS(static_cast<Variable const *>(LHS));
344  Variable const *VRHS(static_cast<Variable const *>(RHS));
345  BasisSet LSet, RSet;
346  LSet.set_variable_basis(VLHS->var_compon(), VLHS->sym_rep_ID());
347  std::vector<std::shared_ptr<BasisSet> > args;
348 
349  Index full_dim(LSet.size());
350  Index LOffset(0);
351  args.push_back(LSet.shared_copy());
352 
353  if((VLHS->var_compon()) != (VRHS->var_compon())) {
354  RSet.set_variable_basis(VRHS->var_compon(), VRHS->sym_rep_ID());
355  args.push_back(RSet.shared_copy());
356  LOffset = LSet.size();
357  full_dim += RSet.size();
358  }
359  PolyTrie<double> tcoeffs(full_dim);
360  Array<Index> expon(full_dim, 0);
361  for(Index i = 0; i < (VLHS->coeffs()).size(); i++) {
362  if(almost_zero((VLHS->coeffs())[i]))
363  continue;
364  expon[i]++;
365  for(Index j = 0; j < (VLHS->coeffs()).size(); j++) {
366  if(almost_zero((VRHS->coeffs())[j]))
367  continue;
368  expon[j + LOffset]++;
369  tcoeffs(expon) = (VLHS->coeffs())[i] * (VRHS->coeffs())[j];
370  expon[j + LOffset]--;
371  }
372  expon[i]--;
373  }
374 
375  return new PolynomialFunction(args, tcoeffs);
376 
377  }
378 
379  //*******************************************************************************************
380  Function *VarVarOperation::subtract(Function const *LHS, Function const *RHS) const {
381 
382  Variable *VLHS_copy(static_cast<Variable *>(LHS->copy()));
383  Variable const *VRHS(static_cast<Variable const *>(RHS));
384 
385  VLHS_copy->minus_equals(VRHS);
386  VLHS_copy->refresh_ID();
387  return VLHS_copy;
388  }
389 
390  //*******************************************************************************************
392  Variable *VLHS(static_cast<Variable *>(LHS));
393  Variable const *VRHS(static_cast<Variable const *>(RHS));
394 
395  VLHS->minus_equals(VRHS);
396  VLHS->refresh_ID();
397 
398  return VLHS;
399 
400  }
401 
402  //*******************************************************************************************
403  Function *VarVarOperation::add(Function const *LHS, Function const *RHS) const {
404  Variable *VLHS_copy(static_cast<Variable *>(LHS->copy()));
405  Variable const *VRHS(static_cast<Variable const *>(RHS));
406 
407  VLHS_copy->plus_equals(VRHS);
408  VLHS_copy->refresh_ID();
409 
410  return VLHS_copy;
411  }
412  //*******************************************************************************************
414  Variable *VLHS(static_cast<Variable *>(LHS));
415  Variable const *VRHS(static_cast<Variable const *>(RHS));
416 
417  VLHS->plus_equals(VRHS);
418 
419  VLHS->refresh_ID();
420 
421  return VLHS;
422  }
423 
424 
425  //*******************************************************************************************
426  //** jsonParser stuff - Variable
427  //*******************************************************************************************
428 
430 
431  Function::to_json(json);
432 
433  // Just write Function::formula for now
434 
435  return json;
436  }
437 
438  //*******************************************************************************************
439 
440  /*
441  void Variable::from_json(const jsonParser &json) {
442 
443  // no reading functions for now
444 
445  }
446  */
447 
448  //*******************************************************************************************
449 
450  jsonParser &to_json(const Variable &var, jsonParser &json) {
451  return var.to_json(json);
452  }
453 
454  /*
455  // No reading functions for now
456  void from_json(Variable &var, const jsonParser &json) {
457  return var.from_json(json);
458  }
459  */
460 
461 }
Function * _apply_sym(const SymOp &op)
Definition: Variable.cc:201
Eigen::MatrixXd MatrixXd
virtual bool visit(Variable &host, BasisSet const *bset_ptr) const
jsonParser & to_json(jsonParser &json) const
Definition: Variable.cc:429
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 _accept(const FunctionVisitor &visitor, BasisSet const *home_basis_ptr=NULL)
Definition: Variable.cc:63
Function * subtract(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:380
void small_to_zero(double tol=TOL)
Definition: Variable.cc:80
bool is_zero() const
Definition: Variable.cc:68
const double * d_ptr() const
Definition: DoF.hh:39
Index size() const
Definition: Array.hh:145
Function * multiply_by(Function *LHS, Function const *RHS) const
Definition: Variable.cc:331
Type-safe ID object for communicating and accessing Symmetry representation info. ...
void push_back(const T &toPush)
Definition: Array.hh:513
bool _update_dof_IDs(const Array< Index > &before_IDs, const Array< Index > &after_IDs)
Definition: Variable.cc:234
virtual jsonParser & to_json(jsonParser &json) const
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
void scale(double scale_factor)
Definition: Variable.cc:275
void make_formula() const
Definition: Variable.cc:135
const Eigen::VectorXd & coeffs() const
Definition: Variable.hh:78
std::shared_ptr< BasisSet > shared_copy() const
Definition: BasisSet.hh:68
Main CASM namespace.
Definition: complete.cpp:8
Function * subtract_from(Function *LHS, Function const *RHS) const
Definition: Variable.cc:391
Function * multiply(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:341
Function * add(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:403
Function * minus_equals(const Variable *RHS)
Definition: Variable.cc:306
double tol
Eigen::MatrixXd const * get_matrix_rep(SymGroupRepID _rep_ID) const
get pointer to matrix representation corresponding to rep_ID
Eigen::MatrixXd::Index EigenIndex
For integer indexing:
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
double remote_eval() const
Definition: Variable.cc:284
virtual Function * copy() const =0
EigenIndex Index
For long integer indexing:
SymGroupRepID m_sym_rep_ID
Definition: Variable.hh:36
bool compare(const Variable *RHS) const
Definition: Variable.cc:259
Eigen::VectorXd VectorXd
std::string m_formula
double dot(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:319
std::string irrational_to_tex_string(double val, int lim, int max_pow=2)
Definition: CASM_math.cc:224
Index num_terms() const
Definition: Variable.cc:90
Index find(const T &test_elem) const
Definition: Array.hh:707
std::string type_name() const
Definition: Variable.hh:55
Eigen::VectorXd m_coeffs
Definition: Variable.hh:39
Function * add_to(Function *LHS, Function const *RHS) const
Definition: Variable.cc:413
static int sclass_ID()
Definition: Variable.hh:92
double remote_deval(const DoF::RemoteHandle &dvar) const
Definition: Variable.cc:294
int register_remotes(const std::string &dof_name, const Array< DoF::RemoteHandle > &remote_handles)
Definition: Variable.cc:216
static Array< Array< InnerProduct * > > inner_prod_table
Variable(const Variable &old_var)
Definition: Variable.cc:35
SymGroupRepID sym_rep_ID() const
Definition: Variable.hh:74
Index ID() const
static void fill_dispatch_table()
Definition: Variable.cc:16
void set_variable_basis(const Array< ContinuousDoF > &tvar_compon, SymGroupRepID _sym_rep_ID)
Define the basis set to contain only variables (e.g., x,y,z)
Definition: BasisSet.cc:289
double get_coefficient(Index i) const
Definition: Variable.cc:127
double leading_coefficient() const
Definition: Variable.cc:105
std::string m_tex_formula
static Array< Array< FunctionOperation * > > operation_table
Array< ContinuousDoF > m_var_compon
Definition: Variable.hh:33
Basic std::vector like container (deprecated)
const Array< ContinuousDoF > & var_compon() const
Definition: Variable.hh:71
bool almost_equal(const GenericCluster< CoordType > &LHS, const GenericCluster< CoordType > &RHS, double tol)
bool compare(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:326
bool valid_index(Index i)
Function * plus_equals(const Variable *RHS)
Definition: Variable.cc:313