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