2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2008, The GROMACS development team.
6 * Copyright (c) 2012,2014, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
50 #ifdef GMX_NATIVE_WINDOWS
54 #include "gromacs/math/utilities.h"
55 #include "random_gausstable.h"
59 #define RNG_MATRIX_A 0x9908b0dfUL /* constant vector a */
60 #define RNG_UPPER_MASK 0x80000000UL /* most significant w-r bits */
61 #define RNG_LOWER_MASK 0x7fffffffUL /* least significant r bits */
63 /* Note that if you change the size of the Gaussian table you will also
64 * have to generate new initialization data for the table in
65 * gmx_random_gausstable.h
67 * A routine print_gaussian_table() is in contrib/random.c
68 * for convenience - use it if you need a different size of the table.
70 #define GAUSS_TABLE 14 /* the size of the gauss table is 2^GAUSS_TABLE */
71 #define GAUSS_SHIFT (32 - GAUSS_TABLE)
75 unsigned int mt[RNG_N];
91 gmx_rng_init(unsigned int seed)
95 if ((rng = (struct gmx_rng *)malloc(sizeof(struct gmx_rng))) == NULL)
100 rng->has_saved = 0; /* no saved gaussian number yet */
102 rng->mt[0] = seed & 0xffffffffUL;
103 for (rng->mti = 1; rng->mti < RNG_N; rng->mti++)
106 (1812433253UL * (rng->mt[rng->mti-1] ^
107 (rng->mt[rng->mti-1] >> 30)) + rng->mti);
108 /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
109 /* In the previous versions, MSBs of the seed affect */
110 /* only MSBs of the array mt[]. */
111 /* 2002/01/09 modified by Makoto Matsumoto */
112 rng->mt[rng->mti] &= 0xffffffffUL;
113 /* for >32 bit machines */
119 gmx_rng_init_array(unsigned int seed[], int seed_length)
124 if ((rng = gmx_rng_init(19650218UL)) == NULL)
130 k = (RNG_N > seed_length ? RNG_N : seed_length);
133 rng->mt[i] = (rng->mt[i] ^ ((rng->mt[i-1] ^
134 (rng->mt[i-1] >> 30)) * 1664525UL))
135 + seed[j] + j; /* non linear */
136 rng->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
140 rng->mt[0] = rng->mt[RNG_N-1]; i = 1;
142 if (j >= seed_length)
147 for (k = RNG_N-1; k; k--)
149 rng->mt[i] = (rng->mt[i] ^ ((rng->mt[i-1] ^
150 (rng->mt[i-1] >> 30)) *
152 - i; /* non linear */
153 rng->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
157 rng->mt[0] = rng->mt[RNG_N-1]; i = 1;
161 rng->mt[0] = 0x80000000UL;
162 /* MSB is 1; assuring non-zero initial array */
168 gmx_rng_destroy(gmx_rng_t rng)
178 gmx_rng_get_state(gmx_rng_t rng, unsigned int *mt, int *mti)
182 for (i = 0; i < RNG_N; i++)
191 gmx_rng_set_state(gmx_rng_t rng, unsigned int *mt, int mti)
195 for (i = 0; i < RNG_N; i++)
204 gmx_rng_make_seed(void)
212 /* We never want Gromacs execution to halt 10-20 seconds while
213 * waiting for enough entropy in the random number generator.
214 * For this reason we should NOT use /dev/random, which will
215 * block in cases like that. That will cause all sorts of
216 * Gromacs programs to block ~20 seconds while waiting for a
217 * super-random-number to generate cool quotes. Apart from the
218 * minor irritation, it is really bad behavior of a program
219 * to abuse the system random numbers like that - other programs
221 * For this reason, we ONLY try to get random numbers from
222 * the pseudo-random stream /dev/urandom, and use other means
223 * if it is not present (in this case fopen() returns NULL).
225 fp = fopen("/dev/urandom", "rb");
231 ret = fread(&data, sizeof(unsigned int), 1, fp);
236 /* No random device available, use time-of-day and process id */
237 #ifdef GMX_NATIVE_WINDOWS
238 my_pid = (long)_getpid();
240 my_pid = (long)getpid();
242 data = (unsigned int)(((long)time(NULL)+my_pid) % (long)1000000);
248 /* The random number state contains RNG_N entries that are returned one by
249 * one as random numbers. When we run out of them, this routine is called to
250 * regenerate RNG_N new entries.
253 gmx_rng_update(gmx_rng_t rng)
255 unsigned int lastx, x1, x2, y, *mt;
257 const unsigned int mag01[2] = {0x0UL, RNG_MATRIX_A};
258 /* mag01[x] = x * MATRIX_A for x=0,1 */
260 /* update random numbers */
261 mt = rng->mt; /* pointer to array - avoid repeated dereferencing */
265 for (k = 0; k < RNG_N-RNG_M-3; k += 4)
268 y = (x1 & RNG_UPPER_MASK) | (x2 & RNG_LOWER_MASK);
269 mt[k] = mt[k+RNG_M] ^ (y >> 1) ^ mag01[y & 0x1UL];
271 y = (x2 & RNG_UPPER_MASK) | (x1 & RNG_LOWER_MASK);
272 mt[k+1] = mt[k+RNG_M+1] ^ (y >> 1) ^ mag01[y & 0x1UL];
274 y = (x1 & RNG_UPPER_MASK) | (x2 & RNG_LOWER_MASK);
275 mt[k+2] = mt[k+RNG_M+2] ^ (y >> 1) ^ mag01[y & 0x1UL];
277 y = (x2 & RNG_UPPER_MASK) | (x1 & RNG_LOWER_MASK);
278 mt[k+3] = mt[k+RNG_M+3] ^ (y >> 1) ^ mag01[y & 0x1UL];
281 y = (x1 & RNG_UPPER_MASK) | (x2 & RNG_LOWER_MASK);
282 mt[k] = mt[k+RNG_M] ^ (y >> 1) ^ mag01[y & 0x1UL];
285 y = (x2 & RNG_UPPER_MASK) | (x1 & RNG_LOWER_MASK);
286 mt[k] = mt[k+RNG_M] ^ (y >> 1) ^ mag01[y & 0x1UL];
289 y = (x1 & RNG_UPPER_MASK) | (x2 & RNG_LOWER_MASK);
290 mt[k] = mt[k+RNG_M] ^ (y >> 1) ^ mag01[y & 0x1UL];
292 for (; k < RNG_N-1; k += 4)
295 y = (x2 & RNG_UPPER_MASK) | (x1 & RNG_LOWER_MASK);
296 mt[k] = mt[k+(RNG_M-RNG_N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
298 y = (x1 & RNG_UPPER_MASK) | (x2 & RNG_LOWER_MASK);
299 mt[k+1] = mt[k+(RNG_M-RNG_N)+1] ^ (y >> 1) ^ mag01[y & 0x1UL];
301 y = (x2 & RNG_UPPER_MASK) | (x1 & RNG_LOWER_MASK);
302 mt[k+2] = mt[k+(RNG_M-RNG_N)+2] ^ (y >> 1) ^ mag01[y & 0x1UL];
304 y = (x1 & RNG_UPPER_MASK) | (x2 & RNG_LOWER_MASK);
305 mt[k+3] = mt[k+(RNG_M-RNG_N)+3] ^ (y >> 1) ^ mag01[y & 0x1UL];
307 y = (x2 & RNG_UPPER_MASK) | (mt[0] & RNG_LOWER_MASK);
308 mt[RNG_N-1] = mt[RNG_M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
315 gmx_rng_gaussian_real(gmx_rng_t rng)
322 return rng->gauss_saved;
328 x = 2.0*gmx_rng_uniform_real(rng)-1.0;
329 y = 2.0*gmx_rng_uniform_real(rng)-1.0;
332 while (r > 1.0 || r == 0.0);
334 r = sqrt(-2.0*log(r)/r);
335 rng->gauss_saved = y*r; /* save second random number */
337 return x*r; /* return first random number */
344 /* Return a random unsigned integer, i.e. 0..4294967295
345 * Provided in header file for performace reasons.
346 * Unfortunately this function cannot be inlined, since
347 * it needs to refer the internal-linkage gmx_rng_update().
350 gmx_rng_uniform_uint32(gmx_rng_t rng)
354 if (rng->mti == RNG_N)
358 y = rng->mt[rng->mti++];
361 y ^= (y << 7) & 0x9d2c5680UL;
362 y ^= (y << 15) & 0xefc60000UL;
372 /* Return a uniform floating point number on the interval 0<=x<1 */
374 gmx_rng_uniform_real(gmx_rng_t rng)
376 if (sizeof(real) == sizeof(double))
378 return ((double)gmx_rng_uniform_uint32(rng))*(1.0/4294967296.0);
382 return ((float)gmx_rng_uniform_uint32(rng))*(1.0/4294967423.0);
384 /* divided by the smallest number that will generate a
385 * single precision real number on 0<=x<1.
386 * This needs to be slightly larger than MAX_UNIT since
387 * we are limited to an accuracy of 1e-7.
394 gmx_rng_gaussian_table(gmx_rng_t rng)
398 i = gmx_rng_uniform_uint32(rng);
400 /* The Gaussian table is a static constant in this file */
401 return gaussian_table[i >> GAUSS_SHIFT];