Hawaii Hybrid
Loading...
Searching...
No Matches
mtwist.h
Go to the documentation of this file.
1#ifndef MTWIST_H
2#define MTWIST_H
3
4#ifndef __cplusplus
5#define REGISTER register
6#else
7#define REGISTER
8#endif
9
10/*
11 * $Id: mtwist.h,v 1.24 2012-12-31 22:22:03-08 geoff Exp $
12 *
13 * Header file for C/C++ use of the Mersenne-Twist pseudo-RNG. See
14 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html for full
15 * information.
16 *
17 * Author of this header file: Geoff Kuenning, March 18, 2001.
18 *
19 * IMPORTANT NOTE: this implementation assumes a modern compiler. In
20 * particular, it assumes that the "inline" keyword is available, and
21 * that the "stdint.h" header file is present.
22 *
23 * The variables above are defined in an inverted sense because I
24 * expect that most modern compilers will support these features. By
25 * inverting the sense, this common case will require no special
26 * compiler flags.
27 *
28 * IMPORTANT NOTE: this software requires access to a 32-bit type.
29 * The Mersenne Twist algorithms are not guaranteed to produce correct
30 * results with a 64-bit type.
31 *
32 * The executable part of this software is based on LGPL-ed code by
33 * Takuji Nishimura. The header file is therefore also distributed
34 * under the LGPL:
35 *
36 * This library is free software; you can redistribute it and/or
37 * modify it under the terms of the GNU Library General Public License
38 * as published by the Free Software Foundation; either version 2 of
39 * the License, or (at your option) any later version.
40 *
41 * This library is distributed in the hope that it will be useful, but
42 * WITHOUT ANY WARRANTY; without even the implied warranty of
43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44 * Library General Public License for more details. You should have
45 * received a copy of the GNU Library General Public License along
46 * with this library; if not, write to the Free Foundation, Inc., 59
47 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
48 *
49 * $Log: mtwist.h,v $
50 * Revision 1.24 2012-12-31 22:22:03-08 geoff
51 * Fix the out-of-bounds bug in mt_llrand and mt_ldrand that were
52 * overlooked because I assumed they used mts_*.
53 *
54 * Revision 1.23 2013-01-01 01:18:52-08 geoff
55 * Fix a lot of compiler warnings.
56 *
57 * Revision 1.22 2012-12-30 16:24:49-08 geoff
58 * Declare the new versions of the /dev/random and urandom seeding
59 * functions, which now return the seed chosen.
60 *
61 * Revision 1.21 2012-09-23 23:15:40-07 geoff
62 * Fix an array index violation found by valgrind and reported by David
63 * Chapman; under some circumstances statevec[-1] could be accessed and
64 * used in random-number generation. The bug only affects the *_llrand
65 * and *_ldrand functions.
66 *
67 * Revision 1.20 2010-12-10 03:28:18-08 geoff
68 * Add support for GENERATE_CODE_IN_HEADER. Fix the URL for the original
69 * Web page.
70 *
71 * Revision 1.19 2010-06-24 20:53:59+12 geoff
72 * Switch to using types from stdint.h. Get rid of all compilation
73 * options.
74 *
75 * Revision 1.18 2010-06-24 00:29:38-07 geoff
76 * Do a better job of auto-determining MT_MACHINE_BITS.
77 *
78 * Revision 1.17 2007-10-26 00:21:06-07 geoff
79 * Introduce, document, and use the new mt_u32bit_t type so that the code
80 * will compile and run on 64-bit platforms (although it does not
81 * currently use the 64-bit Mersenne Twist algorithm).
82 *
83 * Revision 1.16 2005/11/11 08:21:39 geoff
84 * If possible, try to infer MT_MACHINE_BITS from limits.h.
85 *
86 * Revision 1.15 2003/09/11 23:56:20 geoff
87 * Allow stdio references in C++ files; it turns out that ANSI has
88 * blessed it. Declare the various functions as external even if they're
89 * inlined or being compiled directly (in mtwist.c). Get rid of a #ifdef
90 * that can't ever be true.
91 *
92 * Revision 1.14 2003/09/11 05:50:53 geoff
93 * Don't allow stdio references from C++, since they're not guaranteed to
94 * work on all compilers. Disable inlining using the MT_INLINE keyword
95 * rather than #defining inline, since doing the latter can affect other
96 * files and functions than our own.
97 *
98 * Revision 1.13 2003/07/01 23:29:29 geoff
99 * Refer to streams from the standard library using the correct namespace.
100 *
101 * Revision 1.12 2002/10/30 07:39:54 geoff
102 * Declare the new seeding functions.
103 *
104 * Revision 1.11 2001/06/19 00:41:16 geoff
105 * For consistency with other C++ types, don't put out a newline after
106 * the saved data.
107 *
108 * Revision 1.10 2001/06/18 10:09:24 geoff
109 * Fix some places where I forgot to set one of the result values. Make
110 * the C++ state vector protected so the random-distributions package can
111 * pass it to the C functions.
112 *
113 * Revision 1.9 2001/06/18 05:40:12 geoff
114 * Prefix the compile options with MT_.
115 *
116 * Revision 1.8 2001/06/14 10:26:59 geoff
117 * Invert the sense of the #define flags so that the default is the
118 * normal case (if gcc is normal!). Also default MT_MACHINE_BITS to 32.
119 *
120 * Revision 1.7 2001/06/14 10:10:38 geoff
121 * Move the critical-path PRNG code into the header file so that it can
122 * be inlined. Add saving/loading of state. Add functions to seed based
123 * on /dev/random or the time. Add the function-call operator in the C++
124 * code.
125 *
126 * Revision 1.6 2001/06/11 10:00:04 geoff
127 * Add declarations of the refresh and /dev/random seeding functions.
128 * Change getstate to return a complete state pointer, since knowing the
129 * position in the state vector is critical to restoring the state.
130 *
131 * Revision 1.5 2001/04/23 08:36:03 geoff
132 * Remember to zero the state pointer when constructing, since otherwise
133 * proper initialization won't happen.
134 *
135 * Revision 1.4 2001/04/14 01:33:32 geoff
136 * Clarify the license
137 *
138 * Revision 1.3 2001/04/14 01:04:54 geoff
139 * Add a C++ class, mt_prng, that makes usage more convenient for C++
140 * programmers.
141 *
142 * Revision 1.2 2001/04/09 08:45:00 geoff
143 * Fix the name in the #ifndef wrapper, and clean up some outdated comments.
144 *
145 * Revision 1.1 2001/04/07 09:43:41 geoff
146 * Initial revision
147 *
148 */
149
150#include <stdio.h>
151#ifdef __cplusplus
152#include <iostream>
153#endif /* __cplusplus */
154
155#define __STDC_LIMIT_MACROS
156#include <stdint.h>
157
158/*
159 * The following value is a fundamental parameter of the algorithm.
160 * It was found experimentally using methods described in Matsumoto
161 * and Nishimura's paper. It is exceedingly magic; don't change it.
162 */
163#define MT_STATE_SIZE 624 /* Size of the MT state vector */
164
165/*
166 * Internal state for an MT RNG. The user can keep multiple mt_state
167 * structures around as a way of generating multiple streams of random
168 * numbers.
169 *
170 * In Matsumoto and Nishimura's original paper, the state vector was
171 * processed in a forward direction. I have reversed the state vector
172 * in this implementation. The reason for the reversal is that it
173 * allows the critical path to use a test against zero instead of a
174 * test against 624 to detect the need to refresh the state. on most
175 * machines, testing against zero is slightly faster. It also means
176 * that a state that has been set to all zeros will be correctly
177 * detected as needing initialization; this means that setting a state
178 * vector to zero (either with memset or by statically allocating it)
179 * will cause the RNG to operate properly.
180 */
181typedef struct
182 {
184 /* Vector holding current state */
185 int stateptr; /* Next state entry to be used */
186 int initialized; /* NZ if state was initialized */
187 }
188 mt_state;
189
190#ifdef __cplusplus
191extern "C"
192 {
193#endif
194
195/*
196 * Functions for manipulating any generator (given a state pointer).
197 */
198extern void mts_mark_initialized(mt_state* state);
199 /* Mark a PRNG state as initialized */
200extern void mts_seed32(mt_state* state, uint32_t seed);
201 /* Set random seed for any generator */
202extern void mts_seed32new(mt_state* state, uint32_t seed);
203 /* Set random seed for any generator */
204extern void mts_seedfull(mt_state* state,
205 uint32_t seeds[MT_STATE_SIZE]);
206 /* Set complicated seed for any gen. */
207extern uint32_t mts_seed(mt_state* state);
208 /* Choose seed from random input. */
209 /* ..Prefers /dev/urandom; uses time */
210 /* ..if /dev/urandom unavailable. */
211 /* ..Only gives 32 bits of entropy. */
212 /* ..Returns seed usable with seed32 */
213extern uint32_t mts_goodseed(mt_state* state);
214 /* Choose seed from more random */
215 /* ..input than mts_seed. Prefers */
216 /* ../dev/random; uses time if that */
217 /* ..is unavailable. Only gives 32 */
218 /* ..bits of entropy. */
219 /* ..Returns seed usable with seed32 */
220extern void mts_bestseed(mt_state* state);
221 /* Choose seed from extremely random */
222 /* ..input (can be *very* slow). */
223 /* ..Prefers /dev/random and reads */
224 /* ..the entire state from there. */
225 /* ..If /dev/random is unavailable, */
226 /* ..falls back to mt_goodseed(). */
227 /* ..Not usually worth the cost. */
228extern void mts_refresh(mt_state* state);
229 /* Generate 624 more random values */
230extern int mts_savestate(FILE* statefile, mt_state* state);
231 /* Save state to a file (ASCII). */
232 /* ..Returns NZ if succeeded. */
233extern int mts_loadstate(FILE* statefile, mt_state* state);
234 /* Load state from a file (ASCII). */
235 /* ..Returns NZ if succeeded. */
236
237/*
238 * Functions for manipulating the default generator.
239 */
240extern void mt_seed32(uint32_t seed);
241 /* Set random seed for default gen. */
242extern void mt_seed32new(uint32_t seed);
243 /* Set random seed for default gen. */
244extern void mt_seedfull(uint32_t seeds[MT_STATE_SIZE]);
245 /* Set complicated seed for default */
246extern uint32_t mt_seed(void); /* Choose seed from random input. */
247 /* ..Prefers /dev/urandom; uses time */
248 /* ..if /dev/urandom unavailable. */
249 /* ..Only gives 32 bits of entropy. */
250extern uint32_t mt_goodseed(void);
251 /* Choose seed from more random */
252 /* ..input than mts_seed. Prefers */
253 /* ../dev/random; uses time if that */
254 /* ..is unavailable. Only gives 32 */
255 /* ..bits of entropy. */
256extern void mt_bestseed(void);
257 /* Choose seed from extremely random */
258 /* ..input (can be *very* slow). */
259 /* ..Prefers /dev/random and reads */
260 /* ..the entire state from there. */
261 /* ..If /dev/random is unavailable, */
262 /* ..falls back to mt_goodseed(). */
263 /* ..Not usually worth the cost. */
264extern mt_state* mt_getstate(void);
265 /* Get current state of default */
266 /* ..generator */
267extern int mt_savestate(FILE* statefile);
268 /* Save state to a file (ASCII) */
269 /* ..Returns NZ if succeeded. */
270extern int mt_loadstate(FILE* statefile);
271 /* Load state from a file (ASCII) */
272 /* ..Returns NZ if succeeded. */
273
274#ifdef __cplusplus
275 }
276#endif
277
278/*
279 * Functions for generating random numbers. The actual code of the
280 * functions is given in this file so that it can be declared inline.
281 * For compilers that don't have the inline feature, mtwist.c will
282 * incorporate this file with some clever #defining so that the code
283 * actually gets compiled. In that case, however, "extern"
284 * definitions will be needed here, so we give them.
285 */
286#ifdef __cplusplus
287#endif /* __cplusplus */
288
289extern uint32_t mts_lrand(mt_state* state);
290 /* Generate 32-bit value, any gen. */
291#ifdef UINT64_MAX
292extern uint64_t mts_llrand(mt_state* state);
293 /* Generate 64-bit value, any gen. */
294#endif /* UINT64_MAX */
295extern double mts_drand(mt_state* state);
296 /* Generate floating value, any gen. */
297 /* Fast, with only 32-bit precision */
298extern double mts_ldrand(mt_state* state);
299 /* Generate floating value, any gen. */
300 /* Slower, with 64-bit precision */
301
302extern uint32_t mt_lrand(void); /* Generate 32-bit random value */
303#ifdef UINT64_MAX
304extern uint64_t mt_llrand(void);
305 /* Generate 64-bit random value */
306#endif /* UINT64_MAX */
307extern double mt_drand(void);
308 /* Generate floating value */
309 /* Fast, with only 32-bit precision */
310extern double mt_ldrand(void);
311 /* Generate floating value */
312 /* Slower, with 64-bit precision */
313
314/*
315 * Tempering parameters. These are perhaps the most magic of all the magic
316 * values in the algorithm. The values are again experimentally determined.
317 * The values generated by the recurrence relation (constants above) are not
318 * equidistributed in 623-space. For some reason, the tempering process
319 * produces that effect. Don't ask me why. Read the paper if you can
320 * understand the math. Or just trust these magic numbers.
321 */
322#define MT_TEMPERING_MASK_B 0x9d2c5680
323#define MT_TEMPERING_MASK_C 0xefc60000
324#define MT_TEMPERING_SHIFT_U(y) \
325 (y >> 11)
326#define MT_TEMPERING_SHIFT_S(y) \
327 (y << 7)
328#define MT_TEMPERING_SHIFT_T(y) \
329 (y << 15)
330#define MT_TEMPERING_SHIFT_L(y) \
331 (y >> 18)
332
333/*
334 * Macros to do the tempering. MT_PRE_TEMPER does all but the last step;
335 * it's useful for situations where the final step can be incorporated
336 * into a return statement. MT_FINAL_TEMPER does that final step (not as
337 * an assignment). MT_TEMPER does the entire process. Note that
338 * MT_PRE_TEMPER and MT_TEMPER both modify their arguments.
339 */
340#define MT_PRE_TEMPER(value) \
341 do \
342 { \
343 value ^= MT_TEMPERING_SHIFT_U(value); \
344 value ^= MT_TEMPERING_SHIFT_S(value) & MT_TEMPERING_MASK_B; \
345 value ^= MT_TEMPERING_SHIFT_T(value) & MT_TEMPERING_MASK_C; \
346 } \
347 while (0)
348#define MT_FINAL_TEMPER(value) \
349 ((value) ^ MT_TEMPERING_SHIFT_L(value))
350#define MT_TEMPER(value) \
351 do \
352 { \
353 value ^= MT_TEMPERING_SHIFT_U(value); \
354 value ^= MT_TEMPERING_SHIFT_S(value) & MT_TEMPERING_MASK_B; \
355 value ^= MT_TEMPERING_SHIFT_T(value) & MT_TEMPERING_MASK_C; \
356 value ^= MT_TEMPERING_SHIFT_L(value); \
357 } \
358 while (0)
359
360/*
361 * The Mersenne Twist PRNG makes it default state available as an
362 * external variable. This feature is undocumented, but is useful to
363 * use because it allows us to avoid implementing every randistr function
364 * twice. (In fact, the feature was added to enable randistrs.c to be
365 * written. It would be better to write in C++, where I could control
366 * the access to the state.)
367 */
369 /* State of the default generator */
370extern double mt_32_to_double;
371 /* Multiplier to convert long to dbl */
372extern double mt_64_to_double;
373 /* Mult'r to cvt long long to dbl */
374
375/*
376 * In gcc, inline functions must be declared extern or they'll produce
377 * assembly code (and thus linking errors). We have to work around
378 * that difficulty with the MT_EXTERN define.
379 */
380#ifndef MT_EXTERN
381#ifdef __cplusplus
382#define MT_EXTERN /* C++ doesn't need static */
383#else /* __cplusplus */
384#define MT_EXTERN extern /* C (at least gcc) needs extern */
385#endif /* __cplusplus */
386#endif /* MT_EXTERN */
387
388/*
389 * Make it possible for mtwist.c to disable the inline keyword. We
390 * use our own keyword so that we don't interfere with inlining in
391 * C/C++ header files, above.
392 */
393#ifndef MT_INLINE
394#define MT_INLINE inline /* Compiler has inlining */
395#endif /* MT_INLINE */
396
397/*
398 * Try to guess whether the compiler is one (like gcc) that requires
399 * inline code to be available in the header file, or a smarter one
400 * that gets inlines directly from object files. But if we've been
401 * given the information, trust it.
402 */
403#ifndef MT_GENERATE_CODE_IN_HEADER
404#ifdef __GNUC__
405#define MT_GENERATE_CODE_IN_HEADER 1
406#endif /* __GNUC__ */
407#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
408#define MT_GENERATE_CODE_IN_HEADER 0
409#endif /* __INTEL_COMPILER || _MSC_VER */
410#endif /* MT_GENERATE_CODE_IN_HEADER */
411
412#if MT_GENERATE_CODE_IN_HEADER
413/*
414 * Generate a random number in the range 0 to 2^32-1, inclusive, working
415 * from a given state vector.
416 *
417 * The generator is optimized for speed. The primary optimization is that
418 * the pseudorandom numbers are generated in batches of MT_STATE_SIZE. This
419 * saves the cost of a modulus operation in the critical path.
420 */
422 REGISTER mt_state* state) /* State for the PRNG */
423 {
424 REGISTER uint32_t random_value; /* Pseudorandom value generated */
425
426 if (state->stateptr <= 0)
427 mts_refresh(state);
428
429 random_value = state->statevec[--state->stateptr];
430 MT_PRE_TEMPER(random_value);
431 return MT_FINAL_TEMPER(random_value);
432 }
433
434#ifdef UINT64_MAX
435/*
436 * Generate a random number in the range 0 to 2^64-1, inclusive, working
437 * from a given state vector.
438 *
439 * According to Matsumoto and Nishimura, such a number can be generated by
440 * simply concatenating two 32-bit pseudorandom numbers. Who am I to argue?
441 *
442 * Note that there is a slight inefficiency here: if the 624-entry state is
443 * recycled on the second call to mts_lrand, there will be an unnecessary
444 * check to see if the state has been initialized. The cost of that check
445 * seems small (since it happens only once every 624 random numbers, and
446 * never if only 64-bit numbers are being generated), so I didn't bother to
447 * optimize it out. Doing so would be messy, since it would require two
448 * nearly-identical internal implementations of mts_lrand.
449 */
450MT_EXTERN MT_INLINE uint64_t mts_llrand(
451 REGISTER mt_state* state) /* State for the PRNG */
452 {
453 REGISTER uint32_t random_value_1; /* 1st pseudorandom value generated */
454 REGISTER uint32_t random_value_2; /* 2nd pseudorandom value generated */
455
456 /*
457 * For maximum speed, we'll handle the two overflow cases
458 * together. That will save us one test in the common case, at
459 * the expense of an extra one in the overflow case.
460 */
461 if (--state->stateptr <= 0)
462 {
463 if (state->stateptr < 0)
464 {
465 mts_refresh(state);
466 random_value_1 = state->statevec[--state->stateptr];
467 }
468 else
469 {
470 random_value_1 = state->statevec[state->stateptr];
471 mts_refresh(state);
472 }
473 }
474 else
475 random_value_1 = state->statevec[state->stateptr];
476
477 MT_TEMPER(random_value_1);
478
479 random_value_2 = state->statevec[--state->stateptr];
480 MT_PRE_TEMPER(random_value_2);
481
482 return ((uint64_t) random_value_1 << 32)
483 | (uint64_t) MT_FINAL_TEMPER(random_value_2);
484 }
485#endif /* UINT64_MAX */
486
487/*
488 * Generate a double-precision random number between 0 (inclusive) and 1.0
489 * (exclusive). This function is optimized for speed, but it only generates
490 * 32 bits of precision. Use mts_ldrand to get 64 bits of precision.
491 */
493 REGISTER mt_state* state) /* State for the PRNG */
494 {
495 REGISTER uint32_t random_value; /* Pseudorandom value generated */
496
497 if (state->stateptr <= 0)
498 mts_refresh(state);
499
500 random_value = state->statevec[--state->stateptr];
501 MT_TEMPER(random_value);
502
503 return random_value * mt_32_to_double;
504 }
505
506/*
507 * Generate a double-precision random number between 0 (inclusive) and 1.0
508 * (exclusive). This function generates 64 bits of precision. Use
509 * mts_drand for more speed but less precision.
510 */
512 REGISTER mt_state* state) /* State for the PRNG */
513 {
514#ifdef UINT64_MAX
515 uint64_t final_value; /* Final (integer) value */
516#endif /* UINT64_MAX */
517 REGISTER uint32_t random_value_1; /* 1st pseudorandom value generated */
518 REGISTER uint32_t random_value_2; /* 2nd pseudorandom value generated */
519
520 /*
521 * For maximum speed, we'll handle the two overflow cases
522 * together. That will save us one test in the common case, at
523 * the expense of an extra one in the overflow case.
524 */
525 if (--state->stateptr <= 0)
526 {
527 if (state->stateptr < 0)
528 {
529 mts_refresh(state);
530 random_value_1 = state->statevec[--state->stateptr];
531 }
532 else
533 {
534 random_value_1 = state->statevec[state->stateptr];
535 mts_refresh(state);
536 }
537 }
538 else
539 random_value_1 = state->statevec[state->stateptr];
540
541 MT_TEMPER(random_value_1);
542
543 random_value_2 = state->statevec[--state->stateptr];
544 MT_TEMPER(random_value_2);
545
546#ifdef UINT64_MAX
547 final_value = ((uint64_t) random_value_1 << 32) | (uint64_t) random_value_2;
548 return final_value * mt_64_to_double;
549#else /* UINT64_MAX */
550 return random_value_1 * mt_32_to_double + random_value_2 * mt_64_to_double;
551#endif /* UINT64_MAX */
552 }
553
554/*
555 * Generate a random number in the range 0 to 2^32-1, inclusive, working
556 * from the default state vector.
557 *
558 * See mts_lrand for full commentary.
559 */
560MT_EXTERN MT_INLINE uint32_t mt_lrand(void)
561 {
562 REGISTER uint32_t random_value; /* Pseudorandom value generated */
563
564 if (mt_default_state.stateptr <= 0)
566
567 random_value = mt_default_state.statevec[--mt_default_state.stateptr];
568 MT_PRE_TEMPER(random_value);
569
570 return MT_FINAL_TEMPER(random_value);
571 }
572
573#ifdef UINT64_MAX
574/*
575 * Generate a random number in the range 0 to 2^64-1, inclusive, working
576 * from the default state vector.
577 *
578 * See mts_llrand for full commentary.
579 */
580MT_EXTERN MT_INLINE uint64_t mt_llrand(void)
581 {
582 REGISTER uint32_t random_value_1; /* 1st pseudorandom value generated */
583 REGISTER uint32_t random_value_2; /* 2nd pseudorandom value generated */
584
585 /*
586 * For maximum speed, we'll handle the two overflow cases
587 * together. That will save us one test in the common case, at
588 * the expense of an extra one in the overflow case.
589 */
590 if (--mt_default_state.stateptr <= 0)
591 {
592 if (mt_default_state.stateptr < 0)
593 {
595 random_value_1 =
596 mt_default_state.statevec[--mt_default_state.stateptr];
597 }
598 else
599 {
600 random_value_1 =
601 mt_default_state.statevec[mt_default_state.stateptr];
603 }
604 }
605 else
606 random_value_1 = mt_default_state.statevec[mt_default_state.stateptr];
607
608 MT_TEMPER(random_value_1);
609
610 random_value_2 = mt_default_state.statevec[--mt_default_state.stateptr];
611 MT_PRE_TEMPER(random_value_2);
612
613 return ((uint64_t) random_value_1 << 32)
614 | (uint64_t) MT_FINAL_TEMPER(random_value_2);
615 }
616#endif /* UINT64_MAX */
617
618/*
619 * Generate a double-precision random number between 0 (inclusive) and 1.0
620 * (exclusive). This function is optimized for speed, but it only generates
621 * 32 bits of precision. Use mt_ldrand to get 64 bits of precision.
622 */
623MT_EXTERN MT_INLINE double mt_drand(void)
624 {
625 REGISTER uint32_t random_value; /* Pseudorandom value generated */
626
627 if (mt_default_state.stateptr <= 0)
629
630 random_value = mt_default_state.statevec[--mt_default_state.stateptr];
631 MT_TEMPER(random_value);
632
633 return random_value * mt_32_to_double;
634 }
635
636/*
637 * Generate a double-precision random number between 0 (inclusive) and 1.0
638 * (exclusive). This function generates 64 bits of precision. Use
639 * mts_drand for more speed but less precision.
640 */
641MT_EXTERN MT_INLINE double mt_ldrand(void)
642 {
643#ifdef UINT64_MAX
644 uint64_t final_value; /* Final (integer) value */
645#endif /* UINT64_MAX */
646 REGISTER uint32_t random_value_1; /* 1st pseudorandom value generated */
647 REGISTER uint32_t random_value_2; /* 2nd pseudorandom value generated */
648
649 /*
650 * For maximum speed, we'll handle the two overflow cases
651 * together. That will save us one test in the common case, at
652 * the expense of an extra one in the overflow case.
653 */
654 if (--mt_default_state.stateptr <= 0)
655 {
656 if (mt_default_state.stateptr < 0)
657 {
659 random_value_1 =
660 mt_default_state.statevec[--mt_default_state.stateptr];
661 }
662 else
663 {
664 random_value_1 =
665 mt_default_state.statevec[mt_default_state.stateptr];
667 }
668 }
669 else
670 random_value_1 = mt_default_state.statevec[mt_default_state.stateptr];
671
672 MT_TEMPER(random_value_1);
673
674 random_value_2 = mt_default_state.statevec[--mt_default_state.stateptr];
675 MT_TEMPER(random_value_2);
676
677#ifdef UINT64_MAX
678 final_value = ((uint64_t) random_value_1 << 32) | (uint64_t) random_value_2;
679 return final_value * mt_64_to_double;
680#else /* UINT64_MAX */
681 return random_value_1 * mt_32_to_double + random_value_2 * mt_64_to_double;
682#endif /* UINT64_MAX */
683 }
684#endif /* MT_GENERATE_CODE_IN_HEADER */
685
686#ifdef __cplusplus
687/*
688 * C++ interface to the Mersenne Twist PRNG. This class simply
689 * provides a more C++-ish way to access the PRNG. Only state-based
690 * functions are provided. All functions are inlined, both for speed
691 * and so that the same implementation code can be used in C and C++.
692 */
693class mt_prng
694 {
695 friend class mt_empirical_distribution;
696 public:
697 /*
698 * Constructors and destructors. The default constructor
699 * leaves initialization (seeding) for later unless pickSeed
700 * is true, in which case the seed is chosen based on either
701 * /dev/urandom (if available) or the system time. The other
702 * constructors accept either a 32-bit seed, or a full
703 * 624-integer seed.
704 */
705 mt_prng( // Default constructor
706 bool pickSeed = false)
707 // True to get seed from /dev/urandom
708 // ..or time
709 {
710 state.stateptr = 0;
711 state.initialized = 0;
712 if (pickSeed)
713 (void)mts_seed(&state);
714 }
715 mt_prng(uint32_t newseed)
716 // Construct with 32-bit seeding
717 {
718 state.stateptr = 0;
719 state.initialized = 0;
720 mts_seed32(&state, newseed);
721 }
722 mt_prng(uint32_t seeds[MT_STATE_SIZE])
723 // Construct with full seeding
724 {
725 state.stateptr = 0;
726 state.initialized = 0;
727 mts_seedfull(&state, seeds);
728 }
729 ~mt_prng() { }
730
731 /*
732 * Copy and assignment are best left defaulted.
733 */
734
735 /*
736 * PRNG seeding functions.
737 */
738 void seed32(uint32_t newseed)
739 // Set 32-bit random seed
740 {
741 mts_seed32(&state, newseed);
742 }
743 void seed32new(uint32_t newseed)
744 // Set 32-bit random seed
745 {
746 mts_seed32new(&state, newseed);
747 }
748 void seedfull(uint32_t seeds[MT_STATE_SIZE])
749 // Set complicated random seed
750 {
751 mts_seedfull(&state, seeds);
752 }
753 uint32_t seed() // Choose seed from random input
754 {
755 return mts_seed(&state);
756 }
757 uint32_t goodseed() // Choose better seed from random input
758 {
759 return mts_goodseed(&state);
760 }
761 void bestseed() // Choose best seed from random input
762 {
763 mts_bestseed(&state);
764 }
765 friend std::ostream&
766 operator<<(std::ostream& stream, const mt_prng& rng);
767 friend std::istream&
768 operator>>(std::istream& stream, mt_prng& rng);
769
770 /*
771 * PRNG generation functions
772 */
773 uint32_t lrand() // Generate 32-bit pseudo-random value
774 {
775 return mts_lrand(&state);
776 }
777#ifdef UINT64_MAX
778 uint64_t llrand() // Generate 64-bit pseudo-random value
779 {
780 return mts_llrand(&state);
781 }
782#endif /* UINT64_MAX */
783 double drand() // Generate fast 32-bit floating value
784 {
785 return mts_drand(&state);
786 }
787 double ldrand() // Generate slow 64-bit floating value
788 {
789 return mts_ldrand(&state);
790 }
791
792 /*
793 * Following Richard J. Wagner's example, we overload the
794 * function-call operator to return a 64-bit floating value.
795 * That allows the common use of the PRNG to be simplified as
796 * in the following example:
797 *
798 * mt_prng ranno(true);
799 * // ...
800 * coinFlip = ranno() >= 0.5 ? heads : tails;
801 */
802 double operator()()
803 {
804 return mts_drand(&state);
805 }
806 protected:
807 /*
808 * Protected data
809 */
810 mt_state state; // Current state of the PRNG
811 };
812
813#if MT_GENERATE_CODE_IN_HEADER
814/*
815 * Save state to a stream. See mts_savestate.
816 */
817MT_INLINE std::ostream& operator<<(
818 std::ostream& stream, // Stream to save to
819 const mt_prng& rng) // PRNG to save
820 {
821 for (int i = MT_STATE_SIZE; --i >= 0; )
822 {
823 if (!(stream << rng.state.statevec[i] << ' '))
824 return stream;
825 }
826
827 return stream << rng.state.stateptr;
828 }
829
830/*
831 * Restore state from a stream. See mts_loadstate.
832 */
833MT_INLINE std::istream& operator>>(
834 std::istream& stream, // Stream to laod from
835 mt_prng& rng) // PRNG to load
836 {
837 rng.state.initialized = rng.state.stateptr = 0;
838 for (int i = MT_STATE_SIZE; --i >= 0; )
839 {
840 if (!(stream >> rng.state.statevec[i]))
841 return stream;
842 }
843
844 if (!(stream >> rng.state.stateptr))
845 {
846 rng.state.stateptr = 0;
847 return stream;
848 }
849
850 /*
851 * If the state is invalid, all we can do is to make it uninitialized.
852 */
853 if (rng.state.stateptr < 0 || rng.state.stateptr > MT_STATE_SIZE)
854 {
855 rng.state.stateptr = 0;
856 return stream;
857 }
858
859 mts_mark_initialized(&rng.state);
860
861 return stream;
862 }
863#endif /* MT_GENERATE_CODE_IN_HEADER */
864#endif /* __cplusplus */
865
866#endif /* MTWIST_H */
double mt_64_to_double
Definition mtwist.c:312
void mts_bestseed(mt_state *state)
Definition mtwist.c:600
void mts_seedfull(mt_state *state, uint32_t seeds[MT_STATE_SIZE])
Definition mtwist.c:459
mt_state mt_default_state
Definition mtwist.c:299
#define MT_EXTERN
Definition mtwist.c:202
double mt_32_to_double
Definition mtwist.c:310
void mts_seed32new(mt_state *state, uint32_t seed)
Definition mtwist.c:408
void mts_seed32(mt_state *state, uint32_t seed)
Definition mtwist.c:372
uint32_t mts_goodseed(mt_state *state)
Definition mtwist.c:509
uint32_t mts_seed(mt_state *state)
Definition mtwist.c:497
#define MT_INLINE
Definition mtwist.c:201
double mt_drand(void)
#define MT_PRE_TEMPER(value)
Definition mtwist.h:340
void mt_seed32new(uint32_t seed)
Definition mtwist.c:890
void mts_bestseed(mt_state *state)
Definition mtwist.c:600
int mts_loadstate(FILE *statefile, mt_state *state)
Definition mtwist.c:839
void mts_seedfull(mt_state *state, uint32_t seeds[MT_STATE_SIZE])
Definition mtwist.c:459
#define MT_FINAL_TEMPER(value)
Definition mtwist.h:348
mt_state * mt_getstate(void)
Definition mtwist.c:937
uint32_t mts_lrand(mt_state *state)
void mt_seed32(uint32_t seed)
Definition mtwist.c:879
#define MT_STATE_SIZE
Definition mtwist.h:163
void mts_refresh(mt_state *state)
#define MT_TEMPER(value)
Definition mtwist.h:350
double mts_drand(mt_state *state)
int mt_savestate(FILE *statefile)
Definition mtwist.c:946
int mts_savestate(FILE *statefile, mt_state *state)
Definition mtwist.c:804
int mt_loadstate(FILE *statefile)
Definition mtwist.c:955
void mts_seed32new(mt_state *state, uint32_t seed)
Definition mtwist.c:408
#define REGISTER
Definition mtwist.h:5
void mt_bestseed(void)
Definition mtwist.c:926
void mts_mark_initialized(mt_state *state)
Definition mtwist.c:335
void mts_seed32(mt_state *state, uint32_t seed)
Definition mtwist.c:372
uint32_t mt_lrand(void)
void mt_seedfull(uint32_t seeds[MT_STATE_SIZE])
Definition mtwist.c:901
uint32_t mt_seed(void)
Definition mtwist.c:910
uint32_t mt_goodseed(void)
Definition mtwist.c:918
double mts_ldrand(mt_state *state)
double mt_ldrand(void)
uint32_t mts_goodseed(mt_state *state)
Definition mtwist.c:509
uint32_t mts_seed(mt_state *state)
Definition mtwist.c:497
Definition mtwist.h:182
uint32_t statevec[MT_STATE_SIZE]
Definition mtwist.h:183
int initialized
Definition mtwist.h:186
int stateptr
Definition mtwist.h:185