A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  return m_taps[0].GetAmp ();
208  }
209 
210  uint32_t numTaps = static_cast<uint32_t> (duration.GetSeconds () / m_resolution.GetSeconds () + 0.5);
211  double maxAmp = -1;
212  uint32_t maxTapIndex = 0;
213 
214  for (uint32_t i = 0; i < GetNTaps (); i++)
215  {
216  if (std::abs (m_taps[i].GetAmp ()) > maxAmp)
217  {
218  maxAmp = std::abs (m_taps[i].GetAmp ());
219  maxTapIndex = i;
220  }
221  }
222  uint32_t start = maxTapIndex + static_cast<uint32_t> (delay.GetSeconds () / m_resolution.GetSeconds ());
223  uint32_t end = std::min (start + numTaps, GetNTaps ());
224  std::complex<double> sum = 0;
225  for (uint32_t i = start; i < end; i++)
226  {
227  sum += m_taps[i].GetAmp ();
228  }
229  return sum;
230 }
231 double
232 UanPdp::SumTapsFromMaxNc (Time delay, Time duration) const
233 {
234  if (m_resolution <= Seconds (0))
235  {
236  NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
237  "UanPdp with resolution 0 and multiple taps");
238 
239  return std::abs (m_taps[0].GetAmp ());
240  }
241 
242  uint32_t numTaps = static_cast<uint32_t> (duration.GetSeconds () / m_resolution.GetSeconds () + 0.5);
243  double maxAmp = -1;
244  uint32_t maxTapIndex = 0;
245 
246  for (uint32_t i = 0; i < GetNTaps (); i++)
247  {
248  if (std::abs (m_taps[i].GetAmp ()) > maxAmp)
249  {
250  maxAmp = std::abs (m_taps[i].GetAmp ());
251  maxTapIndex = i;
252  }
253  }
254 
255 
256  uint32_t start = maxTapIndex + static_cast<uint32_t> (delay.GetSeconds () / m_resolution.GetSeconds ());
257  uint32_t end = std::min (start + numTaps, GetNTaps ());
258  double sum = 0;
259  for (uint32_t i = start; i < end; i++)
260 
261  {
262  sum += std::abs (m_taps[i].GetAmp ());
263  }
264  return sum;
265 }
266 double
267 UanPdp::SumTapsNc (Time begin, Time end) const
268 {
269  if (m_resolution <= Seconds (0))
270  {
271  NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
272  "UanPdp with resolution 0 and multiple taps");
273 
274  if (begin <= Seconds (0.0) && end >= Seconds (0.0))
275  {
276  return std::abs (m_taps[0].GetAmp ());
277  }
278  else
279  {
280  return 0.0;
281  }
282  }
283 
284  uint32_t stIndex = (uint32_t)(begin.GetSeconds () / m_resolution.GetSeconds () + 0.5);
285  uint32_t endIndex = (uint32_t)(end.GetSeconds () / m_resolution.GetSeconds () + 0.5);
286 
287  endIndex = std::min (endIndex, GetNTaps ());
288  double sum = 0;
289  for (uint32_t i = stIndex; i < endIndex; i++)
290  {
291  sum += std::abs (m_taps[i].GetAmp ());
292  }
293  return sum;
294 
295 }
296 
297 
298 
299 std::complex<double>
300 UanPdp::SumTapsC (Time begin, Time end) const
301 {
302  if (m_resolution <= Seconds (0))
303  {
304  NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in "
305  "UanPdp with resolution 0 and multiple taps");
306 
307  if (begin <= Seconds (0.0) && end >= Seconds (0.0))
308  {
309  return m_taps[0].GetAmp ();
310  }
311  else
312  {
313  return std::complex<double> (0.0);
314  }
315  }
316 
317  uint32_t stIndex = (uint32_t)(begin.GetSeconds () / m_resolution.GetSeconds () + 0.5);
318  uint32_t endIndex = (uint32_t)(end.GetSeconds () / m_resolution.GetSeconds () + 0.5);
319 
320  endIndex = std::min (endIndex, GetNTaps ());
321 
322  std::complex<double> sum = 0;
323  for (uint32_t i = stIndex; i < endIndex; i++)
324  {
325  sum += m_taps[i].GetAmp ();
326  }
327  return sum;
328 }
329 
330 UanPdp
332 {
333  UanPdp pdp;
334  pdp.SetResolution (Seconds (0));
335  pdp.SetTap (1.0,0);
336  return pdp;
337 }
338 
340  ;
341 
343 {
344  static TypeId tid = TypeId ("ns3::UanPropModel")
345  .SetParent<Object> ();
346  return tid;
347 }
348 
349 void
351 {
352 }
353 
354 void
356 {
357  Clear ();
359 }
360 
361 }
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:49
std::complex< double > SumTapsC(Time begin, Time end) const
Compute the coherent sum of tap amplitudes between a start and end time.
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
std::vector< Tap >::const_iterator Iterator
Convenience iterator typedef.
uint32_t GetNTaps(void) const
Get the number of taps.
static UanPdp CreateImpulsePdp(void)
Get a unit impulse PDP at time 0.
virtual void Clear(void)
Clear all pointer references.
Base class for implemented underwater propagation models.
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
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 ...
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
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.
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
double GetSeconds(void) const
Definition: nstime.h:274
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:43
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)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Time m_delay
The time delay.
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:63
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:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
std::complex< double > m_amplitude
The amplitude.