Refactor Jakes loss model for random variable changes
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user