All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Random.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 The plumed team
3  (see the PEOPLE file at the root of the distribution for a list of names)
4 
5  See http://www.plumed-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
8 
9  plumed is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  plumed is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #include "Random.h"
23 #include <cmath>
24 #include <cstdlib>
25 #include <sstream>
26 #include <iostream>
27 
28 namespace PLMD{
29 
30 const double Random::fact=5.9604644775390625e-8; /* 1 / 2^24 */
31 const double Random::EPS=3.0e-16;
32 const double Random::AM=1.0/IM;
33 const double Random::RNMX=(1.0-EPS); // 1.0-EPS;
34 const std::string Random::noname="noname";
35 
36 Random::Random(const std::string & name):
37  switchGaussian(false),
38  saveGaussian(0.0),
39 // this is required because if a Random object is created during
40 // initialization than Random::noname could still be initialized.
41 // In practice: without this it is not possible to declare
42 // a static Random object without enforcing the order of the
43 // static constructors.
44  name(&name!=&noname?name:"noname")
45 {
46  iy=0;
47  iv[0]=0;
48  setSeed(0);
49 }
50 
51 void Random::setSeed(int idum_){
52  idum=idum_;
53  incPrec=false;
54 }
55 
56 double Random::RandU01 ()
57 {
58  if (incPrec)
59  return U01d();
60  else
61  return U01();
62 }
63 
64 
65 double Random::U01d ()
66 {
67  double u;
68  u = U01();
69  u += U01() * fact;
70  return (u < 1.0) ? u : (u - 1.0);
71 }
72 
73 
74 double Random::U01(){
75  int j,k;
76  double temp;
77  if (idum <= 0 || !iy) {
78  if (-idum < 1) idum=1;
79  else idum = -idum;
80  for (j=NTAB+7;j>=0;j--) {
81  k=idum/IQ;
82  idum=IA*(idum-k*IQ)-IR*k;
83  if (idum < 0) idum += IM;
84  if (j < NTAB) iv[j] = idum;
85  }
86  iy=iv[0];
87  }
88  k=idum/IQ;
89  idum=IA*(idum-k*IQ)-IR*k;
90  if (idum < 0) idum += IM;
91  j=iy/NDIV;
92  iy=iv[j];
93  iv[j] = idum;
94  if ((temp=AM*iy) > RNMX) return RNMX;
95  else return temp;
96 }
97 
98 void Random::WriteStateFull(std::ostream & out)const{
99  out<<name<<std::endl;
100  out<<idum<<" "<<iy;
101  for(int i=0;i<NTAB;i++){
102  out<<" "<<iv[i];
103  };
104  out<<" "<<switchGaussian;
105  out<<" "<<saveGaussian;
106  out<<std::endl;
107 }
108 
109 void Random::ReadStateFull (std::istream & in){
110  getline(in,name);
111  in>>idum>>iy;
112  for (int i = 0; i < NTAB; i++) in>>iv[i];
113  in>>switchGaussian;
114  in>>saveGaussian;
115 }
116 
117 void Random::toString(std::string & str)const{
118  std::ostringstream ostr;
119  ostr<<idum<<"|"<<iy;
120  for(int i=0;i<NTAB;i++){
121  ostr<<"|"<<iv[i];
122  };
123  str=ostr.str();
124 }
125 
126 void Random::fromString(const std::string & str){
127  std::string s=str;
128  for(int i=0;i<s.length();i++) if(s[i]=='|') s[i]=' ';
129  std::istringstream istr(s.c_str());
130  istr>>idum>>iy;
131  for (int i = 0; i < NTAB; i++) istr>>iv[i];
132 }
133 
134 // This allows to have the same stream of random numbers
135 // with different compilers:
136 #ifdef __INTEL_COMPILER
137 #pragma intel optimization_level 0
138 #endif
139 
141  double v1,v2,rsq;
142  if(switchGaussian){
143  switchGaussian=false;
144  return saveGaussian;
145  }
146  while(true){
147  v1=2.0*RandU01()-1.0;
148  v2=2.0*RandU01()-1.0;
149  rsq=v1*v1+v2*v2;
150  if(rsq<1.0 && rsq>0.0) break;
151  }
152  double fac=sqrt(-2.*std::log(rsq)/rsq);
153  saveGaussian=v1*fac;
154  switchGaussian=true;
155  return v2*fac;
156 }
157 
158 }
void toString(std::string &str) const
Definition: Random.cpp:117
void fromString(const std::string &str)
Definition: Random.cpp:126
double saveGaussian
Definition: Random.h:41
double U01()
Definition: Random.cpp:74
static const double AM
Definition: Random.h:35
double U01d()
Definition: Random.cpp:65
static const double fact
Definition: Random.h:37
void setSeed(int idum)
Definition: Random.cpp:51
void WriteStateFull(std::ostream &) const
Definition: Random.cpp:98
bool incPrec
Definition: Random.h:39
std::string name
Definition: Random.h:45
void ReadStateFull(std::istream &)
Definition: Random.cpp:109
static const int IQ
Definition: Random.h:32
int idum
Definition: Random.h:44
static const int NDIV
Definition: Random.h:33
Random(const std::string &name=noname)
Definition: Random.cpp:36
static const int IR
Definition: Random.h:32
static const int IA
Definition: Random.h:32
static const int IM
Definition: Random.h:32
bool switchGaussian
Definition: Random.h:40
static const int NTAB
Definition: Random.h:32
static const double EPS
Definition: Random.h:34
double RandU01()
Definition: Random.cpp:56
double Gaussian()
Definition: Random.cpp:140
static const double RNMX
Definition: Random.h:36
int iy
Definition: Random.h:42
static const std::string noname
Definition: Random.h:38
int iv[NTAB]
Definition: Random.h:43