1 /*****************************   randomc.h   **********************************
2 * Author:        Agner Fog
3 * Date created:  1997
4 * Last modified: 2008-11-16
5 * Project:       randomc.h
6 * Source URL:    www.agner.org/random
7 *
8 * Description:
9 * This header file contains class declarations and other definitions for the
10 * randomc class library of uniform random number generators in C++ language.
11 *
12 * Overview of classes:
13 * ====================
14 *
15 * class CRandomMersenne:
16 * Random number generator of type Mersenne twister.
17 * Source file mersenne.cpp
18 *
19 * class CRandomMother:
20 * Random number generator of type Mother-of-All (Multiply with carry).
21 * Source file mother.cpp
22 *
23 * class CRandomSFMT:
24 * Random number generator of type SIMD-oriented Fast Mersenne Twister.
25 * The class definition is not included here because it is not
26 * portable to all platforms. See sfmt.h and sfmt.cpp for details.
27 *
28 * Member functions (methods):
29 * ===========================
30 *
31 * All these classes have identical member functions:
32 *
33 * Constructor(int seed):
34 * The seed can be any integer. The time may be used as seed.
35 * Executing a program twice with the same seed will give the same sequence
36 * of random numbers. A different seed will give a different sequence.
37 *
38 * void RandomInit(int seed);
39 * Re-initializes the random number generator with a new seed.
40 *
41 * void RandomInitByArray(int const seeds[], int NumSeeds);
42 * In CRandomMersenne and CRandomSFMT only: Use this function if you want
43 * to initialize with a seed with more than 32 bits. All bits in the seeds[]
44 * array will influence the sequence of random numbers generated. NumSeeds
45 * is the number of entries in the seeds[] array.
46 *
47 * double Random();
48 * Gives a floating point random number in the interval 0 <= x < 1.
49 * The resolution is 32 bits in CRandomMother and CRandomMersenne, and
50 * 52 bits in CRandomSFMT.
51 *
52 * int IRandom(int min, int max);
53 * Gives an integer random number in the interval min <= x <= max.
54 * (max-min < MAXINT).
55 * The precision is 2^-32 (defined as the difference in frequency between
56 * possible output values). The frequencies are exact if max-min+1 is a
57 * power of 2.
58 *
59 * int IRandomX(int min, int max);
60 * Same as IRandom, but exact. In CRandomMersenne and CRandomSFMT only.
61 * The frequencies of all output values are exactly the same for an
62 * infinitely long sequence. (Only relevant for extremely long sequences).
63 *
64 * uint32_t BRandom();
65 * Gives 32 random bits.
66 *
67 *
68 * Example:
69 * ========
70 * The file EX-RAN.CPP contains an example of how to generate random numbers.
71 *
72 *
73 * Library version:
74 * ================
75 * Optimized versions of these random number generators are provided as function
76 * libraries in randoma.zip. These function libraries are coded in assembly
77 * language and support only x86 platforms, including 32-bit and 64-bit
78 * Windows, Linux, BSD, Mac OS-X (Intel based). Use randoma.h from randoma.zip
79 *
80 *
81 * Non-uniform random number generators:
82 * =====================================
83 * Random number generators with various non-uniform distributions are
84 * available in stocc.zip (www.agner.org/random).
85 *
86 *
87 * Further documentation:
88 * ======================
89 * The file ran-instructions.pdf contains further documentation and
90 * instructions for these random number generators.
91 *
92 * Copyright 1997-2008 by Agner Fog.
93 * GNU General Public License http://www.gnu.org/licenses/gpl.html
94 *******************************************************************************/
95 
96 #ifndef RANDOMC_H
97 #define RANDOMC_H
98 
99 // Define integer types with known size: int32_t, uint32_t, int64_t, uint64_t.
100 // If this doesn't work then insert compiler-specific definitions here:
101 #if defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1600)
102   // Compilers supporting C99 or C++0x have stdint.h defining these integer types
103   #include <stdint.h>
104   #define INT64_SUPPORTED // Remove this if the compiler doesn't support 64-bit integers
105 #elif defined(_WIN16) || defined(__MSDOS__) || defined(_MSDOS)
106   // 16 bit systems use long int for 32 bit integer.
107   typedef   signed long int int32_t;
108   typedef unsigned long int uint32_t;
109 #elif defined(_MSC_VER)
110   // Older Microsoft compilers have their own definition
111   typedef   signed __int32  int32_t;
112   typedef unsigned __int32 uint32_t;
113   typedef   signed __int64  int64_t;
114   typedef unsigned __int64 uint64_t;
115   #define INT64_SUPPORTED // Remove this if the compiler doesn't support 64-bit integers
116 #else
117   // This works with most compilers
118   typedef signed int          int32_t;
119   typedef unsigned int       uint32_t;
120   typedef long long           int64_t;
121   typedef unsigned long long uint64_t;
122   #define INT64_SUPPORTED // Remove this if the compiler doesn't support 64-bit integers
123 #endif
124 
125 
126 /***********************************************************************
127 System-specific user interface functions
128 ***********************************************************************/
129 
130 void EndOfProgram(void);               // System-specific exit code (userintf.cpp)
131 
132 void FatalError(const char *ErrorText);// System-specific error reporting (userintf.cpp)
133 
134 #if defined(__cplusplus)               // class definitions only in C++
135 /***********************************************************************
136 Define random number generator classes
137 ***********************************************************************/
138 
139 class CRandomMersenne {                // Encapsulate random number generator
140 // Choose which version of Mersenne Twister you want:
141 #if 0
142 // Define constants for type MT11213A:
143 #define MERS_N   351
144 #define MERS_M   175
145 #define MERS_R   19
146 #define MERS_U   11
147 #define MERS_S   7
148 #define MERS_T   15
149 #define MERS_L   17
150 #define MERS_A   0xE4BD75F5
151 #define MERS_B   0x655E5280
152 #define MERS_C   0xFFD58000
153 #else
154 // or constants for type MT19937:
155 #define MERS_N   624
156 #define MERS_M   397
157 #define MERS_R   31
158 #define MERS_U   11
159 #define MERS_S   7
160 #define MERS_T   15
161 #define MERS_L   18
162 #define MERS_A   0x9908B0DF
163 #define MERS_B   0x9D2C5680
164 #define MERS_C   0xEFC60000
165 #endif
166 
167 public:
CRandomMersenne(int seed)168    CRandomMersenne(int seed) {         // Constructor
169       RandomInit(seed); LastInterval = 0;}
170    void RandomInit(int seed);          // Re-seed
171    void RandomInitByArray(int const seeds[], int NumSeeds); // Seed by more than 32 bits
172    int IRandom (int min, int max);     // Output random integer
173    int IRandomX(int min, int max);     // Output random integer, exact
174    double Random();                    // Output random float
175    uint32_t BRandom();                 // Output random bits
176 private:
177    void Init0(int seed);               // Basic initialization procedure
178    uint32_t mt[MERS_N];                // State vector
179    int mti;                            // Index into mt
180    uint32_t LastInterval;              // Last interval length for IRandomX
181    uint32_t RLimit;                    // Rejection limit used by IRandomX
182 };
183 
184 
185 class CRandomMother {                  // Encapsulate random number generator
186 public:
187    void RandomInit(int seed);          // Initialization
188    int IRandom(int min, int max);      // Get integer random number in desired interval
189    double Random();                    // Get floating point random number
190    uint32_t BRandom();                 // Output random bits
CRandomMother(int seed)191    CRandomMother(int seed) {           // Constructor
192       RandomInit(seed);}
193 protected:
194    uint32_t x[5];                      // History buffer
195 };
196 
197 #endif // __cplusplus
198 #endif // RANDOMC_H
199