A Discrete-Event Network Simulator
API
uan-prop-model.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 University of Washington
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Leonard Tracy <lentracy@gmail.com>
19  */
20 
21 #include "uan-prop-model.h"
22 #include "ns3/nstime.h"
23 #include <complex>
24 #include <vector>
25 
26 
27 namespace ns3 {
28 
29 std::ostream &
30 operator<< (std::ostream &os, const UanPdp &pdp)
31 {
32  os << pdp.GetNTaps () << '|';
33  os << pdp.GetResolution ().GetSeconds () << '|';
34 
35  UanPdp::Iterator it = pdp.m_taps.begin ();
36  for (; it != pdp.m_taps.end (); it++)
37  {
38  os << (*it).GetAmp () << '|';
39  }
40  return os;
41 
42 }
43 std::istream &
44 operator>> (std::istream &is, UanPdp &pdp)
45 {
46  uint32_t ntaps;
47  double resolution;
48  char c1;
49 
50  is >> ntaps >> c1;
51  if (c1 != '|')
52  {
53  NS_FATAL_ERROR ("UanPdp data corrupted at # of taps");
54  return is;
55  }
56  is >> resolution >> c1;
57  if (c1 != '|')
58  {
59  NS_FATAL_ERROR ("UanPdp data corrupted at resolution");
60  return is;
61  }
62  pdp.m_resolution = Seconds (resolution);
63 
64 
65  std::complex<double> amp;
66  pdp.m_taps = std::vector<Tap> (ntaps);
67  for (uint32_t i = 0; i < ntaps && !is.eof (); i++)
68  {
69  is >> amp >> c1;
70  if (c1 != '|')
71  {
72  NS_FATAL_ERROR ("UanPdp data corrupted at tap " << i);
73  return is;
74  }
75  pdp.m_taps[i] = Tap (Seconds (resolution * i), amp);
76  }
77  return is;
78 
79 }
80 
82  : m_amplitude (0.0),
83  m_delay (Seconds (0))
84 {
85 
86 }
87 
88 Tap::Tap (Time delay, std::complex<double> amp)
89  : m_amplitude (amp),
90  m_delay (delay)
91 {
92 
93 }
94 
95 std::complex<double>
96 Tap::GetAmp (void) const
97 {
98  return m_amplitude;
99 }
100 
101 Time
102 Tap::GetDelay (void) const
103 {
104  return m_delay;
105 }
106 
107 
109 {
110 
111 }
112 
113 UanPdp::UanPdp (std::vector<Tap> taps, Time resolution)
114  : m_taps (taps),
115  m_resolution (resolution)
116 {
117 }
118 
119 UanPdp::UanPdp (std::vector<std::complex<double> > amps, Time resolution)
120  : m_resolution (resolution)
121 {
122  m_taps.resize (amps.size ());
123  Time arrTime = Seconds (0);
124  for (uint32_t index = 0; index < amps.size (); index++)
125  {
126  m_taps[index] = Tap (arrTime, amps[index]);
127  arrTime = arrTime + m_resolution;
128  }
129 }
130 
131 UanPdp::UanPdp (std::vector<double> amps, Time resolution)
132  : m_resolution (resolution)
133 {
134  m_taps.resize (amps.size ());
135  Time arrTime = Seconds (0);
136  for (uint32_t index = 0; index < amps.size (); index++)
137  {
138  m_taps[index] = Tap (arrTime, amps[index]);
139  arrTime = arrTime + m_resolution;
140  }
141 }
142 
144 {
145  m_taps.clear ();
146 }
147 
148 void
149 UanPdp::SetTap (std::complex<double> amp, uint32_t index)
150 {
151  if (m_taps.size () <= index)
152  {
153  m_taps.resize (index + 1);
154  }
155 
156  Time delay = Seconds (index * m_resolution.GetSeconds ());
157  m_taps[index] = Tap (delay, amp);
158 }
159 const Tap &
160 UanPdp::GetTap (uint32_t i) const
161 {
162  NS_ASSERT_MSG (i < GetNTaps (), "Call to UanPdp::GetTap with requested tap out of range");
163  return m_taps[i];
164 }
165 void
166 UanPdp::SetNTaps (uint32_t nTaps)
167 {
168  m_taps.resize (nTaps);
169 }
170 void
172 {
173  m_resolution = resolution;
174 }
176 UanPdp::GetBegin (void) const
177 {
178  return m_taps.begin ();
179 }
180 
182 UanPdp::GetEnd (void) const
183 {
184  return m_taps.end ();
185 }
186 
187 uint32_t
188 UanPdp::GetNTaps (void) const
189 {
190  return m_taps.size ();
191 }
192 
193 Time
195 {
196  return m_resolution;
197 }
198 
199 std::complex<double>
200 UanPdp::SumTapsFromMaxC (Time delay, Time duration) const
201 {
202  if (m_resolution <= Seconds (0))
203  {
204  NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
205  "UanPdp with resolution 0 and multiple taps");
206 
207  if (delay.IsZero ()) return m_taps[0].GetAmp ();
208  return std::complex<double> (0.0, 0.0);
209  }
210 
211  uint32_t numTaps = static_cast<uint32_t> (duration.GetSeconds () / m_resolution.GetSeconds () + 0.5);
212  double maxAmp = -1;
213  uint32_t maxTapIndex = 0;
214 
215  for (uint32_t i = 0; i < GetNTaps (); i++)
216  {
217  if (std::abs (m_taps[i].GetAmp ()) > maxAmp)
218  {
219  maxAmp = std::abs (m_taps[i].GetAmp ());
220  maxTapIndex = i;
221  }
222  }
223  uint32_t start = maxTapIndex + static_cast<uint32_t> (delay.GetSeconds () / m_resolution.GetSeconds ());
224  uint32_t end = std::min (start + numTaps, GetNTaps ());
225  std::complex<double> sum = 0;
226  for (uint32_t i = start; i < end; i++)
227  {
228  sum += m_taps[i].GetAmp ();
229  }
230  return sum;
231 }
232 double
233 UanPdp::SumTapsFromMaxNc (Time delay, Time duration) const
234 {
235  if (m_resolution <= Seconds (0))
236  {
237  NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
238  "UanPdp with resolution 0 and multiple taps");
239 
240  if (delay.IsZero ()) return std::abs (m_taps[0].GetAmp ());
241  return 0;
242  }
243 
244  uint32_t numTaps = static_cast<uint32_t> (duration.GetSeconds () / m_resolution.GetSeconds () + 0.5);
245  double maxAmp = -1;
246  uint32_t maxTapIndex = 0;
247 
248  for (uint32_t i = 0; i < GetNTaps (); i++)
249  {
250  if (std::abs (m_taps[i].GetAmp ()) > maxAmp)
251  {
252  maxAmp = std::abs (m_taps[i].GetAmp ());
253  maxTapIndex = i;
254  }
255  }
256 
257 
258  uint32_t start = maxTapIndex + static_cast<uint32_t> (delay.GetSeconds () / m_resolution.GetSeconds ());
259  uint32_t end = std::min (start + numTaps, GetNTaps ());
260  double sum = 0;
261  for (uint32_t i = start; i < end; i++)
262 
263  {
264  sum += std::abs (m_taps[i].GetAmp ());
265  }
266  return sum;
267 }
268 double
269 UanPdp::SumTapsNc (Time begin, Time end) const
270 {
271  if (m_resolution <= Seconds (0))
272  {
273  NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
274  "UanPdp with resolution 0 and multiple taps");
275 
276  if (begin <= Seconds (0.0) && end >= Seconds (0.0))
277  {
278  return std::abs (m_taps[0].GetAmp ());
279  }
280  else
281  {
282  return 0.0;
283  }
284  }
285 
286  uint32_t stIndex = (uint32_t)(begin.GetSeconds () / m_resolution.GetSeconds () + 0.5);
287  uint32_t endIndex = (uint32_t)(end.GetSeconds () / m_resolution.GetSeconds () + 0.5);
288 
289  endIndex = std::min (endIndex, GetNTaps ());
290  double sum = 0;
291  for (uint32_t i = stIndex; i < endIndex; i++)
292  {
293  sum += std::abs (m_taps[i].GetAmp ());
294  }
295  return sum;
296 
297 }
298 
299 
300 
301 std::complex<double>
302 UanPdp::SumTapsC (Time begin, Time end) const
303 {
304  if (m_resolution <= Seconds (0))
305  {
306  NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
307  "UanPdp with resolution 0 and multiple taps");
308 
309  if (begin <= Seconds (0.0) && end >= Seconds (0.0))
310  {
311  return m_taps[0].GetAmp ();
312  }
313  else
314  {
315  return std::complex<double> (0.0);
316  }
317  }
318 
319  uint32_t stIndex = (uint32_t)(begin.GetSeconds () / m_resolution.GetSeconds () + 0.5);
320  uint32_t endIndex = (uint32_t)(end.GetSeconds () / m_resolution.GetSeconds () + 0.5);
321 
322  endIndex = std::min (endIndex, GetNTaps ());
323 
324  std::complex<double> sum = 0;
325  for (uint32_t i = stIndex; i < endIndex; i++)
326  {
327  sum += m_taps[i].GetAmp ();
328  }
329  return sum;
330 }
331 
332 UanPdp
334 {
335  UanPdp pdp;
336  pdp.SetResolution (Seconds (0));
337  pdp.SetTap (1.0,0);
338  return pdp;
339 }
340 
342 
344 {
345  static TypeId tid = TypeId ("ns3::UanPropModel")
346  .SetParent<Object> ()
347  .SetGroupName ("Uan")
348  ;
349  return tid;
350 }
351 
352 void
354 {
355 }
356 
357 void
359 {
360  Clear ();
362 }
363 
364 }
Holds PDP Tap information (amplitude and delay)
~UanPdp()
Dummy destructor, see DoDispose.
std::istream & operator>>(std::istream &is, Angles &a)
initialize a struct Angles from input
Definition: angles.cc:48
std::complex< double > SumTapsC(Time begin, Time end) const
Compute the coherent sum of tap amplitudes between a start and end time.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
std::vector< Tap >::const_iterator Iterator
Convenience iterator typedef.
uint32_t GetNTaps(void) const
Get the number of taps.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
#define min(a, b)
Definition: 80211b.c:44
static UanPdp CreateImpulsePdp(void)
Get a unit impulse PDP at time 0.
virtual void Clear(void)
Clear all pointer references.
bool IsZero(void) const
Definition: nstime.h:274
def start()
Definition: core.py:1790
Base class for implemented underwater propagation models.
std::vector< Tap > m_taps
The vector of Taps.
double SumTapsFromMaxNc(Time delay, Time duration) const
Compute the non-coherent sum of tap amplitudes starting after a delay from the maximum amplitude for ...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
UanPdp()
Create empty PDP object.
void SetTap(std::complex< double > arrival, uint32_t index)
Set the arrival value for a tap.
Time m_resolution
The time resolution.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
Tap()
Default constructor.
The power delay profile returned by propagation models.
std::complex< double > GetAmp(void) const
Get the complex amplitude of arrival.
void SetResolution(Time resolution)
Set the time duration (resolution) between arrivals.
void SetNTaps(uint32_t nTaps)
Resize the tap vector.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Time GetDelay(void) const
Get the delay time, usually from first arrival of signal.
Time GetResolution(void) const
Get the delay time resolution (time duration between arrivals).
Iterator GetEnd(void) const
Get the end of the tap list (one beyond the last entry).
virtual void DoDispose(void)
Destructor implementation.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
Time m_delay
The time delay.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
std::complex< double > SumTapsFromMaxC(Time delay, Time duration) const
Compute the coherent sum of tap amplitudes starting after a delay from the maximum amplitude for a to...
A base class which provides memory management and object aggregation.
Definition: object.h:87
Iterator GetBegin(void) const
Get the beginning of the tap vector.
const Tap & GetTap(uint32_t i) const
Get the Tap at the specified delay index.
double SumTapsNc(Time begin, Time end) const
Compute the non-coherent sum of tap amplitudes between a start and end time.
static TypeId GetTypeId(void)
Register this type.
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
std::complex< double > m_amplitude
The amplitude.