CASM  1.1.0
A Clusters Approach to Statistical Mechanics
Variable.cc
Go to the documentation of this file.
2 
3 #include <memory>
4 
11 #include "casm/symmetry/SymOp.hh"
12 
13 namespace CASM {
14 
15 //*******************************************************************************************
16 
21 }
22 
23 //*******************************************************************************************
24 
25 Variable::Variable(const DoFSet &_dof_set, int var_ind)
26  : m_dof_set(_dof_set), m_coeffs(_dof_set.size()) {
27  m_coeffs.setZero();
28  m_coeffs[var_ind] = 1.0;
29 }
30 
31 //*******************************************************************************************
32 
33 Variable::Variable(const DoFSet &_dof_set, const Eigen::VectorXd &_coeffs)
34  : m_dof_set(_dof_set), m_coeffs(_coeffs) {}
35 
36 //*******************************************************************************************
37 
38 bool Variable::_accept(const FunctionVisitor &visitor,
39  BasisSet const *home_basis_ptr /*=NULL*/) {
40  return visitor.visit(*this, home_basis_ptr);
41 }
42 
43 //*******************************************************************************************
44 
45 bool Variable::_accept(const FunctionVisitor &visitor,
46  BasisSet const *home_basis_ptr /*=NULL*/) const {
47  return visitor.visit(*this, home_basis_ptr);
48 }
49 
50 //*******************************************************************************************
51 bool Variable::is_zero() const {
52  // Could check to see if arguments are zero. For now, assume this is done at
53  // time of construction
54  for (EigenIndex i = 0; i < m_coeffs.size(); i++) {
55  if (!almost_zero(m_coeffs[i])) {
56  return false;
57  }
58  }
59  return true;
60 }
61 
62 //*******************************************************************************************
63 
64 void Variable::small_to_zero(double tol) {
65  for (EigenIndex i = 0; i < m_coeffs.size(); i++) {
66  if (almost_zero(m_coeffs[i], tol)) {
67  m_coeffs[i] = 0.0;
68  }
69  }
70 }
71 
72 //*******************************************************************************************
73 
75  Index np(0);
76 
77  for (Index i = 0; i < dof_set().size(); i++) {
78  if (!almost_zero(m_coeffs[i])) {
79  np++;
80  }
81  }
82 
83  return np;
84 }
85 
86 //*******************************************************************************************
87 
89  for (Index i = 0; i < dof_set().size(); i++) {
90  if (!almost_zero(m_coeffs[i])) {
91  return m_coeffs[i];
92  }
93  }
94  return 0.0;
95 }
96 
97 //*******************************************************************************************
98 
99 double Variable::leading_coefficient(Index &index) const {
100  for (index = 0; index < dof_set().size(); index++) {
101  if (!almost_zero(m_coeffs[index])) {
102  return m_coeffs[index];
103  }
104  }
105  return 0.0;
106 }
107 
108 //*******************************************************************************************
109 
111  if (EigenIndex(i) < m_coeffs.size()) return m_coeffs[i];
112  return 0.0;
113 }
114 
115 //*******************************************************************************************
116 
118  m_formula.clear();
119  m_tex_formula.clear();
120 
121  std::stringstream tformula, ttex;
122  Array<int> var_ind;
123  bool global_special = false;
124  for (Index i = 0; i < dof_set().size(); i++) {
125  if (!almost_zero(m_coeffs[i])) {
126  var_ind.push_back(i);
127  }
128  if (!global_special && dof_set()[i].is_locked()) {
129  if (!valid_index(dof_set()[i].ID()) ||
130  dof_set()[i].var_name() != dof_set()[0].var_name()) {
131  global_special = true;
132  }
133  }
134  }
135 
136  if (!var_ind.size()) {
137  m_formula = "0";
138  m_tex_formula = "0";
139  return;
140  }
141 
142  double var_scale(m_coeffs[var_ind[0]]);
143  if (almost_zero(var_scale + 1)) {
144  ttex << '-';
145  } else if (!almost_zero(var_scale - 1)) {
146  ttex << irrational_to_tex_string(var_scale,
147  10 * m_coeffs.size() * m_coeffs.size());
148  }
149 
150  if (var_ind.size() > 1) {
151  tformula << "(";
152  ttex << "(";
153  }
154 
155  for (Index i = 0; i < var_ind.size(); i++) {
156  if (i > 0 && m_coeffs[var_ind[i]] > 0) {
157  tformula << '+';
158  }
159  if (almost_zero(m_coeffs[var_ind[i]] + 1)) {
160  tformula << '-';
161  }
162  if (!almost_zero(std::abs(m_coeffs[var_ind[i]]) - 1)) {
163  tformula << m_coeffs[var_ind[i]];
164  tformula << '*';
165  }
166 
167  if (i > 0 && m_coeffs[var_ind[i]] / var_scale > 0) {
168  ttex << '+';
169  }
170  if (almost_zero(m_coeffs[var_ind[i]] / var_scale + 1)) {
171  ttex << '-';
172  }
173  if (!almost_zero(std::abs(m_coeffs[var_ind[i]] / var_scale) - 1)) {
174  ttex << irrational_to_tex_string(m_coeffs[var_ind[i]] / var_scale,
175  10 * m_coeffs.size() * m_coeffs.size())
176  << ' ';
177  }
178 
179  if (global_special) {
180  tformula << dof_set()[var_ind[i]].type_name() << '[' << i << ']';
181  ttex << dof_set()[var_ind[i]]
182  .var_name(); // << '_' << dof_set()[var_ind[i]].ID();
183  } else {
184  tformula << dof_set()[var_ind[i]].var_name() << '['
185  << dof_set()[var_ind[i]].ID() << ']';
186  ttex << dof_set()[var_ind[i]].var_name() << "_{"
187  << dof_set()[var_ind[i]].ID() << "}";
188  }
189  }
190  if (var_ind.size() > 1) {
191  tformula << ")";
192  ttex << ')';
193  }
194  m_tex_formula = ttex.str();
195  m_formula = tformula.str();
196  return;
197 }
198 
199 //*******************************************************************************************
201  m_formula.clear();
202  refresh_ID();
203  Eigen::MatrixXd const *tmat;
204  tmat = op.get_matrix_rep(symrep_ID());
205  if (tmat) {
206  m_coeffs = (*tmat) * m_coeffs;
207  } else {
208  std::cerr << "WARNING: Attempting to reference invalid symmetry matrix "
209  "(From rep_ID "
210  << symrep_ID() << ") in Variable::apply_sym! Continuing...\n";
211  }
212  return this;
213 }
214 //*******************************************************************************************
215 std::set<Index> Variable::dof_IDs() const {
216  std::set<Index> result;
217  for (Index i = 0; i < m_dof_set.size(); i++) {
218  if (!m_dof_set[i].is_locked() && !almost_zero(m_coeffs[i]))
219  result.insert(m_dof_set[i].ID());
220  }
221  return result;
222 }
223 //*******************************************************************************************
225  const std::vector<DoF::RemoteHandle> &remote_handles) {
226  int t_tot(0);
227  for (Index i = 0; i < dof_set().size(); i++) {
228  std::vector<DoF::RemoteHandle>::const_iterator it = find(
229  remote_handles.begin(), remote_handles.end(), dof_set()[i].handle());
230  if (it != remote_handles.end()) {
231  if (!valid_index(dof_set()[i].ID())) {
232  throw std::runtime_error(
233  "In Variable::register_remotes(), attempting to register dof with "
234  "ID = " +
235  std::to_string(dof_set()[i].ID()) + ", which is out of bounds.\n");
236  }
237  dof_set()[i].register_remote(*it);
238  t_tot++;
239  }
240  }
241  return t_tot;
242 }
243 
244 //*******************************************************************************************
245 
246 bool Variable::_update_dof_IDs(const std::vector<Index> &before_IDs,
247  const std::vector<Index> &after_IDs) {
248  bool is_updated = m_dof_set.update_IDs(before_IDs, after_IDs);
249  // std::cout << "_update_dof_IDs from " << before_IDs << " to " << after_IDs
250  // << " on variable: " << formula() << "\n"
251  //<< "is_updated: " << is_updated<<"\n";
252  if (is_updated) {
253  // std::cout << "clearing formulae...\n";
254  m_formula.clear();
255  m_tex_formula.clear();
256  }
257  return is_updated;
258 }
259 
260 //*******************************************************************************************
261 
262 bool Variable::compare(const Variable *RHS) const {
263  if (dof_set().size() != RHS->dof_set().size()) return false;
264 
265  for (Index i = 0; i < dof_set().size(); i++) {
266  if (!dof_set()[i].compare((RHS->dof_set())[i], false)) return false;
267  }
268 
269  return almost_equal(m_coeffs, RHS->m_coeffs);
270 }
271 
272 //*******************************************************************************************
273 
274 void Variable::scale(double scale_factor) {
275  m_tex_formula.clear();
276  m_formula.clear();
277  refresh_ID();
278  m_coeffs *= scale_factor;
279 }
280 
281 //*******************************************************************************************
282 
283 double Variable::remote_eval() const {
284  double t_eval(0.0);
285  for (Index i = 0; i < dof_set().size(); i++)
286  t_eval += m_coeffs[i] * dof_set()[i].remote_value();
287 
288  return t_eval;
289 }
290 
291 //*******************************************************************************************
292 
293 double Variable::remote_deval(const DoF::RemoteHandle &dvar) const {
294  for (Index i = 0; i < dof_set().size(); i++) {
295  if (dvar.d_ptr() && dvar.d_ptr() == dof_set()[i].remote_ptr()) {
296  // std::cout << "derivative hit: " << m_coeffs[i] << '*' <<
297  // dof_set()[i].var_name() << '[' << dof_set()[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 //*******************************************************************************************
320  Function const *RHS) const {
321  Variable const *VLHS(static_cast<Variable const *>(LHS)),
322  *VRHS(static_cast<Variable const *>(RHS));
323  return (VLHS->coeffs()).dot(VRHS->coeffs());
324 }
325 
326 //*******************************************************************************************
327 bool VarVarOperation::compare(const Function *LHS, const Function *RHS) const {
328  return static_cast<const Variable *>(LHS)->compare(
329  static_cast<const Variable *>(RHS));
330 }
331 
332 //*******************************************************************************************
334  Function const *RHS) const {
335  std::cerr << "WARNING: In-place multiplication of one Variable with another "
336  "is not defined!!\n"
337  << " Exiting...\n";
338  exit(1);
339  return NULL;
340 }
341 
342 //*******************************************************************************************
343 
345  Function const *RHS) const {
346  Variable const *VLHS(static_cast<Variable const *>(LHS));
347  Variable const *VRHS(static_cast<Variable const *>(RHS));
348  BasisSet LSet, RSet;
349  LSet.set_variable_basis(VLHS->dof_set());
350  std::vector<std::shared_ptr<BasisSet> > args;
351 
352  Index full_dim(LSet.size());
353  Index LOffset(0);
354  args.push_back(LSet.shared_copy());
355 
356  if ((VLHS->dof_set()) != (VRHS->dof_set())) {
357  RSet.set_variable_basis(VRHS->dof_set());
358  args.push_back(RSet.shared_copy());
359  LOffset = LSet.size();
360  full_dim += RSet.size();
361  }
362  PolyTrie<double> tcoeffs(full_dim);
363  Array<Index> expon(full_dim, 0);
364  for (Index i = 0; i < (VLHS->coeffs()).size(); i++) {
365  if (almost_zero((VLHS->coeffs())[i])) continue;
366  expon[i]++;
367  for (Index j = 0; j < (VLHS->coeffs()).size(); j++) {
368  if (almost_zero((VRHS->coeffs())[j])) continue;
369  expon[j + LOffset]++;
370  tcoeffs(expon) = (VLHS->coeffs())[i] * (VRHS->coeffs())[j];
371  expon[j + LOffset]--;
372  }
373  expon[i]--;
374  }
375 
376  return new PolynomialFunction(args, tcoeffs);
377 }
378 
379 //*******************************************************************************************
381  Function const *RHS) const {
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  Function const *RHS) const {
393  Variable *VLHS(static_cast<Variable *>(LHS));
394  Variable const *VRHS(static_cast<Variable const *>(RHS));
395 
396  VLHS->minus_equals(VRHS);
397  VLHS->refresh_ID();
398 
399  return VLHS;
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 //** jsonParser stuff - Variable
426 //*******************************************************************************************
427 
429  Function::to_json(json);
430 
431  // Just write Function::formula for now
432 
433  return json;
434 }
435 
436 //*******************************************************************************************
437 
438 /*
439 void Variable::from_json(const jsonParser &json) {
440 
441  // no reading functions for now
442 
443 }
444 */
445 
446 //*******************************************************************************************
447 
448 jsonParser &to_json(const Variable &var, jsonParser &json) {
449  return var.to_json(json);
450 }
451 
452 /*
453 // No reading functions for now
454 void from_json(Variable &var, const jsonParser &json) {
455  return var.from_json(json);
456 }
457 */
458 
459 } // namespace CASM
Basic std::vector like container (deprecated)
Definition: Array.hh:45
Index size() const
Definition: Array.hh:131
double dot(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:319
void set_variable_basis(const DoFSet &_dof_set)
Define the basis set to contain only variables (e.g., x,y,z)
Definition: BasisSet.cc:322
std::shared_ptr< BasisSet > shared_copy() const
Definition: BasisSet.hh:93
const double * d_ptr() const
Definition: DoF.hh:88
bool update_IDs(const std::vector< Index > &before_IDs, const std::vector< Index > &after_IDs)
Definition: DoFSet.cc:74
Index size() const
Returns the number of components in this DoFSet.
Definition: DoFSet.hh:191
std::string const & type_name() const
Definition: DoFSet.hh:197
Index ID() const
std::string m_tex_formula
virtual Function * copy() const =0
std::string m_formula
virtual jsonParser & to_json(jsonParser &json) const
static Array< Array< InnerProduct * > > inner_prod_table
static Array< Array< FunctionOperation * > > operation_table
virtual bool visit(Variable const &host, BasisSet const *bset_ptr) const
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
Definition: SymOp.hh:28
Eigen::MatrixXd const * get_matrix_rep(SymGroupRepID _rep_ID) const
get pointer to matrix representation corresponding to rep_ID
Function * add(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:403
bool compare(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:327
Function * add_to(Function *LHS, Function const *RHS) const
Definition: Variable.cc:413
Function * multiply(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:344
Function * multiply_by(Function *LHS, Function const *RHS) const
Definition: Variable.cc:333
Function * subtract_from(Function *LHS, Function const *RHS) const
Definition: Variable.cc:391
Function * subtract(Function const *LHS, Function const *RHS) const
Definition: Variable.cc:380
Variable(const Variable &old_var)=default
bool _accept(const FunctionVisitor &visitor, BasisSet const *home_basis_ptr=NULL) override
Definition: Variable.cc:38
bool is_zero() const override
Definition: Variable.cc:51
bool compare(const Variable *RHS) const
Definition: Variable.cc:262
const DoFSet & dof_set() const
Definition: Variable.hh:63
Function * minus_equals(const Variable *RHS)
Definition: Variable.cc:306
void small_to_zero(double tol=TOL) override
Definition: Variable.cc:64
static int sclass_ID()
Definition: Variable.hh:81
double remote_deval(const DoF::RemoteHandle &dvar) const override
Definition: Variable.cc:293
DoFSet m_dof_set
Definition: Variable.hh:33
double remote_eval() const override
Definition: Variable.cc:283
static void fill_dispatch_table()
Definition: Variable.cc:17
double get_coefficient(Index i) const override
Definition: Variable.cc:110
std::set< Index > dof_IDs() const override
Definition: Variable.cc:215
int register_remotes(const std::vector< DoF::RemoteHandle > &remote_handles) override
Definition: Variable.cc:224
bool _update_dof_IDs(const std::vector< Index > &before_IDs, const std::vector< Index > &after_IDs) override
Definition: Variable.cc:246
Eigen::VectorXd m_coeffs
Definition: Variable.hh:36
const Eigen::VectorXd & coeffs() const
Definition: Variable.hh:67
Function * plus_equals(const Variable *RHS)
Definition: Variable.cc:313
jsonParser & to_json(jsonParser &json) const override
Definition: Variable.cc:428
Index num_terms() const override
Definition: Variable.cc:74
SymGroupRepID symrep_ID() const
Definition: Variable.hh:65
Function * _apply_sym(const SymOp &op) override
Definition: Variable.cc:200
void scale(double scale_factor) override
Definition: Variable.cc:274
void make_formula() const override
Definition: Variable.cc:117
double leading_coefficient() const override
Definition: Variable.cc:88
void push_back(const T &toPush)
Definition: Array.hh:431
std::string to_string(ENUM val)
Return string representation of enum class.
Definition: io_traits.hh:172
Main CASM namespace.
Definition: APICommand.hh:8
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
Eigen::MatrixXd MatrixXd
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Definition: CASM_math.hh:104
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
Definition: algorithm.hh:16
std::string irrational_to_tex_string(double val, int lim, int max_pow=2)
Definition: CASM_math.cc:199
Eigen::MatrixXd::Index EigenIndex
Definition: eigen.hh:7
bool valid_index(Index i)
Definition: definitions.cc:5
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Eigen::VectorXd VectorXd