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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Leonard Tracy <lentracy@gmail.com>
7 */
8
9#include "uan-prop-model.h"
10
11#include "ns3/nstime.h"
12
13#include <complex>
14#include <vector>
15
16namespace ns3
17{
18
19std::ostream&
20operator<<(std::ostream& os, const UanPdp& pdp)
21{
22 os << pdp.GetNTaps() << '|';
23 os << pdp.GetResolution().GetSeconds() << '|';
24
25 auto it = pdp.m_taps.begin();
26 for (; it != pdp.m_taps.end(); it++)
27 {
28 os << (*it).GetAmp() << '|';
29 }
30 return os;
31}
32
33std::istream&
34operator>>(std::istream& is, UanPdp& pdp)
35{
36 uint32_t ntaps;
37 double resolution;
38 char c1;
39
40 is >> ntaps >> c1;
41 if (c1 != '|')
42 {
43 NS_FATAL_ERROR("UanPdp data corrupted at # of taps");
44 return is;
45 }
46 is >> resolution >> c1;
47 if (c1 != '|')
48 {
49 NS_FATAL_ERROR("UanPdp data corrupted at resolution");
50 return is;
51 }
52 pdp.m_resolution = Seconds(resolution);
53
54 std::complex<double> amp;
55 pdp.m_taps = std::vector<Tap>(ntaps);
56 for (uint32_t i = 0; i < ntaps && !is.eof(); i++)
57 {
58 is >> amp >> c1;
59 if (c1 != '|')
60 {
61 NS_FATAL_ERROR("UanPdp data corrupted at tap " << i);
62 return is;
63 }
64 pdp.m_taps[i] = Tap(Seconds(resolution * i), amp);
65 }
66 return is;
67}
68
70 : m_amplitude(0.0),
71 m_delay(Seconds(0))
72{
73}
74
75Tap::Tap(Time delay, std::complex<double> amp)
76 : m_amplitude(amp),
77 m_delay(delay)
78{
79}
80
81std::complex<double>
83{
84 return m_amplitude;
85}
86
87Time
89{
90 return m_delay;
91}
92
96
97UanPdp::UanPdp(std::vector<Tap> taps, Time resolution)
98 : m_taps(taps),
99 m_resolution(resolution)
100{
101}
102
103UanPdp::UanPdp(std::vector<std::complex<double>> amps, Time resolution)
104 : m_resolution(resolution)
105{
106 m_taps.resize(amps.size());
107 Time arrTime = Seconds(0);
108 for (uint32_t index = 0; index < amps.size(); index++)
109 {
110 m_taps[index] = Tap(arrTime, amps[index]);
111 arrTime = arrTime + m_resolution;
112 }
113}
114
115UanPdp::UanPdp(std::vector<double> amps, Time resolution)
116 : m_resolution(resolution)
117{
118 m_taps.resize(amps.size());
119 Time arrTime = Seconds(0);
120 for (uint32_t index = 0; index < amps.size(); index++)
121 {
122 m_taps[index] = Tap(arrTime, amps[index]);
123 arrTime = arrTime + m_resolution;
124 }
125}
126
128{
129 m_taps.clear();
130}
131
132void
133UanPdp::SetTap(std::complex<double> amp, uint32_t index)
134{
135 if (m_taps.size() <= index)
136 {
137 m_taps.resize(index + 1);
138 }
139
140 Time delay = index * m_resolution;
141 m_taps[index] = Tap(delay, amp);
142}
143
144const Tap&
146{
147 NS_ASSERT_MSG(i < GetNTaps(), "Call to UanPdp::GetTap with requested tap out of range");
148 return m_taps[i];
149}
150
151void
153{
154 m_taps.resize(nTaps);
155}
156
157void
159{
160 m_resolution = resolution;
161}
162
165{
166 return m_taps.begin();
167}
168
171{
172 return m_taps.end();
173}
174
177{
178 return static_cast<uint32_t>(m_taps.size());
179}
180
181Time
183{
184 return m_resolution;
185}
186
187std::complex<double>
188UanPdp::SumTapsFromMaxC(Time delay, Time duration) const
189{
190 if (m_resolution <= Seconds(0))
191 {
192 NS_ASSERT_MSG(GetNTaps() == 1,
193 "Attempted to sum taps over time interval in "
194 "UanPdp with resolution 0 and multiple taps");
195
196 if (delay.IsZero())
197 {
198 return m_taps[0].GetAmp();
199 }
200 return std::complex<double>(0.0, 0.0);
201 }
202
203 uint32_t numTaps = (duration / m_resolution + 0.5).GetHigh();
204 double maxAmp = -1;
205 uint32_t maxTapIndex = 0;
206
207 for (uint32_t i = 0; i < GetNTaps(); i++)
208 {
209 if (std::abs(m_taps[i].GetAmp()) > maxAmp)
210 {
211 maxAmp = std::abs(m_taps[i].GetAmp());
212 maxTapIndex = i;
213 }
214 }
215 uint32_t start = maxTapIndex + (delay / m_resolution).GetHigh();
216 uint32_t end = std::min(start + numTaps, GetNTaps());
217 std::complex<double> sum = 0;
218 for (uint32_t i = start; i < end; i++)
219 {
220 sum += m_taps[i].GetAmp();
221 }
222 return sum;
223}
224
225double
226UanPdp::SumTapsFromMaxNc(Time delay, Time duration) const
227{
228 if (m_resolution <= Seconds(0))
229 {
230 NS_ASSERT_MSG(GetNTaps() == 1,
231 "Attempted to sum taps over time interval in "
232 "UanPdp with resolution 0 and multiple taps");
233
234 if (delay.IsZero())
235 {
236 return std::abs(m_taps[0].GetAmp());
237 }
238 return 0;
239 }
240
241 uint32_t numTaps = (duration / m_resolution + 0.5).GetHigh();
242 double maxAmp = -1;
243 uint32_t maxTapIndex = 0;
244
245 for (uint32_t i = 0; i < GetNTaps(); i++)
246 {
247 if (std::abs(m_taps[i].GetAmp()) > maxAmp)
248 {
249 maxAmp = std::abs(m_taps[i].GetAmp());
250 maxTapIndex = i;
251 }
252 }
253
254 uint32_t start = maxTapIndex + (delay / m_resolution).GetHigh();
255 uint32_t end = std::min(start + numTaps, GetNTaps());
256 double sum = 0;
257 for (uint32_t i = start; i < end; i++)
258
259 {
260 sum += std::abs(m_taps[i].GetAmp());
261 }
262 return sum;
263}
264
265double
266UanPdp::SumTapsNc(Time begin, Time end) const
267{
268 if (m_resolution <= Seconds(0))
269 {
270 NS_ASSERT_MSG(GetNTaps() == 1,
271 "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 = (begin / m_resolution + 0.5).GetHigh();
285 uint32_t endIndex = (end / m_resolution + 0.5).GetHigh();
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
296std::complex<double>
297UanPdp::SumTapsC(Time begin, Time end) const
298{
299 if (m_resolution <= Seconds(0))
300 {
301 NS_ASSERT_MSG(GetNTaps() == 1,
302 "Attempted to sum taps over time interval in "
303 "UanPdp with resolution 0 and multiple taps");
304
305 if (begin <= Seconds(0.0) && end >= Seconds(0.0))
306 {
307 return m_taps[0].GetAmp();
308 }
309 else
310 {
311 return std::complex<double>(0.0);
312 }
313 }
314
315 uint32_t stIndex = (begin / m_resolution + 0.5).GetHigh();
316 uint32_t endIndex = (end / m_resolution + 0.5).GetHigh();
317
318 endIndex = std::min(endIndex, GetNTaps());
319
320 std::complex<double> sum = 0;
321 for (uint32_t i = stIndex; i < endIndex; i++)
322 {
323 sum += m_taps[i].GetAmp();
324 }
325 return sum;
326}
327
328UanPdp
330{
331 double sumNc = 0.0;
332 std::vector<Tap> newTaps;
333
334 for (uint32_t i = 0; i < GetNTaps(); i++)
335 {
336 sumNc += std::abs(m_taps[i].GetAmp());
337 }
338
339 for (uint32_t i = 0; i < GetNTaps(); i++)
340 {
341 newTaps.emplace_back(m_taps[i].GetDelay(), (m_taps[i].GetAmp() / sumNc));
342 }
343
344 return UanPdp(newTaps, m_resolution);
345}
346
347UanPdp
349{
350 UanPdp pdp;
351 pdp.SetResolution(Seconds(0));
352 pdp.SetTap(1.0, 0);
353 return pdp;
354}
355
357
358TypeId
360{
361 static TypeId tid = TypeId("ns3::UanPropModel").SetParent<Object>().SetGroupName("Uan");
362 return tid;
363}
364
365void
369
370void
376
377} // namespace ns3
A base class which provides memory management and object aggregation.
Definition object.h:78
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
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:94
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
bool IsZero() const
Exactly equivalent to t == 0.
Definition nstime.h:304
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
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:75
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172