bug 133: automate RandomVariable memory management.
--- a/src/applications/onoff/onoff-application.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/applications/onoff/onoff-application.cc Fri Feb 15 20:03:48 2008 +0100
@@ -91,8 +91,8 @@
m_socket = 0;
m_peer = remote;
m_connected = false;
- m_onTime = onTime.Copy ();
- m_offTime = offTime.Copy ();
+ m_onTime = onTime;
+ m_offTime = offTime;
m_pktSize = size;
m_residualBits = 0;
m_lastStartTime = Seconds (0);
@@ -136,12 +136,6 @@
NS_LOG_FUNCTION;
m_socket = 0;
- delete m_onTime;
- delete m_offTime;
-
- m_onTime = 0;
- m_offTime = 0;
-
// chain up
Application::DoDispose ();
}
@@ -223,7 +217,7 @@
{ // Schedules the event to start sending data (switch to the "On" state)
NS_LOG_FUNCTION;
- Time offInterval = Seconds(m_offTime->GetValue());
+ Time offInterval = Seconds(m_offTime.GetValue());
NS_LOG_LOGIC ("start at " << offInterval);
m_startStopEvent = Simulator::Schedule(offInterval, &OnOffApplication::StartSending, this);
}
@@ -232,7 +226,7 @@
{ // Schedules the event to stop sending data (switch to "Off" state)
NS_LOG_FUNCTION;
- Time onInterval = Seconds(m_onTime->GetValue());
+ Time onInterval = Seconds(m_onTime.GetValue());
Simulator::Schedule(onInterval, &OnOffApplication::StopSending, this);
}
--- a/src/applications/onoff/onoff-application.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/applications/onoff/onoff-application.h Fri Feb 15 20:03:48 2008 +0100
@@ -30,6 +30,7 @@
#include "ns3/ptr.h"
#include "ns3/data-rate.h"
#include "ns3/callback-trace-source.h"
+#include "ns3/random-variable.h"
namespace ns3 {
@@ -128,8 +129,8 @@
Ptr<Socket> m_socket; // Associated socket
Address m_peer; // Peer address
bool m_connected; // True if connected
- RandomVariable* m_onTime; // rng for On Time
- RandomVariable* m_offTime; // rng for Off Time
+ RandomVariable m_onTime; // rng for On Time
+ RandomVariable m_offTime; // rng for Off Time
DataRate m_cbrRate; // Rate that data is generated
uint32_t m_pktSize; // Size of packets
uint32_t m_residualBits; // Number of generated, but not sent, bits
--- a/src/common/error-model.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/common/error-model.cc Fri Feb 15 20:03:48 2008 +0100
@@ -140,13 +140,12 @@
{
NS_LOG_FUNCTION;
// Assume a uniform random variable if user does not specify
- m_ranvar = new UniformVariable ();
+ m_ranvar = UniformVariable ();
}
RateErrorModel::~RateErrorModel ()
{
NS_LOG_FUNCTION;
- delete m_ranvar;
}
enum ErrorUnit
@@ -181,8 +180,7 @@
RateErrorModel::SetRandomVariable (const RandomVariable &ranvar)
{
NS_LOG_FUNCTION;
- delete m_ranvar;
- m_ranvar = ranvar.Copy ();
+ m_ranvar = ranvar;
}
bool
@@ -212,7 +210,7 @@
RateErrorModel::DoCorruptPkt (Ptr<Packet> p)
{
NS_LOG_FUNCTION;
- return (m_ranvar->GetValue () < m_rate);
+ return (m_ranvar.GetValue () < m_rate);
}
bool
@@ -221,7 +219,7 @@
NS_LOG_FUNCTION;
// compute pkt error rate, assume uniformly distributed byte error
double per = 1 - pow (1.0 - m_rate, p->GetSize ());
- return (m_ranvar->GetValue () < per);
+ return (m_ranvar.GetValue () < per);
}
bool
@@ -230,7 +228,7 @@
NS_LOG_FUNCTION;
// compute pkt error rate, assume uniformly distributed bit error
double per = 1 - pow (1.0 - m_rate, (8 * p->GetSize ()) );
- return (m_ranvar->GetValue () < per);
+ return (m_ranvar.GetValue () < per);
}
void
--- a/src/common/error-model.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/common/error-model.h Fri Feb 15 20:03:48 2008 +0100
@@ -23,11 +23,11 @@
#include <list>
#include "ns3/object.h"
+#include "ns3/random-variable.h"
namespace ns3 {
class Packet;
-class RandomVariable;
/**
* \brief General error model that can be used to corrupt packets
@@ -174,7 +174,7 @@
enum ErrorUnit m_unit;
double m_rate;
- RandomVariable* m_ranvar;
+ RandomVariable m_ranvar;
};
/**
--- a/src/core/random-variable-default-value.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/core/random-variable-default-value.cc Fri Feb 15 20:03:48 2008 +0100
@@ -39,17 +39,17 @@
DefaultValueList::Add (this);
}
-RandomVariable *
-RandomVariableDefaultValue::GetCopy (void)
+RandomVariable
+RandomVariableDefaultValue::Get (void) const
{
- RandomVariable *variable;
+ RandomVariable variable;
bool ok;
ok = Parse (m_value, true, &variable);
NS_ASSERT (ok);
return variable;
}
double
-RandomVariableDefaultValue::ReadAsDouble (std::string value, bool &ok)
+RandomVariableDefaultValue::ReadAsDouble (std::string value, bool &ok) const
{
double v;
std::istringstream iss;
@@ -60,7 +60,7 @@
}
bool
RandomVariableDefaultValue::Parse (const std::string &value,
- bool mustCreate, RandomVariable **pVariable)
+ bool mustCreate, RandomVariable *pVariable) const
{
std::string::size_type pos = value.find_first_of(":");
if (pos == std::string::npos)
@@ -76,7 +76,7 @@
if (mustCreate)
{
NS_LOG_LOGIC ("create Constant constant=" << constant);
- *pVariable = new ConstantVariable (constant);
+ *pVariable = ConstantVariable (constant);
}
else
{
@@ -100,7 +100,7 @@
if (mustCreate)
{
NS_LOG_LOGIC ("create Uniform min=" << min << ", max=" << max);
- *pVariable = new UniformVariable (minVal, maxVal);
+ *pVariable = UniformVariable (minVal, maxVal);
}
else
{
--- a/src/core/random-variable-default-value.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/core/random-variable-default-value.h Fri Feb 15 20:03:48 2008 +0100
@@ -33,10 +33,10 @@
std::string help,
std::string defaultValue);
- RandomVariable *GetCopy (void);
+ RandomVariable Get (void) const;
private:
- bool Parse (const std::string &value, bool mustCreate, RandomVariable **pVariable);
- double ReadAsDouble (const std::string value, bool &ok);
+ bool Parse (const std::string &value, bool mustCreate, RandomVariable *pVariable) const;
+ double ReadAsDouble (const std::string value, bool &ok) const;
virtual bool DoParseValue (const std::string &value);
virtual std::string DoGetType (void) const;
virtual std::string DoGetDefaultValue (void) const;
--- a/src/core/random-variable.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/core/random-variable.cc Fri Feb 15 20:03:48 2008 +0100
@@ -30,6 +30,7 @@
#include <fcntl.h>
+#include "assert.h"
#include "random-variable.h"
#include "rng-stream.h"
#include "fatal-error.h"
@@ -40,16 +41,51 @@
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// RandomVariable methods
+// RandomVariableBase methods
+
+
+class RandomVariableBase
+{
+public:
+ RandomVariableBase ();
+ RandomVariableBase (const RandomVariableBase &o);
+ virtual ~RandomVariableBase();
+ virtual double GetValue() = 0;
+ virtual uint32_t GetIntValue();
+ virtual RandomVariableBase* Copy(void) const = 0;
+ virtual void GetSeed(uint32_t seed[6]);
-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
-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;
+ static void UseDevRandom(bool udr = true);
+ static void UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2,
+ uint32_t s3, uint32_t s4, uint32_t s5);
+ static void SetRunNumber(uint32_t n);
+private:
+ static void GetRandomSeeds(uint32_t seeds[6]);
+private:
+ 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
+ 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
+};
+
+
+
+bool RandomVariableBase::initialized = false; // True if RngStream seed set
+bool RandomVariableBase::useDevRandom = false; // True if use /dev/random
+bool RandomVariableBase::globalSeedSet = false; // True if GlobalSeed called
+int RandomVariableBase::devRandom = -1;
+uint32_t RandomVariableBase::globalSeed[6];
+unsigned long RandomVariableBase::heuristic_sequence;
+RngStream* RandomVariableBase::m_static_generator = 0;
+uint32_t RandomVariableBase::runNumber = 0;
//the static object random_variable_initializer initializes the static members
//of RandomVariable
@@ -58,25 +94,25 @@
public:
RandomVariableInitializer()
{
-// RandomVariable::Initialize(); // sets the static package seed
-// RandomVariable::m_static_generator = new RngStream();
-// RandomVariable::m_static_generator->InitializeStream();
+// RandomVariableBase::Initialize(); // sets the static package seed
+// RandomVariableBase::m_static_generator = new RngStream();
+// RandomVariableBase::m_static_generator->InitializeStream();
}
~RandomVariableInitializer()
{
- delete RandomVariable::m_static_generator;
+ delete RandomVariableBase::m_static_generator;
}
} random_variable_initializer;
-RandomVariable::RandomVariable()
+RandomVariableBase::RandomVariableBase()
: m_generator(NULL)
{
// m_generator = new RngStream();
// m_generator->InitializeStream();
-// m_generator->ResetNthSubstream(RandomVariable::runNumber);
+// m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
-RandomVariable::RandomVariable(const RandomVariable& r)
+RandomVariableBase::RandomVariableBase(const RandomVariableBase& r)
:m_generator(0)
{
if(r.m_generator)
@@ -85,61 +121,61 @@
}
}
-RandomVariable::~RandomVariable()
+RandomVariableBase::~RandomVariableBase()
{
delete m_generator;
}
-uint32_t RandomVariable::GetIntValue()
+uint32_t RandomVariableBase::GetIntValue()
{
return (uint32_t)GetValue();
}
-void RandomVariable::UseDevRandom(bool udr)
+void RandomVariableBase::UseDevRandom(bool udr)
{
- RandomVariable::useDevRandom = udr;
+ RandomVariableBase::useDevRandom = udr;
}
-void RandomVariable::GetSeed(uint32_t seed[6])
+void RandomVariableBase::GetSeed(uint32_t seed[6])
{
if(!m_generator)
{
m_generator = new RngStream();
m_generator->InitializeStream();
- m_generator->ResetNthSubstream(RandomVariable::runNumber);
+ m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
m_generator->GetState(seed);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// RandomVariable static methods
-void RandomVariable::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2,
+// RandomVariableBase static methods
+void RandomVariableBase::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2,
uint32_t s3, uint32_t s4, uint32_t s5)
{
- if (RandomVariable::globalSeedSet)
+ if (RandomVariableBase::globalSeedSet)
{
cerr << "Random number generator already initialized!" << endl;
- cerr << "Call to RandomVariable::UseGlobalSeed() ignored" << endl;
+ cerr << "Call to RandomVariableBase::UseGlobalSeed() ignored" << endl;
return;
}
- RandomVariable::globalSeed[0] = s0;
- RandomVariable::globalSeed[1] = s1;
- RandomVariable::globalSeed[2] = s2;
- RandomVariable::globalSeed[3] = s3;
- RandomVariable::globalSeed[4] = s4;
- RandomVariable::globalSeed[5] = s5;
- if (!RngStream::CheckSeed(RandomVariable::globalSeed))
+ RandomVariableBase::globalSeed[0] = s0;
+ RandomVariableBase::globalSeed[1] = s1;
+ RandomVariableBase::globalSeed[2] = s2;
+ RandomVariableBase::globalSeed[3] = s3;
+ RandomVariableBase::globalSeed[4] = s4;
+ RandomVariableBase::globalSeed[5] = s5;
+ if (!RngStream::CheckSeed(RandomVariableBase::globalSeed))
NS_FATAL_ERROR("Invalid seed");
- RandomVariable::globalSeedSet = true;
+ RandomVariableBase::globalSeedSet = true;
}
-void RandomVariable::Initialize()
+void RandomVariableBase::Initialize()
{
- if (RandomVariable::initialized) return; // Already initialized and seeded
- RandomVariable::initialized = true;
- if (!RandomVariable::globalSeedSet)
+ if (RandomVariableBase::initialized) return; // Already initialized and seeded
+ RandomVariableBase::initialized = true;
+ if (!RandomVariableBase::globalSeedSet)
{ // No global seed, try a random one
GetRandomSeeds(globalSeed);
}
@@ -147,20 +183,20 @@
RngStream::SetPackageSeed(globalSeed);
}
-void RandomVariable::GetRandomSeeds(uint32_t seeds[6])
+void RandomVariableBase::GetRandomSeeds(uint32_t seeds[6])
{
// Check if /dev/random exists
- if (RandomVariable::useDevRandom && RandomVariable::devRandom < 0)
+ if (RandomVariableBase::useDevRandom && RandomVariableBase::devRandom < 0)
{
- RandomVariable::devRandom = open("/dev/random", O_RDONLY);
+ RandomVariableBase::devRandom = open("/dev/random", O_RDONLY);
}
- if (RandomVariable::devRandom > 0)
+ if (RandomVariableBase::devRandom > 0)
{ // Use /dev/random
while(true)
{
for (int i = 0; i < 6; ++i)
{
- read(RandomVariable::devRandom, &seeds[i], sizeof(seeds[i]));
+ read(RandomVariableBase::devRandom, &seeds[i], sizeof(seeds[i]));
}
if (RngStream::CheckSeed(seeds)) break; // Got a valid one
}
@@ -194,205 +230,537 @@
}
}
-void RandomVariable::SetRunNumber(uint32_t n)
+void RandomVariableBase::SetRunNumber(uint32_t n)
{
runNumber = n;
}
+
+
+RandomVariable::RandomVariable()
+ : m_variable (0)
+{}
+RandomVariable::RandomVariable(const RandomVariable&o)
+ : m_variable (o.m_variable->Copy ())
+{}
+RandomVariable::RandomVariable (const RandomVariableBase &variable)
+ : m_variable (variable.Copy ())
+{}
+RandomVariable &
+RandomVariable::operator = (const RandomVariable &o)
+{
+ delete m_variable;
+ m_variable = o.m_variable->Copy ();
+ return *this;
+}
+RandomVariable::~RandomVariable()
+{
+ delete m_variable;
+}
+double
+RandomVariable::GetValue (void) const
+{
+ return m_variable->GetValue ();
+}
+
+uint32_t
+RandomVariable::GetIntValue (void) const
+{
+ return m_variable->GetIntValue ();
+}
+void
+RandomVariable::GetSeed(uint32_t seed[6]) const
+{
+ return m_variable->GetSeed (seed);
+}
+void
+RandomVariable::UseDevRandom(bool udr)
+{
+ RandomVariableBase::UseDevRandom (udr);
+}
+void
+RandomVariable::UseGlobalSeed(uint32_t s0, uint32_t s1, uint32_t s2,
+ uint32_t s3, uint32_t s4, uint32_t s5)
+{
+ RandomVariableBase::UseGlobalSeed (s0, s1, s2, s3, s4, s5);
+}
+void
+RandomVariable::SetRunNumber(uint32_t n)
+{
+ RandomVariableBase::SetRunNumber (n);
+}
+RandomVariableBase *
+RandomVariable::Peek (void)
+{
+ return m_variable;
+}
+
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// UniformVariable
-UniformVariable::UniformVariable()
+// UniformVariableImpl
+
+class UniformVariableImpl : public RandomVariableBase {
+public:
+ /**
+ * Creates a uniform random number generator in the
+ * range [0.0 .. 1.0).
+ */
+ UniformVariableImpl();
+
+ /**
+ * Creates a uniform random number generator with the specified range
+ * \param s Low end of the range
+ * \param l High end of the range
+ */
+ UniformVariableImpl(double s, double l);
+
+ UniformVariableImpl(const UniformVariableImpl& c);
+
+ /**
+ * \return A value between low and high values specified by the constructor
+ */
+ virtual double GetValue();
+ virtual RandomVariableBase* Copy(void) 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:
+ double m_min;
+ double m_max;
+};
+
+UniformVariableImpl::UniformVariableImpl()
: m_min(0), m_max(1.0) { }
-UniformVariable::UniformVariable(double s, double l)
+UniformVariableImpl::UniformVariableImpl(double s, double l)
: m_min(s), m_max(l) { }
-UniformVariable::UniformVariable(const UniformVariable& c)
- : RandomVariable(c), m_min(c.m_min), m_max(c.m_max) { }
+UniformVariableImpl::UniformVariableImpl(const UniformVariableImpl& c)
+ : RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max) { }
-double UniformVariable::GetValue()
+double UniformVariableImpl::GetValue()
{
- if(!RandomVariable::initialized)
+ if(!RandomVariableBase::initialized)
{
- RandomVariable::Initialize();
+ RandomVariableBase::Initialize();
}
if(!m_generator)
{
m_generator = new RngStream();
m_generator->InitializeStream();
- m_generator->ResetNthSubstream(RandomVariable::runNumber);
+ m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
return m_min + m_generator->RandU01() * (m_max - m_min);
}
-RandomVariable* UniformVariable::Copy() const
+RandomVariableBase* UniformVariableImpl::Copy() const
+{
+ return new UniformVariableImpl(*this);
+}
+
+double UniformVariableImpl::GetSingleValue(double s, double l)
{
- return new UniformVariable(*this);
+ if(!RandomVariableBase::m_static_generator)
+ {
+ RandomVariableBase::Initialize(); // sets the static package seed
+ RandomVariableBase::m_static_generator = new RngStream();
+ RandomVariableBase::m_static_generator->InitializeStream();
+ }
+ return s + m_static_generator->RandU01() * (l - s);;
+}
+
+UniformVariable::UniformVariable()
+ : RandomVariable (UniformVariableImpl ())
+{}
+UniformVariable::UniformVariable(double s, double l)
+ : RandomVariable (UniformVariableImpl (s, l))
+{}
+double
+UniformVariable::GetSingleValue(double s, double l)
+{
+ return UniformVariableImpl::GetSingleValue (s, l);
}
-double UniformVariable::GetSingleValue(double s, double l)
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// ConstantVariableImpl methods
+
+class ConstantVariableImpl : public RandomVariableBase {
+
+public:
+ /**
+ * Construct a ConstantVariableImpl RNG that returns zero every sample
+ */
+ ConstantVariableImpl();
+
+ /**
+ * Construct a ConstantVariableImpl RNG that returns the specified value
+ * every sample.
+ * \param c Unchanging value for this RNG.
+ */
+ ConstantVariableImpl(double c);
+
+
+ ConstantVariableImpl(const ConstantVariableImpl& c) ;
+
+ /**
+ * \brief Specify a new constant RNG for this generator.
+ * \param c New constant value for this RNG.
+ */
+ void NewConstant(double c);
+
+ /**
+ * \return The constant value specified
+ */
+ virtual double GetValue();
+ virtual uint32_t GetIntValue();
+ virtual RandomVariableBase* Copy(void) const;
+private:
+ double m_const;
+};
+
+ConstantVariableImpl::ConstantVariableImpl()
+ : m_const(0) { }
+
+ConstantVariableImpl::ConstantVariableImpl(double c)
+ : m_const(c) { };
+
+ConstantVariableImpl::ConstantVariableImpl(const ConstantVariableImpl& c)
+ : RandomVariableBase(c), m_const(c.m_const) { }
+
+void ConstantVariableImpl::NewConstant(double c)
+ { m_const = c;}
+
+double ConstantVariableImpl::GetValue()
{
- 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);;
+ return m_const;
+}
+
+uint32_t ConstantVariableImpl::GetIntValue()
+{
+ return (uint32_t)m_const;
+}
+
+RandomVariableBase* ConstantVariableImpl::Copy() const
+{
+ return new ConstantVariableImpl(*this);
+}
+
+ConstantVariable::ConstantVariable()
+ : RandomVariable (ConstantVariableImpl ())
+{}
+ConstantVariable::ConstantVariable(double c)
+ : RandomVariable (ConstantVariableImpl (c))
+{}
+void
+ConstantVariable::SetConstant(double c)
+{
+ *this = ConstantVariable (c);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// ConstantVariable methods
-ConstantVariable::ConstantVariable()
- : m_const(0) { }
+// SequentialVariableImpl methods
-ConstantVariable::ConstantVariable(double c)
- : m_const(c) { };
-
-ConstantVariable::ConstantVariable(const ConstantVariable& c)
- : RandomVariable(c), m_const(c.m_const) { }
+
+class SequentialVariableImpl : public RandomVariableBase {
-void ConstantVariable::NewConstant(double c)
- { m_const = c;}
-
-double ConstantVariable::GetValue()
-{
- return m_const;
-}
+public:
+ /**
+ * \brief Constructor for the SequentialVariableImpl RNG.
+ *
+ * The four parameters define the sequence. For example
+ * SequentialVariableImpl(0,5,1,2) creates a RNG that has the sequence
+ * 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0 ...
+ * \param f First value of the sequence.
+ * \param l One more than the last value of the sequence.
+ * \param i Increment between sequence values
+ * \param c Number of times each member of the sequence is repeated
+ */
+ SequentialVariableImpl(double f, double l, double i = 1, uint32_t c = 1);
-uint32_t ConstantVariable::GetIntValue()
-{
- return (uint32_t)m_const;
-}
+ /**
+ * \brief Constructor for the SequentialVariableImpl RNG.
+ *
+ * Differs from the first only in that the increment parameter is a
+ * random variable
+ * \param f First value of the sequence.
+ * \param l One more than the last value of the sequence.
+ * \param i Reference to a RandomVariableBase for the sequence increment
+ * \param c Number of times each member of the sequence is repeated
+ */
+ SequentialVariableImpl(double f, double l, const RandomVariable& i, uint32_t c = 1);
-RandomVariable* ConstantVariable::Copy() const
-{
- return new ConstantVariable(*this);
-}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// SequentialVariable methods
-SequentialVariable::SequentialVariable(double f, double l, double i, uint32_t c)
- : m_min(f), m_max(l), m_increment(ConstantVariable(i).Copy()), m_consecutive(c),
- m_current(f), m_currentConsecutive(0)
-{
-}
+ SequentialVariableImpl(const SequentialVariableImpl& c);
+
+ ~SequentialVariableImpl();
+ /**
+ * \return The next value in the Sequence
+ */
+ virtual double GetValue();
+ virtual RandomVariableBase* Copy(void) const;
+private:
+ double m_min;
+ double m_max;
+ RandomVariable m_increment;
+ uint32_t m_consecutive;
+ double m_current;
+ uint32_t m_currentConsecutive;
+};
-SequentialVariable::SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c)
- : m_min(f), m_max(l), m_increment(i.Copy()), m_consecutive(c),
+SequentialVariableImpl::SequentialVariableImpl(double f, double l, double i, uint32_t c)
+ : m_min(f), m_max(l), m_increment(ConstantVariable(i)), m_consecutive(c),
m_current(f), m_currentConsecutive(0)
-{
-}
+{}
-SequentialVariable::SequentialVariable(const SequentialVariable& c)
- : RandomVariable(c), m_min(c.m_min), m_max(c.m_max),
- m_increment(c.m_increment->Copy()), m_consecutive(c.m_consecutive),
+SequentialVariableImpl::SequentialVariableImpl(double f, double l, const RandomVariable& i, uint32_t c)
+ : m_min(f), m_max(l), m_increment(i), m_consecutive(c),
+ m_current(f), m_currentConsecutive(0)
+{}
+
+SequentialVariableImpl::SequentialVariableImpl(const SequentialVariableImpl& c)
+ : RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max),
+ m_increment(c.m_increment), m_consecutive(c.m_consecutive),
m_current(c.m_current), m_currentConsecutive(c.m_currentConsecutive)
-{
-}
+{}
-SequentialVariable::~SequentialVariable()
-{
- delete m_increment;
-}
+SequentialVariableImpl::~SequentialVariableImpl()
+{}
-double SequentialVariable::GetValue()
+double SequentialVariableImpl::GetValue()
{ // Return a sequential series of values
double r = m_current;
if (++m_currentConsecutive == m_consecutive)
{ // Time to advance to next
m_currentConsecutive = 0;
- m_current += m_increment->GetValue();
+ m_current += m_increment.GetValue();
if (m_current >= m_max)
m_current = m_min + (m_current - m_max);
}
return r;
}
-RandomVariable* SequentialVariable::Copy() const
+RandomVariableBase* SequentialVariableImpl::Copy() const
{
- return new SequentialVariable(*this);
+ return new SequentialVariableImpl(*this);
}
+
+SequentialVariable::SequentialVariable(double f, double l, double i, uint32_t c)
+ : RandomVariable (SequentialVariableImpl (f, l, i, c))
+{}
+SequentialVariable::SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c)
+ : RandomVariable (SequentialVariableImpl (f, l, i, c))
+{}
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// ExponentialVariable methods
-ExponentialVariable::ExponentialVariable()
+// ExponentialVariableImpl methods
+
+class ExponentialVariableImpl : public RandomVariableBase {
+public:
+ /**
+ * Constructs an exponential random variable with a mean
+ * value of 1.0.
+ */
+ ExponentialVariableImpl();
+
+ /**
+ * \brief Constructs an exponential random variable with a specified mean
+ * \param m Mean value for the random variable
+ */
+ explicit ExponentialVariableImpl(double m);
+
+ /**
+ * \brief Constructs an exponential random variable with spefified
+ * \brief mean and upper limit.
+ *
+ * Since exponential distributions can theoretically return unbounded values,
+ * it is sometimes useful to specify a fixed upper limit. Note however when
+ * the upper limit is specified, the true mean of the distribution is
+ * slightly smaller than the mean value specified.
+ * \param m Mean value of the random variable
+ * \param b Upper bound on returned values
+ */
+ ExponentialVariableImpl(double m, double b);
+
+ ExponentialVariableImpl(const ExponentialVariableImpl& c);
+
+ /**
+ * \return A random value from this exponential distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariableBase* Copy(void) 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:
+ double m_mean; // Mean value of RV
+ double m_bound; // Upper bound on value (if non-zero)
+};
+
+ExponentialVariableImpl::ExponentialVariableImpl()
: m_mean(1.0), m_bound(0) { }
-ExponentialVariable::ExponentialVariable(double m)
+ExponentialVariableImpl::ExponentialVariableImpl(double m)
: m_mean(m), m_bound(0) { }
-ExponentialVariable::ExponentialVariable(double m, double b)
+ExponentialVariableImpl::ExponentialVariableImpl(double m, double b)
: m_mean(m), m_bound(b) { }
-ExponentialVariable::ExponentialVariable(const ExponentialVariable& c)
- : RandomVariable(c), m_mean(c.m_mean), m_bound(c.m_bound) { }
+ExponentialVariableImpl::ExponentialVariableImpl(const ExponentialVariableImpl& c)
+ : RandomVariableBase(c), m_mean(c.m_mean), m_bound(c.m_bound) { }
-double ExponentialVariable::GetValue()
+double ExponentialVariableImpl::GetValue()
{
- if(!RandomVariable::initialized)
+ if(!RandomVariableBase::initialized)
{
- RandomVariable::Initialize();
+ RandomVariableBase::Initialize();
}
if(!m_generator)
{
m_generator = new RngStream();
m_generator->InitializeStream();
- m_generator->ResetNthSubstream(RandomVariable::runNumber);
+ m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
double r = -m_mean*log(m_generator->RandU01());
if (m_bound != 0 && r > m_bound) return m_bound;
return r;
}
-RandomVariable* ExponentialVariable::Copy() const
+RandomVariableBase* ExponentialVariableImpl::Copy() const
{
- return new ExponentialVariable(*this);
+ return new ExponentialVariableImpl(*this);
}
-double ExponentialVariable::GetSingleValue(double m, double b/*=0*/)
+double ExponentialVariableImpl::GetSingleValue(double m, double b/*=0*/)
{
- if(!RandomVariable::m_static_generator)
+ if(!RandomVariableBase::m_static_generator)
{
- RandomVariable::Initialize(); // sets the static package seed
- RandomVariable::m_static_generator = new RngStream();
- RandomVariable::m_static_generator->InitializeStream();
+ RandomVariableBase::Initialize(); // sets the static package seed
+ RandomVariableBase::m_static_generator = new RngStream();
+ RandomVariableBase::m_static_generator->InitializeStream();
}
double r = -m*log(m_static_generator->RandU01());
if (b != 0 && r > b) return b;
return r;
}
+
+ExponentialVariable::ExponentialVariable()
+ : RandomVariable (ExponentialVariableImpl ())
+{}
+ExponentialVariable::ExponentialVariable(double m)
+ : RandomVariable (ExponentialVariableImpl (m))
+{}
+ExponentialVariable::ExponentialVariable(double m, double b)
+ : RandomVariable (ExponentialVariableImpl (m, b))
+{}
+double
+ExponentialVariable::GetSingleValue(double m, double b)
+{
+ return ExponentialVariableImpl::GetSingleValue (m, b);
+}
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// ParetoVariable methods
-ParetoVariable::ParetoVariable()
+// ParetoVariableImpl methods
+class ParetoVariableImpl : public RandomVariableBase {
+public:
+ /**
+ * Constructs a pareto random variable with a mean of 1 and a shape
+ * parameter of 1.5
+ */
+ ParetoVariableImpl();
+
+ /**
+ * Constructs a pareto random variable with specified mean and shape
+ * parameter of 1.5
+ * \param m Mean value of the distribution
+ */
+ explicit ParetoVariableImpl(double m);
+
+ /**
+ * Constructs a pareto random variable with the specified mean value and
+ * shape parameter.
+ * \param m Mean value of the distribution
+ * \param s Shape parameter for the distribution
+ */
+ ParetoVariableImpl(double m, double s);
+
+ /**
+ * \brief Constructs a pareto random variable with the specified mean
+ * \brief value, shape (alpha), and upper bound.
+ *
+ * Since pareto distributions can theoretically return unbounded values,
+ * it is sometimes useful to specify a fixed upper limit. Note however
+ * when the upper limit is specified, the true mean of the distribution
+ * is slightly smaller than the mean value specified.
+ * \param m Mean value
+ * \param s Shape parameter
+ * \param b Upper limit on returned values
+ */
+ ParetoVariableImpl(double m, double s, double b);
+
+ ParetoVariableImpl(const ParetoVariableImpl& c);
+
+ /**
+ * \return A random value from this Pareto distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariableBase* 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:
+ double m_mean; // Mean value of RV
+ double m_shape; // Shape parameter
+ double m_bound; // Upper bound on value (if non-zero)
+};
+
+ParetoVariableImpl::ParetoVariableImpl()
: m_mean(1.0), m_shape(1.5), m_bound(0) { }
-ParetoVariable::ParetoVariable(double m)
+ParetoVariableImpl::ParetoVariableImpl(double m)
: m_mean(m), m_shape(1.5), m_bound(0) { }
-ParetoVariable::ParetoVariable(double m, double s)
+ParetoVariableImpl::ParetoVariableImpl(double m, double s)
: m_mean(m), m_shape(s), m_bound(0) { }
-ParetoVariable::ParetoVariable(double m, double s, double b)
+ParetoVariableImpl::ParetoVariableImpl(double m, double s, double b)
: m_mean(m), m_shape(s), m_bound(b) { }
-ParetoVariable::ParetoVariable(const ParetoVariable& c)
- : RandomVariable(c), m_mean(c.m_mean), m_shape(c.m_shape),
+ParetoVariableImpl::ParetoVariableImpl(const ParetoVariableImpl& c)
+ : RandomVariableBase(c), m_mean(c.m_mean), m_shape(c.m_shape),
m_bound(c.m_bound) { }
-double ParetoVariable::GetValue()
+double ParetoVariableImpl::GetValue()
{
- if(!RandomVariable::initialized)
+ if(!RandomVariableBase::initialized)
{
- RandomVariable::Initialize();
+ RandomVariableBase::Initialize();
}
if(!m_generator)
{
m_generator = new RngStream();
m_generator->InitializeStream();
- m_generator->ResetNthSubstream(RandomVariable::runNumber);
+ m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
double scale = m_mean * ( m_shape - 1.0) / m_shape;
double r = (scale * ( 1.0 / pow(m_generator->RandU01(), 1.0 / m_shape)));
@@ -400,49 +768,127 @@
return r;
}
-RandomVariable* ParetoVariable::Copy() const
+RandomVariableBase* ParetoVariableImpl::Copy() const
{
- return new ParetoVariable(*this);
+ return new ParetoVariableImpl(*this);
}
-double ParetoVariable::GetSingleValue(double m, double s, double b/*=0*/)
+double ParetoVariableImpl::GetSingleValue(double m, double s, double b/*=0*/)
{
- if(!RandomVariable::m_static_generator)
+ if(!RandomVariableBase::m_static_generator)
{
- RandomVariable::Initialize(); // sets the static package seed
- RandomVariable::m_static_generator = new RngStream();
- RandomVariable::m_static_generator->InitializeStream();
+ RandomVariableBase::Initialize(); // sets the static package seed
+ RandomVariableBase::m_static_generator = new RngStream();
+ RandomVariableBase::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;
return r;
}
+
+ParetoVariable::ParetoVariable ()
+ : RandomVariable (ParetoVariableImpl ())
+{}
+ParetoVariable::ParetoVariable(double m)
+ : RandomVariable (ParetoVariableImpl (m))
+{}
+ParetoVariable::ParetoVariable(double m, double s)
+ : RandomVariable (ParetoVariableImpl (m, s))
+{}
+ParetoVariable::ParetoVariable(double m, double s, double b)
+ : RandomVariable (ParetoVariableImpl (m, s, b))
+{}
+double
+ParetoVariable::GetSingleValue(double m, double s, double b)
+{
+ return ParetoVariableImpl::GetSingleValue (m, s, b);
+}
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// WeibullVariable methods
-WeibullVariable::WeibullVariable() : m_mean(1.0), m_alpha(1), m_bound(0) { }
-WeibullVariable::WeibullVariable(double m)
+// WeibullVariableImpl methods
+
+class WeibullVariableImpl : public RandomVariableBase {
+public:
+ /**
+ * Constructs a weibull random variable with a mean
+ * value of 1.0 and a shape (alpha) parameter of 1
+ */
+ WeibullVariableImpl();
+
+
+ /**
+ * Constructs a weibull random variable with the specified mean
+ * value and a shape (alpha) parameter of 1.5.
+ * \param m mean value of the distribution
+ */
+ WeibullVariableImpl(double m) ;
+
+ /**
+ * Constructs a weibull random variable with the specified mean
+ * value and a shape (alpha).
+ * \param m Mean value for the distribution.
+ * \param s Shape (alpha) parameter for the distribution.
+ */
+ WeibullVariableImpl(double m, double s);
+
+ /**
+ * \brief Constructs a weibull random variable with the specified mean
+ * \brief value, shape (alpha), and upper bound.
+ * Since WeibullVariableImpl distributions can theoretically return unbounded values,
+ * it is sometimes usefull to specify a fixed upper limit. Note however
+ * that when the upper limit is specified, the true mean of the distribution
+ * is slightly smaller than the mean value specified.
+ * \param m Mean value for the distribution.
+ * \param s Shape (alpha) parameter for the distribution.
+ * \param b Upper limit on returned values
+ */
+ WeibullVariableImpl(double m, double s, double b);
+
+ WeibullVariableImpl(const WeibullVariableImpl& c);
+
+ /**
+ * \return A random value from this Weibull distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariableBase* Copy(void) 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:
+ double m_mean; // Mean value of RV
+ double m_alpha; // Shape parameter
+ double m_bound; // Upper bound on value (if non-zero)
+};
+
+WeibullVariableImpl::WeibullVariableImpl() : m_mean(1.0), m_alpha(1), m_bound(0) { }
+WeibullVariableImpl::WeibullVariableImpl(double m)
: m_mean(m), m_alpha(1), m_bound(0) { }
-WeibullVariable::WeibullVariable(double m, double s)
+WeibullVariableImpl::WeibullVariableImpl(double m, double s)
: m_mean(m), m_alpha(s), m_bound(0) { }
-WeibullVariable::WeibullVariable(double m, double s, double b)
+WeibullVariableImpl::WeibullVariableImpl(double m, double s, double b)
: m_mean(m), m_alpha(s), m_bound(b) { };
-WeibullVariable::WeibullVariable(const WeibullVariable& c)
- : RandomVariable(c), m_mean(c.m_mean), m_alpha(c.m_alpha),
+WeibullVariableImpl::WeibullVariableImpl(const WeibullVariableImpl& c)
+ : RandomVariableBase(c), m_mean(c.m_mean), m_alpha(c.m_alpha),
m_bound(c.m_bound) { }
-double WeibullVariable::GetValue()
+double WeibullVariableImpl::GetValue()
{
- if(!RandomVariable::initialized)
+ if(!RandomVariableBase::initialized)
{
- RandomVariable::Initialize();
+ RandomVariableBase::Initialize();
}
if(!m_generator)
{
m_generator = new RngStream();
m_generator->InitializeStream();
- m_generator->ResetNthSubstream(RandomVariable::runNumber);
+ m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
double exponent = 1.0 / m_alpha;
double r = m_mean * pow( -log(m_generator->RandU01()), exponent);
@@ -450,52 +896,114 @@
return r;
}
-RandomVariable* WeibullVariable::Copy() const
+RandomVariableBase* WeibullVariableImpl::Copy() const
{
- return new WeibullVariable(*this);
+ return new WeibullVariableImpl(*this);
}
-double WeibullVariable::GetSingleValue(double m, double s, double b/*=0*/)
+double WeibullVariableImpl::GetSingleValue(double m, double s, double b/*=0*/)
{
- if(!RandomVariable::m_static_generator)
+ if(!RandomVariableBase::m_static_generator)
{
- RandomVariable::Initialize(); // sets the static package seed
- RandomVariable::m_static_generator = new RngStream();
- RandomVariable::m_static_generator->InitializeStream();
+ RandomVariableBase::Initialize(); // sets the static package seed
+ RandomVariableBase::m_static_generator = new RngStream();
+ RandomVariableBase::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;
return r;
}
+
+WeibullVariable::WeibullVariable()
+ : RandomVariable (WeibullVariableImpl ())
+{}
+WeibullVariable::WeibullVariable(double m)
+ : RandomVariable (WeibullVariableImpl (m))
+{}
+WeibullVariable::WeibullVariable(double m, double s)
+ : RandomVariable (WeibullVariableImpl (m, s))
+{}
+WeibullVariable::WeibullVariable(double m, double s, double b)
+ : RandomVariable (WeibullVariableImpl (m, s, b))
+{}
+double
+WeibullVariable::GetSingleValue(double m, double s, double b)
+{
+ return WeibullVariableImpl::GetSingleValue (m, s, b);
+}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// NormalVariable methods
-bool NormalVariable::m_static_nextValid = false;
-double NormalVariable::m_static_next;
-const double NormalVariable::INFINITE_VALUE = 1e307;
+// NormalVariableImpl methods
+
+class NormalVariableImpl : public RandomVariableBase { // Normally Distributed random var
+
+public:
+ static const double INFINITE_VALUE;
+ /**
+ * Constructs an normal random variable with a mean
+ * value of 0 and variance of 1.
+ */
+ NormalVariableImpl();
+
+ /**
+ * \brief Construct a normal random variable with specified mean and variance
+ * \param m Mean value
+ * \param v Variance
+ * \param b Bound. The NormalVariableImpl is bounded within +-bound.
+ */
+ NormalVariableImpl(double m, double v, double b = INFINITE_VALUE);
-NormalVariable::NormalVariable()
+ NormalVariableImpl(const NormalVariableImpl& c);
+
+ /**
+ * \return A value from this normal distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariableBase* Copy(void) const;
+public:
+ /**
+ * \param m Mean value
+ * \param v Variance
+ * \param b Bound. The NormalVariableImpl 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:
+ double m_mean; // Mean value of RV
+ double m_variance; // Mean value of RV
+ double m_bound; // Bound on value (absolute value)
+ bool m_nextValid; // True if next valid
+ double m_next; // The algorithm produces two values at a time
+ static bool m_static_nextValid;
+ static double m_static_next;
+};
+
+bool NormalVariableImpl::m_static_nextValid = false;
+double NormalVariableImpl::m_static_next;
+const double NormalVariableImpl::INFINITE_VALUE = 1e307;
+
+NormalVariableImpl::NormalVariableImpl()
: m_mean(0.0), m_variance(1.0), m_bound(INFINITE_VALUE), m_nextValid(false){}
-NormalVariable::NormalVariable(double m, double v, double b/*=INFINITE_VALUE*/)
+NormalVariableImpl::NormalVariableImpl(double m, double v, double b/*=INFINITE_VALUE*/)
: m_mean(m), m_variance(v), m_bound(b), m_nextValid(false) { }
-NormalVariable::NormalVariable(const NormalVariable& c)
- : RandomVariable(c), m_mean(c.m_mean), m_variance(c.m_variance),
+NormalVariableImpl::NormalVariableImpl(const NormalVariableImpl& c)
+ : RandomVariableBase(c), m_mean(c.m_mean), m_variance(c.m_variance),
m_bound(c.m_bound) { }
-double NormalVariable::GetValue()
+double NormalVariableImpl::GetValue()
{
- if(!RandomVariable::initialized)
+ if(!RandomVariableBase::initialized)
{
- RandomVariable::Initialize();
+ RandomVariableBase::Initialize();
}
if(!m_generator)
{
m_generator = new RngStream();
m_generator->InitializeStream();
- m_generator->ResetNthSubstream(RandomVariable::runNumber);
+ m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
if (m_nextValid)
{ // use previously generated
@@ -523,18 +1031,18 @@
}
}
-RandomVariable* NormalVariable::Copy() const
+RandomVariableBase* NormalVariableImpl::Copy() const
{
- return new NormalVariable(*this);
+ return new NormalVariableImpl(*this);
}
-double NormalVariable::GetSingleValue(double m, double v, double b)
+double NormalVariableImpl::GetSingleValue(double m, double v, double b)
{
- if(!RandomVariable::m_static_generator)
+ if(!RandomVariableBase::m_static_generator)
{
- RandomVariable::Initialize(); // sets the static package seed
- RandomVariable::m_static_generator = new RngStream();
- RandomVariable::m_static_generator->InitializeStream();
+ RandomVariableBase::Initialize(); // sets the static package seed
+ RandomVariableBase::m_static_generator = new RngStream();
+ RandomVariableBase::m_static_generator->InitializeStream();
}
if (m_static_nextValid)
{ // use previously generated
@@ -562,39 +1070,89 @@
}
}
+NormalVariable::NormalVariable()
+ : RandomVariable (NormalVariableImpl ())
+{}
+NormalVariable::NormalVariable(double m, double v, double b)
+ : RandomVariable (NormalVariableImpl (m, v, b))
+{}
+double
+NormalVariable::GetSingleValue(double m, double v, double b)
+{
+ return NormalVariableImpl::GetSingleValue (m, v, b);
+}
+
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
+class EmpiricalVariableImpl : public RandomVariableBase {
+public:
+ /**
+ * Constructor for the EmpiricalVariableImpl random variables.
+ */
+ explicit EmpiricalVariableImpl();
+
+ virtual ~EmpiricalVariableImpl();
+ EmpiricalVariableImpl(const EmpiricalVariableImpl& c);
+ /**
+ * \return A value from this empirical distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariableBase* Copy(void) const;
+ /**
+ * \brief Specifies a point in the empirical distribution
+ * \param v The function value for this point
+ * \param c Probability that the function is less than or equal to v
+ */
+ virtual void CDF(double v, double c); // Value, prob <= Value
+
+private:
+ class ValueCDF {
+ public:
+ ValueCDF();
+ ValueCDF(double v, double c);
+ ValueCDF(const ValueCDF& c);
+ double value;
+ double cdf;
+ };
+ virtual void Validate(); // Insure non-decreasing emiprical values
+ virtual double Interpolate(double, double, double, double, double);
+ bool validated; // True if non-decreasing validated
+ std::vector<ValueCDF> emp; // Empicical CDF
+};
+
+
// ValueCDF methods
-EmpiricalVariable::ValueCDF::ValueCDF()
+EmpiricalVariableImpl::ValueCDF::ValueCDF()
: value(0.0), cdf(0.0){ }
-EmpiricalVariable::ValueCDF::ValueCDF(double v, double c)
+EmpiricalVariableImpl::ValueCDF::ValueCDF(double v, double c)
: value(v), cdf(c) { }
-EmpiricalVariable::ValueCDF::ValueCDF(const ValueCDF& c)
+EmpiricalVariableImpl::ValueCDF::ValueCDF(const ValueCDF& c)
: value(c.value), cdf(c.cdf) { }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// EmpiricalVariable methods
-EmpiricalVariable::EmpiricalVariable()
+// EmpiricalVariableImpl methods
+EmpiricalVariableImpl::EmpiricalVariableImpl()
: validated(false) { }
-EmpiricalVariable::EmpiricalVariable(const EmpiricalVariable& c)
- : RandomVariable(c), validated(c.validated), emp(c.emp) { }
+EmpiricalVariableImpl::EmpiricalVariableImpl(const EmpiricalVariableImpl& c)
+ : RandomVariableBase(c), validated(c.validated), emp(c.emp) { }
-EmpiricalVariable::~EmpiricalVariable() { }
+EmpiricalVariableImpl::~EmpiricalVariableImpl() { }
-double EmpiricalVariable::GetValue()
+double EmpiricalVariableImpl::GetValue()
{ // Return a value from the empirical distribution
// This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
- if(!RandomVariable::initialized)
+ if(!RandomVariableBase::initialized)
{
- RandomVariable::Initialize();
+ RandomVariableBase::Initialize();
}
if(!m_generator)
{
m_generator = new RngStream();
m_generator->InitializeStream();
- m_generator->ResetNthSubstream(RandomVariable::runNumber);
+ m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
if (emp.size() == 0) return 0.0; // HuH? No empirical data
if (!validated) Validate(); // Insure in non-decreasing
@@ -619,18 +1177,18 @@
}
}
-RandomVariable* EmpiricalVariable::Copy() const
+RandomVariableBase* EmpiricalVariableImpl::Copy() const
{
- return new EmpiricalVariable(*this);
+ return new EmpiricalVariableImpl(*this);
}
-void EmpiricalVariable::CDF(double v, double c)
+void EmpiricalVariableImpl::CDF(double v, double c)
{ // Add a new empirical datapoint to the empirical cdf
// NOTE. These MUST be inserted in non-decreasing order
emp.push_back(ValueCDF(v, c));
}
-void EmpiricalVariable::Validate()
+void EmpiricalVariableImpl::Validate()
{
ValueCDF prior;
for (std::vector<ValueCDF>::size_type i = 0; i < emp.size(); ++i)
@@ -650,66 +1208,156 @@
validated = true;
}
-double EmpiricalVariable::Interpolate(double c1, double c2,
+double EmpiricalVariableImpl::Interpolate(double c1, double c2,
double v1, double v2, double r)
{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
return (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// Integer EmpiricalVariable methods
-IntEmpiricalVariable::IntEmpiricalVariable() { }
-
-uint32_t IntEmpiricalVariable::GetIntValue()
+EmpiricalVariable::EmpiricalVariable()
+ : RandomVariable (EmpiricalVariableImpl ())
+{}
+EmpiricalVariable::EmpiricalVariable (const RandomVariableBase &variable)
+ : RandomVariable (variable)
+{}
+void
+EmpiricalVariable::CDF(double v, double c)
{
- return (uint32_t)GetValue();
-}
-
-RandomVariable* IntEmpiricalVariable::Copy() const
-{
- return new IntEmpiricalVariable(*this);
-}
-
-double IntEmpiricalVariable::Interpolate(double c1, double c2,
- double v1, double v2, double r)
-{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
- return ceil(v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
+ EmpiricalVariableImpl *impl = dynamic_cast<EmpiricalVariableImpl *> (Peek ());
+ NS_ASSERT (impl);
+ impl->CDF (v, c);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// DeterministicVariable
-DeterministicVariable::DeterministicVariable(double* d, uint32_t c)
+// Integer EmpiricalVariableImpl methods
+class IntEmpiricalVariableImpl : public EmpiricalVariableImpl {
+public:
+
+ IntEmpiricalVariableImpl();
+
+ virtual RandomVariableBase* Copy(void) const;
+ /**
+ * \return An integer value from this empirical distribution
+ */
+ virtual uint32_t GetIntValue();
+private:
+ virtual double Interpolate(double, double, double, double, double);
+};
+
+
+IntEmpiricalVariableImpl::IntEmpiricalVariableImpl() { }
+
+uint32_t IntEmpiricalVariableImpl::GetIntValue()
+{
+ return (uint32_t)GetValue();
+}
+
+RandomVariableBase* IntEmpiricalVariableImpl::Copy() const
+{
+ return new IntEmpiricalVariableImpl(*this);
+}
+
+double IntEmpiricalVariableImpl::Interpolate(double c1, double c2,
+ double v1, double v2, double r)
+{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
+ return ceil(v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
+}
+
+IntEmpiricalVariable::IntEmpiricalVariable()
+ : EmpiricalVariable (IntEmpiricalVariableImpl ())
+{}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// DeterministicVariableImpl
+class DeterministicVariableImpl : public RandomVariableBase
+{
+
+public:
+ /**
+ * \brief Constructor
+ *
+ * Creates a generator that returns successive elements of the d array
+ * on successive calls to ::Value(). Note that the d pointer is copied
+ * for use by the generator (shallow-copy), not its contents, so the
+ * contents of the array d points to have to remain unchanged for the use
+ * of DeterministicVariableImpl to be meaningful.
+ * \param d Pointer to array of random values to return in sequence
+ * \param c Number of values in the array
+ */
+ explicit DeterministicVariableImpl(double* d, uint32_t c);
+
+ virtual ~DeterministicVariableImpl();
+ /**
+ * \return The next value in the deterministic sequence
+ */
+ virtual double GetValue();
+ virtual RandomVariableBase* Copy(void) const;
+private:
+ uint32_t count;
+ uint32_t next;
+ double* data;
+};
+
+DeterministicVariableImpl::DeterministicVariableImpl(double* d, uint32_t c)
: count(c), next(c), data(d)
{ // Nothing else needed
}
-DeterministicVariable::~DeterministicVariable() { }
+DeterministicVariableImpl::~DeterministicVariableImpl() { }
-double DeterministicVariable::GetValue()
+double DeterministicVariableImpl::GetValue()
{
if (next == count) next = 0;
return data[next++];
}
-RandomVariable* DeterministicVariable::Copy() const
+RandomVariableBase* DeterministicVariableImpl::Copy() const
{
- return new DeterministicVariable(*this);
+ return new DeterministicVariableImpl(*this);
}
+DeterministicVariable::DeterministicVariable(double* d, uint32_t c)
+ : RandomVariable (DeterministicVariableImpl (d, c))
+{}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// LogNormalVariable
+// LogNormalVariableImpl
+class LogNormalVariableImpl : public RandomVariableBase {
+public:
+ /**
+ * \param mu mu parameter of the lognormal distribution
+ * \param sigma sigma parameter of the lognormal distribution
+ */
+ LogNormalVariableImpl (double mu, double sigma);
-RandomVariable* LogNormalVariable::Copy () const
+ /**
+ * \return A random value from this distribution
+ */
+ virtual double GetValue ();
+ virtual RandomVariableBase* Copy(void) const;
+public:
+ /**
+ * \param mu mu parameter of the underlying normal distribution
+ * \param sigma sigma parameter 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:
+ double m_mu;
+ double m_sigma;
+};
+
+
+RandomVariableBase* LogNormalVariableImpl::Copy () const
{
- return new LogNormalVariable (m_mu, m_sigma);
+ return new LogNormalVariableImpl (m_mu, m_sigma);
}
-LogNormalVariable::LogNormalVariable (double mu, double sigma)
+LogNormalVariableImpl::LogNormalVariableImpl (double mu, double sigma)
:m_mu(mu), m_sigma(sigma)
{
}
@@ -741,17 +1389,17 @@
for x > 0. Lognormal random numbers are the exponentials of
gaussian random numbers */
double
-LogNormalVariable::GetValue ()
+LogNormalVariableImpl::GetValue ()
{
- if(!RandomVariable::initialized)
+ if(!RandomVariableBase::initialized)
{
- RandomVariable::Initialize();
+ RandomVariableBase::Initialize();
}
if(!m_generator)
{
m_generator = new RngStream();
m_generator->InitializeStream();
- m_generator->ResetNthSubstream(RandomVariable::runNumber);
+ m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
double u, v, r2, normal, z;
@@ -774,13 +1422,13 @@
return z;
}
-double LogNormalVariable::GetSingleValue (double mu, double sigma)
+double LogNormalVariableImpl::GetSingleValue (double mu, double sigma)
{
- if(!RandomVariable::m_static_generator)
+ if(!RandomVariableBase::m_static_generator)
{
- RandomVariable::Initialize(); // sets the static package seed
- RandomVariable::m_static_generator = new RngStream();
- RandomVariable::m_static_generator->InitializeStream();
+ RandomVariableBase::Initialize(); // sets the static package seed
+ RandomVariableBase::m_static_generator = new RngStream();
+ RandomVariableBase::m_static_generator->InitializeStream();
}
double u, v, r2, normal, z;
do
@@ -801,29 +1449,78 @@
return z;
}
+LogNormalVariable::LogNormalVariable (double mu, double sigma)
+ : RandomVariable (LogNormalVariableImpl (mu, sigma))
+{}
+double
+LogNormalVariable::GetSingleValue(double mu, double sigma)
+{
+ return LogNormalVariableImpl::GetSingleValue (mu, sigma);
+}
+
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-// TriangularVariable methods
-TriangularVariable::TriangularVariable()
+// TriangularVariableImpl methods
+class TriangularVariableImpl : public RandomVariableBase {
+public:
+ /**
+ * Creates a triangle distribution random number generator in the
+ * range [0.0 .. 1.0), with mean of 0.5
+ */
+ TriangularVariableImpl();
+
+ /**
+ * Creates a triangle distribution random number generator with the specified
+ * range
+ * \param s Low end of the range
+ * \param l High end of the range
+ * \param mean mean of the distribution
+ */
+ TriangularVariableImpl(double s, double l, double mean);
+
+ TriangularVariableImpl(const TriangularVariableImpl& c);
+
+ /**
+ * \return A value from this distribution
+ */
+ virtual double GetValue();
+ virtual RandomVariableBase* Copy(void) const;
+public:
+ /**
+ * \param s Low end of the range
+ * \param l High end of the range
+ * \param mean mean of the distribution
+ * \return A triangularly distributed random number between s and l
+ */
+ static double GetSingleValue(double s, double l, double mean);
+private:
+ double m_min;
+ double m_max;
+ double m_mode; //easier to work with the mode internally instead of the mean
+ //they are related by the simple: mean = (min+max+mode)/3
+};
+
+TriangularVariableImpl::TriangularVariableImpl()
: m_min(0), m_max(1), m_mode(0.5) { }
-TriangularVariable::TriangularVariable(double s, double l, double mean)
+TriangularVariableImpl::TriangularVariableImpl(double s, double l, double mean)
: m_min(s), m_max(l), m_mode(3.0*mean-s-l) { }
-TriangularVariable::TriangularVariable(const TriangularVariable& c)
- : RandomVariable(c), m_min(c.m_min), m_max(c.m_max), m_mode(c.m_mode) { }
+TriangularVariableImpl::TriangularVariableImpl(const TriangularVariableImpl& c)
+ : RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max), m_mode(c.m_mode) { }
-double TriangularVariable::GetValue()
+double TriangularVariableImpl::GetValue()
{
- if(!RandomVariable::initialized)
+ if(!RandomVariableBase::initialized)
{
- RandomVariable::Initialize();
+ RandomVariableBase::Initialize();
}
if(!m_generator)
{
m_generator = new RngStream();
m_generator->InitializeStream();
- m_generator->ResetNthSubstream(RandomVariable::runNumber);
+ m_generator->ResetNthSubstream(RandomVariableBase::runNumber);
}
double u = m_generator->RandU01();
if(u <= (m_mode - m_min) / (m_max - m_min) )
@@ -832,18 +1529,18 @@
return m_max - sqrt( (1-u) * (m_max - m_min) * (m_max - m_mode) );
}
-RandomVariable* TriangularVariable::Copy() const
+RandomVariableBase* TriangularVariableImpl::Copy() const
{
- return new TriangularVariable(*this);
+ return new TriangularVariableImpl(*this);
}
-double TriangularVariable::GetSingleValue(double s, double l, double mean)
+double TriangularVariableImpl::GetSingleValue(double s, double l, double mean)
{
- if(!RandomVariable::m_static_generator)
+ if(!RandomVariableBase::m_static_generator)
{
- RandomVariable::Initialize(); // sets the static package seed
- RandomVariable::m_static_generator = new RngStream();
- RandomVariable::m_static_generator->InitializeStream();
+ RandomVariableBase::Initialize(); // sets the static package seed
+ RandomVariableBase::m_static_generator = new RngStream();
+ RandomVariableBase::m_static_generator->InitializeStream();
}
double mode = 3.0*mean-s-l;
double u = m_static_generator->RandU01();
@@ -853,6 +1550,19 @@
return l - sqrt( (1-u) * (l - s) * (l - mode) );
}
+TriangularVariable::TriangularVariable()
+ : RandomVariable (TriangularVariableImpl ())
+{}
+TriangularVariable::TriangularVariable(double s, double l, double mean)
+ : RandomVariable (TriangularVariableImpl (s,l,mean))
+{}
+double
+TriangularVariable::GetSingleValue(double s, double l, double mean)
+{
+ return TriangularVariableImpl::GetSingleValue (s,l,mean);
+}
+
+
}//namespace ns3
--- a/src/core/random-variable.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/core/random-variable.h Fri Feb 15 20:03:48 2008 +0100
@@ -33,7 +33,7 @@
namespace ns3{
-class RngStream;
+class RandomVariableBase;
/**
* \brief The basic RNG for NS-3.
@@ -44,46 +44,31 @@
* the University of Montreal.
*
* NS-3 has a rich set of random number generators.
- * Class RandomVariable defines the base class functionalty
+ * Class RandomVariableBase defines the base class functionalty
* required for all random number generators. By default, the underlying
* generator is seeded with the time of day, and then deterministically
* creates a sequence of seeds for each subsequent generator that is created.
* The rest of the documentation outlines how to change this behavior.
*/
-class RandomVariable {
-
+class RandomVariable
+{
public:
- /**
- * \brief Constructor for a random number generator with a random seed.
- */
RandomVariable();
-
- /**
- * \brief Copy constructor
- */
- RandomVariable(const RandomVariable&);
-
- /**
- * \brief Destructor for a random number generator with a random seed.
- */
- virtual ~RandomVariable();
+ RandomVariable(const RandomVariable&o);
+ RandomVariable &operator = (const RandomVariable &o);
+ ~RandomVariable();
/**
* \brief Returns a random double from the underlying distribution
* \return A floating point random value
*/
- virtual double GetValue() = 0;
+ double GetValue (void) const;
/**
* \brief Returns a random integer integer from the underlying distribution
* \return Integer cast of ::GetValue()
*/
- virtual uint32_t GetIntValue();
-
- /**
- * \return A copy of this object
- */
- virtual RandomVariable* Copy() const = 0;
+ uint32_t GetIntValue (void) const;
/**
* \brief Get the internal state of the RNG
@@ -94,7 +79,7 @@
* \param seed Output parameter; gets overwritten with the internal state of
* of the RNG.
*/
- virtual void GetSeed(uint32_t seed[6]);
+ void GetSeed(uint32_t seed[6]) const;
/**
* \brief Set seeding behavior
@@ -104,7 +89,7 @@
* generator is seeded with data from /dev/random instead of
* being seeded based upon the time of day. For this to be effective,
* it must be called before the creation of the first instance of a
- * RandomVariable or subclass. Example:
+ * RandomVariableBase or subclass. Example:
* \code
* RandomVariable::UseDevRandom();
* UniformVariable x(2,3); //these are seeded randomly
@@ -174,23 +159,12 @@
*/
static void SetRunNumber(uint32_t n);
private:
- static void GetRandomSeeds(uint32_t seeds[6]);
-private:
- 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
- friend class RandomVariableInitializer;
+ RandomVariableBase *m_variable;
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
+ RandomVariable (const RandomVariableBase &variable);
+ RandomVariableBase *Peek (void);
};
-
/**
* \brief The uniform distribution RNG for NS-3.
* \ingroup randomvariable
@@ -207,7 +181,8 @@
* UniformVariable::GetSingleValue(100,1000); //returns a value [100,1000)
* \endcode
*/
-class UniformVariable : public RandomVariable {
+class UniformVariable : public RandomVariable
+{
public:
/**
* Creates a uniform random number generator in the
@@ -221,14 +196,6 @@
* \param l High end of the range
*/
UniformVariable(double s, double l);
-
- UniformVariable(const UniformVariable& c);
-
- /**
- * \return A value between low and high values specified by the constructor
- */
- virtual double GetValue();
- virtual RandomVariable* Copy() const;
public:
/**
* \param s Low end of the range
@@ -236,50 +203,36 @@
* \return A uniformly distributed random number between s and l
*/
static double GetSingleValue(double s, double l);
-private:
- double m_min;
- double m_max;
};
/**
* \brief A random variable that returns a constant
* \ingroup randomvariable
*
- * Class ConstantVariable defines a random number generator that
+ * Class ConstantVariableImpl defines a random number generator that
* returns the same value every sample.
*/
class ConstantVariable : public RandomVariable {
public:
/**
- * Construct a ConstantVariable RNG that returns zero every sample
+ * Construct a ConstantVariableImpl RNG that returns zero every sample
*/
ConstantVariable();
/**
- * Construct a ConstantVariable RNG that returns the specified value
+ * Construct a ConstantVariableImpl RNG that returns the specified value
* every sample.
* \param c Unchanging value for this RNG.
*/
ConstantVariable(double c);
-
- ConstantVariable(const ConstantVariable& c) ;
-
/**
* \brief Specify a new constant RNG for this generator.
* \param c New constant value for this RNG.
*/
- void NewConstant(double c);
+ void SetConstant(double c);
- /**
- * \return The constant value specified
- */
- virtual double GetValue();
- virtual uint32_t GetIntValue();
- virtual RandomVariable* Copy() const;
-private:
- double m_const;
};
/**
@@ -291,14 +244,14 @@
* increases for a period, then wraps around to the low value
* and begins monotonicaly increasing again.
*/
-class SequentialVariable : public RandomVariable {
-
+class SequentialVariable : public RandomVariable
+{
public:
/**
- * \brief Constructor for the SequentialVariable RNG.
+ * \brief Constructor for the SequentialVariableImpl RNG.
*
* The four parameters define the sequence. For example
- * SequentialVariable(0,5,1,2) creates a RNG that has the sequence
+ * SequentialVariableImpl(0,5,1,2) creates a RNG that has the sequence
* 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0 ...
* \param f First value of the sequence.
* \param l One more than the last value of the sequence.
@@ -308,32 +261,17 @@
SequentialVariable(double f, double l, double i = 1, uint32_t c = 1);
/**
- * \brief Constructor for the SequentialVariable RNG.
+ * \brief Constructor for the SequentialVariableImpl RNG.
*
* Differs from the first only in that the increment parameter is a
* random variable
* \param f First value of the sequence.
* \param l One more than the last value of the sequence.
- * \param i Reference to a RandomVariable for the sequence increment
+ * \param i Reference to a RandomVariableBase for the sequence increment
* \param c Number of times each member of the sequence is repeated
*/
SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c = 1);
- SequentialVariable(const SequentialVariable& c);
-
- ~SequentialVariable();
- /**
- * \return The next value in the Sequence
- */
- virtual double GetValue();
- virtual RandomVariable* Copy() const;
-private:
- double m_min;
- double m_max;
- RandomVariable* m_increment;
- uint32_t m_consecutive;
- double m_current;
- uint32_t m_currentConsecutive;
};
/**
@@ -353,14 +291,15 @@
* \f$ \left\{ \begin{array}{cl} \alpha e^{-\alpha x} & x < bound \\ bound & x > bound \end{array}\right. \f$
*
* \code
- * ExponentialVariable x(3.14);
+ * ExponentialVariableImpl 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
+ * ExponentialVariableImpl::GetSingleValue(20.1); //returns with mean 20.1
+ * ExponentialVariableImpl::GetSingleValue(108); //returns with mean 108
* \endcode
*
*/
-class ExponentialVariable : public RandomVariable {
+class ExponentialVariable : public RandomVariable
+{
public:
/**
* Constructs an exponential random variable with a mean
@@ -387,27 +326,16 @@
*/
ExponentialVariable(double m, double b);
- ExponentialVariable(const ExponentialVariable& c);
-
- /**
- * \return A random value from this exponential distribution
- */
- virtual double GetValue();
- 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:
- double m_mean; // Mean value of RV
- double m_bound; // Upper bound on value (if non-zero)
};
/**
- * \brief ParetoVariable distributed random var
+ * \brief ParetoVariableImpl distributed random var
* \ingroup randomvariable
*
* This class supports the creation of objects that return random numbers
@@ -422,19 +350,20 @@
* with the equation \f$ x_m = mean \frac{k-1}{k}, k > 1\f$.
*
* \code
- * ParetoVariable x(3.14);
+ * ParetoVariableImpl 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
+ * ParetoVariableImpl::GetSingleValue(20.1); //returns with mean 20.1
+ * ParetoVariableImpl::GetSingleValue(108); //returns with mean 108
* \endcode
*/
-class ParetoVariable : public RandomVariable {
+class ParetoVariable : public RandomVariable
+{
public:
/**
* Constructs a pareto random variable with a mean of 1 and a shape
* parameter of 1.5
*/
- ParetoVariable();
+ ParetoVariable ();
/**
* Constructs a pareto random variable with specified mean and shape
@@ -465,14 +394,6 @@
*/
ParetoVariable(double m, double s, double b);
- ParetoVariable(const ParetoVariable& c);
-
- /**
- * \return A random value from this Pareto distribution
- */
- virtual double GetValue();
- virtual RandomVariable* Copy() const;
-public:
/**
* \param m The mean value of the distribution from which the return value
* is drawn.
@@ -483,14 +404,10 @@
* parameter s.
*/
static double GetSingleValue(double m, double s, double b=0);
-private:
- double m_mean; // Mean value of RV
- double m_shape; // Shape parameter
- double m_bound; // Upper bound on value (if non-zero)
};
/**
- * \brief WeibullVariable distributed random var
+ * \brief WeibullVariableImpl distributed random var
* \ingroup randomvariable
*
* This class supports the creation of objects that return random numbers
@@ -530,7 +447,7 @@
/**
* \brief Constructs a weibull random variable with the specified mean
* \brief value, shape (alpha), and upper bound.
- * Since WeibullVariable distributions can theoretically return unbounded values,
+ * Since WeibullVariableImpl distributions can theoretically return unbounded values,
* it is sometimes usefull to specify a fixed upper limit. Note however
* that when the upper limit is specified, the true mean of the distribution
* is slightly smaller than the mean value specified.
@@ -539,15 +456,6 @@
* \param b Upper limit on returned values
*/
WeibullVariable(double m, double s, double b);
-
- WeibullVariable(const WeibullVariable& c);
-
- /**
- * \return A random value from this Weibull distribution
- */
- virtual double GetValue();
- virtual RandomVariable* Copy() const;
-public:
/**
* \param m Mean value for the distribution.
* \param s Shape (alpha) parameter for the distribution.
@@ -555,14 +463,10 @@
* \return Random number from a distribution specified by m,s, and b
*/
static double GetSingleValue(double m, double s, double b=0);
-private:
- double m_mean; // Mean value of RV
- double m_alpha; // Shape parameter
- double m_bound; // Upper bound on value (if non-zero)
};
/**
- * \brief Class NormalVariable defines a random variable with a
+ * \brief Class NormalVariableImpl defines a random variable with a
* normal (Gaussian) distribution.
* \ingroup randomvariable
*
@@ -575,8 +479,8 @@
* where \f$ mean = \mu \f$ and \f$ variance = \sigma^2 \f$
*
*/
-class NormalVariable : public RandomVariable { // Normally Distributed random var
-
+class NormalVariable : public RandomVariable
+{
public:
static const double INFINITE_VALUE;
/**
@@ -589,37 +493,20 @@
* \brief Construct a normal random variable with specified mean and variance
* \param m Mean value
* \param v Variance
- * \param b Bound. The NormalVariable is bounded within +-bound.
+ * \param b Bound. The NormalVariableImpl is bounded within +-bound.
*/
NormalVariable(double m, double v, double b = INFINITE_VALUE);
-
- NormalVariable(const NormalVariable& c);
-
- /**
- * \return A value from this normal distribution
- */
- virtual double GetValue();
- virtual RandomVariable* Copy() const;
-public:
/**
* \param m Mean value
* \param v Variance
- * \param b Bound. The NormalVariable is bounded within +-bound.
+ * \param b Bound. The NormalVariableImpl 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:
- double m_mean; // Mean value of RV
- double m_variance; // Mean value of RV
- double m_bound; // Bound on value (absolute value)
- bool m_nextValid; // True if next valid
- double m_next; // The algorithm produces two values at a time
- static bool m_static_nextValid;
- static double m_static_next;
};
/**
- * \brief EmpiricalVariable distribution random var
+ * \brief EmpiricalVariableImpl distribution random var
* \ingroup randomvariable
*
* Defines a random variable that has a specified, empirical
@@ -634,37 +521,18 @@
class EmpiricalVariable : public RandomVariable {
public:
/**
- * Constructor for the EmpiricalVariable random variables.
+ * Constructor for the EmpiricalVariableImpl random variables.
*/
explicit EmpiricalVariable();
- virtual ~EmpiricalVariable();
- EmpiricalVariable(const EmpiricalVariable& c);
- /**
- * \return A value from this empirical distribution
- */
- virtual double GetValue();
- virtual RandomVariable* Copy() const;
/**
* \brief Specifies a point in the empirical distribution
* \param v The function value for this point
* \param c Probability that the function is less than or equal to v
*/
- virtual void CDF(double v, double c); // Value, prob <= Value
-
-private:
- class ValueCDF {
- public:
- ValueCDF();
- ValueCDF(double v, double c);
- ValueCDF(const ValueCDF& c);
- double value;
- double cdf;
- };
- virtual void Validate(); // Insure non-decreasing emiprical values
- virtual double Interpolate(double, double, double, double, double);
- bool validated; // True if non-decreasing validated
- std::vector<ValueCDF> emp; // Empicical CDF
+ void CDF(double v, double c); // Value, prob <= Value
+protected:
+ EmpiricalVariable (const RandomVariableBase &variable);
};
/**
@@ -672,20 +540,13 @@
* \ingroup randomvariable
*
* Defines an empirical distribution where all values are integers.
- * Indentical to EmpiricalVariable, but with slightly different
+ * Indentical to EmpiricalVariableImpl, but with slightly different
* interpolation between points.
*/
-class IntEmpiricalVariable : public EmpiricalVariable {
+class IntEmpiricalVariable : public EmpiricalVariable
+{
public:
-
IntEmpiricalVariable();
-
- virtual RandomVariable* Copy() const;
- /**
- * \return An integer value from this empirical distribution
- */
- virtual uint32_t GetIntValue();
- virtual double Interpolate(double, double, double, double, double);
};
/**
@@ -697,8 +558,8 @@
* the RNG to return a known sequence, perhaps to
* compare NS-3 to some other simulator
*/
-class DeterministicVariable : public RandomVariable {
-
+class DeterministicVariable : public RandomVariable
+{
public:
/**
* \brief Constructor
@@ -707,22 +568,11 @@
* on successive calls to ::Value(). Note that the d pointer is copied
* for use by the generator (shallow-copy), not its contents, so the
* contents of the array d points to have to remain unchanged for the use
- * of DeterministicVariable to be meaningful.
+ * of DeterministicVariableImpl to be meaningful.
* \param d Pointer to array of random values to return in sequence
* \param c Number of values in the array
*/
explicit DeterministicVariable(double* d, uint32_t c);
-
- virtual ~DeterministicVariable();
- /**
- * \return The next value in the deterministic sequence
- */
- virtual double GetValue();
- virtual RandomVariable* Copy() const;
-private:
- uint32_t count;
- uint32_t next;
- double* data;
};
@@ -730,7 +580,7 @@
* \brief Log-normal Distributed random var
* \ingroup randomvariable
*
- * LogNormalVariable defines a random variable with log-normal
+ * LogNormalVariableImpl defines a random variable with log-normal
* distribution. If one takes the natural logarithm of random
* variable following the log-normal distribution, the obtained values
* follow a normal distribution.
@@ -748,7 +598,8 @@
* \f$ \mu = ln(mean) - \frac{1}{2}ln\left(1+\frac{stddev}{mean^2}\right)\f$, and,
* \f$ \sigma = \sqrt{ln\left(1+\frac{stddev}{mean^2}\right)}\f$
*/
-class LogNormalVariable : public RandomVariable {
+class LogNormalVariable : public RandomVariable
+{
public:
/**
* \param mu mu parameter of the lognormal distribution
@@ -757,20 +608,11 @@
LogNormalVariable (double mu, double sigma);
/**
- * \return A random value from this distribution
- */
- virtual double GetValue ();
- virtual RandomVariable* Copy() const;
-public:
- /**
* \param mu mu parameter of the underlying normal distribution
* \param sigma sigma parameter 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:
- double m_mu;
- double m_sigma;
};
/**
@@ -780,7 +622,8 @@
* This distribution is a triangular distribution. The probablility density
* is in the shape of a triangle.
*/
-class TriangularVariable : public RandomVariable {
+class TriangularVariable : public RandomVariable
+{
public:
/**
* Creates a triangle distribution random number generator in the
@@ -796,15 +639,6 @@
* \param mean mean of the distribution
*/
TriangularVariable(double s, double l, double mean);
-
- TriangularVariable(const TriangularVariable& c);
-
- /**
- * \return A value from this distribution
- */
- virtual double GetValue();
- virtual RandomVariable* Copy() const;
-public:
/**
* \param s Low end of the range
* \param l High end of the range
@@ -812,11 +646,6 @@
* \return A triangularly distributed random number between s and l
*/
static double GetSingleValue(double s, double l, double mean);
-private:
- double m_min;
- double m_max;
- double m_mode; //easier to work with the mode internally instead of the mean
- //they are related by the simple: mean = (min+max+mode)/3
};
}//namespace ns3
--- a/src/devices/wifi/propagation-delay-model.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/devices/wifi/propagation-delay-model.cc Fri Feb 15 20:03:48 2008 +0100
@@ -69,20 +69,18 @@
}
RandomPropagationDelayModel::RandomPropagationDelayModel ()
- : m_variable (g_random.GetCopy ())
+ : m_variable (g_random.Get ())
{}
RandomPropagationDelayModel::RandomPropagationDelayModel (const RandomVariable &variable)
- : m_variable (variable.Copy ())
+ : m_variable (variable)
{}
RandomPropagationDelayModel::~RandomPropagationDelayModel ()
-{
- delete m_variable;
-}
+{}
Time
RandomPropagationDelayModel::GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
{
- return Seconds (m_variable->GetValue ());
+ return Seconds (m_variable.GetValue ());
}
ConstantSpeedPropagationDelayModel::ConstantSpeedPropagationDelayModel (double speed)
--- a/src/devices/wifi/propagation-delay-model.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/devices/wifi/propagation-delay-model.h Fri Feb 15 20:03:48 2008 +0100
@@ -23,13 +23,12 @@
#include "ns3/ptr.h"
#include "ns3/object.h"
#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
namespace ns3 {
class MobilityModel;
-class RandomVariable;
-
/**
* \brief calculate a propagation delay.
*/
@@ -71,7 +70,7 @@
virtual ~RandomPropagationDelayModel ();
virtual Time GetDelay (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const;
private:
- RandomVariable *m_variable;
+ RandomVariable m_variable;
};
/**
--- a/src/devices/wifi/propagation-loss-model.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/devices/wifi/propagation-loss-model.cc Fri Feb 15 20:03:48 2008 +0100
@@ -104,23 +104,21 @@
}
}
RandomPropagationLossModel::RandomPropagationLossModel ()
- : m_variable (g_random.GetCopy ())
+ : m_variable (g_random.Get ())
{}
RandomPropagationLossModel::RandomPropagationLossModel (const RandomVariable &variable)
- : m_variable (variable.Copy ())
+ : m_variable (variable)
{}
RandomPropagationLossModel::~RandomPropagationLossModel ()
-{
- delete m_variable;
-}
+{}
double
RandomPropagationLossModel::GetRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const
{
- double rxPower = txPowerDbm - m_variable->GetValue ();
+ double rxPower = txPowerDbm - m_variable.GetValue ();
NS_LOG_DEBUG ("tx power="<<txPowerDbm<<"dbm, rx power="<<rxPower<<"Dbm");
return rxPower;
}
--- a/src/devices/wifi/propagation-loss-model.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/devices/wifi/propagation-loss-model.h Fri Feb 15 20:03:48 2008 +0100
@@ -21,13 +21,12 @@
#define PROPAGATION_LOSS_MODEL_H
#include "ns3/object.h"
+#include "ns3/random-variable.h"
namespace ns3 {
class MobilityModel;
-class RandomVariable;
-
/**
* \brief Modelize the propagation loss through a transmission medium
*
@@ -76,7 +75,7 @@
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const;
private:
- RandomVariable *m_variable;
+ RandomVariable m_variable;
};
/**
--- a/src/mobility/random-direction-2d-mobility-model.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/mobility/random-direction-2d-mobility-model.cc Fri Feb 15 20:03:48 2008 +0100
@@ -54,8 +54,8 @@
RandomDirection2dMobilityModelParameters::RandomDirection2dMobilityModelParameters ()
: m_bounds (g_bounds.GetValue ()),
- m_speedVariable (g_speedVariable.GetCopy ()),
- m_pauseVariable (g_pauseVariable.GetCopy ())
+ m_speedVariable (g_speedVariable.Get ()),
+ m_pauseVariable (g_pauseVariable.Get ())
{}
RandomDirection2dMobilityModelParameters::RandomDirection2dMobilityModelParameters
@@ -63,29 +63,22 @@
const RandomVariable &speedVariable,
const RandomVariable &pauseVariable)
: m_bounds (bounds),
- m_speedVariable (speedVariable.Copy ()),
- m_pauseVariable (pauseVariable.Copy ())
+ m_speedVariable (speedVariable),
+ m_pauseVariable (pauseVariable)
{}
RandomDirection2dMobilityModelParameters::~RandomDirection2dMobilityModelParameters ()
-{
- delete m_speedVariable;
- delete m_pauseVariable;
- m_speedVariable = 0;
- m_pauseVariable = 0;
-}
+{}
void
RandomDirection2dMobilityModelParameters::SetSpeed (const RandomVariable &speedVariable)
{
- delete m_speedVariable;
- m_speedVariable = speedVariable.Copy ();
+ m_speedVariable = speedVariable;
}
void
RandomDirection2dMobilityModelParameters::SetPause (const RandomVariable &pauseVariable)
{
- delete m_pauseVariable;
- m_pauseVariable = pauseVariable.Copy ();
+ m_pauseVariable = pauseVariable;
}
void
RandomDirection2dMobilityModelParameters::SetBounds (const Rectangle &bounds)
@@ -149,7 +142,7 @@
void
RandomDirection2dMobilityModel::BeginPause (void)
{
- Time pause = Seconds (m_parameters->m_pauseVariable->GetValue ());
+ Time pause = Seconds (m_parameters->m_pauseVariable.GetValue ());
m_helper.Pause ();
m_event = Simulator::Schedule (pause, &RandomDirection2dMobilityModel::ResetDirectionAndSpeed, this);
NotifyCourseChange ();
@@ -159,7 +152,7 @@
RandomDirection2dMobilityModel::SetDirectionAndSpeed (double direction)
{
NS_LOG_FUNCTION;
- double speed = m_parameters->m_speedVariable->GetValue ();
+ double speed = m_parameters->m_speedVariable.GetValue ();
const Vector vector (std::cos (direction) * speed,
std::sin (direction) * speed,
0.0);
--- a/src/mobility/random-direction-2d-mobility-model.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/mobility/random-direction-2d-mobility-model.h Fri Feb 15 20:03:48 2008 +0100
@@ -26,13 +26,12 @@
#include "ns3/nstime.h"
#include "ns3/event-id.h"
#include "ns3/rectangle.h"
+#include "ns3/random-variable.h"
#include "mobility-model.h"
#include "static-speed-helper.h"
namespace ns3 {
-class RandomVariable;
-
/**
* \brief the parameters to control a RandomDirection mobility model.
*/
@@ -73,8 +72,8 @@
static Ptr<RandomDirection2dMobilityModelParameters> GetCurrent (void);
Rectangle m_bounds;
- RandomVariable *m_speedVariable;
- RandomVariable *m_pauseVariable;
+ RandomVariable m_speedVariable;
+ RandomVariable m_pauseVariable;
};
/**
--- a/src/mobility/random-position.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/mobility/random-position.cc Fri Feb 15 20:03:48 2008 +0100
@@ -88,26 +88,21 @@
}
RandomRectanglePosition::RandomRectanglePosition ()
- : m_x (g_rectangleX.GetCopy ()),
- m_y (g_rectangleY.GetCopy ())
+ : m_x (g_rectangleX.Get ()),
+ m_y (g_rectangleY.Get ())
{}
RandomRectanglePosition::RandomRectanglePosition (const RandomVariable &x,
const RandomVariable &y)
- : m_x (x.Copy ()),
- m_y (y.Copy ())
+ : m_x (x),
+ m_y (y)
{}
RandomRectanglePosition::~RandomRectanglePosition ()
-{
- delete m_x;
- delete m_y;
- m_x = 0;
- m_y = 0;
-}
+{}
Vector
RandomRectanglePosition::Get (void) const
{
- double x = m_x->GetValue ();
- double y = m_y->GetValue ();
+ double x = m_x.GetValue ();
+ double y = m_y.GetValue ();
return Vector (x, y, 0.0);
}
@@ -124,31 +119,26 @@
}
RandomDiscPosition::RandomDiscPosition ()
- : m_theta (g_discTheta.GetCopy ()),
- m_rho (g_discRho.GetCopy ()),
+ : m_theta (g_discTheta.Get ()),
+ m_rho (g_discRho.Get ()),
m_x (g_discX.GetValue ()),
m_y (g_discY.GetValue ())
{}
RandomDiscPosition::RandomDiscPosition (const RandomVariable &theta,
const RandomVariable &rho,
double x, double y)
- : m_theta (theta.Copy ()),
- m_rho (rho.Copy ()),
+ : m_theta (theta),
+ m_rho (rho),
m_x (0.0),
m_y (0.0)
{}
RandomDiscPosition::~RandomDiscPosition ()
-{
- delete m_theta;
- delete m_rho;
- m_theta = 0;
- m_rho = 0;
-}
+{}
Vector
RandomDiscPosition::Get (void) const
{
- double theta = m_theta->GetValue ();
- double rho = m_rho->GetValue ();
+ double theta = m_theta.GetValue ();
+ double rho = m_rho.GetValue ();
double x = m_x + std::cos (theta) * rho;
double y = m_y + std::sin (theta) * rho;
NS_LOG_DEBUG ("Disc position x=" << x << ", y=" << y);
--- a/src/mobility/random-position.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/mobility/random-position.h Fri Feb 15 20:03:48 2008 +0100
@@ -21,12 +21,11 @@
#define RANDOM_POSITION_H
#include "ns3/object.h"
+#include "ns3/random-variable.h"
#include "vector.h"
namespace ns3 {
-class RandomVariable;
-
/**
* \brief choose a position at random.
*
@@ -69,8 +68,8 @@
virtual ~RandomRectanglePosition ();
virtual Vector Get (void) const;
private:
- RandomVariable *m_x;
- RandomVariable *m_y;
+ RandomVariable m_x;
+ RandomVariable m_y;
};
/**
@@ -107,8 +106,8 @@
virtual ~RandomDiscPosition ();
virtual Vector Get (void) const;
private:
- RandomVariable *m_theta;
- RandomVariable *m_rho;
+ RandomVariable m_theta;
+ RandomVariable m_rho;
double m_x;
double m_y;
};
--- a/src/mobility/random-walk-2d-mobility-model.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/mobility/random-walk-2d-mobility-model.cc Fri Feb 15 20:03:48 2008 +0100
@@ -69,30 +69,23 @@
: m_mode (g_mode.GetValue ()),
m_modeDistance (g_modeDistance.GetValue ()),
m_modeTime (g_modeTime.GetValue ()),
- m_speed (g_speed.GetCopy ()),
- m_direction (g_direction.GetCopy ()),
+ m_speed (g_speed.Get ()),
+ m_direction (g_direction.Get ()),
m_bounds (g_rectangle.GetValue ())
{}
RandomWalk2dMobilityModelParameters::~RandomWalk2dMobilityModelParameters ()
-{
- delete m_speed;
- delete m_direction;
- m_speed = 0;
- m_direction = 0;
-}
+{}
void
RandomWalk2dMobilityModelParameters::SetSpeed (const RandomVariable &speed)
{
- delete m_speed;
- m_speed = speed.Copy ();
+ m_speed = speed;
}
void
RandomWalk2dMobilityModelParameters::SetDirection (const RandomVariable &direction)
{
- delete m_direction;
- m_direction = direction.Copy ();
+ m_direction = direction;
}
void
RandomWalk2dMobilityModelParameters::SetModeDistance (double distance)
@@ -154,8 +147,8 @@
void
RandomWalk2dMobilityModel::Start (void)
{
- double speed = m_parameters->m_speed->GetValue ();
- double direction = m_parameters->m_direction->GetValue ();
+ double speed = m_parameters->m_speed.GetValue ();
+ double direction = m_parameters->m_direction.GetValue ();
Vector vector (std::cos (direction) * speed,
std::sin (direction) * speed,
0.0);
--- a/src/mobility/random-walk-2d-mobility-model.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/mobility/random-walk-2d-mobility-model.h Fri Feb 15 20:03:48 2008 +0100
@@ -25,12 +25,12 @@
#include "ns3/nstime.h"
#include "ns3/event-id.h"
#include "ns3/rectangle.h"
+#include "ns3/random-variable.h"
#include "mobility-model.h"
#include "static-speed-helper.h"
namespace ns3 {
-class RandomVariable;
/**
* \brief parameters to control a random walk 2d model
@@ -93,8 +93,8 @@
enum Mode m_mode;
double m_modeDistance;
Time m_modeTime;
- RandomVariable *m_speed;
- RandomVariable *m_direction;
+ RandomVariable m_speed;
+ RandomVariable m_direction;
Rectangle m_bounds;
};
--- a/src/mobility/random-waypoint-mobility-model.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/mobility/random-waypoint-mobility-model.cc Fri Feb 15 20:03:48 2008 +0100
@@ -47,16 +47,16 @@
RandomWaypointMobilityModelParameters::RandomWaypointMobilityModelParameters ()
- : m_speed (g_speed.GetCopy ()),
- m_pause (g_pause.GetCopy ())
+ : m_speed (g_speed.Get ()),
+ m_pause (g_pause.Get ())
{
m_position = g_position.GetValue ().CreateObject ()->GetObject<RandomPosition> ();
}
RandomWaypointMobilityModelParameters::RandomWaypointMobilityModelParameters (Ptr<RandomPosition> randomPosition,
const RandomVariable &speed,
const RandomVariable &pause)
- : m_speed (speed.Copy ()),
- m_pause (pause.Copy ()),
+ : m_speed (speed),
+ m_pause (pause),
m_position (randomPosition)
{}
void
@@ -67,23 +67,17 @@
void
RandomWaypointMobilityModelParameters::SetSpeed (const RandomVariable &speed)
{
- delete m_speed;
- m_speed = speed.Copy ();
+ m_speed = speed;
}
void
RandomWaypointMobilityModelParameters::SetPause (const RandomVariable &pause)
{
- delete m_pause;
- m_pause = pause.Copy ();
+ m_pause = pause;
}
void
RandomWaypointMobilityModelParameters::DoDispose (void)
{
m_position = 0;
- delete m_pause;
- delete m_speed;
- m_pause = 0;
- m_speed = 0;
}
Ptr<RandomWaypointMobilityModelParameters>
@@ -128,7 +122,7 @@
{
Vector m_current = m_helper.GetCurrentPosition ();
Vector destination = m_parameters->m_position->Get ();
- double speed = m_parameters->m_speed->GetValue ();
+ double speed = m_parameters->m_speed.GetValue ();
double dx = (destination.x - m_current.x);
double dy = (destination.y - m_current.y);
double dz = (destination.z - m_current.z);
@@ -144,7 +138,7 @@
void
RandomWaypointMobilityModel::Start (void)
{
- Time pause = Seconds (m_parameters->m_pause->GetValue ());
+ Time pause = Seconds (m_parameters->m_pause.GetValue ());
m_helper.Pause ();
NotifyCourseChange ();
m_event = Simulator::Schedule (pause, &RandomWaypointMobilityModel::BeginWalk, this);
--- a/src/mobility/random-waypoint-mobility-model.h Fri Feb 15 19:14:35 2008 +0100
+++ b/src/mobility/random-waypoint-mobility-model.h Fri Feb 15 20:03:48 2008 +0100
@@ -25,11 +25,10 @@
#include "mobility-model.h"
#include "random-position.h"
#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
namespace ns3 {
-class RandomVariable;
-
/**
* \brief the parameters which control the behavior of a random waypoint
* mobility model.
@@ -66,8 +65,8 @@
friend class RandomWaypointMobilityModel;
static Ptr<RandomWaypointMobilityModelParameters> GetCurrent (void);
virtual void DoDispose (void);
- RandomVariable *m_speed;
- RandomVariable *m_pause;
+ RandomVariable m_speed;
+ RandomVariable m_pause;
Ptr<RandomPosition> m_position;
};
--- a/src/node/application.cc Fri Feb 15 19:14:35 2008 +0100
+++ b/src/node/application.cc Fri Feb 15 20:03:48 2008 +0100
@@ -59,9 +59,8 @@
void Application::Start(const RandomVariable& startVar)
{
- RandomVariable *v = startVar.Copy ();
- ScheduleStart (Seconds (v->GetValue ()));
- delete v;
+ RandomVariable v = startVar;
+ ScheduleStart (Seconds (v.GetValue ()));
}
@@ -72,9 +71,8 @@
void Application::Stop(const RandomVariable& stopVar)
{
- RandomVariable *v = stopVar.Copy ();
- ScheduleStop (Seconds (v->GetValue ()));
- delete v;
+ RandomVariable v = stopVar;
+ ScheduleStop (Seconds (v.GetValue ()));
}
Ptr<Node> Application::GetNode() const