ThreeB 1.1
randomc.h
Go to the documentation of this file.
00001 /*
00002     This file is part of B-cubed.
00003 
00004     Copyright (C) 2009, 2010, 2011, Edward Rosten and Susan Cox
00005 
00006     B-cubed is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 3.0 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License     
00017     along with this program.  If not, see <http://www.gnu.org/licenses/>
00018 */
00019 
00020 /*****************************   randomc.h   **********************************
00021 * Author:        Agner Fog
00022 * Date created:  1997
00023 * Last modified: 2008-11-16
00024 * Project:       randomc.h
00025 * Source URL:    www.agner.org/random
00026 *
00027 * Description:
00028 * This header file contains class declarations and other definitions for the 
00029 * randomc class library of uniform random number generators in C++ language.
00030 *
00031 * Overview of classes:
00032 * ====================
00033 *
00034 * class CRandomMersenne:
00035 * Random number generator of type Mersenne twister.
00036 * Source file mersenne.cpp
00037 *
00038 * class CRandomMother:
00039 * Random number generator of type Mother-of-All (Multiply with carry).
00040 * Source file mother.cpp
00041 *
00042 * class CRandomSFMT:
00043 * Random number generator of type SIMD-oriented Fast Mersenne Twister.
00044 * The class definition is not included here because it is not
00045 * portable to all platforms. See sfmt.h and sfmt.cpp for details.
00046 *
00047 * Member functions (methods):
00048 * ===========================
00049 *
00050 * All these classes have identical member functions:
00051 *
00052 * Constructor(int seed):
00053 * The seed can be any integer. The time may be used as seed.
00054 * Executing a program twice with the same seed will give the same sequence 
00055 * of random numbers. A different seed will give a different sequence.
00056 *
00057 * void RandomInit(int seed);
00058 * Re-initializes the random number generator with a new seed.
00059 *
00060 * void RandomInitByArray(int const seeds[], int NumSeeds);
00061 * In CRandomMersenne and CRandomSFMT only: Use this function if you want 
00062 * to initialize with a seed with more than 32 bits. All bits in the seeds[]
00063 * array will influence the sequence of random numbers generated. NumSeeds 
00064 * is the number of entries in the seeds[] array.
00065 *
00066 * double Random();
00067 * Gives a floating point random number in the interval 0 <= x < 1.
00068 * The resolution is 32 bits in CRandomMother and CRandomMersenne, and
00069 * 52 bits in CRandomSFMT.
00070 *
00071 * int IRandom(int min, int max);
00072 * Gives an integer random number in the interval min <= x <= max.
00073 * (max-min < MAXINT).
00074 * The precision is 2^-32 (defined as the difference in frequency between 
00075 * possible output values). The frequencies are exact if max-min+1 is a
00076 * power of 2.
00077 *
00078 * int IRandomX(int min, int max);
00079 * Same as IRandom, but exact. In CRandomMersenne and CRandomSFMT only.
00080 * The frequencies of all output values are exactly the same for an 
00081 * infinitely long sequence. (Only relevant for extremely long sequences).
00082 *
00083 * uint32_t BRandom();
00084 * Gives 32 random bits. 
00085 *
00086 *
00087 * Example:
00088 * ========
00089 * The file EX-RAN.CPP contains an example of how to generate random numbers.
00090 *
00091 *
00092 * Library version:
00093 * ================
00094 * Optimized versions of these random number generators are provided as function
00095 * libraries in randoma.zip. These function libraries are coded in assembly
00096 * language and support only x86 platforms, including 32-bit and 64-bit
00097 * Windows, Linux, BSD, Mac OS-X (Intel based). Use randoma.h from randoma.zip
00098 *
00099 *
00100 * Non-uniform random number generators:
00101 * =====================================
00102 * Random number generators with various non-uniform distributions are 
00103 * available in stocc.zip (www.agner.org/random).
00104 *
00105 *
00106 * Further documentation:
00107 * ======================
00108 * The file ran-instructions.pdf contains further documentation and 
00109 * instructions for these random number generators.
00110 *
00111 * Copyright 1997-2008 by Agner Fog. 
00112 * GNU General Public License http://www.gnu.org/licenses/gpl.html
00113 *******************************************************************************/
00114 
00115 #ifndef RANDOMC_H
00116 #define RANDOMC_H
00117 
00118 // Define integer types with known size: int32_t, uint32_t, int64_t, uint64_t.
00119 // If this doesn't work then insert compiler-specific definitions here:
00120 #if defined(__GNUC__)
00121   // Compilers supporting C99 or C++0x have inttypes.h defining these integer types
00122   #include <inttypes.h>
00123   #define INT64_SUPPORTED // Remove this if the compiler doesn't support 64-bit integers
00124 #elif defined(_WIN16) || defined(__MSDOS__) || defined(_MSDOS) 
00125    // 16 bit systems use long int for 32 bit integer
00126   typedef   signed long int int32_t;
00127   typedef unsigned long int uint32_t;
00128 #elif defined(_MSC_VER)
00129   // Microsoft have their own definition
00130   typedef   signed __int32  int32_t;
00131   typedef unsigned __int32 uint32_t;
00132   typedef   signed __int64  int64_t;
00133   typedef unsigned __int64 uint64_t;
00134   #define INT64_SUPPORTED // Remove this if the compiler doesn't support 64-bit integers
00135 #else
00136   // This works with most compilers
00137   typedef signed int          int32_t;
00138   typedef unsigned int       uint32_t;
00139   typedef long long           int64_t;
00140   typedef unsigned long long uint64_t;
00141   #define INT64_SUPPORTED // Remove this if the compiler doesn't support 64-bit integers
00142 #endif
00143 
00144 
00145 /***********************************************************************
00146 System-specific user interface functions
00147 ***********************************************************************/
00148 
00149 void EndOfProgram(void);               // System-specific exit code (userintf.cpp)
00150 
00151 void FatalError(const char *ErrorText);// System-specific error reporting (userintf.cpp)
00152 
00153 #if defined(__cplusplus)               // class definitions only in C++
00154 /***********************************************************************
00155 Define random number generator classes
00156 ***********************************************************************/
00157 
00158 class CRandomMersenne {                // Encapsulate random number generator
00159 // Choose which version of Mersenne Twister you want:
00160 #if 0 
00161 // Define constants for type MT11213A:
00162 #define MERS_N   351
00163 #define MERS_M   175
00164 #define MERS_R   19
00165 #define MERS_U   11
00166 #define MERS_S   7
00167 #define MERS_T   15
00168 #define MERS_L   17
00169 #define MERS_A   0xE4BD75F5
00170 #define MERS_B   0x655E5280
00171 #define MERS_C   0xFFD58000
00172 #else    
00173 // or constants for type MT19937:
00174 #define MERS_N   624
00175 #define MERS_M   397
00176 #define MERS_R   31
00177 #define MERS_U   11
00178 #define MERS_S   7
00179 #define MERS_T   15
00180 #define MERS_L   18
00181 #define MERS_A   0x9908B0DF
00182 #define MERS_B   0x9D2C5680
00183 #define MERS_C   0xEFC60000
00184 #endif
00185 
00186 public:
00187    CRandomMersenne(int seed) {         // Constructor
00188       RandomInit(seed); LastInterval = 0;}
00189    void RandomInit(int seed);          // Re-seed
00190    void RandomInitByArray(int const seeds[], int NumSeeds); // Seed by more than 32 bits
00191    int IRandom (int min, int max);     // Output random integer
00192    int IRandomX(int min, int max);     // Output random integer, exact
00193    double Random();                    // Output random float
00194    uint32_t BRandom();                 // Output random bits
00195 
00196    uint32_t* get_state()
00197    {
00198         return mt;
00199    }
00200 
00201    int& get_index()
00202    {
00203         return mti;
00204    }
00205 private:
00206    void Init0(int seed);               // Basic initialization procedure
00207    uint32_t mt[MERS_N];                // State vector
00208    int mti;                            // Index into mt
00209    uint32_t LastInterval;              // Last interval length for IRandomX
00210    uint32_t RLimit;                    // Rejection limit used by IRandomX
00211 };    
00212 
00213 
00214 class CRandomMother {                  // Encapsulate random number generator
00215 public:
00216    void RandomInit(int seed);          // Initialization
00217    int IRandom(int min, int max);      // Get integer random number in desired interval
00218    double Random();                    // Get floating point random number
00219    uint32_t BRandom();                 // Output random bits
00220    CRandomMother(int seed) {           // Constructor
00221       RandomInit(seed);}
00222 protected:
00223    uint32_t x[5];                      // History buffer
00224 };
00225 
00226 #endif // __cplusplus
00227 #endif // RANDOMC_H