RandomNumberGenerator.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "Exception.hpp"
00037 #include "RandomNumberGenerator.hpp"
00038
00039 RandomNumberGenerator* RandomNumberGenerator::mpInstance = NULL;
00040
00041 RandomNumberGenerator::RandomNumberGenerator()
00042 : mMersenneTwisterGenerator(0u),
00043 mGenerateUnitReal(mMersenneTwisterGenerator, boost::uniform_real<>()),
00044 #if BOOST_VERSION < 105600
00045 mGenerateStandardNormal(mMersenneTwisterGenerator, boost::random::normal_distribution_v156<>(mMersenneTwisterGenerator, 0.0, 1.0))
00046 #else
00047 mGenerateStandardNormal(mMersenneTwisterGenerator, boost::normal_distribution<>(0.0, 1.0))
00048 #endif
00049 {
00050 assert(mpInstance == NULL);
00051 }
00052
00053 RandomNumberGenerator* RandomNumberGenerator::Instance()
00054 {
00055 if (mpInstance == NULL)
00056 {
00057 mpInstance = new RandomNumberGenerator();
00058 }
00059 return mpInstance;
00060 }
00061
00062 void RandomNumberGenerator::Destroy()
00063 {
00064 if (mpInstance)
00065 {
00066 delete mpInstance;
00067 mpInstance = NULL;
00068 }
00069 }
00070
00071 unsigned RandomNumberGenerator::randMod(unsigned base)
00072 {
00073 assert(base > 0u);
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 #if BOOST_VERSION < 103700
00086 unsigned base_range =(mMersenneTwisterGenerator.max)() - (mMersenneTwisterGenerator.min)();
00087 unsigned val = mMersenneTwisterGenerator() - (mMersenneTwisterGenerator.min)();
00088 #else
00089
00090
00091 unsigned base_range =
00092 boost::random::detail::subtract<unsigned>()((mMersenneTwisterGenerator.max)(), (mMersenneTwisterGenerator.min)());
00093 unsigned val =
00094 boost::random::detail::subtract<unsigned>()(mMersenneTwisterGenerator(), (mMersenneTwisterGenerator.min)());
00095 #endif
00096
00097 if (base - 1u >= base_range)
00098 {
00099
00100
00101 NEVER_REACHED;
00102
00103 }
00104 else
00105 {
00106 return (val % base);
00107 }
00108 }
00109
00110 double RandomNumberGenerator::ranf()
00111 {
00112 return mGenerateUnitReal();
00113 }
00114
00115 double RandomNumberGenerator::StandardNormalRandomDeviate()
00116 {
00117 return mGenerateStandardNormal();
00118 }
00119
00120 double RandomNumberGenerator::NormalRandomDeviate(double mean, double stdDev)
00121 {
00122 return stdDev * StandardNormalRandomDeviate() + mean;
00123 }
00124
00125 double RandomNumberGenerator::GammaRandomDeviate(double shape, double scale)
00126 {
00127 boost::gamma_distribution<> gd(shape);
00128 boost::variate_generator<boost::mt19937& , boost::gamma_distribution<> > var_gamma(mMersenneTwisterGenerator, gd);
00129
00130 return scale*var_gamma();
00131 }
00132
00133 double RandomNumberGenerator::ExponentialRandomDeviate(double scale)
00134 {
00135
00136 boost::exponential_distribution<> ed(scale);
00137
00138
00139 boost::variate_generator<boost::mt19937& , boost::exponential_distribution<> > var_exponential(mMersenneTwisterGenerator, ed);
00140
00141
00142 return var_exponential();
00143 }
00144
00145 void RandomNumberGenerator::Reseed(unsigned seed)
00146 {
00147 mMersenneTwisterGenerator.seed(seed);
00148
00149
00150 mGenerateStandardNormal.distribution().reset();
00151
00152
00153 mGenerateUnitReal.distribution().reset();
00154 }
00155
00156 void RandomNumberGenerator::Shuffle(unsigned num, std::vector<unsigned>& rValues)
00157 {
00158 rValues.resize(num);
00159 for (unsigned i=0; i<num; i++)
00160 {
00161 rValues[i] = i;
00162 }
00163
00164 for (unsigned end=num-1; end>0; end--)
00165 {
00166
00167 unsigned k = RandomNumberGenerator::Instance()->randMod(end+1);
00168 unsigned temp = rValues[end];
00169 rValues[end] = rValues[k];
00170 rValues[k] = temp;
00171 }
00172 }