Fixed randomvariable bugs and modified unit tests so that there is no non-deterministic failure on the tests
This commit is contained in:
@@ -42,7 +42,6 @@ namespace ns3{
|
||||
//-----------------------------------------------------------------------------
|
||||
// RandomVariable methods
|
||||
|
||||
uint32_t RandomVariable::runNumber = 0;
|
||||
bool RandomVariable::initialized = false; // True if RngStream seed set
|
||||
bool RandomVariable::useDevRandom = false; // True if use /dev/random
|
||||
bool RandomVariable::globalSeedSet = false; // True if GlobalSeed called
|
||||
@@ -50,6 +49,7 @@ int RandomVariable::devRandom = -1;
|
||||
uint32_t RandomVariable::globalSeed[6];
|
||||
unsigned long RandomVariable::heuristic_sequence;
|
||||
RngStream* RandomVariable::m_static_generator = 0;
|
||||
uint32_t RandomVariable::runNumber = 0;
|
||||
|
||||
//the static object random_variable_initializer initializes the static members
|
||||
//of RandomVariable
|
||||
@@ -58,9 +58,9 @@ static class RandomVariableInitializer
|
||||
public:
|
||||
RandomVariableInitializer()
|
||||
{
|
||||
RandomVariable::Initialize(); // sets the static package seed
|
||||
RandomVariable::m_static_generator = new RngStream();
|
||||
RandomVariable::m_static_generator->InitializeStream();
|
||||
// RandomVariable::Initialize(); // sets the static package seed
|
||||
// RandomVariable::m_static_generator = new RngStream();
|
||||
// RandomVariable::m_static_generator->InitializeStream();
|
||||
}
|
||||
~RandomVariableInitializer()
|
||||
{
|
||||
@@ -69,10 +69,11 @@ static class RandomVariableInitializer
|
||||
} random_variable_initializer;
|
||||
|
||||
RandomVariable::RandomVariable()
|
||||
: m_generator(NULL)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
// m_generator = new RngStream();
|
||||
// m_generator->InitializeStream();
|
||||
// m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
|
||||
RandomVariable::RandomVariable(const RandomVariable& r)
|
||||
@@ -97,6 +98,12 @@ void RandomVariable::UseDevRandom(bool udr)
|
||||
|
||||
void RandomVariable::GetSeed(uint32_t seed[6])
|
||||
{
|
||||
if(!m_generator)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
m_generator->GetState(seed);
|
||||
}
|
||||
|
||||
@@ -202,6 +209,16 @@ UniformVariable::UniformVariable(const UniformVariable& c)
|
||||
|
||||
double UniformVariable::GetValue()
|
||||
{
|
||||
if(!RandomVariable::initialized)
|
||||
{
|
||||
RandomVariable::Initialize();
|
||||
}
|
||||
if(!m_generator)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
return m_min + m_generator->RandU01() * (m_max - m_min);
|
||||
}
|
||||
|
||||
@@ -212,6 +229,12 @@ RandomVariable* UniformVariable::Copy() const
|
||||
|
||||
double UniformVariable::GetSingleValue(double s, double l)
|
||||
{
|
||||
if(!RandomVariable::m_static_generator)
|
||||
{
|
||||
RandomVariable::Initialize(); // sets the static package seed
|
||||
RandomVariable::m_static_generator = new RngStream();
|
||||
RandomVariable::m_static_generator->InitializeStream();
|
||||
}
|
||||
return s + m_static_generator->RandU01() * (l - s);;
|
||||
}
|
||||
|
||||
@@ -305,6 +328,16 @@ ExponentialVariable::ExponentialVariable(const ExponentialVariable& c)
|
||||
|
||||
double ExponentialVariable::GetValue()
|
||||
{
|
||||
if(!RandomVariable::initialized)
|
||||
{
|
||||
RandomVariable::Initialize();
|
||||
}
|
||||
if(!m_generator)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
double r = -m_mean*log(m_generator->RandU01());
|
||||
if (m_bound != 0 && r > m_bound) return m_bound;
|
||||
return r;
|
||||
@@ -316,6 +349,12 @@ RandomVariable* ExponentialVariable::Copy() const
|
||||
}
|
||||
double ExponentialVariable::GetSingleValue(double m, double b/*=0*/)
|
||||
{
|
||||
if(!RandomVariable::m_static_generator)
|
||||
{
|
||||
RandomVariable::Initialize(); // sets the static package seed
|
||||
RandomVariable::m_static_generator = new RngStream();
|
||||
RandomVariable::m_static_generator->InitializeStream();
|
||||
}
|
||||
double r = -m*log(m_static_generator->RandU01());
|
||||
if (b != 0 && r > b) return b;
|
||||
return r;
|
||||
@@ -341,6 +380,16 @@ ParetoVariable::ParetoVariable(const ParetoVariable& c)
|
||||
|
||||
double ParetoVariable::GetValue()
|
||||
{
|
||||
if(!RandomVariable::initialized)
|
||||
{
|
||||
RandomVariable::Initialize();
|
||||
}
|
||||
if(!m_generator)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
double scale = m_mean * ( m_shape - 1.0) / m_shape;
|
||||
double r = (scale * ( 1.0 / pow(m_generator->RandU01(), 1.0 / m_shape)));
|
||||
if (m_bound != 0 && r > m_bound) return m_bound;
|
||||
@@ -354,6 +403,12 @@ RandomVariable* ParetoVariable::Copy() const
|
||||
|
||||
double ParetoVariable::GetSingleValue(double m, double s, double b/*=0*/)
|
||||
{
|
||||
if(!RandomVariable::m_static_generator)
|
||||
{
|
||||
RandomVariable::Initialize(); // sets the static package seed
|
||||
RandomVariable::m_static_generator = new RngStream();
|
||||
RandomVariable::m_static_generator->InitializeStream();
|
||||
}
|
||||
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;
|
||||
@@ -375,6 +430,16 @@ WeibullVariable::WeibullVariable(const WeibullVariable& c)
|
||||
|
||||
double WeibullVariable::GetValue()
|
||||
{
|
||||
if(!RandomVariable::initialized)
|
||||
{
|
||||
RandomVariable::Initialize();
|
||||
}
|
||||
if(!m_generator)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
double exponent = 1.0 / m_alpha;
|
||||
double r = m_mean * pow( -log(m_generator->RandU01()), exponent);
|
||||
if (m_bound != 0 && r > m_bound) return m_bound;
|
||||
@@ -388,6 +453,12 @@ RandomVariable* WeibullVariable::Copy() const
|
||||
|
||||
double WeibullVariable::GetSingleValue(double m, double s, double b/*=0*/)
|
||||
{
|
||||
if(!RandomVariable::m_static_generator)
|
||||
{
|
||||
RandomVariable::Initialize(); // sets the static package seed
|
||||
RandomVariable::m_static_generator = new RngStream();
|
||||
RandomVariable::m_static_generator->InitializeStream();
|
||||
}
|
||||
double exponent = 1.0 / s;
|
||||
double r = m * pow( -log(m_static_generator->RandU01()), exponent);
|
||||
if (b != 0 && r > b) return b;
|
||||
@@ -412,6 +483,16 @@ NormalVariable::NormalVariable(const NormalVariable& c)
|
||||
|
||||
double NormalVariable::GetValue()
|
||||
{
|
||||
if(!RandomVariable::initialized)
|
||||
{
|
||||
RandomVariable::Initialize();
|
||||
}
|
||||
if(!m_generator)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
if (m_nextValid)
|
||||
{ // use previously generated
|
||||
m_nextValid = false;
|
||||
@@ -445,6 +526,12 @@ RandomVariable* NormalVariable::Copy() const
|
||||
|
||||
double NormalVariable::GetSingleValue(double m, double v, double b)
|
||||
{
|
||||
if(!RandomVariable::m_static_generator)
|
||||
{
|
||||
RandomVariable::Initialize(); // sets the static package seed
|
||||
RandomVariable::m_static_generator = new RngStream();
|
||||
RandomVariable::m_static_generator->InitializeStream();
|
||||
}
|
||||
if (m_static_nextValid)
|
||||
{ // use previously generated
|
||||
m_static_nextValid = false;
|
||||
@@ -495,6 +582,16 @@ EmpiricalVariable::~EmpiricalVariable() { }
|
||||
double EmpiricalVariable::GetValue()
|
||||
{ // Return a value from the empirical distribution
|
||||
// This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
|
||||
if(!RandomVariable::initialized)
|
||||
{
|
||||
RandomVariable::Initialize();
|
||||
}
|
||||
if(!m_generator)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
if (emp.size() == 0) return 0.0; // HuH? No empirical data
|
||||
if (!validated) Validate(); // Insure in non-decreasing
|
||||
double r = m_generator->RandU01();
|
||||
@@ -642,6 +739,16 @@ LogNormalVariable::LogNormalVariable (double mu, double sigma)
|
||||
double
|
||||
LogNormalVariable::GetValue ()
|
||||
{
|
||||
if(!RandomVariable::initialized)
|
||||
{
|
||||
RandomVariable::Initialize();
|
||||
}
|
||||
if(!m_generator)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
double u, v, r2, normal, z;
|
||||
|
||||
do
|
||||
@@ -665,6 +772,12 @@ LogNormalVariable::GetValue ()
|
||||
|
||||
double LogNormalVariable::GetSingleValue (double mu, double sigma)
|
||||
{
|
||||
if(!RandomVariable::m_static_generator)
|
||||
{
|
||||
RandomVariable::Initialize(); // sets the static package seed
|
||||
RandomVariable::m_static_generator = new RngStream();
|
||||
RandomVariable::m_static_generator->InitializeStream();
|
||||
}
|
||||
double u, v, r2, normal, z;
|
||||
do
|
||||
{
|
||||
@@ -698,6 +811,16 @@ TriangularVariable::TriangularVariable(const TriangularVariable& c)
|
||||
|
||||
double TriangularVariable::GetValue()
|
||||
{
|
||||
if(!RandomVariable::initialized)
|
||||
{
|
||||
RandomVariable::Initialize();
|
||||
}
|
||||
if(!m_generator)
|
||||
{
|
||||
m_generator = new RngStream();
|
||||
m_generator->InitializeStream();
|
||||
m_generator->ResetNthSubstream(RandomVariable::runNumber);
|
||||
}
|
||||
double u = m_generator->RandU01();
|
||||
if(u <= (m_mode - m_min) / (m_max - m_min) )
|
||||
return m_min + sqrt(u * (m_max - m_min) * (m_mode - m_min) );
|
||||
@@ -712,6 +835,12 @@ RandomVariable* TriangularVariable::Copy() const
|
||||
|
||||
double TriangularVariable::GetSingleValue(double s, double l, double mean)
|
||||
{
|
||||
if(!RandomVariable::m_static_generator)
|
||||
{
|
||||
RandomVariable::Initialize(); // sets the static package seed
|
||||
RandomVariable::m_static_generator = new RngStream();
|
||||
RandomVariable::m_static_generator->InitializeStream();
|
||||
}
|
||||
double mode = 3.0*mean-s-l;
|
||||
double u = m_static_generator->RandU01();
|
||||
if(u <= (mode - s) / (l - s) )
|
||||
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
* \brief Returns a random double from the underlying distribution
|
||||
* \return A floating point random value
|
||||
*/
|
||||
virtual double GetValue() = 0;
|
||||
virtual double GetValue() = 0;
|
||||
|
||||
/**
|
||||
* \brief Returns a random integer integer from the underlying distribution
|
||||
@@ -173,19 +173,19 @@ public:
|
||||
*/
|
||||
static void SetRunNumber(uint32_t n);
|
||||
private:
|
||||
static void Initialize(); // Initialize the RNG system
|
||||
static void GetRandomSeeds(uint32_t seeds[6]);
|
||||
private:
|
||||
static bool initialized; // True if package seed is set
|
||||
static bool useDevRandom; // True if using /dev/random desired
|
||||
static bool globalSeedSet; // True if global seed has been specified
|
||||
static int devRandom; // File handle for /dev/random
|
||||
static uint32_t globalSeed[6]; // The global seed to use
|
||||
static uint32_t runNumber;
|
||||
friend class RandomVariableInitializer;
|
||||
protected:
|
||||
static unsigned long heuristic_sequence;
|
||||
static RngStream* m_static_generator;
|
||||
static uint32_t runNumber;
|
||||
static void Initialize(); // Initialize the RNG system
|
||||
static bool initialized; // True if package seed is set
|
||||
RngStream* m_generator; //underlying generator being wrapped
|
||||
};
|
||||
|
||||
|
||||
@@ -21,11 +21,13 @@
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/packet-metadata.h"
|
||||
#include "ns3/random-variable.h"
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
#ifdef RUN_SELF_TESTS
|
||||
ns3::RandomVariable::UseGlobalSeed(1,2,3,4,5,6);
|
||||
ns3::PacketMetadata::Enable ();
|
||||
ns3::TestManager::EnableVerbose ();
|
||||
bool success = ns3::TestManager::RunTests ();
|
||||
|
||||
Reference in New Issue
Block a user