00001
00002
00003
00004 #include "SdlArs.h"
00005
00006
00007 #define WANT_MATH
00008 #include "include.h"
00009
00010 #include "newran.h"
00011
00012 #ifdef use_namespace
00013 namespace NEWRAN {
00014 #endif
00015
00016
00017
00018
00019
00020 class ChiSq1 : public Normal
00021
00022 {
00023 Real deltasq;
00024 Real delta;
00025
00026 public:
00027 ChiSq1(Real);
00028 ExtReal Mean() const { return 1.0+deltasq; }
00029 ExtReal Variance() const { return 2.0+4.0*deltasq; }
00030 Real Next();
00031 };
00032
00033
00034
00035 class Poisson1 : public AsymGen
00036 {
00037 Real mu, ln_mu;
00038 public:
00039 Poisson1(Real);
00040 Real Density(Real) const;
00041 Real Next() { return floor(AsymGen::Next()); }
00042 ExtReal Mean() const { return mu; }
00043 ExtReal Variance() const { return mu; }
00044 };
00045
00046
00047
00048 class Poisson2 : public Random
00049 {
00050 DiscreteGen* dg;
00051 public:
00052 Poisson2(Real);
00053 ~Poisson2();
00054 Real Next() { return dg->Next(); }
00055 ExtReal Mean() const { return dg->Mean(); }
00056 ExtReal Variance() const { return dg->Variance(); }
00057 };
00058
00059
00060
00061 class Gamma1 : public PosGen
00062
00063 {
00064 Real ln_gam, ralpha, alpha;
00065 public:
00066 Gamma1(Real);
00067 Real Density(Real) const;
00068 Real Next();
00069 ExtReal Mean() const { return alpha; }
00070 ExtReal Variance() const { return alpha; }
00071 };
00072
00073
00074
00075 class Gamma2 : public AsymGen
00076
00077 {
00078 Real alpha, ln_gam;
00079 public:
00080 Gamma2(Real);
00081 Real Density(Real) const;
00082 ExtReal Mean() const { return alpha; }
00083 ExtReal Variance() const { return alpha; }
00084 };
00085
00086
00087
00088 class Binomial1 : public AsymGen
00089 {
00090 Real p, q, ln_p, ln_q, ln_n_fac; int n;
00091 public:
00092 Binomial1(int nx, Real px);
00093 Real Density(Real) const;
00094 Real Next() { return floor(AsymGen::Next()); }
00095 ExtReal Mean() const { return p * n; }
00096 ExtReal Variance() const { return p * q * n; }
00097 };
00098
00099
00100
00101 class Binomial2 : public Random
00102 {
00103 DiscreteGen* dg;
00104 public:
00105 Binomial2(int nx, Real px);
00106 ~Binomial2();
00107 Real Next() { return dg->Next(); }
00108 ExtReal Mean() const { return dg->Mean(); }
00109 ExtReal Variance() const { return dg->Variance(); }
00110 };
00111
00112
00113
00114 double Random::seed;
00115
00116
00117 Real Normal::Nxi;
00118 Real* Normal::Nsx;
00119 Real* Normal::Nsfx;
00120 long Normal::count=0;
00121
00122
00123
00124 inline Real square(Real x) { return x*x; }
00125 inline ExtReal square(const ExtReal& x) { return x*x; }
00126
00127 static void ErrorNoSpace() { Throw(Bad_alloc("Newran: out of space")); }
00128
00129
00130
00131
00132 Real Random::Raw()
00133 {
00134
00135
00136 long iseed = (long)seed;
00137 long hi = iseed / 127773L;
00138 long lo = iseed - hi * 127773L;
00139 iseed = 16807 * lo - 2836 * hi;
00140 if (iseed <= 0) iseed += 2147483647L;
00141 seed = (double)iseed; return seed*4.656612875e-10;
00142 }
00143
00144 Real Random::Density(Real) const
00145 { Throw(Logic_error("density function not defined")); return 0.0; }
00146
00147 #ifdef _MSC_VER
00148 static void DoNothing(int) {}
00149 #endif
00150
00151 Real Random::Next()
00152 {
00153 if (!seed)
00154 Throw(Logic_error("Random number generator not initialised"));
00155 int i = (int)(Raw()*128);
00156 #ifdef _MSC_VER
00157 DoNothing(i); DoNothing(i);
00158 #endif
00159 Real f = Buffer[i]; Buffer[i] = Raw();
00160 return f;
00161
00162
00163 }
00164
00165 double Random::Get()
00166 { return seed/2147483648L; }
00167
00168 Random::Random( void )
00169 {
00170 for (int i = 0; i<128; i++)
00171 Buffer[i] = Raw();
00172 }
00173
00174 void Random::Set(double s)
00175
00176 {
00177 if (s>=1.0 || s<=0.0)
00178 Throw(Logic_error("Newran: seed out of range"));
00179
00180 seed = (long)(s*2147483648L);
00181 }
00182
00183
00184 PosGen::PosGen()
00185 {
00186 #ifdef MONITOR
00187 tron << "constructing PosGen\n";
00188 #endif
00189 NotReady=true;
00190 }
00191
00192 PosGen::~PosGen()
00193 {
00194 if (!NotReady)
00195 {
00196 #ifdef MONITOR
00197 tron << "freeing PosGen arrays\n";
00198 #endif
00199 delete [] sx; delete [] sfx;
00200 }
00201 #ifdef MONITOR
00202 tron << "destructing PosGen\n";
00203 #endif
00204 }
00205
00206 void PosGen::Build(bool sym)
00207 {
00208 #ifdef MONITOR
00209 tron << "building PosGen arrays\n";
00210 #endif
00211 int i;
00212 NotReady=false;
00213 sx=new Real[60]; sfx=new Real[60];
00214 if (!sx || !sfx) ErrorNoSpace();
00215 Real sxi=0.0; Real inc = sym ? 0.01 : 0.02;
00216 for (i=0; i<60; i++)
00217 {
00218 sx[i]=sxi; Real f1=Density(sxi); sfx[i]=f1;
00219 if (f1<=0.0) goto L20;
00220 sxi+=inc/f1;
00221 }
00222 Throw(Runtime_error("Newran: area too large"));
00223 L20:
00224 if (i<50) Throw(Runtime_error("Newran: area too small"));
00225 xi = sym ? 2*i : i;
00226 return;
00227 }
00228
00229 Real PosGen::Next()
00230 {
00231 Real ak,y; int ir;
00232 if (NotReady) Build(false);
00233 do
00234 {
00235 Real r1=Random::Next();
00236 ir = (int)(r1*xi); Real sxi=sx[ir];
00237 ak=sxi+(sx[ir+1]-sxi)*Random::Next();
00238 y=sfx[ir]*Random::Next();
00239 }
00240 while ( y>=sfx[ir+1] && y>=Density(ak) );
00241 return ak;
00242 }
00243
00244 Real SymGen::Next()
00245 {
00246 Real s,ak,y; int ir;
00247 if (NotReady) Build(true);
00248 do
00249 {
00250 s=1.0;
00251 Real r1=Random::Next();
00252 if (r1>0.5) { s=-1.0; r1=1.0-r1; }
00253 ir = (int)(r1*xi); Real sxi=sx[ir];
00254 ak=sxi+(sx[ir+1]-sxi)*Random::Next();
00255 y=sfx[ir]*Random::Next();
00256 }
00257 while ( y>=sfx[ir+1] && y>=Density(ak) );
00258 return s*ak;
00259 }
00260
00261 AsymGen::AsymGen(Real modex)
00262 {
00263 #ifdef MONITOR
00264 tron << "constructing AsymGen\n";
00265 #endif
00266 mode=modex; NotReady=true;
00267 }
00268
00269 void AsymGen::Build()
00270 {
00271 #ifdef MONITOR
00272 tron << "building AsymGen arrays\n";
00273 #endif
00274 int i;
00275 NotReady=false;
00276 sx=new Real[121]; sfx=new Real[121];
00277 if (!sx || !sfx) ErrorNoSpace();
00278 Real sxi=mode;
00279 for (i=0; i<120; i++)
00280 {
00281 sx[i]=sxi; Real f1=Density(sxi); sfx[i]=f1;
00282 if (f1<=0.0) goto L20;
00283 sxi+=0.01/f1;
00284 }
00285 Throw(Runtime_error("Newran: area too large (a)"));
00286 L20:
00287 ic=i-1; sx[120]=sxi; sfx[120]=0.0;
00288 sxi=mode;
00289 for (; i<120; i++)
00290 {
00291 sx[i]=sxi; Real f1=Density(sxi); sfx[i]=f1;
00292 if (f1<=0.0) goto L30;
00293 sxi-=0.01/f1;
00294 }
00295 Throw(Runtime_error("Newran: area too large (b)"));
00296 L30:
00297 if (i<100) Throw(Runtime_error("Newran: area too small"));
00298 xi=i;
00299 return;
00300 }
00301
00302 Real AsymGen::Next()
00303 {
00304 Real ak,y; int ir1;
00305 if (NotReady) Build();
00306 do
00307 {
00308 Real r1=Random::Next();
00309 int ir=(int)(r1*xi); Real sxi=sx[ir];
00310 ir1 = (ir==ic) ? 120 : ir+1;
00311 ak=sxi+(sx[ir1]-sxi)*Random::Next();
00312 y=sfx[ir]*Random::Next();
00313 }
00314 while ( y>=sfx[ir1] && y>=Density(ak) );
00315 return ak;
00316 }
00317
00318 AsymGen::~AsymGen()
00319 {
00320 if (!NotReady)
00321 {
00322 #ifdef MONITOR
00323 tron << "freeing AsymGen arrays\n";
00324 #endif
00325 delete [] sx; delete [] sfx;
00326 }
00327 #ifdef MONITOR
00328 tron << "destructing AsymGen\n";
00329 #endif
00330 }
00331
00332 PosGenX::PosGenX(PDF fx) { f=fx; }
00333
00334 SymGenX::SymGenX(PDF fx) { f=fx; }
00335
00336 AsymGenX::AsymGenX(PDF fx, Real mx) : AsymGen(mx) { f=fx; }
00337
00338
00339 Normal::Normal()
00340 {
00341 if (count) { NotReady=false; xi=Nxi; sx=Nsx; sfx=Nsfx; }
00342 else { Build(true); Nxi=xi; Nsx=sx; Nsfx=sfx; }
00343 count++;
00344 }
00345
00346 Normal::~Normal()
00347 {
00348 count--;
00349 if (count) NotReady=true;
00350 }
00351
00352 Real Normal::Density(Real x) const
00353 { return (fabs(x)>8.0) ? 0 : 0.398942280 * exp(-x*x / 2); }
00354
00355 ChiSq1::ChiSq1(Real d) : Normal()
00356 { deltasq=d; delta=sqrt(d); }
00357
00358 Real ChiSq1::Next()
00359 { Real z=Normal::Next()+delta; return z*z; }
00360
00361 ChiSq::ChiSq(int df, Real noncen)
00362 {
00363 if (df<=0 || noncen<0.0) Throw(Logic_error("Newran: illegal parameters"));
00364 else if (df==1) { version=0; c1=new ChiSq1(noncen); }
00365 else if (noncen==0.0)
00366 {
00367 if (df==2) { version=1; c1=new Exponential(); }
00368 else { version=2; c1=new Gamma2(0.5*df); }
00369 }
00370 else if (df==2) { version=3; c1=new ChiSq1(noncen/2.0); }
00371 else if (df==3) { version=4; c1=new Exponential(); c2=new ChiSq1(noncen); }
00372 else { version=5; c1=new Gamma2(0.5*(df-1)); c2=new ChiSq1(noncen); }
00373 if (!c1 || (version>3 && !c2)) ErrorNoSpace();
00374 mean=df+noncen; var=2*df+4.0*noncen;
00375 }
00376
00377 ChiSq::~ChiSq() { delete c1; if (version>3) delete c2; }
00378
00379 Real ChiSq::Next()
00380 {
00381 switch(version)
00382 {
00383 case 0: return c1->Next();
00384 case 1: case 2: return c1->Next()*2.0;
00385 case 3: return c1->Next() + c1->Next();
00386 case 4: case 5: Real s1 = c1->Next()*2.0; Real s2 = c2->Next();
00387 return s1 + s2;
00388 }
00389 return 0;
00390 }
00391
00392 Pareto::Pareto(Real shape) : Shape(shape)
00393 {
00394 if (Shape <= 0) Throw(Logic_error("Newran: illegal parameter"));
00395 RS = -1.0 / Shape;
00396 }
00397
00398 Real Pareto::Next()
00399 { return pow(Random::Next(), RS); }
00400
00401 ExtReal Pareto::Mean() const
00402 {
00403 if (Shape > 1) return Shape/(Shape-1.0);
00404 else return PlusInfinity;
00405 }
00406
00407 ExtReal Pareto::Variance() const
00408 {
00409 if (Shape > 2) return Shape/(square(Shape-1.0))/(Shape-2.0);
00410 else return PlusInfinity;
00411 }
00412
00413 Real Cauchy::Density(Real x) const
00414 { return (fabs(x)>1.0e15) ? 0 : 0.31830988618 / (1.0+x*x); }
00415
00416 Poisson1::Poisson1(Real mux) : AsymGen(mux)
00417 { mu=mux; ln_mu=log(mu); }
00418
00419 Real Poisson1::Density(Real x) const
00420 {
00421 if (x < 0.0) return 0.0;
00422 double ix = floor(x);
00423 double l = ln_mu * ix - mu - ln_gamma(1.0 + ix);
00424 return (l < -40.0) ? 0.0 : exp(l);
00425 }
00426
00427 Binomial1::Binomial1(int nx, Real px)
00428 : AsymGen((nx + 1) * px), p(px), q(1.0 - px), n(nx)
00429 { ln_p = log(p); ln_q = log(q); ln_n_fac = ln_gamma(n+1); }
00430
00431 Real Binomial1::Density(Real x) const
00432 {
00433 double ix = floor(x);
00434 if (ix < 0.0 || ix > n) return 0.0;
00435 double l = ln_n_fac - ln_gamma(ix+1) - ln_gamma(n-ix+1)
00436 + ix * ln_p + (n-ix) * ln_q;
00437 return (l < -40.0) ? 0.0 : exp(l);
00438 }
00439
00440 Poisson2::Poisson2(Real mux)
00441 {
00442 Real probs[40];
00443 probs[0]=exp(-mux);
00444 for (int i=1; i<40; i++) probs[i]=probs[i-1]*mux/i;
00445 dg=new DiscreteGen(40,probs);
00446 if (!dg) ErrorNoSpace();
00447 }
00448
00449 Poisson2::~Poisson2() { delete dg; }
00450
00451 Binomial2::Binomial2(int nx, Real px)
00452 {
00453 Real qx = 1.0 - px;
00454 Real probs[40];
00455 int k = (int)(nx * px);
00456 probs[k] = exp(ln_gamma(nx+1) - ln_gamma(k+1) - ln_gamma(nx-k+1)
00457 + k * log(px) + (nx-k) * log(qx));
00458 int i;
00459 int m = (nx >= 40) ? 39 : nx;
00460 for (i=k+1; i<=m; i++) probs[i]=probs[i-1] * px * (nx-i+1) / qx / i;
00461 for (i=k-1; i>=0; i--) probs[i]=probs[i+1] * qx * (i+1) / px / (nx-i);
00462 dg = new DiscreteGen(m + 1, probs);
00463 if (!dg) ErrorNoSpace();
00464 }
00465
00466 Binomial2::~Binomial2() { delete dg; }
00467
00468 Real Exponential::Density(Real x) const
00469 { return (x > 40.0 || x < 0.0) ? 0.0 : exp(-x); }
00470
00471 Poisson::Poisson(Real mu)
00472 {
00473 if (mu <= 8.0) method = new Poisson2(mu);
00474 else method = new Poisson1(mu);
00475 if (!method) ErrorNoSpace();
00476 }
00477
00478 Binomial::Binomial(int nx, Real px)
00479 {
00480 if (nx < 40 || nx * px <= 8.0) method = new Binomial2(nx, px);
00481 else method = new Binomial1(nx, px);
00482 if (!method) ErrorNoSpace();
00483 }
00484
00485 NegativeBinomial::NegativeBinomial(Real NX, Real PX)
00486 : AsymGen(0.0), N(NX), P(PX), Q(1.0 + PX)
00487 {
00488 p = 1.0 / Q; ln_q = log(1.0 - p);
00489 c = N * log(p) - ln_gamma(N); mode = (N - 1) * P;
00490 if (mode < 1.0) mode = 0.0;
00491 }
00492
00493 Real NegativeBinomial::Next() { return floor(AsymGen::Next()); }
00494
00495 Real NegativeBinomial::Density(Real x) const
00496 {
00497 if (x < 0.0) return 0.0;
00498 Real ix = floor(x);
00499 Real l = c + ln_gamma(ix + N) - ln_gamma(ix + 1) + ix * ln_q;
00500 return (l < -40.0) ? 0.0 : exp(l);
00501 }
00502
00503 Gamma1::Gamma1(Real alphax)
00504 { ralpha=1.0/alphax; ln_gam=ln_gamma(alphax+1.0); alpha=alphax; }
00505
00506 Real Gamma1::Density(Real x) const
00507 {
00508 Real l = - pow(x,ralpha) - ln_gam;
00509 return (l < -40.0) ? 0.0 : exp(l);
00510 }
00511
00512 Real Gamma1::Next()
00513 { return pow(PosGen::Next(),ralpha); }
00514
00515 Gamma2::Gamma2(Real alphax) : AsymGen(alphax-1.0)
00516 { alpha=alphax; ln_gam=ln_gamma(alpha); }
00517
00518 Real Gamma2::Density(Real x) const
00519 {
00520 if (x<=0.0) return 0.0;
00521 double l = (alpha-1.0)*log(x) - x - ln_gam;
00522 return (l < -40.0) ? 0.0 : exp(l);
00523 }
00524
00525 Gamma::Gamma(Real alpha)
00526 {
00527 if (alpha<1.0) method = new Gamma1(alpha);
00528 else if (alpha==1.0) method = new Exponential();
00529 else method = new Gamma2(alpha);
00530 if (!method) ErrorNoSpace();
00531 }
00532
00533 DiscreteGen::DiscreteGen(int n1, Real* prob)
00534
00535 {
00536 #ifdef MONITOR
00537 tron << "constructing DiscreteGen\n";
00538 #endif
00539 Gen(n1, prob); val=0;
00540 mean=0.0; var=0.0;
00541 { for (int i=0; i<n; i++) mean = mean + i*prob[i]; }
00542 { for (int i=0; i<n; i++) var = var + square(i-mean) * prob[i]; }
00543 }
00544
00545 DiscreteGen::DiscreteGen(int n1, Real* prob, Real* val1)
00546
00547
00548 {
00549 #ifdef MONITOR
00550 tron << "constructing DiscreteGen\n";
00551 #endif
00552 Gen(n1, prob); val = new Real[n1];
00553 if (!val) ErrorNoSpace();
00554 for (int i=0; i<n1; i++) val[i]=val1[i];
00555 mean=0.0; var=0.0;
00556 { for (int i=0; i<n; i++) mean = mean + val[i]*prob[i]; }
00557 { for (int i=0; i<n; i++) var = var + square(val[i]-mean)*prob[i]; }
00558 }
00559
00560
00561 void DiscreteGen::Gen(int n1, Real* prob)
00562 {
00563 n=n1;
00564 p=new Real[n]; ialt=new int[n];
00565 if (!p || !ialt) ErrorNoSpace();
00566 Real rn = 1.0/n; Real px = 0; int i;
00567 for (i=0; i<n; i++) { p[i]=0.0; ialt[i]=-1; }
00568 for (i=0; i<n; i++)
00569 {
00570 Real pmin=1.0; Real pmax=-1.0; int jmin=-1; int jmax=-1;
00571 for (int j=0; j<n; j++)
00572 {
00573 if (ialt[j]<0)
00574 {
00575 px=prob[j]-p[j];
00576 if (pmax<=px) { pmax=px; jmax=j; }
00577 if (pmin>=px) { pmin=px; jmin=j; }
00578 }
00579 }
00580 if ((jmax<0) || (jmin<0)) Throw(Runtime_error("Newran: method fails"));
00581 ialt[jmin]=jmax;
00582 px=rn-pmin;
00583 p[jmax]+=px;
00584 px*=n;
00585 p[jmin]=px;
00586 if ((px>1.00001)||(px<-.00001))
00587 Throw(Runtime_error("Newran: probs don't add to 1 (a)"));
00588 }
00589 if (px>0.00001) Throw(Runtime_error("Newran: probs don't add to 1 (b)"));
00590 }
00591
00592 DiscreteGen::~DiscreteGen()
00593 {
00594 delete [] p; delete [] ialt; delete [] val;
00595 #ifdef MONITOR
00596 tron << "destructing DiscreteGen\n";
00597 #endif
00598 }
00599
00600 Real DiscreteGen::Next()
00601 {
00602 int i = (int)(n * Random::Next());
00603 Real t = Random::Next();
00604 if( t < p[i] )
00605 i = ialt[i];
00606 return val ? val[i] : (Real)i;
00607 }
00608
00609 Real ln_gamma(Real xx)
00610 {
00611
00612
00613 if (xx<1.0)
00614 {
00615 double piz = 3.14159265359 * (1.0-xx);
00616 return log(piz/sin(piz))-ln_gamma(2.0-xx);
00617 }
00618 else
00619 {
00620 static double cof[6]={76.18009173,-86.50532033,24.01409822,
00621 -1.231739516,0.120858003e-2,-0.536382e-5};
00622
00623 double x=xx-1.0; double tmp=x+5.5;
00624 tmp -= (x+0.5)*log(tmp); double ser=1.0;
00625 for (int j=0;j<=5;j++) { x += 1.0; ser += cof[j]/x; }
00626 return -tmp+log(2.50662827465*ser);
00627 }
00628 }
00629
00630
00631 Real NegatedRandom::Next() { return - rv->Next(); }
00632
00633 ExtReal NegatedRandom::Mean() const { return - rv->Mean(); }
00634
00635 ExtReal NegatedRandom::Variance() const { return rv->Variance(); }
00636
00637 Real ScaledRandom::Next() { return rv->Next() * s; }
00638
00639 ExtReal ScaledRandom::Mean() const { return rv->Mean() * s; }
00640
00641 ExtReal ScaledRandom::Variance() const { return rv->Variance() * (s*s); }
00642
00643 Real ShiftedRandom::Next() { return rv->Next() + s; }
00644
00645 ExtReal ShiftedRandom::Mean() const { return rv->Mean() + s; }
00646
00647 ExtReal ShiftedRandom::Variance() const { return rv->Variance(); }
00648
00649 Real ReverseShiftedRandom::Next() { return s - rv->Next(); }
00650
00651 ExtReal ReverseShiftedRandom::Mean() const { return - rv->Mean() + s; }
00652
00653 ExtReal ReverseShiftedRandom::Variance() const { return rv->Variance(); }
00654
00655 Real ReciprocalRandom::Next() { return s / rv->Next(); }
00656
00657 ExtReal RepeatedRandom::Mean() const { return rv->Mean() * (Real)n; }
00658
00659 ExtReal RepeatedRandom::Variance() const { return rv->Variance() * (Real)n; }
00660
00661 RepeatedRandom& Random::operator()(int n)
00662 {
00663 RepeatedRandom* r = new RepeatedRandom(*this, n);
00664 if (!r) ErrorNoSpace(); return *r;
00665 }
00666
00667 NegatedRandom& operator-(Random& rv)
00668 {
00669 NegatedRandom* r = new NegatedRandom(rv);
00670 if (!r) ErrorNoSpace(); return *r;
00671 }
00672
00673 ShiftedRandom& operator+(Random& rv, Real s)
00674 {
00675 ShiftedRandom* r = new ShiftedRandom(rv, s);
00676 if (!r) ErrorNoSpace(); return *r;
00677 }
00678
00679 ShiftedRandom& operator-(Random& rv, Real s)
00680 {
00681 ShiftedRandom* r = new ShiftedRandom(rv, -s);
00682 if (!r) ErrorNoSpace(); return *r;
00683 }
00684
00685 ScaledRandom& operator*(Random& rv, Real s)
00686 {
00687 ScaledRandom* r = new ScaledRandom(rv, s);
00688 if (!r) ErrorNoSpace(); return *r;
00689 }
00690
00691 ShiftedRandom& operator+(Real s, Random& rv)
00692 {
00693 ShiftedRandom* r = new ShiftedRandom(rv, s);
00694 if (!r) ErrorNoSpace(); return *r;
00695 }
00696
00697 ReverseShiftedRandom& operator-(Real s, Random& rv)
00698 {
00699 ReverseShiftedRandom* r = new ReverseShiftedRandom(rv, s);
00700 if (!r) ErrorNoSpace(); return *r;
00701 }
00702
00703 ScaledRandom& operator*(Real s, Random& rv)
00704 {
00705 ScaledRandom* r = new ScaledRandom(rv, s);
00706 if (!r) ErrorNoSpace(); return *r;
00707 }
00708
00709 ScaledRandom& operator/(Random& rv, Real s)
00710 {
00711 ScaledRandom* r = new ScaledRandom(rv, 1.0/s);
00712 if (!r) ErrorNoSpace(); return *r;
00713 }
00714
00715 ReciprocalRandom& operator/(Real s, Random& rv)
00716 {
00717 ReciprocalRandom* r = new ReciprocalRandom(rv, s);
00718 if (!r) ErrorNoSpace(); return *r;
00719 }
00720
00721 AddedRandom& operator+(Random& rv1, Random& rv2)
00722 {
00723 AddedRandom* r = new AddedRandom(rv1, rv2);
00724 if (!r) ErrorNoSpace(); return *r;
00725 }
00726
00727 OredRandom& operator|(Random& rv1, Random& rv2)
00728 {
00729 OredRandom* r = new OredRandom(rv1, rv2);
00730 if (!r) ErrorNoSpace(); return *r;
00731 }
00732
00733 MultipliedRandom& operator*(Random& rv1, Random& rv2)
00734 {
00735 MultipliedRandom* r = new MultipliedRandom(rv1, rv2);
00736 if (!r) ErrorNoSpace(); return *r;
00737 }
00738
00739 SubtractedRandom& operator-(Random& rv1, Random& rv2)
00740 {
00741 SubtractedRandom* r = new SubtractedRandom(rv1, rv2);
00742 if (!r) ErrorNoSpace(); return *r;
00743 }
00744
00745 DividedRandom& operator/(Random& rv1, Random& rv2)
00746 {
00747 DividedRandom* r = new DividedRandom(rv1, rv2);
00748 if (!r) ErrorNoSpace(); return *r;
00749 }
00750
00751 Real AddedRandom::Next() { return rv1->Next() + rv2->Next() ; }
00752
00753 ExtReal AddedRandom::Mean() const { return rv1->Mean() + rv2->Mean() ; }
00754
00755 ExtReal AddedRandom::Variance() const
00756 { return rv1->Variance() + rv2->Variance() ; }
00757
00758 Real OredRandom::Next()
00759 {
00760 i = (i + 1) % 2;
00761 if( i )
00762 return rv1->Next();
00763 else
00764 return rv2->Next();
00765 }
00766
00767 ExtReal OredRandom::Mean() const { return rv1->Mean() + rv2->Mean() ; }
00768
00769 ExtReal OredRandom::Variance() const
00770 { return rv1->Variance() + rv2->Variance() ; }
00771
00772 Real SubtractedRandom::Next() { return rv1->Next() - rv2->Next() ; }
00773
00774 ExtReal SubtractedRandom::Mean() const { return rv1->Mean() - rv2->Mean() ; }
00775
00776 ExtReal SubtractedRandom::Variance() const
00777 { return rv1->Variance() + rv2->Variance() ; }
00778
00779 Real MultipliedRandom::Next()
00780 { return rv1->Next() * rv2->Next() ; }
00781
00782 ExtReal MultipliedRandom::Mean() const { return rv1->Mean() * rv2->Mean() ; }
00783
00784 ExtReal MultipliedRandom::Variance() const
00785 {
00786 ExtReal e1 = square(rv1->Mean()); ExtReal e2 = square(rv2->Mean());
00787 ExtReal v1 = rv1->Variance(); ExtReal v2 = rv2->Variance();
00788 ExtReal r=v1*v2+v1*e2+e1*v2;
00789 return r;
00790 }
00791
00792 Real DividedRandom::Next() { return rv1->Next() / rv2->Next() ; }
00793
00794 void Random::load(int*,Real*,Random**)
00795 { Throw(Logic_error("Newran: illegal combination")); }
00796
00797 void SelectedRandom::load(int* i, Real* probs, Random** rvx)
00798 {
00799 probs[*i]=p; rvx[*i]=rv; (*i)++;
00800 delete this;
00801 }
00802
00803 Real SelectedRandom::Next()
00804 { Throw(Logic_error("Newran: Next not defined")); return 0.0; }
00805
00806 Real AddedSelectedRandom::Next()
00807 { Throw(Logic_error("Newran: Next not defined")); return 0.0; }
00808
00809 Real RepeatedRandom::Next()
00810 { Real sum=0.0; for (int i=0; i<n; i++) sum+=rv->Next(); return sum; }
00811
00812 MixedRandom::MixedRandom(int nx, Real* probs, Random** rvx)
00813 {
00814 n = nx;
00815 rv = new Random*[n]; if (!rv) ErrorNoSpace();
00816 for (int i=0; i<n; i++) rv[i]=rvx[i];
00817 Build(probs);
00818 }
00819
00820 MixedRandom::MixedRandom(AddedSelectedRandom& sr)
00821 {
00822 n = sr.nelems();
00823 Real* probs = new Real[n]; rv = new Random*[n];
00824 if (!probs || !rv) ErrorNoSpace();
00825 int i=0; sr.load(&i,probs,rv);
00826 Build(probs); delete [] probs;
00827 }
00828
00829 void MixedRandom::Build(Real* probs)
00830 {
00831 int i;
00832 dg=new DiscreteGen(n,probs);
00833 if (!dg) ErrorNoSpace();
00834 mean=0.0; var=0.0;
00835 for (i=0; i<n; i++) mean = mean + (rv[i])->Mean()*probs[i];
00836 for (i=0; i<n; i++)
00837 {
00838 ExtReal sigsq=(rv[i])->Variance();
00839 ExtReal mudif=(rv[i])->Mean()-mean;
00840 var = var + (sigsq+square(mudif))*probs[i];
00841 }
00842
00843 }
00844
00845 MixedRandom::~MixedRandom()
00846 {
00847 for (int i=0; i<n; i++) rv[i]->tDelete();
00848 delete [] rv; delete dg;
00849 }
00850
00851 Real MixedRandom::Next()
00852 { int i = (int)(dg->Next()); return (rv[i])->Next(); }
00853
00854 int AddedSelectedRandom::nelems() const
00855 { return rv1->nelems() + rv2->nelems(); }
00856
00857 void AddedSelectedRandom::load(int* i, Real* probs, Random** rvx)
00858 {
00859 rv1->load(i, probs, rvx); rv2->load(i, probs, rvx);
00860 delete this;
00861 }
00862
00863 AddedSelectedRandom& operator+(SelectedRandom& rv1,
00864 SelectedRandom& rv2)
00865 {
00866 AddedSelectedRandom* r = new AddedSelectedRandom(rv1, rv2);
00867 if (!r) ErrorNoSpace(); return *r;
00868 }
00869
00870 AddedSelectedRandom& operator+(AddedSelectedRandom& rv1,
00871 SelectedRandom& rv2)
00872 {
00873 AddedSelectedRandom* r = new AddedSelectedRandom(rv1, rv2);
00874 if (!r) ErrorNoSpace(); return *r;
00875 }
00876
00877 AddedSelectedRandom& operator+(SelectedRandom& rv1,
00878 AddedSelectedRandom& rv2)
00879 {
00880 AddedSelectedRandom* r = new AddedSelectedRandom(rv1, rv2);
00881 if (!r) ErrorNoSpace(); return *r;
00882 }
00883
00884 AddedSelectedRandom& operator+(AddedSelectedRandom& rv1,
00885 AddedSelectedRandom& rv2)
00886 {
00887 AddedSelectedRandom* r = new AddedSelectedRandom(rv1, rv2);
00888 if (!r) ErrorNoSpace(); return *r;
00889 }
00890
00891 SelectedRandom& Random::operator()(double p)
00892 {
00893 SelectedRandom* r = new SelectedRandom(*this, p);
00894 if (!r) ErrorNoSpace(); return *r;
00895 }
00896
00897
00898
00899
00900
00901
00902 char* Random::Name() { return "Random"; }
00903 char* Uniform::Name() { return "Uniform"; }
00904 char* Constant::Name() { return "Constant"; }
00905 char* PosGen::Name() { return "PosGen"; }
00906 char* SymGen::Name() { return "SymGen"; }
00907 char* AsymGen::Name() { return "AsymGen"; }
00908 char* PosGenX::Name() { return "PosGenX"; }
00909 char* SymGenX::Name() { return "SymGenX"; }
00910 char* AsymGenX::Name() { return "AsymGenX"; }
00911 char* Normal::Name() { return "Normal"; }
00912 char* ChiSq::Name() { return "ChiSq"; }
00913 char* Cauchy::Name() { return "Cauchy"; }
00914 char* Exponential::Name() { return "Exponential"; }
00915 char* Poisson::Name() { return "Poisson"; }
00916 char* Binomial::Name() { return "Binomial"; }
00917 char* NegativeBinomial::Name() { return "NegativeBinomial"; }
00918 char* Gamma::Name() { return "Gamma"; }
00919 char* Pareto::Name() { return "Pareto"; }
00920 char* DiscreteGen::Name() { return "DiscreteGen"; }
00921 char* SumRandom::Name() { return "SumRandom"; }
00922 char* MixedRandom::Name() { return "MixedRandom"; }
00923
00924
00925
00926
00927 void RandomPermutation::Next(int N, int M, int p[], int start)
00928 {
00929
00930 if (N < M) Throw(Logic_error("Newran: N < M in RandomPermutation"));
00931 int i;
00932 int* q = new int [N];
00933 if (!q) ErrorNoSpace();
00934 for (i = 0; i < N; i++) q[i] = start + i;
00935 for (i = 0; i < M; i++)
00936 {
00937 int k = i + (int)(U.Next() * (N - i));
00938 p[i] = q[k]; q[k] = q[i];
00939
00940 }
00941 delete [] q;
00942 }
00943
00944 void RandomCombination::SortAscending(int n, int gm[])
00945 {
00946
00947
00948 const double aln2i = 1.442695022; const double tiny = 1.0e-5;
00949 int m = n; int lognb2 = (int)(aln2i * log((double)n) + tiny);
00950 while (lognb2--)
00951 {
00952 m >>= 1;
00953 for (int j = m; j<n; j++)
00954 {
00955 int* gmj = gm+j; int i = j-m; int* gmi = gmj-m; int t = *gmj;
00956 while (i>=0 && *gmi>t) { *gmj = *gmi; gmj = gmi; gmi -= m; i -= m; }
00957 *gmj = t;
00958 }
00959 }
00960 }
00961
00962 #ifdef use_namespace
00963 }
00964 #endif
00965
00966