CASM  1.1.0
A Clusters Approach to Statistical Mechanics
CASM_math.hh
Go to the documentation of this file.
1 #ifndef CASM_MATH_HH
2 #define CASM_MATH_HH
4 
5 /*
6 //Maybe we should transition to boost math library?
7 //#include <boost/math/special_functions/binomial.hpp>
8 #include <boost/math/special_functions/factorials.hpp>
9 #include <cstddef>
10 #include <iostream>
11 #include <sstream>
12 #include <string>
13 */
14 
15 #include <cassert>
16 #include <cmath>
17 #include <complex>
18 #include <vector>
19 
20 namespace CASM {
21 
22 namespace CASM_TMP {
23 
24 // --------------------
25 
26 // Definitions for IfIntegralTol
27 template <typename tol_type, bool IsIntegral>
29 
30 template <typename tol_type>
31 struct IfIntegralTol<tol_type, true> {
33  IfIntegralTol(tol_type){};
34  tol_type tol() const { return 0; }
35 };
36 
37 template <typename tol_type>
38 struct IfIntegralTol<tol_type, false> {
39  IfIntegralTol(tol_type _tol) : m_tol(_tol){};
40  tol_type tol() { return m_tol; }
41 
42  private:
43  tol_type m_tol;
44 };
45 
46 template <typename T>
48 // End of IfIntegralTol
49 
50 // Definitions for MuchLessThan
51 template <typename value_type>
54  IntegralLessThan(value_type){};
55  bool operator()(const value_type &A, const value_type &B) const {
56  return A < B;
57  };
58 };
59 
60 template <typename value_type>
62  FloatingPointLessThan(value_type _tol = TOL) : m_tol(_tol){};
63  bool operator()(const value_type &A, const value_type &B) const {
64  return A + m_tol < B;
65  };
66 
67  private:
68  value_type m_tol;
69 };
70 
71 template <typename T>
72 using MuchLessThan =
73  typename std::conditional<std::is_integral<T>::value, IntegralLessThan<T>,
75 // End of MuchLessThan
76 
77 } // namespace CASM_TMP
78 
79 // *******************************************************************************************
80 
81 // round function -- rounds to nearest whole number; half-integers are rounded
82 // away from zero
83 int round(double val);
84 
85 // *******************************************************************************************
86 
87 template <typename T>
88 T min(const T &A, const T &B) {
89  return A < B ? A : B;
90 }
91 
92 // *******************************************************************************************
93 
94 template <typename T>
95 T max(const T &A, const T &B) {
96  return A > B ? A : B;
97 }
98 
99 // *******************************************************************************************
100 
102 template <typename T, typename std::enable_if<std::is_floating_point<T>::value,
103  T>::type * = nullptr>
104 inline bool almost_zero(const T &val, double tol = TOL) {
105  return std::abs(val) < tol;
106 }
107 
109 template <typename T, typename std::enable_if<std::is_floating_point<T>::value,
110  T>::type * = nullptr>
111 inline bool almost_zero(const std::complex<T> &val, double tol = TOL) {
112  return std::abs(val) < tol;
113 }
114 
116 template <typename T, typename std::enable_if<std::is_integral<T>::value,
117  T>::type * = nullptr>
118 inline bool almost_zero(const T &val, double tol = TOL) {
119  return val == 0;
120 }
121 
122 // *******************************************************************************************
123 
125 template <typename T, typename std::enable_if<!std::is_integral<T>::value,
126  T>::type * = nullptr>
127 bool almost_equal(const T &val1, const T &val2, double tol = TOL) {
128  return almost_zero(val1 - val2, tol);
129 }
130 
132 template <typename T, typename std::enable_if<std::is_integral<T>::value,
133  T>::type * = nullptr>
134 bool almost_equal(const T &val1, const T &val2, double tol = TOL) {
135  return val1 == val2;
136 }
137 
138 // *******************************************************************************************
139 
147 template <typename T, typename std::enable_if<std::is_floating_point<T>::value,
148  T>::type * = nullptr>
149 bool compare(const T &A, const T &B, double tol) {
150  if (!almost_equal(A, B, tol)) {
151  return A < B;
152  }
153  return false;
154 }
155 
156 struct FloatCompare {
157  double tol;
158 
159  FloatCompare(double _tol) : tol(_tol) {}
160 
161  template <typename T>
162  bool operator()(const T &A, const T &B) const {
163  return compare(A, B, tol);
164  }
165 };
166 
168 template <class InputIt1, class InputIt2>
169 bool float_lexicographical_compare(InputIt1 first1, InputIt1 last1,
170  InputIt2 first2, InputIt2 last2,
171  double tol) {
172  FloatCompare compare(tol);
173  return std::lexicographical_compare(first1, last1, first2, last2, compare);
174 }
175 
176 // *******************************************************************************************
177 // Return sign of integral number
178 template <typename T, typename std::enable_if<std::is_integral<T>::value,
179  T>::type * = nullptr>
180 int sgn(T val) {
181  return (T(0) < val) - (val < T(0));
182 }
183 
184 // *******************************************************************************************
185 // Return sign of floating-point number
186 template <typename T, typename std::enable_if<std::is_floating_point<T>::value,
187  T>::type * = nullptr>
188 int float_sgn(T val, double compare_tol = TOL) {
189  T zeroval(0);
190  if (compare(zeroval, val, compare_tol)) {
191  return 1;
192  }
193 
194  else if (compare(val, zeroval, compare_tol)) {
195  return -1;
196  }
197 
198  else {
199  return 0;
200  }
201 }
202 
203 // *******************************************************************************************
204 
205 // Works for signed and unsigned types
206 template <typename IntType>
207 IntType nchoosek(IntType n, IntType k) {
208  if (n < k) return 0;
209 
210  assert(0 <= k);
211  if (n < 2 * k) k = n - k;
212 
213  n -= k;
214 
215  IntType result(1);
216  for (IntType i = 1; i < k + 1; i++) {
217  result *= n + i;
218  result /= i;
219  }
220 
221  return result;
222 }
223 
224 // *******************************************************************************************
225 
226 // Works for signed and unsigned types
227 template <typename IntType>
228 std::vector<IntType> index_to_kcombination(IntType ind, IntType k) {
229  std::vector<IntType> result;
230  result.reserve(k);
231  IntType n;
232  IntType big, bigger;
233  for (; k > 0; --k) {
234  n = k;
235  bigger = 1;
236  while (bigger <= ind) {
237  big = bigger;
238  bigger = nchoosek(++n, k);
239  }
240  result.push_back(n - 1);
241  ind -= big;
242  }
243  return result;
244 }
245 
246 // *******************************************************************************************
250 int dl_string_dist(const std::string &a, const std::string &b);
251 
252 // *******************************************************************************************
253 
254 double ran0(int &idum);
255 
256 // *******************************************************************************************
258 int gcf(int i1, int i2);
259 
260 // *******************************************************************************************
262 int lcm(int i1, int i2);
263 
264 // *******************************************************************************************
276 template <typename IntType>
277 IntType extended_gcf(IntType i1, IntType i2, IntType &p1, IntType &p2) {
278  using std::swap;
279 
280  IntType s1 = sgn(i1);
281  IntType s2 = sgn(i2);
282 
283  IntType a = i1, b = i2;
284  p1 = 1;
285  p2 = 0;
286  IntType tp1(0), tp2(1), quotient;
287 
288  i1 = std::abs(i1);
289  i2 = std::abs(i2);
290 
291  while (i2 != 0) {
292  quotient = i1 / i2;
293  i1 = i1 % i2;
294  swap(i1, i2);
295  p1 = p1 - quotient * tp1;
296  swap(p1, tp1);
297  p2 = p2 - quotient * tp2;
298  swap(p2, tp2);
299  }
300 
301  p1 *= s1;
302  p2 *= s2;
303  return p1 * a + p2 * b;
304 }
305 
306 // *******************************************************************************************
307 
308 // evaluates Gaussians using the formula:
309 // f(x) = a*e^(-(x-b)^2/(c^2))
310 double gaussian(double a, double x, double b, double c);
311 
312 // calculates Gaussian moments given by the integral:
313 // m = \int_{\infty}^{\infty} dx
314 // x^pow*exp[-x^2/(2*sigma^2)]/(\sqrt(2*\pi)*sigma)
315 double gaussian_moment(int expon, double sigma);
316 
317 // calculates Gaussian moments given by the integral:
318 // m = \int_{\infty}^{\infty} dx
319 // x^pow*exp[-(x-x0)^2/(2*sigma^2)]/(\sqrt(2*\pi)*sigma)
320 double gaussian_moment(int expon, double sigma, double x0);
321 
322 // *******************************************************************************************
323 // finds rational number that approximates 'val' to within 'tol' --
324 // -- almost_int(double(denominator)*val, tol) == true OR
325 // almost_int(val/double(numerator), tol) == true OR
326 // -- denominator is always positive
327 // -- sign(numerator)=sign(val)
328 // -- if(almost_zero(val,tol)) --> numerator = 0, denominator = 1
329 // *******************************************************************************************
330 
331 void nearest_rational_number(double val, long &numerator, long &denominator,
332  double tol = TOL);
333 
334 // *******************************************************************************************
335 /*
336  * Finds best irrational number approximation of double 'val' and
337  * returns tex-formated string that contains irrational approximation
338  * Searches numbers of the form (x/y)^(1/z), where x and y range from 1 to 'lim'
339  * z ranges from 1 to 'max_pow'
340  */
341 // *******************************************************************************************
342 
343 std::string irrational_to_tex_string(double val, int lim, int max_pow = 2);
344 
345 // *******************************************************************************************
346 /*
347  * Returns string representation of an integer that has the same number of
348  * characters as its maximum allowed value. To fix the length of the resulting
349  * string, the character 'prepend_char' is prepended. When prepend_char is '0',
350  * the resulting strings have sequential numerical values when ordered
351  * alphabetically.
352  */
353 std::string to_sequential_string(Index i, Index max_i, char prepend_char = '0');
354 
355 // *******************************************************************************************
356 // John G 010413
357 int mod(int a, int b);
358 
359 // *******************************************************************************************
360 
361 double cuberoot(double number);
362 
363 } // namespace CASM
364 
365 #endif
Eigen::CwiseUnaryOp< decltype(Local::round_l< typename Derived::Scalar >), const Derived > round(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd.
typename std::conditional< std::is_integral< T >::value, IntegralLessThan< T >, FloatingPointLessThan< T > >::type MuchLessThan
Definition: CASM_math.hh:74
Main CASM namespace.
Definition: APICommand.hh:8
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
double gaussian_moment(int expon, double sigma)
Definition: CASM_math.cc:130
IntType extended_gcf(IntType i1, IntType i2, IntType &p1, IntType &p2)
Calculate greatest common factor of two integers, and bezout coefficients.
Definition: CASM_math.hh:277
bool compare(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Compare ClusterInvariants.
void nearest_rational_number(double val, long &numerator, long &denominator, double tol=TOL)
Definition: CASM_math.cc:165
double cuberoot(double number)
Definition: CASM_math.cc:272
IntType nchoosek(IntType n, IntType k)
Definition: CASM_math.hh:207
void swap(ConfigDoF &A, ConfigDoF &B)
Definition: ConfigDoF.cc:260
std::string to_sequential_string(Index i, Index max_i, char prepend_char='0')
Definition: CASM_math.cc:248
int sgn(T val)
Definition: CASM_math.hh:180
const double TOL
Definition: definitions.hh:30
int lcm(const Array< int > &series)
Find least common multiple.
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
Definition: CASM_math.hh:104
int dl_string_dist(const std::string &a, const std::string &b)
Computes the Damerescau-Levenshtein distance – the number of edits (deletions, insertions,...
Definition: CASM_math.cc:45
int float_sgn(T val, double compare_tol=TOL)
Definition: CASM_math.hh:188
bool float_lexicographical_compare(const Eigen::Ref< const Eigen::MatrixXd > &A, const Eigen::Ref< const Eigen::MatrixXd > &B, double tol)
Floating point lexicographical comparison with tol.
T min(const T &A, const T &B)
Definition: CASM_math.hh:88
std::string irrational_to_tex_string(double val, int lim, int max_pow=2)
Definition: CASM_math.cc:199
int mod(int a, int b)
Definition: CASM_math.cc:262
double gaussian(double a, double x, double b, double c)
Definition: CASM_math.cc:120
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
double ran0(int &idum)
Definition: CASM_math.cc:16
int gcf(int i1, int i2)
Find greatest common factor.
Definition: CASM_math.cc:94
std::vector< IntType > index_to_kcombination(IntType ind, IntType k)
Definition: CASM_math.hh:228
T max(const T &A, const T &B)
Definition: CASM_math.hh:95
FloatingPointLessThan(value_type _tol=TOL)
Definition: CASM_math.hh:62
bool operator()(const value_type &A, const value_type &B) const
Definition: CASM_math.hh:63
bool operator()(const value_type &A, const value_type &B) const
Definition: CASM_math.hh:55
FloatCompare(double _tol)
Definition: CASM_math.hh:159
bool operator()(const T &A, const T &B) const
Definition: CASM_math.hh:162