CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
FunctionVisitor.cc
Go to the documentation of this file.
2 
7 #include "casm/misc/CASM_math.hh"
8 namespace CASM {
9 
10 
11  OccFuncLabeler::OccFuncLabeler(const std::string &_template) {
12  // parse _template into the Array m_sub_strings
13  if(_template.size())
14  m_sub_strings.push_back(std::string());
15  for(Index i = 0; i < _template.size(); i++) {
16  if(_template[i] == '%') {
17  if(m_sub_strings.back().size())
18  m_sub_strings.push_back(std::string());
19  m_sub_strings.back() = _template.substr(i, 2);
20  if((++i) + 1 < _template.size())
21  m_sub_strings.push_back(std::string());
22  }
23  else
24  m_sub_strings.back().push_back(_template[i]);
25  }
26  //std::cout << "substring expression: " << m_sub_strings << '\n';
27  }
28 
29  //*******************************************************************************************
30 
31 
32  bool OccFuncLabeler::visit(OccupantFunction &host, BasisSet const *bset_ptr)const {
33  m_ss.str(std::string());
34  m_ss.clear();
35 
36  for(Index i = 0; i < m_sub_strings.size(); i++) {
37  if(m_sub_strings[i] == "%n") {
38  if(valid_index(host.dof().ID()))
39  m_ss << host.dof().ID();
40  else
41  m_ss << '?';
42  }
43  else if(m_sub_strings[i] == "%f") {
44  if(valid_index(host.occ_func_ind()))
45  m_ss << host.occ_func_ind();
46  else
47  m_ss << '?';
48  }
49  else if(m_sub_strings[i] == "%b") {
50  if(valid_index(host.basis_ind()))
51  m_ss << host.basis_ind();
52  else
53  m_ss << '?';
54  }
55  else
56  m_ss << m_sub_strings[i];
57  }
58  //std::cout << "Paying a visit. Formula before: " << host.formula() << "\n";
59  host.set_formula(m_ss.str());
60  //std::cout << " Formula after: " << host.formula() << "\n";
61  return true;
62  }
63 
64  //*******************************************************************************************
65 
66  VariableLabeler::VariableLabeler(const std::string &_template) {
67  // parse _template into the Array m_sub_strings
68  if(_template.size())
69  m_sub_strings.push_back(std::string());
70  for(Index i = 0; i < _template.size(); i++) {
71  if(_template[i] == '%') {
72  if(m_sub_strings.back().size())
73  m_sub_strings.push_back(std::string());
74  m_sub_strings.back() = _template.substr(i, 2);
75  if((++i) + 1 < _template.size())
76  m_sub_strings.push_back(std::string());
77  }
78  else
79  m_sub_strings.back().push_back(_template[i]);
80  }
81  //std::cout << "substring expression: " << m_sub_strings << '\n';
82  }
83 
84  //*******************************************************************************************
85 
86 
87  bool VariableLabeler::visit(Variable &host, BasisSet const *bset_ptr)const {
88 
89  std::stringstream tformula, ttex;
90  Array<int> var_ind;
91 
92  for(Index i = 0; i < host.var_compon().size(); i++) {
93  if(!almost_zero(host.coeffs()[i])) {
94  var_ind.push_back(i);
95  }
96  }
97 
98  if(!var_ind.size()) {
99  host.set_formula("0");
100  host.set_tex_formula("0");
101  return false;
102  }
103 
104  double var_scale(host.coeffs()[var_ind[0]]);
105  if(almost_zero(var_scale + 1)) {
106  ttex << '-';
107  }
108  else if(!almost_zero(var_scale - 1)) {
109  ttex << irrational_to_tex_string(var_scale, 10 * host.coeffs().size() * host.coeffs().size());
110  }
111 
112  if(var_ind.size() > 1) {
113  tformula << "(";
114  ttex << "(";
115  }
116 
117  double coeff;
118  for(Index i = 0; i < var_ind.size(); i++) {
119  const ContinuousDoF &var_compon(host.var_compon()[var_ind[i]]);
120  coeff = host.coeffs()[var_ind[i]];
121 
122  if(i > 0 && coeff > 0) {
123  tformula << '+';
124  }
125  if(almost_zero(coeff + 1)) {
126  tformula << '-';
127  }
128  if(!almost_zero(std::abs(coeff) - 1)) {
129  tformula << coeff;
130  tformula << '*';
131  }
132 
133  if(i > 0 && coeff / var_scale > 0) {
134  ttex << '+';
135  }
136  if(almost_zero(coeff / var_scale + 1)) {
137  ttex << '-';
138  }
139  if(!almost_zero(std::abs(coeff / var_scale) - 1)) {
140  ttex << irrational_to_tex_string(coeff / var_scale, 10 * host.coeffs().size() * host.coeffs().size()) << ' ';
141  }
142 
143  for(Index j = 0; j < m_sub_strings.size(); j++) {
144  if(m_sub_strings[j] == "%n") {
145  if(valid_index(var_compon.ID())) {
146  ttex << var_compon.ID();
147  tformula << var_compon.ID();
148  }
149  else {
150  //std::cout << "type_name is " << var_compon.type_name() << ", ID is " << var_compon.ID() << "\n";
151  ttex << '?';
152  tformula << '?';
153  }
154  }
155  else if(m_sub_strings[j] == "%p") {
156  std::string prefix = var_compon.type_name_prefix();
157  if(prefix.empty())
158  prefix = "?";
159  ttex << prefix;
160  tformula << prefix;
161  }
162  else if(m_sub_strings[j] == "%s") {
163  std::string suffix = var_compon.type_name_suffix();
164  if(suffix.empty())
165  suffix = "?";
166  ttex << suffix;
167  tformula << suffix;
168  }
169  else {
170  ttex << m_sub_strings[j];
171  tformula << m_sub_strings[j];
172  }
173  }
174  }
175  if(var_ind.size() > 1) {
176  tformula << ")";
177  ttex << ')';
178  }
179  host.set_tex_formula(ttex.str());
180  host.set_formula(tformula.str());
181  return true;
182  }
183 
184  //*******************************************************************************************
185 
186  bool OccFuncBasisIndexer::visit(OccupantFunction &host, BasisSet const *bset_ptr)const {
188  return true;
189  }
190 
191  //*******************************************************************************************
192  SubExpressionLabeler::SubExpressionLabeler(const std::string &_bset_name, const std::string &_template) : m_bset_name(_bset_name) {
193  // parse _template into the Array m_sub_strings
194  if(_template.size())
195  m_sub_strings.push_back(std::string());
196  for(Index i = 0; i < _template.size(); i++) {
197  if(_template[i] == '%') {
198  if(m_sub_strings.back().size())
199  m_sub_strings.push_back(std::string());
200  m_sub_strings.back() = _template.substr(i, 2);
201  if((++i) + 1 < _template.size())
202  m_sub_strings.push_back(std::string());
203  }
204  else
205  m_sub_strings.back().push_back(_template[i]);
206  }
207  //std::cout << "substring expression: " << m_sub_strings << " and bset_name is " << m_bset_name << '\n';
208  }
209 
210  //*******************************************************************************************
211 
212  bool SubExpressionLabeler::visit(Variable &host, BasisSet const *bset_ptr)const {
213  return _generic_visit(host, bset_ptr);
214  }
215 
216  //*******************************************************************************************
217 
218  bool SubExpressionLabeler::visit(OccupantFunction &host, BasisSet const *bset_ptr)const {
219  return _generic_visit(host, bset_ptr);
220  }
221 
222  //*******************************************************************************************
223 
224  bool SubExpressionLabeler::visit(PolynomialFunction &host, BasisSet const *bset_ptr)const {
225  return _generic_visit(host, bset_ptr);
226  }
227 
228  //*******************************************************************************************
229 
230  bool SubExpressionLabeler::_generic_visit(Function &host, BasisSet const *bset_ptr) const {
231 
232  if(bset_ptr == NULL || (bset_ptr->name()).find(m_bset_name) != 0) {
233  //std::cout << "_generic_visit(): bset_ptr is " << bset_ptr << "\n";
234  return false;
235  }
236 
237  m_ss.str(std::string());
238  m_ss.clear();
239 
240  for(Index i = 0; i < m_sub_strings.size(); i++) {
241  if(m_sub_strings[i] == "%n") {
242  if(bset_ptr->dof_IDs().size() == 0) {
243  m_ss << '?';
244  }
245  else {
246  for(Index i = 0; i < bset_ptr->dof_IDs().size(); i++) {
247  m_ss << (bset_ptr->dof_IDs())[i];
248  if(i + 1 < bset_ptr->dof_IDs().size())
249  m_ss << '_';
250  }
251  }
252  }
253  else if(m_sub_strings[i] == "%f") {
254  Index f = bset_ptr->find(&host);
255  if(f < bset_ptr->size())
256  m_ss << f;
257  else
258  m_ss << '?';
259  }
260  else
261  m_ss << m_sub_strings[i];
262  }
263  //std::cout << "Paying a visit. Formula before: " << host.formula() << "\n";
264  host.set_formula(m_ss.str());
265  //std::cout << " Formula after: " << host.formula() << "\n";
266  return true;
267 
268 
269  }
270 }
271 
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Definition: CASM_math.hh:41
std::stringstream m_ss
Index ID() const
Definition: DoF.hh:71
bool visit(Variable &host, BasisSet const *bset_ptr) const
Index size() const
Definition: Array.hh:145
void push_back(const T &toPush)
Definition: Array.hh:513
const Eigen::VectorXd & coeffs() const
Definition: Variable.hh:78
Array< std::string > m_sub_strings
const std::string & name() const
Definition: BasisSet.hh:45
Main CASM namespace.
Definition: complete.cpp:8
bool visit(Variable &host, BasisSet const *bset_ptr) const
EigenIndex Index
For long integer indexing:
SubExpressionLabeler(const std::string &_bset_name, const std::string &_template)
Array< std::string > m_sub_strings
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:10
std::string irrational_to_tex_string(double val, int lim, int max_pow=2)
Definition: CASM_math.cc:224
bool _generic_visit(Function &host, BasisSet const *bset_ptr) const
OccFuncLabeler(const std::string &_template)
void set_tex_formula(const std::string &new_formula)
Index find(const T &test_elem) const
Definition: Array.hh:707
void set_basis_ind(int new_ind)
Array< std::string > m_sub_strings
void set_formula(const std::string &new_formula)
VariableLabeler(const std::string &_template)
bool visit(OccupantFunction &host, BasisSet const *bset_ptr) const
bool visit(OccupantFunction &host, BasisSet const *bset_ptr) const
Index occ_func_ind() const
T & back()
Definition: Array.hh:177
const Array< ContinuousDoF > & var_compon() const
Definition: Variable.hh:71
const DiscreteDoF & dof() const
const Array< Index > & dof_IDs() const
Definition: BasisSet.hh:139
bool valid_index(Index i)