⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 newran.cpp

📁 随机数发生器C++写的
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  else if (df==3) { version=4; c1=new Exponential(); c2=new ChiSq1(noncen); }  else { version=5; c1=new Gamma2(0.5*(df-1)); c2=new ChiSq1(noncen); }  if (!c1 || (version>3 && !c2)) ErrorNoSpace();  mean=df+noncen; var=2*df+4.0*noncen;}ChiSq::~ChiSq() { delete c1; if (version>3) delete c2; }Real ChiSq::Next(){   switch(version)   {   case 0: return c1->Next();   case 1: case 2: return c1->Next()*2.0;   case 3: return c1->Next() + c1->Next();   case 4: case 5: Real s1 = c1->Next()*2.0; Real s2 = c2->Next();	   return s1 + s2; // this is to make it work with Microsoft VC5   }   return 0;}Pareto::Pareto(Real shape) : Shape(shape){   if (Shape <= 0) Throw(Logic_error("Newran: illegal parameter"));   RS = -1.0 / Shape;}Real Pareto::Next(){ return pow(Random::Next(), RS); }ExtReal Pareto::Mean() const{   if (Shape > 1) return Shape/(Shape-1.0);   else return PlusInfinity;}ExtReal Pareto::Variance() const{   if (Shape > 2) return Shape/(square(Shape-1.0))/(Shape-2.0);   else return PlusInfinity;}Real Cauchy::Density(Real x) const               // Cauchy density function{ return (fabs(x)>1.0e15) ? 0 : 0.31830988618 / (1.0+x*x); }Poisson1::Poisson1(Real mux) : AsymGen(mux)      // Constructor{ mu=mux; ln_mu=log(mu); }Real Poisson1::Density(Real x) const             // Poisson density function{   if (x < 0.0) return 0.0;   double ix = floor(x);                         // use integer part   double l = ln_mu * ix - mu - ln_gamma(1.0 + ix);   return  (l < -40.0) ? 0.0 : exp(l);}Binomial1::Binomial1(int nx, Real px)   : AsymGen((nx + 1) * px), p(px), q(1.0 - px), n(nx)      { ln_p = log(p); ln_q = log(q); ln_n_fac = ln_gamma(n+1); }Real Binomial1::Density(Real x) const            // Binomial density function{   double ix = floor(x);                         // use integer part   if (ix < 0.0 || ix > n) return 0.0;   double l = ln_n_fac - ln_gamma(ix+1) - ln_gamma(n-ix+1)      + ix * ln_p + (n-ix) * ln_q;   return  (l < -40.0) ? 0.0 : exp(l);}Poisson2::Poisson2(Real mux){   Real probs[40];   probs[0]=exp(-mux);   for (int i=1; i<40; i++) probs[i]=probs[i-1]*mux/i;   dg=new DiscreteGen(40,probs);   if (!dg) ErrorNoSpace();}Poisson2::~Poisson2() { delete dg; }Binomial2::Binomial2(int nx, Real px){   Real qx = 1.0 - px;   Real probs[40];   int k = (int)(nx * px);   probs[k] = exp(ln_gamma(nx+1) - ln_gamma(k+1) - ln_gamma(nx-k+1)      + k * log(px) + (nx-k) * log(qx));   int i;   int m = (nx >= 40) ? 39 : nx;   for (i=k+1; i<=m; i++) probs[i]=probs[i-1] * px * (nx-i+1) / qx / i;   for (i=k-1; i>=0; i--) probs[i]=probs[i+1] * qx * (i+1) / px / (nx-i);   dg = new DiscreteGen(m + 1, probs);   if (!dg) ErrorNoSpace();}Binomial2::~Binomial2() { delete dg; }Real Exponential::Density(Real x) const          // Negative exponential{ return  (x > 40.0 || x < 0.0) ? 0.0 : exp(-x); }Poisson::Poisson(Real mu){   if (mu <= 8.0) method = new Poisson2(mu);   else method = new Poisson1(mu);   if (!method) ErrorNoSpace();}Binomial::Binomial(int nx, Real px){   if (nx < 40 || nx * px <= 8.0) method = new Binomial2(nx, px);   else method = new Binomial1(nx, px);   if (!method) ErrorNoSpace();}NegativeBinomial::NegativeBinomial(Real NX, Real PX)   : AsymGen(0.0), N(NX), P(PX), Q(1.0 + PX){   p = 1.0 / Q;  ln_q = log(1.0 - p);   c = N * log(p) - ln_gamma(N);  mode = (N - 1) * P;   if (mode < 1.0) mode = 0.0;}Real NegativeBinomial::Next() { return floor(AsymGen::Next()); }Real NegativeBinomial::Density(Real x) const{   if (x < 0.0) return 0.0;   Real ix = floor(x);   Real l = c + ln_gamma(ix + N) - ln_gamma(ix + 1) + ix * ln_q;   return  (l < -40.0) ? 0.0 : exp(l);}Gamma1::Gamma1(Real alphax)                      // constructor (Real=shape){ ralpha=1.0/alphax; ln_gam=ln_gamma(alphax+1.0); alpha=alphax; }Real Gamma1::Density(Real x) const               // density function for{                                                // transformed gamma   Real l = - pow(x,ralpha) - ln_gam;   return  (l < -40.0) ? 0.0 : exp(l);}Real Gamma1::Next()                               // transform variable{ return pow(PosGen::Next(),ralpha); }Gamma2::Gamma2(Real alphax) : AsymGen(alphax-1.0) // constructor (Real=shape){ alpha=alphax; ln_gam=ln_gamma(alpha); }Real Gamma2::Density(Real x) const                // gamma density function{   if (x<=0.0) return 0.0;   double l = (alpha-1.0)*log(x) - x - ln_gam;   return  (l < -40.0) ? 0.0 : exp(l);}Gamma::Gamma(Real alpha)                         // general gamma generator{   if (alpha<1.0) method = new Gamma1(alpha);   else if (alpha==1.0) method = new Exponential();   else method = new Gamma2(alpha);   if (!method)  ErrorNoSpace();}DiscreteGen::DiscreteGen(int n1, Real* prob)     // discrete generator						 // values on 0,...,n1-1{   #ifdef MONITOR      cout << "constructing DiscreteGen\n";   #endif   Gen(n1, prob); val=0;   mean=0.0; var=0.0;   { for (int i=0; i<n; i++) mean = mean + i*prob[i]; }   { for (int i=0; i<n; i++) var = var + square(i-mean) * prob[i]; }}DiscreteGen::DiscreteGen(int n1, Real* prob, Real* val1)                                                 // discrete generator                                                 // values on *val{   #ifdef MONITOR      cout << "constructing DiscreteGen\n";   #endif   Gen(n1, prob); val = new Real[n1];   if (!val)  ErrorNoSpace();   for (int i=0; i<n1; i++) val[i]=val1[i];   mean=0.0; var=0.0;   { for (int i=0; i<n; i++) mean = mean + val[i]*prob[i]; }   { for (int i=0; i<n; i++) var = var + square(val[i]-mean)*prob[i]; }}void DiscreteGen::Gen(int n1, Real* prob){   n=n1;                                         // number of values   p=new Real[n]; ialt=new int[n];   if (!p || !ialt)  ErrorNoSpace();   Real rn = 1.0/n; Real px = 0; int i;   for (i=0; i<n; i++) { p[i]=0.0; ialt[i]=-1; }   for (i=0; i<n; i++)   {      Real pmin=1.0; Real pmax=-1.0; int jmin=-1; int jmax=-1;      for (int j=0; j<n; j++)      {         if (ialt[j]<0)         {            px=prob[j]-p[j];            if (pmax<=px) { pmax=px; jmax=j; }            if (pmin>=px) { pmin=px; jmin=j; }         }      }      if ((jmax<0) || (jmin<0)) Throw(Runtime_error("Newran: method fails"));      ialt[jmin]=jmax; px=rn-pmin; p[jmax]+=px; px*=n; p[jmin]=px;      if ((px>1.00001)||(px<-.00001))         Throw(Runtime_error("Newran: probs don't add to 1 (a)"));   }   if (px>0.00001) Throw(Runtime_error("Newran: probs don't add to 1 (b)"));}DiscreteGen::~DiscreteGen(){   delete [] p; delete [] ialt; delete [] val;   #ifdef MONITOR      cout << "destructing DiscreteGen\n";   #endif}Real DiscreteGen::Next()                  // Next discrete random variable{   int i = (int)(n*Random::Next()); if (Random::Next()<p[i]) i=ialt[i];   return val ? val[i] : (Real)i;}Real ln_gamma(Real xx){   // log gamma function adapted from numerical recipes in C   if (xx<1.0)                           // Use reflection formula   {      double piz = 3.14159265359 * (1.0-xx);      return log(piz/sin(piz))-ln_gamma(2.0-xx);   }   else   {      static double cof[6]={76.18009173,-86.50532033,24.01409822,         -1.231739516,0.120858003e-2,-0.536382e-5};      double x=xx-1.0; double tmp=x+5.5;      tmp -= (x+0.5)*log(tmp); double ser=1.0;      for (int j=0;j<=5;j++) { x += 1.0; ser += cof[j]/x; }      return -tmp+log(2.50662827465*ser);   }}Real NegatedRandom::Next() { return - rv->Next(); }ExtReal NegatedRandom::Mean() const { return - rv->Mean(); }ExtReal NegatedRandom::Variance() const { return rv->Variance(); }Real ScaledRandom::Next() { return rv->Next() * s; }ExtReal ScaledRandom::Mean() const { return rv->Mean() * s; }ExtReal ScaledRandom::Variance() const { return rv->Variance() * (s*s); }Real ShiftedRandom::Next() { return rv->Next() + s; }ExtReal ShiftedRandom::Mean() const { return rv->Mean() + s; }ExtReal ShiftedRandom::Variance() const { return rv->Variance(); }Real ReverseShiftedRandom::Next() { return s - rv->Next(); }ExtReal ReverseShiftedRandom::Mean() const { return - rv->Mean() + s; }ExtReal ReverseShiftedRandom::Variance() const { return rv->Variance(); }Real ReciprocalRandom::Next() { return s / rv->Next(); }ExtReal RepeatedRandom::Mean() const { return rv->Mean() * (Real)n; }ExtReal RepeatedRandom::Variance() const { return rv->Variance() * (Real)n; }RepeatedRandom& Random::operator()(int n){   RepeatedRandom* r = new RepeatedRandom(*this, n);   if (!r) ErrorNoSpace(); return *r;}NegatedRandom& operator-(Random& rv){   NegatedRandom* r = new NegatedRandom(rv);   if (!r) ErrorNoSpace(); return *r;}ShiftedRandom& operator+(Random& rv, Real s){   ShiftedRandom* r = new ShiftedRandom(rv, s);   if (!r) ErrorNoSpace(); return *r;}ShiftedRandom& operator-(Random& rv, Real s){   ShiftedRandom* r = new ShiftedRandom(rv, -s);   if (!r) ErrorNoSpace(); return *r;}ScaledRandom& operator*(Random& rv, Real s){   ScaledRandom* r = new ScaledRandom(rv, s);   if (!r) ErrorNoSpace(); return *r;}ShiftedRandom& operator+(Real s, Random& rv){   ShiftedRandom* r = new ShiftedRandom(rv, s);   if (!r) ErrorNoSpace(); return *r;}ReverseShiftedRandom& operator-(Real s, Random& rv){   ReverseShiftedRandom* r = new ReverseShiftedRandom(rv, s);   if (!r) ErrorNoSpace(); return *r;}ScaledRandom& operator*(Real s, Random& rv){   ScaledRandom* r = new ScaledRandom(rv, s);   if (!r) ErrorNoSpace(); return *r;}ScaledRandom& operator/(Random& rv, Real s){   ScaledRandom* r = new ScaledRandom(rv, 1.0/s);   if (!r) ErrorNoSpace(); return *r;}ReciprocalRandom& operator/(Real s, Random& rv){   ReciprocalRandom* r = new ReciprocalRandom(rv, s);   if (!r) ErrorNoSpace(); return *r;}AddedRandom& operator+(Random& rv1, Random& rv2){   AddedRandom* r = new AddedRandom(rv1, rv2);   if (!r) ErrorNoSpace(); return *r;}MultipliedRandom& operator*(Random& rv1, Random& rv2){   MultipliedRandom* r = new MultipliedRandom(rv1, rv2);   if (!r) ErrorNoSpace(); return *r;}SubtractedRandom& operator-(Random& rv1, Random& rv2){   SubtractedRandom* r = new SubtractedRandom(rv1, rv2);   if (!r) ErrorNoSpace(); return *r;}DividedRandom& operator/(Random& rv1, Random& rv2){   DividedRandom* r = new DividedRandom(rv1, rv2);   if (!r) ErrorNoSpace(); return *r;}Real AddedRandom::Next()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -