12 #ifndef SIMPLE_RNG_HPP 
   13 #define SIMPLE_RNG_HPP 
   27     unsigned int GetUint()
 
   29         m_z = 36969 * (m_z & 65535) + (m_z >> 16);
 
   30         m_w = 18000 * (m_w & 65535) + (m_w >> 16);
 
   31         return (m_z << 16) + m_w;
 
   49     void SetSeed(
unsigned int u, 
unsigned int v)
 
   55     void SetSeed(
unsigned int u)
 
   60     void SetSeedFromSystemTime()
 
   63         SetSeed((
unsigned int)(x >> 16), (
unsigned int)(x % 4294967296));
 
   71         unsigned int u = GetUint();
 
   74         return (u + 1.0) * 2.328306435454494e-10;
 
   81         double u1 = GetUniform();
 
   82         double u2 = GetUniform();
 
   83         double r = std::sqrt( -2.0*std::log(u1) );
 
   84         double theta = 2.0*3.14159265359*u2;
 
   85         return r*std::sin(theta);
 
   89     double GetNormal(
double mean, 
double standardDeviation)
 
   91         if (standardDeviation <= 0.0)
 
   93             std::cerr << __FILE__ << 
":" << __LINE__ << 
" Shape must be positive. Received." << std::to_string(standardDeviation);
 
   96         return mean + standardDeviation*GetNormal();
 
  100     double GetExponential()
 
  102         return -std::log( GetUniform() );
 
  106     double GetExponential(
double mean)
 
  110             std::cerr << __FILE__ << 
":" << __LINE__ << 
"Mean must be positive. Received " << mean;
 
  113         return mean*GetExponential();
 
  116     double GetGamma(
double shape, 
double scale)
 
  122         double d, c, x, xsquared, v, u;
 
  127             c = 1.0/std::sqrt(9.0*d);
 
  139                 if (u < 1.0 -.0331*xsquared*xsquared || std::log(u) < 0.5*xsquared + d*(1.0 - v + std::log(v)))
 
  143         else if (shape <= 0.0)
 
  145             std::cerr << __FILE__ << 
":" << __LINE__ << 
" Shape must be positive. Received" << shape << 
"\n";
 
  150             double g = GetGamma(shape+1.0, 1.0);
 
  151             double w = GetUniform();
 
  152             return scale*g*std::pow(w, 1.0/shape);
 
  156     double GetChiSquare(
double degreesOfFreedom)
 
  160         return GetGamma(0.5 * degreesOfFreedom, 2.0);
 
  163     double GetInverseGamma(
double shape, 
double scale)
 
  167         return 1.0 / GetGamma(shape, 1.0 / scale);
 
  170     double GetWeibull(
double shape, 
double scale)
 
  172         if (shape <= 0.0 || scale <= 0.0)
 
  174             std::cerr << __FILE__ << 
":" << __LINE__ << 
" Shape and scale parameters must be positive. Recieved " << shape << 
" and " << scale;
 
  177         return scale * std::pow(-std::log(GetUniform()), 1.0 / shape);
 
  180     double GetCauchy(
double median, 
double scale)
 
  184             std::cerr << __FILE__ << 
":" << __LINE__ << 
"Scale must be positive. Received " << scale << 
"\n";
 
  188         double p = GetUniform();
 
  191         return median + scale*std::tan(3.14159265359*(p - 0.5));
 
  194     double GetStudentT(
double degreesOfFreedom)
 
  196         if (degreesOfFreedom <= 0)
 
  198             std::cerr << __FILE__ << 
":" << __LINE__ << 
" Degrees of freedom must be positive. Received " << degreesOfFreedom;
 
  203         double y1 = GetNormal();
 
  204         double y2 = GetChiSquare(degreesOfFreedom);
 
  205         return y1 / std::sqrt(y2 / degreesOfFreedom);
 
  209     double GetLaplace(
double mean, 
double scale)
 
  211         double u = GetUniform();
 
  213             mean + scale*std::log(2.0*u) :
 
  214             mean - scale*std::log(2*(1-u));
 
  217     double GetLogNormal(
double mu, 
double sigma)
 
  219         return std::exp(GetNormal(mu, sigma));
 
  222     double GetBeta(
double a, 
double b)
 
  224         if (a <= 0.0 || b <= 0.0)
 
  226             std::cerr << __FILE__ << 
":" << __LINE__ << 
"Beta parameters must be positive. Received " << a << 
" and " << b << 
"\n";
 
  235         double u = GetGamma(a, 1.0);
 
  236         double v = GetGamma(b, 1.0);
 
SimpleRNG is a simple random number generator based on George Marsaglia's MWC (multiply with carry) g...