From bd2778169aae28aabffb6b5c0cfc149eb8f856e0 Mon Sep 17 00:00:00 2001 From: Kirill Andreev Date: Fri, 24 Aug 2012 10:50:35 -0700 Subject: [PATCH] Refactor Jakes loss model for random variable changes --- src/propagation/model/jakes-process.cc | 52 ++++++++++--------- src/propagation/model/jakes-process.h | 10 ++-- .../model/jakes-propagation-loss-model.cc | 28 ++++++++-- .../model/jakes-propagation-loss-model.h | 5 ++ src/propagation/model/propagation-cache.h | 10 ++-- 5 files changed, 70 insertions(+), 35 deletions(-) diff --git a/src/propagation/model/jakes-process.cc b/src/propagation/model/jakes-process.cc index 2c166c2f4..bd9072a3f 100644 --- a/src/propagation/model/jakes-process.cc +++ b/src/propagation/model/jakes-process.cc @@ -22,11 +22,10 @@ #include "ns3/simulator.h" #include "ns3/double.h" #include "ns3/uinteger.h" +#include "propagation-loss-model.h" +#include "jakes-propagation-loss-model.h" namespace ns3 { -const double JakesProcess::PI = 3.14159265358979323846; - -Ptr JakesProcess::m_uniformVariable = CreateObject (); /// Represents a single oscillator JakesProcess::Oscillator::Oscillator (std::complex amplitude, double initialPhase, double omega) : @@ -61,43 +60,49 @@ JakesProcess::GetTypeId () return tid; } +void +JakesProcess::SetPropagationLossModel (Ptr propagationModel) +{ + Ptr jakes = propagationModel->GetObject (); + NS_ASSERT_MSG (jakes != 0, "Jakes Process can work only with JakesPropagationLossModel!"); + m_jakes = jakes; + + NS_ASSERT (m_nOscillators != 0); + NS_ASSERT (m_omegaDopplerMax != 0); + + ConstructOscillators (); +} + void JakesProcess::SetNOscillators (unsigned int nOscillators) { m_nOscillators = nOscillators; - if (m_omegaDopplerMax != 0) - { - ConstructOscillators (); - } } void JakesProcess::SetDopplerFrequencyHz (double dopplerFrequencyHz) { - m_omegaDopplerMax = 2 * dopplerFrequencyHz * PI; - if (m_nOscillators != 0) - { - ConstructOscillators (); - } + m_omegaDopplerMax = 2 * dopplerFrequencyHz * JakesPropagationLossModel::PI; } void JakesProcess::ConstructOscillators () { + NS_ASSERT (m_jakes); // Initial phase is common for all oscillators: - double phi = m_uniformVariable->GetValue (); + double phi = m_jakes->GetUniformRandomVariable ()->GetValue (); // Theta is common for all oscillatoer: - double theta = m_uniformVariable->GetValue (); + double theta = m_jakes->GetUniformRandomVariable ()->GetValue (); for (unsigned int i = 0; i < m_nOscillators; i++) { unsigned int n = i + 1; /// 1. Rotation speed /// 1a. Initiate \f[ \alpha_n = \frac{2\pi n - \pi + \theta}{4M}, n=1,2, \ldots,M\f], n is oscillatorNumber, M is m_nOscillators - double alpha = (2.0 * PI * n - PI + theta) / (4.0 * m_nOscillators); + double alpha = (2.0 * JakesPropagationLossModel::PI * n - JakesPropagationLossModel::PI + theta) / (4.0 * m_nOscillators); /// 1b. Initiate rotation speed: double omega = m_omegaDopplerMax * cos (alpha); /// 2. Initiate complex amplitude: - double psi = m_uniformVariable->GetValue (); + double psi = m_jakes->GetUniformRandomVariable ()->GetValue (); std::complex amplitude = std::complex (cos (psi), sin (psi)) * 2.0 / sqrt (m_nOscillators); /// 3. Construct oscillator: m_oscillators.push_back (Oscillator (amplitude, phi, omega)); @@ -108,8 +113,6 @@ JakesProcess::JakesProcess () : m_omegaDopplerMax (0), m_nOscillators (0) { - m_uniformVariable->SetAttribute ("Min", DoubleValue (-1.0 * PI)); - m_uniformVariable->SetAttribute ("Max", DoubleValue (PI)); } JakesProcess::~JakesProcess() @@ -117,6 +120,12 @@ JakesProcess::~JakesProcess() m_oscillators.clear (); } +void +JakesProcess::DoDispose () +{ + m_jakes = 0; +} + std::complex JakesProcess::GetComplexGain () const { @@ -135,11 +144,4 @@ JakesProcess::GetChannelGainDb () const return (10 * log10 ((pow (complexGain.real (), 2) + pow (complexGain.imag (), 2)) / 2)); } -int64_t -JakesProcess::AssignStreams (int64_t stream) -{ - m_uniformVariable->SetStream (stream); - return 1; -} - } // namespace ns3 diff --git a/src/propagation/model/jakes-process.h b/src/propagation/model/jakes-process.h index 615dbb8d2..c845e9e12 100644 --- a/src/propagation/model/jakes-process.h +++ b/src/propagation/model/jakes-process.h @@ -27,6 +27,8 @@ namespace ns3 { +class PropagationLossModel; +class JakesPropagationLossModel; /** * \ingroup fading * @@ -56,10 +58,11 @@ public: static TypeId GetTypeId (void); JakesProcess (); virtual ~JakesProcess(); + virtual void DoDispose (); std::complex GetComplexGain () const; /// Get Channel gain [dB] double GetChannelGainDb () const; - static int64_t AssignStreams (int64_t stream); + void SetPropagationLossModel (Ptr); private: /// Represents a single oscillator struct Oscillator @@ -75,8 +78,6 @@ private: /// Rotation speed of the oscillator \f[\omega_d \cos(\alpha_n)] double m_omega; }; - /// PI Constant - static const double PI; private: void SetNOscillators (unsigned int nOscillators); void SetDopplerFrequencyHz (double dopplerFrequencyHz); @@ -88,7 +89,8 @@ private: ///\{ double m_omegaDopplerMax; unsigned int m_nOscillators; - static Ptr m_uniformVariable; + Ptr m_uniformVariable; + Ptr m_jakes; ///\} }; } // namespace ns3 diff --git a/src/propagation/model/jakes-propagation-loss-model.cc b/src/propagation/model/jakes-propagation-loss-model.cc index 55a7c59dc..146759166 100644 --- a/src/propagation/model/jakes-propagation-loss-model.cc +++ b/src/propagation/model/jakes-propagation-loss-model.cc @@ -19,13 +19,21 @@ */ #include "jakes-propagation-loss-model.h" +#include "ns3/double.h" namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (JakesPropagationLossModel); + +const double JakesPropagationLossModel::PI = 3.14159265358979323846; + JakesPropagationLossModel::JakesPropagationLossModel() -{} +{ + m_uniformVariable = CreateObject (); + m_uniformVariable->SetAttribute ("Min", DoubleValue (-1.0 * PI)); + m_uniformVariable->SetAttribute ("Max", DoubleValue (PI)); +} JakesPropagationLossModel::~JakesPropagationLossModel() {} @@ -45,13 +53,27 @@ JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm, Ptr a, Ptr b) const { - return txPowerDbm + m_propagationCache.GetPathData (a, b, 0 /**Spectrum model uid is not used in PropagationLossModel*/)->GetChannelGainDb (); + Ptr pathData = m_propagationCache.GetPathData (a, b, 0 /**Spectrum model uid is not used in PropagationLossModel*/); + if (pathData == 0) + { + pathData = CreateObject (); + pathData->SetPropagationLossModel (this); + m_propagationCache.AddPathData (pathData, a, b, 0/**Spectrum model uid is not used in PropagationLossModel*/); + } + return txPowerDbm + pathData->GetChannelGainDb (); +} + +Ptr +JakesPropagationLossModel::GetUniformRandomVariable () const +{ + return m_uniformVariable; } int64_t JakesPropagationLossModel::DoAssignStreams (int64_t stream) { - return JakesProcess::AssignStreams (stream); + m_uniformVariable->SetStream (stream); + return 1; } } // namespace ns3 diff --git a/src/propagation/model/jakes-propagation-loss-model.h b/src/propagation/model/jakes-propagation-loss-model.h index 199ad5f74..dc71efa71 100644 --- a/src/propagation/model/jakes-propagation-loss-model.h +++ b/src/propagation/model/jakes-propagation-loss-model.h @@ -39,13 +39,18 @@ public: static TypeId GetTypeId (); JakesPropagationLossModel (); virtual ~JakesPropagationLossModel (); + + static const double PI; private: + friend class JakesProcess; double DoCalcRxPower (double txPowerDbm, Ptr a, Ptr b) const; virtual int64_t DoAssignStreams (int64_t stream); + Ptr GetUniformRandomVariable () const; + Ptr m_uniformVariable; private: mutable PropagationCache m_propagationCache; }; diff --git a/src/propagation/model/propagation-cache.h b/src/propagation/model/propagation-cache.h index 3bd83fa27..d9270c880 100644 --- a/src/propagation/model/propagation-cache.h +++ b/src/propagation/model/propagation-cache.h @@ -43,12 +43,16 @@ public: typename PathCache::iterator it = m_pathCache.find (key); if (it == m_pathCache.end ()) { - Ptr newPath = CreateObject (); - m_pathCache.insert (std::make_pair (key, newPath)); - return newPath; + return 0; } return it->second; }; + void AddPathData (Ptr data, Ptr a, Ptr b, uint32_t modelUid) + { + PropagationPathIdentifier key = PropagationPathIdentifier (a, b, modelUid); + NS_ASSERT (m_pathCache.find (key) == m_pathCache.end ()); + m_pathCache.insert (std::make_pair (key, data)); + }; private: /// Each path is identified by struct PropagationPathIdentifier