00001 #ifndef INDII_ML_AUX_RANDOM_HPP 00002 #define INDII_ML_AUX_RANDOM_HPP 00003 00004 #include "vector.hpp" 00005 #include "matrix.hpp" 00006 00007 #include <gsl/gsl_errno.h> 00008 #include <gsl/gsl_randist.h> 00009 00010 namespace indii { 00011 namespace ml { 00012 namespace aux { 00013 /** 00014 * %Random numbers. 00015 * 00016 * @author Lawrence Murray <lawrence@indii.org> 00017 * @version $Rev: 471 $ 00018 * @date $Date: 2008-05-30 14:21:19 +0100 (Fri, 30 May 2008) $ 00019 * 00020 * This class makes use of the random number generation features of 00021 * the @ref GSL "GSL", in particular making use of the MT19937 00022 * generator of @ref Matsumoto1998 "Matsumoto & Nishimura (1998)". If 00023 * not explicitly seeded, it is seeded with the current time as 00024 * returned by the system's time() function the first time one of the 00025 * provided functions is called. 00026 * 00027 * More information on the implementation of this random number 00028 * generator is available in the GSL manual. 00029 * 00030 * @section Random_references References 00031 * 00032 * @anchor GSL 00033 * The GNU Scientific Library (GSL). http://www.gnu.org/software/gsl/ 00034 * 00035 * @anchor Matsumoto1998 Matsumoto, M. and Nishimura, 00036 * T. Mersenne Twister: A 623-dimensionally equidistributed 00037 * uniform pseudorandom number generator. <i>ACM Transactions on 00038 * Modeling and Computer Simulation</i>, <b>1998</b>, 8, 3-30. 00039 */ 00040 class Random { 00041 public: 00042 /** 00043 * Seed the random number generator. 00044 * 00045 * @param seed Seed value. 00046 * 00047 * Seeds the random number generator for future use using the given 00048 * seed value. If not explicitly seeded, the generator is seeded 00049 * with the current time the first time it is used. 00050 */ 00051 static void seed(unsigned int seed); 00052 00053 /** 00054 * Generate a random number from a uniform distribution over the 00055 * given interval. 00056 * 00057 * @param lower Lower bound on the interval. 00058 * @param upper Upper bound on the interval. 00059 * 00060 * @return The random number. 00061 */ 00062 static double uniform(const double lower = 0.0, const double upper = 1.0); 00063 00064 /** 00065 * Generate a random number from a Gaussian distribution with the 00066 * given mean and standard deviation. 00067 * 00068 * @param mean Mean of the distribution. 00069 * @param sigma Standard deviation of the distribution. 00070 * 00071 * @return The random number. 00072 */ 00073 static double gaussian(const double mean = 0.0, const double sigma = 1.0); 00074 00075 /** 00076 * Generate a boolean value from a Bernoulli distribution. 00077 * 00078 * @param p Probability of true, between 0 and 1 inclusive. 00079 * 00080 * @return The random boolean value, 1 for true, 0 for false. 00081 */ 00082 static unsigned int bernoulli(const double p = 0.5); 00083 00084 /** 00085 * Generate a random unit vector. 00086 * 00087 * @param N Size of unit vector. 00088 * 00089 * @return Random unit vector in @p N dimensions. 00090 */ 00091 static vector unitVector(const unsigned int N); 00092 00093 /** 00094 * Generate a random orthonormal matrix. 00095 * 00096 * @param N Size of matrix. 00097 * 00098 * @return Random @p N by @p N orthonormal matrix. 00099 */ 00100 static matrix orthonormalMatrix(const unsigned int N); 00101 00102 private: 00103 /** 00104 * Is random number generator initialised? 00105 */ 00106 static bool isInit; 00107 00108 /** 00109 * Random number generator. 00110 */ 00111 static gsl_rng* rng; 00112 00113 /** 00114 * Initialise random number generator. 00115 */ 00116 static void init(); 00117 00118 /** 00119 * Terminate random number generator. 00120 */ 00121 static void terminate(); 00122 00123 }; 00124 00125 } 00126 } 00127 } 00128 00129 inline double indii::ml::aux::Random::uniform(const double lower, 00130 const double upper) { 00131 if (!isInit) { 00132 init(); 00133 } 00134 return gsl_ran_flat(rng, lower, upper); 00135 } 00136 00137 inline double indii::ml::aux::Random::gaussian(const double mean, 00138 const double sigma) { 00139 if (!isInit) { 00140 init(); 00141 } 00142 return (sigma == 0.0) ? mean : mean + gsl_ran_gaussian(rng, sigma); 00143 } 00144 00145 inline unsigned int indii::ml::aux::Random::bernoulli(const double p) { 00146 /* pre-condition */ 00147 assert (p >= 0.0 && p <= 1.0); 00148 00149 if (!isInit) { 00150 init(); 00151 } 00152 return gsl_ran_bernoulli(rng, p); 00153 } 00154 00155 #endif 00156
1.5.3