Fixed randomvariable bugs and modified unit tests so that there is no non-deterministic failure on the tests

This commit is contained in:
Raj Bhattacharjea
2007-10-30 13:27:33 -04:00
parent d17845d767
commit 5a0fa236cb
3 changed files with 142 additions and 11 deletions

View File

@@ -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) )

View File

@@ -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
};

View File

@@ -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 ();