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

📄 newran.cpp

📁 随机数生成程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   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() { return rv1->Next() + rv2->Next() ; }ExtReal AddedRandom::Mean() const { return rv1->Mean() + rv2->Mean() ; }ExtReal AddedRandom::Variance() const   { return rv1->Variance() + rv2->Variance() ; }Real SubtractedRandom::Next() { return rv1->Next() - rv2->Next() ; }ExtReal SubtractedRandom::Mean() const { return rv1->Mean() - rv2->Mean() ; }ExtReal SubtractedRandom::Variance() const   { return rv1->Variance() + rv2->Variance() ; }Real MultipliedRandom::Next() { return rv1->Next() * rv2->Next() ; }ExtReal MultipliedRandom::Mean() const { return rv1->Mean() * rv2->Mean() ; }ExtReal MultipliedRandom::Variance() const{   ExtReal e1 = square(rv1->Mean()); ExtReal e2 = square(rv2->Mean());   ExtReal v1 = rv1->Variance(); ExtReal v2 = rv2->Variance();   ExtReal r=v1*v2+v1*e2+e1*v2;   return r;}Real DividedRandom::Next() { return rv1->Next() / rv2->Next() ; }void Random::load(int*,Real*,Random**)   { Throw(Logic_error("Newran: illegal combination")); }void SelectedRandom::load(int* i, Real* probs, Random** rvx){   probs[*i]=p; rvx[*i]=rv; (*i)++;   delete this;}Real SelectedRandom::Next()   { Throw(Logic_error("Newran: Next not defined")); return 0.0; }Real AddedSelectedRandom::Next()   { Throw(Logic_error("Newran: Next not defined")); return 0.0; }Real RepeatedRandom::Next()   { Real sum=0.0; for (int i=0; i<n; i++) sum+=rv->Next(); return sum; }MixedRandom::MixedRandom(int nx, Real* probs, Random** rvx){   n = nx;   rv = new Random*[n]; if (!rv) ErrorNoSpace();   for (int i=0; i<n; i++) rv[i]=rvx[i];   Build(probs);}MixedRandom::MixedRandom(AddedSelectedRandom& sr){   n = sr.nelems();                       // number of terms;   Real* probs = new Real[n]; rv = new Random*[n];   if (!probs || !rv) ErrorNoSpace();   int i=0; sr.load(&i,probs,rv);   Build(probs); delete [] probs;}void MixedRandom::Build(Real* probs){   int i;   dg=new DiscreteGen(n,probs);   if (!dg) ErrorNoSpace();   mean=0.0; var=0.0;   for (i=0; i<n; i++) mean = mean + (rv[i])->Mean()*probs[i];   for (i=0; i<n; i++)   {      ExtReal sigsq=(rv[i])->Variance();      ExtReal mudif=(rv[i])->Mean()-mean;      var = var + (sigsq+square(mudif))*probs[i];   }}MixedRandom::~MixedRandom(){   for (int i=0; i<n; i++) rv[i]->tDelete();   delete [] rv; delete dg;}Real MixedRandom::Next()   { int i = (int)(dg->Next()); return (rv[i])->Next(); }int AddedSelectedRandom::nelems() const   { return rv1->nelems() + rv2->nelems(); }void AddedSelectedRandom::load(int* i, Real* probs, Random** rvx){   rv1->load(i, probs, rvx); rv2->load(i, probs, rvx);   delete this;}AddedSelectedRandom& operator+(SelectedRandom& rv1,   SelectedRandom& rv2){   AddedSelectedRandom* r = new AddedSelectedRandom(rv1, rv2);   if (!r) ErrorNoSpace(); return *r;}AddedSelectedRandom& operator+(AddedSelectedRandom& rv1,   SelectedRandom& rv2){   AddedSelectedRandom* r = new AddedSelectedRandom(rv1, rv2);   if (!r) ErrorNoSpace(); return *r;}AddedSelectedRandom& operator+(SelectedRandom& rv1,   AddedSelectedRandom& rv2){   AddedSelectedRandom* r = new AddedSelectedRandom(rv1, rv2);   if (!r) ErrorNoSpace(); return *r;}AddedSelectedRandom& operator+(AddedSelectedRandom& rv1,   AddedSelectedRandom& rv2){   AddedSelectedRandom* r = new AddedSelectedRandom(rv1, rv2);   if (!r) ErrorNoSpace(); return *r;}SelectedRandom& Random::operator()(double p){   SelectedRandom* r = new SelectedRandom(*this, p);   if (!r) ErrorNoSpace(); return *r;}// Identification routines for each class - may not work on all compilers?char* Random::Name()            { return "Random";           }char* Uniform::Name()           { return "Uniform";          }char* Constant::Name()          { return "Constant";         }char* PosGen::Name()            { return "PosGen";           }char* SymGen::Name()            { return "SymGen";           }char* AsymGen::Name()           { return "AsymGen";          }char* PosGenX::Name()           { return "PosGenX";          }char* SymGenX::Name()           { return "SymGenX";          }char* AsymGenX::Name()          { return "AsymGenX";         }char* Normal::Name()            { return "Normal";           }char* ChiSq::Name()             { return "ChiSq";            }char* Cauchy::Name()            { return "Cauchy";           }char* Exponential::Name()       { return "Exponential";      }char* Poisson::Name()           { return "Poisson";          }char* Binomial::Name()          { return "Binomial";         }char* NegativeBinomial::Name()  { return "NegativeBinomial"; }char* Gamma::Name()             { return "Gamma";            }char* Pareto::Name()            { return "Pareto";           }char* DiscreteGen::Name()       { return "DiscreteGen";      }char* SumRandom::Name()         { return "SumRandom";        }char* MixedRandom::Name()       { return "MixedRandom";      }// ********************** permutation generator ***************************void RandomPermutation::Next(int N, int M, int p[], int start){   // N = size of urn; M = number of draws   if (N < M) Throw(Logic_error("Newran: N < M in RandomPermutation"));   int i;   int* q = new int [N];   if (!q) ErrorNoSpace();   for (i = 0; i < N; i++) q[i] = start + i;   for (i = 0; i < M; i++)   {      int k = i + (int)(U.Next() * (N - i));       // uniform on i ... N-1      p[i] = q[k]; q[k] = q[i];                    // swap i and k terms                                                   // but put i-th term into p   }   delete [] q;}void RandomCombination::SortAscending(int n, int gm[]){   // from numerical recipies in C - Shell sort   const double aln2i = 1.442695022; const double tiny = 1.0e-5;   int m = n; int lognb2 = (int)(aln2i * log((double)n) + tiny);   while (lognb2--)   {      m >>= 1;      for (int j = m; j<n; j++)      {         int* gmj = gm+j; int i = j-m; int* gmi = gmj-m; int t = *gmj;         while (i>=0 && *gmi>t)  { *gmj = *gmi; gmj = gmi; gmi -= m; i -= m; }         *gmj = t;      }   }}#ifdef use_namespace}#endif

⌨️ 快捷键说明

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