00001 // This is core/vnl/vnl_random.h 00002 #ifndef vnl_random_h 00003 #define vnl_random_h 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \author Aaron Kotcheff (Manchester) 00010 // \brief A superior random number generator 00011 00012 const unsigned int vnl_random_array_size = 37; 00013 00014 //: A superior random number generator. 00015 // Implements a new random number generator that 00016 // recently appeared in the literature. It generates 32 bit 00017 // numbers with a higher degree of randomness than previous 00018 // generators and has a cycle of 10^354 i.e. so huge that in 00019 // practice it never cycles. 00020 // For the mathematics behind it see: 00021 // "A New Class of Random Number Generators" G. Marsaglia and A. Zaman, 00022 // Annals of Applied Probability 1991, Vol. 1, No. 3, 462. 00023 class vnl_random 00024 { 00025 enum {linear_congruential_multiplier = 1664525, mz_previous1 = 24}; 00026 unsigned long linear_congruential_previous; 00027 unsigned long mz_seed_array[vnl_random_array_size]; 00028 unsigned long mz_array[vnl_random_array_size]; 00029 unsigned int mz_array_position; 00030 int mz_borrow; 00031 unsigned long linear_congruential_lrand32(); 00032 00033 double mz_previous_normal; 00034 int mz_previous_normal_flag; 00035 00036 public: 00037 //: Default constructor. 00038 // Initializes the random number generator non-deterministically. 00039 // i.e. it will generate a different series of random numbers each 00040 // time the program is run. 00041 vnl_random(); 00042 00043 //: Destructor 00044 ~vnl_random(); 00045 00046 //: Construct with seed. 00047 // Initializes the random number generator deterministically 00048 // using a single ulong as the 'seed'. A linear congruential 00049 // generator is used to generate the 37 ulongs needed 00050 // as the real seed. The same seed will produce the 00051 // same series of random numbers. 00052 // 00053 // 9667566 is a good seed. 00054 vnl_random(unsigned long seed); 00055 00056 //: Construct with seed. 00057 // Initializes the random number generator deterministically 00058 // using 37 ulongs as the 'seed'. The same seed will 00059 // produce the same series of random numbers. 00060 vnl_random(unsigned long seed[vnl_random_array_size]); 00061 00062 //: Copy constructor. 00063 // Initializes/sets the random number generator to exactly 00064 // the same state as the argument, i.e. both will generate exactly 00065 // the same series of random numbers from then on. 00066 vnl_random(const vnl_random&); 00067 00068 //: Copy operator. 00069 // Initializes/sets the random number generator to exactly 00070 // the same state as the argument, i.e. both will generate exactly 00071 // the same series of random numbers from then on. 00072 vnl_random& operator=(const vnl_random&); 00073 00074 //: Starts a new non-deterministic sequence from an already declared generator. 00075 void reseed(); 00076 00077 //: Starts a new deterministic sequence from an already declared generator using the provided seed. 00078 void reseed(unsigned long); 00079 00080 //: Starts a new deterministic sequence from an already declared generator using the provided seed. 00081 void reseed(unsigned long[vnl_random_array_size]); 00082 00083 //: This restarts the sequence of random numbers. 00084 // Restarts so that it repeats 00085 // from the point at which you declared the generator, last 00086 // initialized it, or last called a 'reseed'. 00087 void restart(); 00088 00089 //: Generates a random unsigned 32-bit number. 00090 unsigned long lrand32(); 00091 00092 //: Generates a random unsigned long in [a,b] 00093 int lrand32(int a, int b); 00094 00095 //: Generates a random unsigned long in [0,b] 00096 int lrand32(int b) {return lrand32(0, b);} 00097 00098 //: Generates a random unsigned long in [a,b] 00099 int lrand32(int a, int b, int&); 00100 00101 //: Generates a random double in the range a <= x <= b with 32 bit randomness. 00102 // drand32(1,0) is random down to about the 10th decimal place. 00103 double drand32(double a, double b); 00104 00105 //: Generates a random unsigned integer in [0,n) 00106 // This function allows the random number generator to be used as 00107 // a functor, e.g. with vcl_random_shuffle() 00108 unsigned long operator()(unsigned n) { return lrand32(0, n-1); } 00109 00110 //: Generates a random double in the range 0 <= x <= b with 32 bit randomness. 00111 // drand32(1.0) is random down to about the 10th decimal place. 00112 double drand32(double b) {return drand32(0.0, b);} 00113 00114 //: Generates a random double in the range 0 <= x <= 1 with 32 bit randomness. 00115 // drand32() is random down to about the 10th decimal place. 00116 double drand32() {return drand32(0.0, 1.0);} 00117 00118 //: Generates a random double in the range a <= x <= b with 64 bit randomness. 00119 // Completely random down to the accuracy of an IEEE double. 00120 double drand64(double a, double b); 00121 00122 //: Generates a random double in the range 0 <= x <= b with 64 bit randomness. 00123 // Completely random down to the accuracy of an IEEE double. 00124 double drand64(double b) {return drand64(0.0, b);} 00125 00126 //: Generates a random double in the range 0 <= x <= 1 with 64 bit randomness. 00127 // Completely random down to the accuracy of an IEEE double. 00128 double drand64() {return drand64(0.0, 1.0);} 00129 00130 //: Random value from a unit normal distribution about zero. 00131 // Uses a drand32() as its underlying generator. 00132 // Because the function uses a probability transform, the randomness (and 00133 // quantisation) is non-linearly dependent on the value. The further the 00134 // sample is from zero, the lower the number of bits on which it is random. 00135 double normal(); 00136 00137 //: Random value from a unit normal distribution about zero. 00138 // Uses a drand64() as its underlying generator. 00139 // Because the function uses a probability transform, the randomness (and 00140 // quantisation) is non-linearly dependent on the value. The further the 00141 // sample is from zero, the lower the number of bits on which it is random. 00142 double normal64(); 00143 }; 00144 00145 #endif // vnl_random_h