diff --git a/src/core/random-variable.cc b/src/core/random-variable.cc index 1b29fe312..f67f6eb29 100644 --- a/src/core/random-variable.cc +++ b/src/core/random-variable.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include "assert.h" @@ -249,6 +250,10 @@ RandomVariable::RandomVariable (const RandomVariableBase &variable) RandomVariable & RandomVariable::operator = (const RandomVariable &o) { + if (&o == this) + { + return *this; + } delete m_variable; m_variable = o.m_variable->Copy (); return *this; @@ -290,10 +295,24 @@ RandomVariable::SetRunNumber(uint32_t n) RandomVariableBase::SetRunNumber (n); } RandomVariableBase * -RandomVariable::Peek (void) +RandomVariable::Peek (void) const { return m_variable; } +RandomVariable::RandomVariable (PValue value) +{ + const RandomVariableValue *v = value.DynCast (); + if (v == 0) + { + NS_FATAL_ERROR ("assigning non-RandomVariable value to RandomVariable value."); + } + m_variable = v->Get ().m_variable->Copy (); + +} +RandomVariable::operator PValue () const +{ + return PValue::Create (*this); +} //----------------------------------------------------------------------------- @@ -316,6 +335,9 @@ public: UniformVariableImpl(double s, double l); UniformVariableImpl(const UniformVariableImpl& c); + + double GetMin (void) const; + double GetMax (void) const; /** * \return A value between low and high values specified by the constructor @@ -344,6 +366,18 @@ UniformVariableImpl::UniformVariableImpl(double s, double l) UniformVariableImpl::UniformVariableImpl(const UniformVariableImpl& c) : RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max) { } +double +UniformVariableImpl::GetMin (void) const +{ + return m_min; +} +double +UniformVariableImpl::GetMax (void) const +{ + return m_max; +} + + double UniformVariableImpl::GetValue() { if(!RandomVariableBase::initialized) @@ -1563,6 +1597,78 @@ TriangularVariable::GetSingleValue(double s, double l, double mean) } +RandomVariableValue::RandomVariableValue (RandomVariable variable) + : m_variable (variable) +{} +void +RandomVariableValue::Set (RandomVariable variable) +{ + m_variable = variable; +} +RandomVariable +RandomVariableValue::Get (void) const +{ + return m_variable; +} + +PValue +RandomVariableValue::Copy (void) const +{ + return PValue::Create (m_variable); +} +std::string +RandomVariableValue::SerializeToString (Ptr spec) const +{ + std::ostringstream oss; + RandomVariableBase *base = m_variable.Peek (); + ConstantVariableImpl *constant = dynamic_cast (base); + if (constant != 0) + { + oss << "Constant:" << constant->GetValue (); + return oss.str (); + } + UniformVariableImpl *uniform = dynamic_cast (base); + if (uniform != 0) + { + oss << "Uniform:" << uniform->GetMin () << ":" << uniform->GetMax (); + return oss.str (); + } + // XXX: support other distributions + return ""; +} +bool +RandomVariableValue::DeserializeFromString (std::string value, Ptr spec) +{ + std::string::size_type tmp; + tmp = value.find (":"); + if (tmp == std::string::npos) + { + return false; + } + std::string type = value.substr (0, tmp); + if (value == "Constant") + { + // XXX + return true; + } + else if (value == "Uniform") + { + // XXX + return true; + } + // XXX: support other distributions. + return false; +} +RandomVariableValue::RandomVariableValue (PValue value) + : m_variable (value) +{} +RandomVariableValue::operator PValue () const +{ + return m_variable; +} + + + }//namespace ns3 diff --git a/src/core/random-variable.h b/src/core/random-variable.h index dd0280745..370ff9e79 100644 --- a/src/core/random-variable.h +++ b/src/core/random-variable.h @@ -24,6 +24,7 @@ #include #include #include +#include "value.h" /** * \ingroup core @@ -158,11 +159,17 @@ public: * \endcode */ static void SetRunNumber(uint32_t n); + + + RandomVariable (PValue value); + operator PValue () const; + private: + friend class RandomVariableValue; RandomVariableBase *m_variable; protected: RandomVariable (const RandomVariableBase &variable); - RandomVariableBase *Peek (void); + RandomVariableBase *Peek (void) const; }; /** @@ -648,5 +655,39 @@ public: static double GetSingleValue(double s, double l, double mean); }; + +class RandomVariableValue : public Value +{ +public: + RandomVariableValue (RandomVariable variable); + void Set (RandomVariable variable); + RandomVariable Get (void) const; + + virtual PValue Copy (void) const; + virtual std::string SerializeToString (Ptr spec) const; + virtual bool DeserializeFromString (std::string value, Ptr spec); + + RandomVariableValue (PValue value); + operator PValue () const; +private: + RandomVariable m_variable; +}; + +template +Ptr MakeRandomVariableParamSpec (RandomVariable T::*m_memberVariable, + RandomVariable initialValue); + }//namespace ns3 + + +namespace ns3 { + +template +Ptr MakeRandomVariableParamSpec (RandomVariable T::*memberVariable, + RandomVariable initialValue) +{ + return MakeMemberVariableParamSpec (memberVariable, RandomVariableValue (initialValue)); +} + +} // namespace ns3 #endif diff --git a/src/core/value-test.cc b/src/core/value-test.cc index c7d8fe24d..dc31c45b1 100644 --- a/src/core/value-test.cc +++ b/src/core/value-test.cc @@ -5,6 +5,7 @@ #include "int-value.h" #include "uint-value.h" #include "enum-value.h" +#include "random-variable.h" #if 0 #include "fp-value.h" #endif @@ -66,6 +67,9 @@ public: TEST_A, "TestA", TEST_B, "TestB", TEST_C, "TestC")) + .AddParameter ("TestRandom", "help text", + MakeRandomVariableParamSpec (&ParamSpecObjectTest::m_random, + ConstantVariable (1.0))) #if 0 .AddParameter ("TestFloat", "help text", MakeFpParamSpec (-1.1, &ParamSpecObjectTest::m_float)) @@ -97,6 +101,7 @@ private: uint8_t m_uint8; float m_float; enum TestEnum m_enum; + RandomVariable m_random; }; @@ -265,6 +270,11 @@ ParamSpecTest::RunTests (void) CHECK_GET_STR (p, "TestEnum", "TestB"); CHECK_GET_PARAM (p, "TestEnum", EnumValue, ParamSpecObjectTest::TEST_B); + RandomVariable ran = p->Get ("TestRandom"); + NS_TEST_ASSERT (p->Set ("TestRandom", UniformVariable (0.0, 1.0))); + NS_TEST_ASSERT (p->Set ("TestRandom", ConstantVariable (10.0))); + + #if 0 p->Set ("TestBoolName", "true"); NS_TEST_ASSERT_EQUAL (p->Get ("TestBoolName"), "true");