Refactor Jakes loss model for random variable changes

This commit is contained in:
Kirill Andreev
2012-08-24 10:50:35 -07:00
parent f923098b5d
commit bd2778169a
5 changed files with 70 additions and 35 deletions

View File

@@ -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<UniformRandomVariable> JakesProcess::m_uniformVariable = CreateObject<UniformRandomVariable> ();
/// Represents a single oscillator
JakesProcess::Oscillator::Oscillator (std::complex<double> amplitude, double initialPhase, double omega) :
@@ -61,43 +60,49 @@ JakesProcess::GetTypeId ()
return tid;
}
void
JakesProcess::SetPropagationLossModel (Ptr<const PropagationLossModel> propagationModel)
{
Ptr<const JakesPropagationLossModel> jakes = propagationModel->GetObject<JakesPropagationLossModel> ();
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<double> amplitude = std::complex<double> (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<double>
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

View File

@@ -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<double> GetComplexGain () const;
/// Get Channel gain [dB]
double GetChannelGainDb () const;
static int64_t AssignStreams (int64_t stream);
void SetPropagationLossModel (Ptr<const PropagationLossModel>);
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<UniformRandomVariable> m_uniformVariable;
Ptr<UniformRandomVariable> m_uniformVariable;
Ptr<const JakesPropagationLossModel> m_jakes;
///\}
};
} // namespace ns3

View File

@@ -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<UniformRandomVariable> ();
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<MobilityModel> a,
Ptr<MobilityModel> b) const
{
return txPowerDbm + m_propagationCache.GetPathData (a, b, 0 /**Spectrum model uid is not used in PropagationLossModel*/)->GetChannelGainDb ();
Ptr<JakesProcess> pathData = m_propagationCache.GetPathData (a, b, 0 /**Spectrum model uid is not used in PropagationLossModel*/);
if (pathData == 0)
{
pathData = CreateObject<JakesProcess> ();
pathData->SetPropagationLossModel (this);
m_propagationCache.AddPathData (pathData, a, b, 0/**Spectrum model uid is not used in PropagationLossModel*/);
}
return txPowerDbm + pathData->GetChannelGainDb ();
}
Ptr<UniformRandomVariable>
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

View File

@@ -39,13 +39,18 @@ public:
static TypeId GetTypeId ();
JakesPropagationLossModel ();
virtual ~JakesPropagationLossModel ();
static const double PI;
private:
friend class JakesProcess;
double DoCalcRxPower (double txPowerDbm,
Ptr<MobilityModel> a,
Ptr<MobilityModel> b) const;
virtual int64_t DoAssignStreams (int64_t stream);
Ptr<UniformRandomVariable> GetUniformRandomVariable () const;
Ptr<UniformRandomVariable> m_uniformVariable;
private:
mutable PropagationCache<JakesProcess> m_propagationCache;
};

View File

@@ -43,12 +43,16 @@ public:
typename PathCache::iterator it = m_pathCache.find (key);
if (it == m_pathCache.end ())
{
Ptr<T> newPath = CreateObject<T> ();
m_pathCache.insert (std::make_pair (key, newPath));
return newPath;
return 0;
}
return it->second;
};
void AddPathData (Ptr<T> data, Ptr<const MobilityModel> a, Ptr<const MobilityModel> 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