ParM  parm
A molecular dynamics library
vecrand.hpp
Go to the documentation of this file.
1 #ifndef VECRAND_H
2 #define VECRAND_H
3 #ifdef VEC2D
4 #define NDIM 2
5 #define DIMROTATIONS 4
6 #else
7 #ifndef VEC3D
8 #define VEC3D
9 #endif
10 #endif
11 #ifdef VEC3D
12 #define NDIM 3
13 #define DIMROTATIONS 24
14 #endif
15 #include <iostream>
16 #include <ctime>
17 #include <vector>
18 #include <cmath>
19 
20 #include <boost/random/mersenne_twister.hpp>
21 #include <boost/random/variate_generator.hpp>
22 #include <boost/random/normal_distribution.hpp>
23 #include <boost/array.hpp>
24 #include <Eigen/Dense>
25 
26 using namespace std;
27 typedef unsigned int uint;
28 #ifdef LONGFLOAT
29  typedef long double flt;
30 
31  // on MAC OS, g++ is short for clang, and they already define the following functions pretty much
32  // the same way I do
33  #ifndef __APPLE__
34  inline flt cbrt(flt n){return cbrtl(n);};
35  inline flt expm1(flt n){return expm1l(n);};
36  inline flt copysign(flt n, flt m){return copysignl(n,m);};
37  inline flt remainder(flt n, flt m){return remainderl(n,m);};
38  inline flt round(flt n){return roundl(n);};
39  #endif
40 #else
41 
45  typedef double flt;
46 #endif
47 
48 typedef std::complex<flt> cmplx; // need the std:: for SWIG complex.i, not sure why
49 
53 typedef Eigen::Matrix<flt, NDIM, 1> Vec;
54 typedef Eigen::Matrix<flt, 2, 1> Vec2;
55 typedef Eigen::Matrix<flt, 3, 1> Vec3;
56 typedef Eigen::Matrix<flt, NDIM, NDIM> Matrix;
57 typedef Eigen::Matrix<flt, 2, 2> Matrix2;
58 typedef Eigen::Matrix<flt, 3, 3> Matrix3;
59 typedef Eigen::Matrix<flt, NDIM, 2> VecPair;
60 
61 using namespace std;
62 
66 const flt OVERNDIM = ((flt) 1.0)/NDIM;
67 
71 #ifdef VEC3D
72 inline Vec vec(){return Vec(0,0,0);};
73 #endif
74 #ifdef VEC2D
75 inline Vec vec(){return Vec(0,0);};
76 #endif
77 inline Vec2 vec(double x, double y){return Vec2(x,y);};
78 inline Vec3 vec(double x, double y, double z){return Vec3(x,y,z);};
79 
80 inline Vec3 cross(Vec3 v1, Vec3 v2){return v1.cross(v2);};
81 inline flt cross(Vec2 v1, Vec2 v2){return v1(0)*v2(1) - v2(0)*v1(1);};
82 inline Vec2 cross(Vec2 v, flt n){return Vec2(v(1)*n, -v(0)*n);};
83 
84 inline Vec2 perp(Vec2 v){return Vec2(-v(1),v(0));};
85 inline Vec perpto(Vec r, Vec to){
86  return r - to * ((r.dot(to)) / to.squaredNorm());
87 }
88 
89 inline Vec2 rotate(Vec2 v, uint i){
90  if(i % 4 == 0) return v;
91  else if(i % 4 == 3) return Vec2(v(1), -v(0));
92  else if(i % 4 == 2) return Vec2(-v(0), -v(1));
93  else return Vec2(-v(1), v(0));
94 };
95 inline Vec2 rotate_inv(Vec2 v, uint i){
96  return rotate(v, 4 - i);
97 };
98 inline Vec2 flip(Vec2 v){return Vec2(v(1), v(0));};
99 inline Vec2 rotate_flip(Vec2 v, uint i){
100  if((i / 4) % 2 == 1) return rotate(flip(v), i%4);
101  return rotate(v, i%4);
102 };
103 
105  Vec2 inv = rotate(v, 4-(i%4));
106  if((i / 4) % 2 == 0) return inv;
107  return flip(inv);
108 };
109 
110 inline Vec3 rotate(Vec3 v, uint i){
111  i %= 24;
112  if(i == 0) return v;
113  else if(i == 1) return Vec3( v(0),-v(1),-v(2));
114  else if(i == 2) return Vec3( v(1), v(0),-v(2));
115  else if(i == 3) return Vec3( v(2),-v(1), v(0));
116  else if(i == 4) return Vec3(-v(2),-v(1),-v(0));
117  else if(i == 5) return Vec3(-v(1),-v(0),-v(2));
118  else if(i == 6) return Vec3(-v(0), v(1),-v(2));
119  else if(i == 7) return Vec3(-v(0), v(2), v(1));
120  else if(i == 8) return Vec3(-v(0),-v(2),-v(1));
121  else if(i == 9) return Vec3(-v(0),-v(1), v(2));
122  else if(i == 10) return Vec3( v(0), v(2),-v(1));
123  else if(i == 11) return Vec3( v(1), v(2), v(0));
124  else if(i == 12) return Vec3( v(1),-v(2),-v(0));
125  else if(i == 13) return Vec3( v(1),-v(0), v(2));
126  else if(i == 14) return Vec3( v(2), v(1),-v(0));
127  else if(i == 15) return Vec3( v(2),-v(0),-v(1));
128  else if(i == 16) return Vec3(-v(2),-v(0), v(1));
129  else if(i == 17) return Vec3(-v(1), v(2),-v(0));
130  else if(i == 18) return Vec3(-v(1),-v(2), v(0));
131  else if(i == 19) return Vec3(-v(2), v(1), v(0));
132  else if(i == 20) return Vec3(-v(1), v(0), v(2));
133  else if(i == 21) return Vec3(-v(2), v(0),-v(1));
134  else if(i == 22) return Vec3( v(2), v(0), v(1));
135  else if(i == 23) return Vec3( v(0),-v(2), v(1));
136  throw std::runtime_error("This should be impossible to reach.");
137 };
138 
139 inline Vec3 rotate_inv(Vec3 v, uint i){
140  i %= 24;
141  if(i < 10) return rotate(v, i);
142  else return rotate(v, 33 - i);
143 };
144 inline Vec3 flip(Vec3 v){return -v;};
145 inline Vec3 rotate_flip(Vec3 v, uint i){
146  if((i / 24) % 2 == 1) return rotate(flip(v), i%24);
147  return rotate(v, i%24);
148 };
149 
151  Vec3 inv = rotate_inv(v, i%24);
152  if((i / 24) % 2 == 0) return inv;
153  return flip(inv);
154 };
155 
156 
157 inline uint vecsize(){return sizeof(Vec);}
158 
159 typedef boost::mt19937 engine;
160 typedef boost::normal_distribution<flt> normdistribution;
161 typedef boost::uniform_01<flt, flt> lindistribution;
162 typedef boost::variate_generator<engine&, normdistribution > normgenerator;
163 typedef boost::variate_generator<engine&, lindistribution > lingenerator;
164 
167 flt rand01();
174 Vec rand_vec();
178 #ifdef VEC3D
179 
181 Vec rand_vec_sphere(flt radius=1);
182 #endif
183 
186 unsigned int seed(unsigned int n);
191 unsigned int seed();
192 
193 class GaussVec {
194  protected:
197  public:
198  GaussVec(flt sigma);
199  void set(flt sigma){distro = normdistribution(0,sigma);};
200 #ifdef VEC2D
201  Vec generate(){return Vec(gauss(),gauss());};
202 #else
203  Vec generate(){return Vec(gauss(),gauss(),gauss());};
204 #endif
205 };
206 
213  protected:
219 
220  public:
224  BivariateGauss(const flt s1=1, const flt s2=1, const flt corr=0);
232  void set(const flt s1, const flt s2, const flt corr);
234  Eigen::Matrix<flt, 1, 2> generate();
235 #ifdef VEC2D
236 
239  Vec gen_vec(){return Vec(gauss(), gauss());};
240 #else
241 
244  Vec gen_vec(){return Vec(gauss(), gauss(), gauss());};
245 #endif
246 
247  VecPair gen_vecs();
248 };
249 
250 long double to_LD(double e);
251 double from_LD(long double e);
252 vector<long double> LDVector(vector<double> dists);
254 template<typename Derived>
258 inline bool hasNaN(const Eigen::DenseBase<Derived> &m) {
259  // return m.hasNan();
260  return !((m.derived().array()==m.derived().array()).all());
261 }
262 
263 
267 template<typename Derived>
268 inline bool allFinite(const Eigen::DenseBase<Derived> &m){
269  // return m.allFinite();
270  return !hasNaN(((m.derived()-m.derived())));
271 }
272 
273 template<typename Derived>
274 void finite_or_throw(const Eigen::DenseBase<Derived> &m){
275  if(!allFinite(m)) {
276  std::cerr << "Matrix !Finite ERROR" << std::endl;
277  std::cerr << m << std::endl;
278  throw std::invalid_argument("Matrix was not finite, cannot continue.");
279  }
280 }
281 
282 
283 #ifdef VEC3D
284 Matrix best_rotation_matrix(Eigen::Matrix<flt, Eigen::Dynamic, NDIM> &from, Eigen::Matrix<flt, Eigen::Dynamic, NDIM> &to);
285 #endif
286 #endif
Vec perpto(Vec r, Vec to)
Definition: vecrand.hpp:85
Vec vec()
A one-liner for creating a Vec object, occasionally useful from within Python.
Definition: vecrand.hpp:72
normgenerator gauss
Definition: vecrand.hpp:215
A class for generating two random numbers from a Gaussian distribution, with a given correlation...
Definition: vecrand.hpp:212
Vec rand_vec_boxed()
Generate a random vector inside a box with sides of length 1.
Definition: vecrand.cpp:19
Vec2 rotate_flip_inv(Vec2 v, uint i)
Definition: vecrand.hpp:104
unsigned int seed(unsigned int n)
Seed the global random number generator with a given integer.
Definition: vecrand.cpp:36
normgenerator gauss
Definition: vecrand.hpp:196
vector< long double > LDVector(vector< double > dists)
Go to and from Long Doubles.
Definition: vecrand.cpp:99
bool allFinite(const Eigen::DenseBase< Derived > &m)
Are all values finite, i.e.
Definition: vecrand.hpp:268
unsigned int uint
Definition: vec.hpp:20
double flt
The basic floating point type used in the simulations.
Definition: vecrand.hpp:45
boost::mt19937 engine
Definition: vecrand.hpp:159
Vec2 flip(Vec2 v)
Definition: vecrand.hpp:98
Definition: vecrand.hpp:193
flt x22
Definition: vecrand.hpp:218
std::complex< flt > cmplx
Definition: vecrand.hpp:48
normdistribution distro
Definition: vecrand.hpp:214
long double to_LD(double e)
Go to and from Long Doubles.
Definition: vecrand.cpp:97
Vec2 perp(Vec2 v)
Definition: vecrand.hpp:84
Vec2 rotate_inv(Vec2 v, uint i)
Definition: vecrand.hpp:95
Eigen::Matrix< flt, NDIM, NDIM > Matrix
Definition: vecrand.hpp:56
bool hasNaN(const Eigen::DenseBase< Derived > &m)
Is there a NaN in this matrix? Eigen has an allFinite and hasNan function as of version 3...
Definition: vecrand.hpp:258
flt x11
Definition: vecrand.hpp:216
double from_LD(long double e)
Go to and from Long Doubles.
Definition: vecrand.cpp:98
Vec gen_vec()
Generate a single Vec.
Definition: vecrand.hpp:239
Eigen::Matrix< flt, 3, 3 > Matrix3
Definition: vecrand.hpp:58
boost::uniform_01< flt, flt > lindistribution
Definition: vecrand.hpp:161
Eigen::Matrix< flt, NDIM, 2 > VecPair
Definition: vecrand.hpp:59
flt rand01()
Generate a random number between 0 and 1, using the "global" random number generator.
Definition: vecrand.cpp:12
uint vecsize()
Definition: vecrand.hpp:157
Vec rand_vec()
Generate a random vector from a Gaussian distribution, i.e.
Definition: vecrand.cpp:15
Eigen::Matrix< flt, 2, 1 > Vec2
Definition: vecrand.hpp:54
boost::normal_distribution< flt > normdistribution
Definition: vecrand.hpp:160
unsigned int uint
Definition: vecrand.hpp:27
Vec rand_vec_sphere(flt radius=1)
Generate a random vector inside a sphere.
A 3x3 matrix, with methods for adding, subtracting, dot product, etc.
Definition: vec.hpp:360
normgenerator gauss(randengine, mynormaldistribution)
void finite_or_throw(const Eigen::DenseBase< Derived > &m)
Definition: vecrand.hpp:274
flt x21
Definition: vecrand.hpp:217
Eigen::Matrix< flt, 2, 2 > Matrix2
Definition: vecrand.hpp:57
Vec2 rotate_flip(Vec2 v, uint i)
Definition: vecrand.hpp:99
Vec generate()
Definition: vecrand.hpp:201
Matrix best_rotation_matrix(Eigen::Matrix< flt, Eigen::Dynamic, NDIM > &from, Eigen::Matrix< flt, Eigen::Dynamic, NDIM > &to)
Definition: vecrand.cpp:108
#define NDIM
Definition: vecrand.hpp:12
Vec2 rotate(Vec2 v, uint i)
Definition: vecrand.hpp:89
boost::variate_generator< engine &, normdistribution > normgenerator
Definition: vecrand.hpp:162
normdistribution distro
Definition: vecrand.hpp:195
boost::variate_generator< engine &, lindistribution > lingenerator
Definition: vecrand.hpp:163
Eigen::Matrix< flt, NDIM, 1 > Vec
The basic physics vector.
Definition: vecrand.hpp:53
Vec3 cross(Vec3 v1, Vec3 v2)
Definition: vecrand.hpp:80
Eigen::Matrix< flt, 3, 1 > Vec3
Definition: vecrand.hpp:55
const flt OVERNDIM
A constant equal to , where is the number of dimensions.
Definition: vecrand.hpp:66
void set(flt sigma)
Definition: vecrand.hpp:199