Added static RNGs, like ExponentialVariable::GetSingleValue(mean)
parent
34160210b4
commit
c7db73ec6b
|
@ -44,16 +44,33 @@ namespace ns3{
|
||||||
|
|
||||||
uint32_t RandomVariable::runNumber = 0;
|
uint32_t RandomVariable::runNumber = 0;
|
||||||
bool RandomVariable::initialized = false; // True if RngStream seed set
|
bool RandomVariable::initialized = false; // True if RngStream seed set
|
||||||
bool RandomVariable::useDevRandom = false; // True if use /dev/random desired
|
bool RandomVariable::useDevRandom = false; // True if use /dev/random
|
||||||
bool RandomVariable::globalSeedSet = false; // True if GlobalSeed called
|
bool RandomVariable::globalSeedSet = false; // True if GlobalSeed called
|
||||||
int RandomVariable::devRandom = -1;
|
int RandomVariable::devRandom = -1;
|
||||||
uint32_t RandomVariable::globalSeed[6];
|
uint32_t RandomVariable::globalSeed[6];
|
||||||
unsigned long RandomVariable::heuristic_sequence;
|
unsigned long RandomVariable::heuristic_sequence;
|
||||||
|
RngStream* RandomVariable::m_static_generator = 0;
|
||||||
|
|
||||||
|
//the static object random_variable_initializer initializes the static members
|
||||||
|
//of RandomVariable
|
||||||
|
static class RandomVariableInitializer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RandomVariableInitializer()
|
||||||
|
{
|
||||||
|
RandomVariable::Initialize(); // sets the static package seed
|
||||||
|
RandomVariable::m_static_generator = new RngStream();
|
||||||
|
RandomVariable::m_static_generator->InitializeStream();
|
||||||
|
}
|
||||||
|
~RandomVariableInitializer()
|
||||||
|
{
|
||||||
|
delete RandomVariable::m_static_generator;
|
||||||
|
}
|
||||||
|
} random_variable_initializer;
|
||||||
|
|
||||||
RandomVariable::RandomVariable()
|
RandomVariable::RandomVariable()
|
||||||
{
|
{
|
||||||
m_generator = new RngStream();
|
m_generator = new RngStream();
|
||||||
RandomVariable::Initialize(); // sets the seed for the static object
|
|
||||||
m_generator->InitializeStream();
|
m_generator->InitializeStream();
|
||||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||||
}
|
}
|
||||||
|
@ -173,7 +190,7 @@ void RandomVariable::SetRunNumber(uint32_t n)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// UniformVariable methods
|
// UniformVariable
|
||||||
UniformVariable::UniformVariable()
|
UniformVariable::UniformVariable()
|
||||||
: m_min(0), m_max(1.0) { }
|
: m_min(0), m_max(1.0) { }
|
||||||
|
|
||||||
|
@ -192,6 +209,12 @@ RandomVariable* UniformVariable::Copy() const
|
||||||
{
|
{
|
||||||
return new UniformVariable(*this);
|
return new UniformVariable(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double UniformVariable::GetSingleValue(double s, double l)
|
||||||
|
{
|
||||||
|
return s + m_static_generator->RandU01() * (l - s);;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// ConstantVariable methods
|
// ConstantVariable methods
|
||||||
|
@ -291,6 +314,12 @@ RandomVariable* ExponentialVariable::Copy() const
|
||||||
{
|
{
|
||||||
return new ExponentialVariable(*this);
|
return new ExponentialVariable(*this);
|
||||||
}
|
}
|
||||||
|
double ExponentialVariable::GetSingleValue(double m, double b/*=0*/)
|
||||||
|
{
|
||||||
|
double r = -m*log(m_static_generator->RandU01());
|
||||||
|
if (b != 0 && r > b) return b;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// ParetoVariable methods
|
// ParetoVariable methods
|
||||||
|
@ -322,6 +351,14 @@ RandomVariable* ParetoVariable::Copy() const
|
||||||
{
|
{
|
||||||
return new ParetoVariable(*this);
|
return new ParetoVariable(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double ParetoVariable::GetSingleValue(double m, double s, double b/*=0*/)
|
||||||
|
{
|
||||||
|
double scale = m * ( s - 1.0) / s;
|
||||||
|
double r = (scale * ( 1.0 / pow(m_static_generator->RandU01(), 1.0 / s)));
|
||||||
|
if (b != 0 && r > b) return b;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// WeibullVariable methods
|
// WeibullVariable methods
|
||||||
|
@ -348,14 +385,25 @@ RandomVariable* WeibullVariable::Copy() const
|
||||||
{
|
{
|
||||||
return new WeibullVariable(*this);
|
return new WeibullVariable(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double WeibullVariable::GetSingleValue(double m, double s, double b/*=0*/)
|
||||||
|
{
|
||||||
|
double exponent = 1.0 / s;
|
||||||
|
double r = m * pow( -log(m_static_generator->RandU01()), exponent);
|
||||||
|
if (b != 0 && r > b) return b;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// NormalVariable methods
|
// NormalVariable methods
|
||||||
|
bool NormalVariable::m_static_nextValid = false;
|
||||||
|
double NormalVariable::m_static_next;
|
||||||
const double NormalVariable::INFINITE_VALUE = 1e307;
|
const double NormalVariable::INFINITE_VALUE = 1e307;
|
||||||
|
|
||||||
NormalVariable::NormalVariable()
|
NormalVariable::NormalVariable()
|
||||||
: m_mean(0.0), m_variance(1.0), m_bound(INFINITE_VALUE), m_nextValid(false){}
|
: m_mean(0.0), m_variance(1.0), m_bound(INFINITE_VALUE), m_nextValid(false){}
|
||||||
|
|
||||||
NormalVariable::NormalVariable(double m, double v, double b)
|
NormalVariable::NormalVariable(double m, double v, double b/*=INFINITE_VALUE*/)
|
||||||
: m_mean(m), m_variance(v), m_bound(b), m_nextValid(false) { }
|
: m_mean(m), m_variance(v), m_bound(b), m_nextValid(false) { }
|
||||||
|
|
||||||
NormalVariable::NormalVariable(const NormalVariable& c)
|
NormalVariable::NormalVariable(const NormalVariable& c)
|
||||||
|
@ -395,6 +443,34 @@ RandomVariable* NormalVariable::Copy() const
|
||||||
return new NormalVariable(*this);
|
return new NormalVariable(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double NormalVariable::GetSingleValue(double m, double v, double b)
|
||||||
|
{
|
||||||
|
if (m_static_nextValid)
|
||||||
|
{ // use previously generated
|
||||||
|
m_static_nextValid = false;
|
||||||
|
return m_static_next;
|
||||||
|
}
|
||||||
|
while(1)
|
||||||
|
{ // See Simulation Modeling and Analysis p. 466 (Averill Law)
|
||||||
|
// for algorithm
|
||||||
|
double u1 = m_static_generator->RandU01();
|
||||||
|
double u2 = m_static_generator->RandU01();;
|
||||||
|
double v1 = 2 * u1 - 1;
|
||||||
|
double v2 = 2 * u2 - 1;
|
||||||
|
double w = v1 * v1 + v2 * v2;
|
||||||
|
if (w <= 1.0)
|
||||||
|
{ // Got good pair
|
||||||
|
double y = sqrt((-2 * log(w))/w);
|
||||||
|
m_static_next = m + v2 * y * sqrt(v);
|
||||||
|
if (fabs(m_static_next) > b) m_static_next = b * (m_static_next)/fabs(m_static_next);
|
||||||
|
m_static_nextValid = true;
|
||||||
|
double x1 = m + v1 * y * sqrt(v);
|
||||||
|
if (fabs(x1) > b) x1 = b * (x1)/fabs(x1);
|
||||||
|
return x1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// ValueCDF methods
|
// ValueCDF methods
|
||||||
|
@ -533,9 +609,8 @@ RandomVariable* LogNormalVariable::Copy () const
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNormalVariable::LogNormalVariable (double mu, double sigma)
|
LogNormalVariable::LogNormalVariable (double mu, double sigma)
|
||||||
|
:m_mu(mu), m_sigma(sigma)
|
||||||
{
|
{
|
||||||
m_mu = mu;
|
|
||||||
m_sigma = sigma;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The code from this function was adapted from the GNU Scientific
|
// The code from this function was adapted from the GNU Scientific
|
||||||
|
@ -588,5 +663,26 @@ LogNormalVariable::GetValue ()
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double LogNormalVariable::GetSingleValue(double sigma,double mu)
|
||||||
|
{
|
||||||
|
double u, v, r2, normal, z;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* choose x,y in uniform square (-1,-1) to (+1,+1) */
|
||||||
|
u = -1 + 2 * m_static_generator->RandU01 ();
|
||||||
|
v = -1 + 2 * m_static_generator->RandU01 ();
|
||||||
|
|
||||||
|
/* see if it is in the unit circle */
|
||||||
|
r2 = u * u + v * v;
|
||||||
|
}
|
||||||
|
while (r2 > 1.0 || r2 == 0);
|
||||||
|
|
||||||
|
normal = u * sqrt (-2.0 * log (r2) / r2);
|
||||||
|
|
||||||
|
z = exp (sigma * normal + mu);
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
}//namespace ns3
|
}//namespace ns3
|
||||||
|
|
||||||
|
|
|
@ -182,8 +182,10 @@ private:
|
||||||
static int devRandom; // File handle for /dev/random
|
static int devRandom; // File handle for /dev/random
|
||||||
static uint32_t globalSeed[6]; // The global seed to use
|
static uint32_t globalSeed[6]; // The global seed to use
|
||||||
static uint32_t runNumber;
|
static uint32_t runNumber;
|
||||||
|
friend class RandomVariableInitializer;
|
||||||
protected:
|
protected:
|
||||||
static unsigned long heuristic_sequence;
|
static unsigned long heuristic_sequence;
|
||||||
|
static RngStream* m_static_generator;
|
||||||
RngStream* m_generator; //underlying generator being wrapped
|
RngStream* m_generator; //underlying generator being wrapped
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -191,6 +193,13 @@ protected:
|
||||||
/**
|
/**
|
||||||
* \brief The uniform distribution RNG for NS-3.
|
* \brief The uniform distribution RNG for NS-3.
|
||||||
* \ingroup randomvariable
|
* \ingroup randomvariable
|
||||||
|
* This class supports the creation of objects that return random numbers
|
||||||
|
* from a fixed uniform distribution. It also supports the generation of
|
||||||
|
* single random numbers from various uniform distributions.
|
||||||
|
* \code
|
||||||
|
* UniformVariable x(0,10);
|
||||||
|
* x.GetValue(); //will always return numbers [0,10]
|
||||||
|
* UniformVariable::GetSingleValue(100,1000); //returns a value [100,1000]
|
||||||
*/
|
*/
|
||||||
class UniformVariable : public RandomVariable {
|
class UniformVariable : public RandomVariable {
|
||||||
public:
|
public:
|
||||||
|
@ -214,6 +223,13 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual double GetValue();
|
virtual double GetValue();
|
||||||
virtual RandomVariable* Copy() const;
|
virtual RandomVariable* Copy() const;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \param s Low end of the range
|
||||||
|
* \param l High end of the range
|
||||||
|
* \return A uniformly distributed random number between s and l
|
||||||
|
*/
|
||||||
|
static double GetSingleValue(double s, double l);
|
||||||
private:
|
private:
|
||||||
double m_min;
|
double m_min;
|
||||||
double m_max;
|
double m_max;
|
||||||
|
@ -317,8 +333,16 @@ private:
|
||||||
/**
|
/**
|
||||||
* \brief Exponentially Distributed random var
|
* \brief Exponentially Distributed random var
|
||||||
* \ingroup randomvariable
|
* \ingroup randomvariable
|
||||||
|
* This class supports the creation of objects that return random numbers
|
||||||
|
* from a fixed exponential distribution. It also supports the generation of
|
||||||
|
* single random numbers from various exponential distributions.
|
||||||
|
* \code
|
||||||
|
* ExponentialVariable x(3.14);
|
||||||
|
* x.GetValue(); //will always return with mean 3.14
|
||||||
|
* ExponentialVariable::GetSingleValue(20.1); //returns with mean 20.1
|
||||||
|
* ExponentialVariable::GetSingleValue(108); //returns with mean 108
|
||||||
|
* \endcode
|
||||||
*
|
*
|
||||||
* ExponentialVariable defines a random variable with an exponential distribution
|
|
||||||
*/
|
*/
|
||||||
class ExponentialVariable : public RandomVariable {
|
class ExponentialVariable : public RandomVariable {
|
||||||
public:
|
public:
|
||||||
|
@ -354,6 +378,13 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual double GetValue();
|
virtual double GetValue();
|
||||||
virtual RandomVariable* Copy() const;
|
virtual RandomVariable* Copy() const;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \param m The mean of the distribution from which the return value is drawn
|
||||||
|
* \param b The upper bound value desired, beyond which values get clipped
|
||||||
|
* \return A random number from an exponential distribution with mean m
|
||||||
|
*/
|
||||||
|
static double GetSingleValue(double m, double b=0);
|
||||||
private:
|
private:
|
||||||
double m_mean; // Mean value of RV
|
double m_mean; // Mean value of RV
|
||||||
double m_bound; // Upper bound on value (if non-zero)
|
double m_bound; // Upper bound on value (if non-zero)
|
||||||
|
@ -362,8 +393,17 @@ private:
|
||||||
/**
|
/**
|
||||||
* \brief ParetoVariable distributed random var
|
* \brief ParetoVariable distributed random var
|
||||||
* \ingroup randomvariable
|
* \ingroup randomvariable
|
||||||
|
* This class supports the creation of objects that return random numbers
|
||||||
|
* from a fixed pareto distribution. It also supports the generation of
|
||||||
|
* single random numbers from various pareto distributions.
|
||||||
|
* \code
|
||||||
|
* ParetoVariable x(3.14);
|
||||||
|
* x.GetValue(); //will always return with mean 3.14
|
||||||
|
* ParetoVariable::GetSingleValue(20.1); //returns with mean 20.1
|
||||||
|
* ParetoVariable::GetSingleValue(108); //returns with mean 108
|
||||||
|
* \endcode
|
||||||
*/
|
*/
|
||||||
class ParetoVariable : public RandomVariable { //
|
class ParetoVariable : public RandomVariable {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructs a pareto random variable with a mean of 1 and a shape
|
* Constructs a pareto random variable with a mean of 1 and a shape
|
||||||
|
@ -389,6 +429,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* \brief Constructs a pareto random variable with the specified mean
|
* \brief Constructs a pareto random variable with the specified mean
|
||||||
* \brief value, shape (alpha), and upper bound.
|
* \brief value, shape (alpha), and upper bound.
|
||||||
|
*
|
||||||
* Since pareto distributions can theoretically return unbounded values,
|
* Since pareto distributions can theoretically return unbounded values,
|
||||||
* it is sometimes useful to specify a fixed upper limit. Note however
|
* it is sometimes useful to specify a fixed upper limit. Note however
|
||||||
* when the upper limit is specified, the true mean of the distribution
|
* when the upper limit is specified, the true mean of the distribution
|
||||||
|
@ -406,6 +447,17 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual double GetValue();
|
virtual double GetValue();
|
||||||
virtual RandomVariable* Copy() const;
|
virtual RandomVariable* Copy() const;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \param m The mean value of the distribution from which the return value
|
||||||
|
* is drawn.
|
||||||
|
* \param s The shape parameter of the distribution from which the return
|
||||||
|
* value is drawn.
|
||||||
|
* \param b The upper bound to which to restrict return values
|
||||||
|
* \return A random number from a Pareto distribution with mean m and shape
|
||||||
|
* parameter s.
|
||||||
|
*/
|
||||||
|
static double GetSingleValue(double m, double s, double b=0);
|
||||||
private:
|
private:
|
||||||
double m_mean; // Mean value of RV
|
double m_mean; // Mean value of RV
|
||||||
double m_shape; // Shape parameter
|
double m_shape; // Shape parameter
|
||||||
|
@ -415,6 +467,9 @@ private:
|
||||||
/**
|
/**
|
||||||
* \brief WeibullVariable distributed random var
|
* \brief WeibullVariable distributed random var
|
||||||
* \ingroup randomvariable
|
* \ingroup randomvariable
|
||||||
|
* This class supports the creation of objects that return random numbers
|
||||||
|
* from a fixed weibull distribution. It also supports the generation of
|
||||||
|
* single random numbers from various weibull distributions.
|
||||||
*/
|
*/
|
||||||
class WeibullVariable : public RandomVariable {
|
class WeibullVariable : public RandomVariable {
|
||||||
public:
|
public:
|
||||||
|
@ -460,6 +515,14 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual double GetValue();
|
virtual double GetValue();
|
||||||
virtual RandomVariable* Copy() const;
|
virtual RandomVariable* Copy() const;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \param m Mean value for the distribution.
|
||||||
|
* \param s Shape (alpha) parameter for the distribution.
|
||||||
|
* \param b Upper limit on returned values
|
||||||
|
* \return Random number from a distribution specified by m,s, and b
|
||||||
|
*/
|
||||||
|
static double GetSingleValue(double m, double s, double b=0);
|
||||||
private:
|
private:
|
||||||
double m_mean; // Mean value of RV
|
double m_mean; // Mean value of RV
|
||||||
double m_alpha; // Shape parameter
|
double m_alpha; // Shape parameter
|
||||||
|
@ -469,6 +532,10 @@ private:
|
||||||
/**
|
/**
|
||||||
* \brief Class NormalVariable defines a random variable with a
|
* \brief Class NormalVariable defines a random variable with a
|
||||||
* normal (Gaussian) distribution.
|
* normal (Gaussian) distribution.
|
||||||
|
*
|
||||||
|
* This class supports the creation of objects that return random numbers
|
||||||
|
* from a fixed normal distribution. It also supports the generation of
|
||||||
|
* single random numbers from various normal distributions.
|
||||||
* \ingroup randomvariable
|
* \ingroup randomvariable
|
||||||
*/
|
*/
|
||||||
class NormalVariable : public RandomVariable { // Normally Distributed random var
|
class NormalVariable : public RandomVariable { // Normally Distributed random var
|
||||||
|
@ -481,7 +548,6 @@ public:
|
||||||
*/
|
*/
|
||||||
NormalVariable();
|
NormalVariable();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Construct a normal random variable with specified mean and variance
|
* \brief Construct a normal random variable with specified mean and variance
|
||||||
* \param m Mean value
|
* \param m Mean value
|
||||||
|
@ -497,12 +563,22 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual double GetValue();
|
virtual double GetValue();
|
||||||
virtual RandomVariable* Copy() const;
|
virtual RandomVariable* Copy() const;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \param m Mean value
|
||||||
|
* \param v Variance
|
||||||
|
* \param b Bound. The NormalVariable is bounded within +-bound.
|
||||||
|
* \return A random number from a distribution specified by m,v, and b.
|
||||||
|
*/
|
||||||
|
static double GetSingleValue(double m, double v, double b = INFINITE_VALUE);
|
||||||
private:
|
private:
|
||||||
double m_mean; // Mean value of RV
|
double m_mean; // Mean value of RV
|
||||||
double m_variance; // Mean value of RV
|
double m_variance; // Mean value of RV
|
||||||
double m_bound; // Bound on value (absolute value)
|
double m_bound; // Bound on value (absolute value)
|
||||||
bool m_nextValid; // True if next valid
|
bool m_nextValid; // True if next valid
|
||||||
double m_next; // The algorithm produces two values at a time
|
double m_next; // The algorithm produces two values at a time
|
||||||
|
static bool m_static_nextValid;
|
||||||
|
static double m_static_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -620,6 +696,9 @@ private:
|
||||||
* distribution. If one takes the natural logarithm of random
|
* distribution. If one takes the natural logarithm of random
|
||||||
* variable following the log-normal distribution, the obtained values
|
* variable following the log-normal distribution, the obtained values
|
||||||
* follow a normal distribution.
|
* follow a normal distribution.
|
||||||
|
* This class supports the creation of objects that return random numbers
|
||||||
|
* from a fixed lognormal distribution. It also supports the generation of
|
||||||
|
* single random numbers from various lognormal distributions.
|
||||||
*/
|
*/
|
||||||
class LogNormalVariable : public RandomVariable {
|
class LogNormalVariable : public RandomVariable {
|
||||||
public:
|
public:
|
||||||
|
@ -645,6 +724,13 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual double GetValue ();
|
virtual double GetValue ();
|
||||||
virtual RandomVariable* Copy() const;
|
virtual RandomVariable* Copy() const;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \param mu Mean value of the underlying normal distribution.
|
||||||
|
* \param sigma Standard deviation of the underlying normal distribution.
|
||||||
|
* \return A random number from the distribution specified by mu and sigma
|
||||||
|
*/
|
||||||
|
static double GetSingleValue(double mu, double sigma);
|
||||||
private:
|
private:
|
||||||
double m_mu;
|
double m_mu;
|
||||||
double m_sigma;
|
double m_sigma;
|
||||||
|
|
Loading…
Reference in New Issue