]> git.donarmstrong.com Git - rsem.git/blob - randomc.h
RSEM Source Codes
[rsem.git] / randomc.h
1 /*************************** RANDOMC.H ***************** 2007-09-22 Agner Fog *\r
2 *\r
3 * This file contains class declarations and other definitions for the C++ \r
4 * library of uniform random number generators.\r
5 *\r
6 * Overview of classes:\r
7 * ====================\r
8 *\r
9 * class CRandomMersenne:\r
10 * Random number generator of type Mersenne twister.\r
11 * Source file mersenne.cpp\r
12 *\r
13 * class CRandomMother:\r
14 * Random number generator of type Mother-of-All (Multiply with carry).\r
15 * Source file mother.cpp\r
16 *\r
17 *\r
18 * Member functions (methods):\r
19 * ===========================\r
20 *\r
21 * All these classes have identical member functions:\r
22 *\r
23 * Constructor(uint32 seed):\r
24 * The seed can be any integer. Usually the time is used as seed.\r
25 * Executing a program twice with the same seed will give the same sequence of\r
26 * random numbers. A different seed will give a different sequence.\r
27 *\r
28 * void RandomInit(uint32 seed);\r
29 * Re-initializes the random number generator with a new seed.\r
30 *\r
31 * void RandomInitByArray(uint32 seeds[], int length);\r
32 * In CRandomMersenne only: Use this function if you want to initialize with\r
33 * a seed with more than 32 bits. All bits in the seeds[] array will influence\r
34 * the sequence of random numbers generated. length is the number of entries\r
35 * in the seeds[] array.\r
36 *\r
37 * double Random();\r
38 * Gives a floating point random number in the interval 0 <= x < 1.\r
39 * The resolution is 32 bits in CRandomMother and CRandomMersenne.\r
40 *\r
41 * int IRandom(int min, int max);\r
42 * Gives an integer random number in the interval min <= x <= max.\r
43 * (max-min < MAXINT).\r
44 * The precision is 2^-32 (defined as the difference in frequency between \r
45 * possible output values). The frequencies are exact if max-min+1 is a\r
46 * power of 2.\r
47 *\r
48 * int IRandomX(int min, int max);\r
49 * Same as IRandom, but exact. In CRandomMersenne only.\r
50 * The frequencies of all output values are exactly the same for an \r
51 * infinitely long sequence. (Only relevant for extremely long sequences).\r
52 *\r
53 * uint32 BRandom();\r
54 * Gives 32 random bits. \r
55 *\r
56 *\r
57 * Example:\r
58 * ========\r
59 * The file EX-RAN.CPP contains an example of how to generate random numbers.\r
60 *\r
61 *\r
62 * Optimized version:\r
63 * ==================\r
64 * Faster versions of these random number generators are provided as function\r
65 * libraries in asmlib.zip. These function libraries are coded in assembly\r
66 * language and support only x86 platforms, including 32-bit and 64-bit\r
67 * Windows, Linux, BSD, Mac OS-X (Intel based). Use asmlibran.h from asmlib.zip\r
68 *\r
69 *\r
70 * Non-uniform random number generators:\r
71 * =====================================\r
72 * Random number generators with various non-uniform distributions are available\r
73 * in stocc.zip (www.agner.org/random).\r
74 *\r
75 *\r
76 * Further documentation:\r
77 * ======================\r
78 * The file randomc.htm contains further documentation on these random number\r
79 * generators.\r
80 *\r
81 *\r
82 * Copyright:\r
83 ============\r
84 * © 1997 - 2007 Agner Fog. All software in this library is published under the\r
85 * GNU General Public License with the further restriction that it cannot be \r
86 * used for gambling applications. See licence.htm\r
87 *******************************************************************************/\r
88 \r
89 #ifndef RANDOMC_H\r
90 #define RANDOMC_H\r
91 \r
92 \r
93 // Define 32 bit signed and unsigned integers.\r
94 // Change these definitions, if necessary, to match a particular platform\r
95 #if defined(_WIN16) || defined(__MSDOS__) || defined(_MSDOS) \r
96    // 16 bit systems use long int for 32 bit integer\r
97    typedef long int           int32;   // 32 bit signed integer\r
98    typedef unsigned long int  uint32;  // 32 bit unsigned integer\r
99 #else\r
100    // Most other systems use int for 32 bit integer\r
101    typedef int                int32;   // 32 bit signed integer\r
102    typedef unsigned int       uint32;  // 32 bit unsigned integer\r
103 #endif\r
104 \r
105 // Define 64 bit signed and unsigned integers, if possible\r
106 #if (defined(__WINDOWS__) || defined(_WIN32)) && (defined(_MSC_VER) || defined(__INTEL_COMPILER))\r
107    // Microsoft and other compilers under Windows use __int64\r
108    typedef __int64            int64;   // 64 bit signed integer\r
109    typedef unsigned __int64   uint64;  // 64 bit unsigned integer\r
110    #define INT64_DEFINED               // Remember that int64 is defined\r
111 #elif defined(__unix__) && (defined(_M_IX86) || defined(_M_X64))\r
112    // Gnu and other compilers under Linux etc. use long long\r
113    typedef long long          int64;   // 64 bit signed integer\r
114    typedef unsigned long long uint64;  // 64 bit unsigned integer\r
115    #define INT64_DEFINED               // Remember that int64 is defined\r
116 #else\r
117    // 64 bit integers not defined\r
118    // You may include definitions for other platforms here\r
119 #endif\r
120 \r
121 \r
122 /***********************************************************************\r
123 System-specific user interface functions\r
124 ***********************************************************************/\r
125 \r
126 void EndOfProgram(void);               // System-specific exit code (userintf.cpp)\r
127 \r
128 void FatalError(char * ErrorText);     // System-specific error reporting (userintf.cpp)\r
129 \r
130 \r
131 /***********************************************************************\r
132 Define random number generator classes\r
133 ***********************************************************************/\r
134 \r
135 class CRandomMersenne {                // Encapsulate random number generator\r
136 #if 0\r
137    // Define constants for type MT11213A:\r
138 #define MERS_N   351\r
139 #define MERS_M   175\r
140 #define MERS_R   19\r
141 #define MERS_U   11\r
142 #define MERS_S   7\r
143 #define MERS_T   15\r
144 #define MERS_L   17\r
145 #define MERS_A   0xE4BD75F5\r
146 #define MERS_B   0x655E5280\r
147 #define MERS_C   0xFFD58000\r
148 #else    \r
149    // or constants for type MT19937:\r
150 #define MERS_N   624\r
151 #define MERS_M   397\r
152 #define MERS_R   31\r
153 #define MERS_U   11\r
154 #define MERS_S   7\r
155 #define MERS_T   15\r
156 #define MERS_L   18\r
157 #define MERS_A   0x9908B0DF\r
158 #define MERS_B   0x9D2C5680\r
159 #define MERS_C   0xEFC60000\r
160 #endif\r
161 public:\r
162    CRandomMersenne(uint32 seed) {      // Constructor\r
163       RandomInit(seed); LastInterval = 0;}\r
164    void RandomInit(uint32 seed);       // Re-seed\r
165    void RandomInitByArray(uint32 seeds[], int length); // Seed by more than 32 bits\r
166    int IRandom (int min, int max);     // Output random integer\r
167    int IRandomX(int min, int max);     // Output random integer, exact\r
168    double Random();                    // Output random float\r
169    uint32 BRandom();                   // Output random bits\r
170 private:\r
171    void Init0(uint32 seed);            // Basic initialization procedure\r
172    uint32 mt[MERS_N];                  // State vector\r
173    int mti;                            // Index into mt\r
174    uint32 LastInterval;                // Last interval length for IRandomX\r
175    uint32 RLimit;                      // Rejection limit used by IRandomX\r
176    enum TArch {LITTLE_ENDIAN1, BIG_ENDIAN1, NONIEEE}; // Definition of architecture\r
177    TArch Architecture;                 // Conversion to float depends on architecture\r
178 };    \r
179 \r
180 \r
181 class CRandomMother {             // Encapsulate random number generator\r
182 public:\r
183    void RandomInit(uint32 seed);       // Initialization\r
184    int IRandom(int min, int max);      // Get integer random number in desired interval\r
185    double Random();                    // Get floating point random number\r
186    uint32 BRandom();                   // Output random bits\r
187    CRandomMother(uint32 seed) {   // Constructor\r
188       RandomInit(seed);}\r
189 protected:\r
190    uint32 x[5];                        // History buffer\r
191 };\r
192 \r
193 #endif\r