Fixed randomvariable bugs and modified unit tests so that there is no non-deterministic failure on the tests
authorRaj Bhattacharjea <raj.b@gatech.edu>
Tue, 30 Oct 2007 13:27:33 -0400
changeset 1806 34e115600ef2
parent 1805 44dfedabcac7
child 1808 36b3cb561c6b
Fixed randomvariable bugs and modified unit tests so that there is no non-deterministic failure on the tests
src/core/random-variable.cc
src/core/random-variable.h
utils/run-tests.cc
--- a/src/core/random-variable.cc	Tue Oct 30 15:55:50 2007 +0000
+++ b/src/core/random-variable.cc	Tue Oct 30 13:27:33 2007 -0400
@@ -42,7 +42,6 @@
 //-----------------------------------------------------------------------------
 // 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 @@
 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 @@
   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 @@
 } 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::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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 }
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 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 @@
 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 @@
 
 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 @@
 
 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 @@
 
 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) )
--- a/src/core/random-variable.h	Tue Oct 30 15:55:50 2007 +0000
+++ b/src/core/random-variable.h	Tue Oct 30 13:27:33 2007 -0400
@@ -71,7 +71,7 @@
    * \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 @@
    */
   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
 };
 
--- a/utils/run-tests.cc	Tue Oct 30 15:55:50 2007 +0000
+++ b/utils/run-tests.cc	Tue Oct 30 13:27:33 2007 -0400
@@ -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 ();