00001 #include "RandomEngine.h"
00002 #include "RandomDistribution.h"
00003 #include "PCSIMException.h"
00004
00005
00006
00007
00008
00009
00010
00011 shared_ptr< std::vector<double> > RandomDistribution::operator()(RandomEngine &eng, size_t n )
00012 {
00013 shared_ptr< std::vector<double> > v( new std::vector<double>(n) );
00014 for( size_t i=0; i<n; i++ ) {
00015 (*v)[i] = (*this)( eng );
00016 }
00017 return v;
00018 }
00019
00020 double UniformIntegerDistribution::get( RandomEngine &eng )
00021 {
00022 return a + eng() * range;
00023 }
00024
00025 ClippedDistribution::ClippedDistribution( RandomDistribution const& dist, double a, double b, size_t n ) :
00026 dist(NULL), a(a), b(b), n(n)
00027 {
00028 this->dist = dist.clone();
00029 range = b-a;
00030 if( range <= 0 ) {
00031 throw( PCSIM::Exception( "ClippedDistribution", "Invalid bounderies." ) );
00032 }
00033 }
00034
00035 ClippedDistribution::~ClippedDistribution()
00036 {
00037 if( dist ) delete dist;
00038 }
00039
00040 double ClippedDistribution::get( RandomEngine &eng )
00041 {
00042 double v = (*dist)( eng );
00043 size_t c = 1;
00044 bool invalid = v < a || v > b;
00045 while( c < n && invalid ) {
00046 v = (*dist)( eng );
00047 invalid = v < a || v > b;
00048 c++;
00049 }
00050 if( invalid ) {
00051 v = a + eng() * range;
00052 }
00053 return v;
00054 }
00055
00056
00057 Gamma2Distribution::Gamma2Distribution(double a, double b)
00058 :GammaDistribution(a), a(a), b(b)
00059 {
00060 }
00061
00062
00063 double Gamma2Distribution::get( RandomEngine &eng )
00064 {
00065 return GammaDistribution::get(eng)*b;
00066 }
00067
00068
00069
00070
00071 BndGammaDistribution::BndGammaDistribution(double mu, double cv, double upperBound)
00072 :Gamma2Distribution(1/(cv*cv), fabs(mu*cv*cv)), mu(mu), cv(cv), ub(upperBound)
00073 {
00074 }
00075
00076
00077 double BndGammaDistribution::get( RandomEngine &eng )
00078 {
00079 if(mu == 0.0 || cv <= 0.0)
00080 return mu;
00081
00082 double v=Gamma2Distribution::get(eng);
00083 double lb=0;
00084
00085 if (v > ub) {
00086 double maxd = std::min(std::min(mu-lb, ub-mu), fabs(5*cv*mu));
00087 double clb = mu-maxd;
00088 double cub = mu+maxd;
00089
00090 v = clb + fabs(cub-clb)*uniform.get(eng);
00091 }
00092
00093 return v;
00094 }
00095
00096
00097 BndNormalDistribution::BndNormalDistribution(double mu, double cv, double lowerBound, double upperBound)
00098 :NormalDistribution(mu, fabs(cv*mu)), mu(mu), cv(cv), lb(lowerBound), ub(upperBound)
00099 {
00100 }
00101
00102
00103 double BndNormalDistribution::get( RandomEngine &eng )
00104 {
00105 if(mu == 0.0 || cv <= 0.0)
00106 return mu;
00107
00108 double v=NormalDistribution::get(eng);
00109
00110 if (v < lb || v > ub) {
00111 double maxd = std::min(std::min(mu-lb,ub-mu), fabs(5*cv*mu));
00112 double clb = mu-maxd;
00113 double cub = mu+maxd;
00114
00115 v = clb + fabs(cub-clb)*uniform.get(eng);
00116 }
00117
00118
00119 return v;
00120 }
00121
00122
00123 QuadDistribution::QuadDistribution(double a, double b)
00124 :UniformDistribution(0,1), a(a), b(b)
00125 {
00126 }
00127
00128
00129 double QuadDistribution::get( RandomEngine &eng )
00130 {
00131 double v=UniformDistribution::get(eng);
00132
00133 return a + b*v*v;
00134 }
00135
00136
00137 double foo(void)
00138 {
00139 MersenneTwister19937 mt;
00140 mt.seed( 1234 );
00141 double x = mt();
00142
00143 MersenneTwister11213b mt2;
00144 mt2.seed( 12345 );
00145 x = mt2();
00146
00147 LaggedFibonacci4423 lf;
00148 lf.seed( 3456 );
00149 x = lf();
00150
00151 BernoulliDistribution bd;
00152 x = bd( mt2 );
00153
00154 BinomialDistribution bind;
00155 x = bind( lf );
00156
00157 CauchyDistribution cd;
00158 x = cd( lf );
00159 x = cd( mt2 );
00160
00161 ConstantNumber cn( 4 );
00162 x = cn( lf );
00163
00164 ExponentialDistribution ed( 2.3 );
00165 x = ed( lf );
00166
00167 GammaDistribution ad( 3.4 );
00168 x = ad( mt2 );
00169
00170 LogNormalDistribution lnd( 4, 5 );
00171 x = lnd( lf );
00172
00173 NormalDistribution nd( 1, 2);
00174 x = nd( mt );
00175
00176 PoissonDistribution pd( 10 );
00177 x = pd( mt );
00178
00179 TriangleDistribution td( 1, 2, 3 );
00180 x= td( lf );
00181
00182 UniformDistribution cud( 3, 4 );
00183 x = cud( mt );
00184
00185 UniformIntegerDistribution iud( 1, 100 );
00186 x = iud( lf );
00187
00188 return x;
00189 }