core/vnl/vnl_random.h
Go to the documentation of this file.
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