MADNESS 0.10.1
ran.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32#ifndef MADNESS_MISC_RAN_H__INCLUDED
33#define MADNESS_MISC_RAN_H__INCLUDED
34
36#include <algorithm>
37#include <mutex>
38
39#include <complex>
40typedef std::complex<float> float_complex;
41typedef std::complex<double> double_complex;
42
43
44namespace madness {
45
46 struct RandomState {
47 int cur;
48 double u[1279];
49 };
50
51 /// A random number generator (portable, vectorized, and thread-safe)
52
53 /// Following Brent 1992, we use a 48-bit generalized Fibonacci generator
54 /// \code
55 /// u[n] = alpha*u[n-r] + beta*u[n-s] mod m
56 /// \endcode
57 /// with alpha=1, beta=7, r=1279, s=861, m=2^48. Double precision
58 /// numbers are used to perform exact integer arithmetic. 48-bit
59 /// because we have 52 bits of mantissa, alpha+1 is 3 bits and 1 bit spare.
60 ///
61 /// The period is nominally 2^m (2^r - 1) / 2 but if p is the period,
62 /// X[n] and X[n+p/2k] differ by at most k bits (0 < k < 48) so usage
63 /// should be limited to the first 2^r-1 entries (about 10^385 values).
64 ///
65 /// Each instance provides a separate stream, but it is up to the
66 /// user to partition the sequence by selecting distinct seeds or
67 /// other means.
68 ///
69 /// The streams are thread safe.
70 ///
71 /// A default stream is provided as madness::default_random_generator.
72 class Random {
73 private:
74 mutable std::mutex mutex_; ///< serializes access to the stream; mutable so getstate() can be const
75 const int r;
76 const int s;
77 const double beta;
78 int cur; // Removed volatile since always access in scope of mutex with implied barriers
79 double* const u;
80 unsigned int simple_state;
81
82 void generate();
83
84 unsigned int simple();
85
86 public:
87 Random(unsigned int seed = 5461);
88
89 virtual ~Random();
90
91 double get() {
92 std::lock_guard<std::mutex> safe(mutex_);
93 if (cur >= r) generate();
94 return u[cur++];
95 }
96
97 /// Returns a vector of uniform doubles in [0,1)
98 template <typename T>
99 void getv(int n, T * MADNESS_RESTRICT v) {
100 std::lock_guard<std::mutex> safe(mutex_);
101 while (n) {
102 if (cur >= r) generate();
103 int ndo = std::min(n,r-cur);
104 const double* ucur = const_cast<const double*>(u) + cur;
105 for (int i=0; i<ndo; ++i) v[i] = (T)(ucur[i]);
106 n -= ndo;
107 v += ndo;
108 cur += ndo;
109 }
110 }
111
112 /// Returns vector of random bytes in [0,256)
113 void getbytes(int n, unsigned char * MADNESS_RESTRICT v);
114
115 /// Returns full state of the generator
116 RandomState getstate() const;
117
118 /// Restores state of the generator
119 void setstate(const RandomState &s);
120
121 /// Sets state of the generator from integer
122 void setstate(unsigned int seed);
123
124 /// Test the generator
125 static void test();
126 };
127
128
129 /// The default random number stream
130 extern Random default_random_generator;
131
132 /// Random value that wraps the default Fibonacci generator
133 template <class T> T RandomValue();
134
135 /// Random double
136 template <> double RandomValue<double> ();
137
138 /// Random float
139 template <> float RandomValue<float> ();
140
141 /// Random int
142 template <> int RandomValue<int> ();
143
144 /// Random long
145 template <> long RandomValue<long> ();
146
147 /// Random double_complex
149
150 /// Random float_complex
152
153 template <class T> void RandomVector(int n, T* t) {
154 for (int i=0; i<n; ++i) t[i] = RandomValue<T>();
155 }
156
157 template <> void RandomVector<double>(int n, double* t);
158
159 template <> void RandomVector<float>(int n, float* t);
160
161 template <> void RandomVector<double_complex>(int n, double_complex* t);
162
163 template <> void RandomVector<float_complex>(int n, float_complex* t);
164}
165
166#endif // MADNESS_MISC_RAN_H__INCLUDED
std::complex< double > double_complex
Definition cfft.h:14
A random number generator (portable, vectorized, and thread-safe)
Definition ran.h:72
void getbytes(int n, unsigned char *MADNESS_RESTRICT v)
Returns vector of random bytes in [0,256)
Definition ran.cc:154
const double beta
Definition ran.h:77
unsigned int simple_state
Definition ran.h:80
std::mutex mutex_
serializes access to the stream; mutable so getstate() can be const
Definition ran.h:74
double *const u
Definition ran.h:79
const int s
Definition ran.h:76
static void test()
Test the generator.
Definition ran.cc:182
virtual ~Random()
Definition ran.cc:127
void setstate(const RandomState &s)
Restores state of the generator.
Definition ran.cc:175
void getv(int n, T *MADNESS_RESTRICT v)
Returns a vector of uniform doubles in [0,1)
Definition ran.h:99
RandomState getstate() const
Returns full state of the generator.
Definition ran.cc:167
unsigned int simple()
Definition ran.cc:66
double get()
Definition ran.h:91
const int r
Definition ran.h:75
int cur
Definition ran.h:78
void generate()
Definition ran.cc:45
static const double v
Definition hatom_sf_dirac.cc:20
Macros and tools pertaining to the configuration of MADNESS.
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
void RandomVector(int n, T *t)
Definition ran.h:153
float RandomValue< float >()
Random float.
Definition ran.cc:238
double RandomValue< double >()
Random double.
Definition ran.cc:234
void RandomVector< float >(int n, float *t)
Definition ran.cc:262
long RandomValue< long >()
Random long.
Definition ran.cc:254
int RandomValue< int >()
Random int.
Definition ran.cc:250
float_complex RandomValue< float_complex >()
Random float_complex.
Definition ran.cc:246
double_complex RandomValue< double_complex >()
Random double_complex.
Definition ran.cc:242
void RandomVector< float_complex >(int n, float_complex *t)
Definition ran.cc:270
T RandomValue()
Random value that wraps the default Fibonacci generator.
void RandomVector< double >(int n, double *t)
Definition ran.cc:258
void RandomVector< double_complex >(int n, double_complex *t)
Definition ran.cc:266
static XNonlinearSolver< std::vector< Function< T, NDIM > >, T, vector_function_allocator< T, NDIM > > nonlinear_vector_solver(World &world, const long nvec)
Definition nonlinsol.h:371
Random default_random_generator
The default random number stream.
Definition ran.cc:231
std::complex< double > double_complex
Definition ran.h:41
std::complex< float > float_complex
Definition ran.h:40
Definition ran.h:46
double u[1279]
Definition ran.h:48
int cur
Definition ran.h:47