From ac13b5523f10f9e9cf9e2716b58e3fb19d2e003d Mon Sep 17 00:00:00 2001 From: Raj Bhattacharjea Date: Thu, 22 Mar 2007 12:16:10 -0400 Subject: [PATCH] Fixed major memory bug and docs in RandomVariable --- src/core/random-variable.cc | 33 +++++++++++++++++++++++---------- src/core/random-variable.h | 24 ++++++++++++++++++++---- src/core/rng-stream.cc | 12 ++++++++++++ src/core/rng-stream.h | 5 +---- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/core/random-variable.cc b/src/core/random-variable.cc index 97cd29d60..16e32ae61 100644 --- a/src/core/random-variable.cc +++ b/src/core/random-variable.cc @@ -103,6 +103,12 @@ RandomVariable::RandomVariable() m_generator->InitializeStream(); } +RandomVariable::RandomVariable(const RandomVariable& r) +{ + m_generator = new RngStream(*r.m_generator); + RandomVariable::Initialize(); +} + RandomVariable::~RandomVariable() { delete m_generator; @@ -237,7 +243,7 @@ UniformVariable::UniformVariable(double s, double l) : m_min(s), m_max(l) { } UniformVariable::UniformVariable(const UniformVariable& c) - : m_min(c.m_min), m_max(c.m_max) { } + : RandomVariable(c), m_min(c.m_min), m_max(c.m_max) { } double UniformVariable::GetValue() { @@ -258,7 +264,7 @@ ConstantVariable::ConstantVariable(double c) : m_const(c) { }; ConstantVariable::ConstantVariable(const ConstantVariable& c) - : m_const(c.m_const) { } + : RandomVariable(c), m_const(c.m_const) { } void ConstantVariable::NewConstant(double c) { m_const = c;} @@ -293,12 +299,17 @@ SequentialVariable::SequentialVariable(double f, double l, const RandomVariable& } SequentialVariable::SequentialVariable(const SequentialVariable& c) - : m_min(c.m_min), m_max(c.m_max), + : RandomVariable(c), m_min(c.m_min), m_max(c.m_max), m_increment(c.m_increment->Copy()), m_consecutive(c.m_consecutive), m_current(c.m_current), m_currentConsecutive(c.m_currentConsecutive) { } +SequentialVariable::~SequentialVariable() +{ + delete m_increment; +} + double SequentialVariable::GetValue() { // Return a sequential series of values double r = m_current; @@ -329,7 +340,7 @@ ExponentialVariable::ExponentialVariable(double m, double b) : m_mean(m), m_bound(b) { } ExponentialVariable::ExponentialVariable(const ExponentialVariable& c) - : m_mean(c.m_mean), m_bound(c.m_bound) { } + : RandomVariable(c), m_mean(c.m_mean), m_bound(c.m_bound) { } double ExponentialVariable::GetValue() { @@ -358,7 +369,8 @@ ParetoVariable::ParetoVariable(double m, double s, double b) : m_mean(m), m_shape(s), m_bound(b) { } ParetoVariable::ParetoVariable(const ParetoVariable& c) - : m_mean(c.m_mean), m_shape(c.m_shape), m_bound(c.m_bound) { } + : RandomVariable(c), m_mean(c.m_mean), m_shape(c.m_shape), + m_bound(c.m_bound) { } double ParetoVariable::GetValue() { @@ -383,7 +395,8 @@ WeibullVariable::WeibullVariable(double m, double s) WeibullVariable::WeibullVariable(double m, double s, double b) : m_mean(m), m_alpha(s), m_bound(b) { }; WeibullVariable::WeibullVariable(const WeibullVariable& c) - : m_mean(c.m_mean), m_alpha(c.m_alpha), m_bound(c.m_bound) { } + : RandomVariable(c), m_mean(c.m_mean), m_alpha(c.m_alpha), + m_bound(c.m_bound) { } double WeibullVariable::GetValue() { @@ -407,7 +420,8 @@ NormalVariable::NormalVariable(double m, double v, double b) : m_mean(m), m_variance(v), m_bound(b), m_nextValid(false) { } NormalVariable::NormalVariable(const NormalVariable& c) - : m_mean(c.m_mean), m_variance(c.m_variance), m_bound(c.m_bound) { } + : RandomVariable(c), m_mean(c.m_mean), m_variance(c.m_variance), + m_bound(c.m_bound) { } double NormalVariable::GetValue() { @@ -458,8 +472,8 @@ ValueCDF::ValueCDF(const ValueCDF& c) EmpiricalVariable::EmpiricalVariable() : validated(false) { } -EmpiricalVariable::EmpiricalVariable(const EmpiricalVariable& c) - : validated(c.validated), emp(c.emp) { } +EmpiricalVariable::EmpiricalVariable(const EmpiricalVariable& c) + : RandomVariable(c), validated(c.validated), emp(c.emp) { } EmpiricalVariable::~EmpiricalVariable() { } @@ -541,7 +555,6 @@ 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) diff --git a/src/core/random-variable.h b/src/core/random-variable.h index e7193f632..b6bf7335a 100644 --- a/src/core/random-variable.h +++ b/src/core/random-variable.h @@ -87,6 +87,11 @@ public: */ RandomVariable(); + /** + * \brief Copy constructor + */ + RandomVariable(const RandomVariable&); + /** * \brief Destructor for a random number generator with a random seed. */ @@ -145,6 +150,7 @@ public: /** * \brief Use the global seed to force precisely reproducible results. + * * It is often desirable to create a simulation that uses random * numbers, while at the same time is completely reproducible. * Specifying this set of six random seeds initializes the @@ -210,6 +216,7 @@ private: /** * \brief A random variable that returns a constant + * * Class ConstantVariable defines a random number generator that * returns the same value every sample. */ @@ -217,7 +224,7 @@ class ConstantVariable : public RandomVariable { public: /** - * \brief Construct a ConstantVariable RNG that returns zero every sample + * Construct a ConstantVariable RNG that returns zero every sample */ ConstantVariable(); @@ -249,6 +256,7 @@ private: /** * \brief Return a sequential list of values + * * Class SequentialVariable defines a random number generator that * returns a sequential sequence. The sequence monotonically * increases for a period, then wraps around to the low value @@ -259,6 +267,7 @@ class SequentialVariable : public RandomVariable { public: /** * \brief Constructor for the SequentialVariable RNG. + * * The four parameters define the sequence. For example * SequentialVariable(0,5,1,2) creates a RNG that has the sequence * 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0 ... @@ -271,16 +280,19 @@ public: /** * \brief Constructor for the SequentialVariable 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 Random variable for the sequence increment + * \param i Reference to a RandomVariable 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 */ @@ -297,6 +309,7 @@ private: /** * \brief Exponentially Distributed random var + * * ExponentialVariable defines a random variable with an exponential distribution */ class ExponentialVariable : public RandomVariable { @@ -316,6 +329,7 @@ public: /** * \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 @@ -492,6 +506,7 @@ public: /** * \brief EmpiricalVariable distribution random var + * * Defines a random variable that has a specified, empirical * distribution. The distribution is specified by a * series of calls the the CDF member function, specifying a @@ -531,14 +546,14 @@ private: /** * Defines an empirical distribution where all values are integers. - * Indentical to {\tt EmpiricalVariable}, but with slightly different + * Indentical to EmpiricalVariable, but with slightly different * interpolation between points. */ class IntEmpiricalVariable : public EmpiricalVariable { public: IntEmpiricalVariable(); - + virtual RandomVariable* Copy() const; /** * \return An integer value from this empirical distribution @@ -558,6 +573,7 @@ class DeterministicVariable : public RandomVariable { 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 diff --git a/src/core/rng-stream.cc b/src/core/rng-stream.cc index e8397f23d..da13079c5 100644 --- a/src/core/rng-stream.cc +++ b/src/core/rng-stream.cc @@ -316,6 +316,18 @@ RngStream::RngStream () // Stream initialization moved to separate method. } +RngStream::RngStream(const RngStream& r) +{ + anti = r.anti; + incPrec = r.incPrec; + for (int i = 0; i < 6; ++i) { + Cg[i] = r.Cg[i]; + Bg[i] = r.Bg[i]; + Ig[i] = r.Ig[i]; + } +} + + void RngStream::InitializeStream() { // Moved from the RngStream constructor above to allow seeding // AFTER the global package seed has been set in the Random diff --git a/src/core/rng-stream.h b/src/core/rng-stream.h index e1670b085..94e6ac659 100644 --- a/src/core/rng-stream.h +++ b/src/core/rng-stream.h @@ -23,13 +23,10 @@ namespace ns3{ -/** - * \brief RngStream by Pierre L'Ecuyer, University of Montreal - * Adapted to NS3 by Rajib Bhattacharjea, Georgia Tech. - */ class RngStream { public: //public api RngStream (); + RngStream (const RngStream&); void InitializeStream(); // Separate initialization void ResetStartStream (); void ResetStartSubstream ();