OLD | NEW |
(Empty) | |
| 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 as published by |
| 7 * the Free Software Foundation, either version 3 of the License, or |
| 8 * (at your option) any later version. |
| 9 * |
| 10 * This program is distributed in the hope that it will be useful, |
| 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 * GNU General Public License for more details. |
| 14 * |
| 15 * You should have received a copy of the GNU General Public License |
| 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 * |
| 18 * Author: Leonard Tracy <lentracy@u.washington.edu> |
| 19 * |
| 20 * |
| 21 */ |
| 22 |
| 23 |
| 24 #include "uan-prop-model.h" |
| 25 #include "ns3/nstime.h" |
| 26 #include <complex> |
| 27 #include <vector> |
| 28 |
| 29 |
| 30 namespace ns3 |
| 31 { |
| 32 |
| 33 std::ostream & |
| 34 operator<< (std::ostream &os, UanPdp &pdp) |
| 35 { |
| 36 os << pdp.GetNTaps () << '|'; |
| 37 os << pdp.GetResolution ().GetSeconds () << '|'; |
| 38 |
| 39 UanPdp::Iterator it = pdp.m_taps.begin (); |
| 40 for (;it!= pdp.m_taps.end ();it++) |
| 41 { |
| 42 os << (*it).GetAmp () << '|'; |
| 43 } |
| 44 return os; |
| 45 |
| 46 } |
| 47 std::istream & |
| 48 operator>> (std::istream &is, UanPdp &pdp) |
| 49 { |
| 50 uint32_t ntaps; |
| 51 double resolution; |
| 52 char c1; |
| 53 |
| 54 is >> ntaps >> c1; |
| 55 if (c1 != '|') |
| 56 { |
| 57 NS_FATAL_ERROR ("UanPdp data corrupted at # of taps"); |
| 58 return is; |
| 59 } |
| 60 is >> resolution >> c1; |
| 61 if (c1 != '|') |
| 62 { |
| 63 NS_FATAL_ERROR ("UanPdp data corrupted at resolution"); |
| 64 return is; |
| 65 } |
| 66 pdp.m_resolution = Seconds (resolution); |
| 67 |
| 68 |
| 69 std::complex<double> amp; |
| 70 pdp.m_taps = std::vector<Tap> (ntaps); |
| 71 for (uint32_t i=0;i<ntaps;i++) |
| 72 { |
| 73 is >> amp >> c1; |
| 74 if (c1 != '|') |
| 75 { |
| 76 NS_FATAL_ERROR ("UanPdp data corrupted at tap " << i); |
| 77 return is; |
| 78 } |
| 79 pdp.m_taps[i] = Tap (Seconds (resolution*i), amp); |
| 80 } |
| 81 return is; |
| 82 |
| 83 } |
| 84 |
| 85 Tap::Tap () : |
| 86 m_amplitude (0.0), |
| 87 m_delay (Seconds (0)) |
| 88 { |
| 89 |
| 90 } |
| 91 |
| 92 Tap::Tap (Time delay, std::complex<double> amp) : |
| 93 m_amplitude (amp), |
| 94 m_delay (delay) |
| 95 { |
| 96 |
| 97 } |
| 98 |
| 99 std::complex<double> |
| 100 Tap::GetAmp (void) const |
| 101 { |
| 102 return m_amplitude; |
| 103 } |
| 104 |
| 105 Time |
| 106 Tap::GetDelay (void) const |
| 107 { |
| 108 return m_delay; |
| 109 } |
| 110 |
| 111 |
| 112 UanPdp::UanPdp () |
| 113 { |
| 114 |
| 115 } |
| 116 |
| 117 UanPdp::UanPdp (std::vector<Tap> taps, Time resolution) : |
| 118 m_taps (taps), |
| 119 m_resolution (resolution) |
| 120 { |
| 121 } |
| 122 |
| 123 UanPdp::UanPdp (std::vector<std::complex<double> > amps, Time resolution) : |
| 124 m_resolution (resolution) |
| 125 { |
| 126 m_taps.resize (amps.size ()); |
| 127 Time arrTime = Seconds (0); |
| 128 for(uint32_t index=0; index < amps.size (); index++) |
| 129 { |
| 130 m_taps[index] = Tap (arrTime, amps[index]); |
| 131 arrTime = arrTime + m_resolution; |
| 132 } |
| 133 } |
| 134 |
| 135 UanPdp::UanPdp (std::vector<double> amps, Time resolution) : |
| 136 m_resolution (resolution) |
| 137 { |
| 138 m_taps.resize (amps.size ()); |
| 139 Time arrTime = Seconds (0); |
| 140 for (uint32_t index=0; index < amps.size (); index++) |
| 141 { |
| 142 m_taps[index] = Tap (arrTime, amps[index]); |
| 143 arrTime = arrTime + m_resolution; |
| 144 } |
| 145 } |
| 146 |
| 147 UanPdp::~UanPdp () |
| 148 { |
| 149 m_taps.clear (); |
| 150 } |
| 151 |
| 152 void |
| 153 UanPdp::SetTap (std::complex<double> amp, uint32_t index) |
| 154 { |
| 155 if (m_taps.size () <= index) |
| 156 m_taps.resize (index+1); |
| 157 |
| 158 Time delay = Seconds (index*m_resolution.GetSeconds ()); |
| 159 m_taps[index] = Tap (delay, amp); |
| 160 } |
| 161 const Tap & |
| 162 UanPdp::GetTap (uint32_t i) const |
| 163 { |
| 164 NS_ASSERT_MSG (i < GetNTaps (), "Call to UanPdp::GetTap with requested tap out
of range"); |
| 165 return m_taps[i]; |
| 166 } |
| 167 void |
| 168 UanPdp::SetNTaps (uint32_t nTaps) |
| 169 { |
| 170 m_taps.resize (nTaps); |
| 171 } |
| 172 void |
| 173 UanPdp::SetResolution (Time resolution) |
| 174 { |
| 175 m_resolution = resolution; |
| 176 } |
| 177 UanPdp::Iterator |
| 178 UanPdp::GetBegin (void) const |
| 179 { |
| 180 return m_taps.begin (); |
| 181 } |
| 182 |
| 183 UanPdp::Iterator |
| 184 UanPdp::GetEnd (void) const |
| 185 { |
| 186 return m_taps.end (); |
| 187 } |
| 188 |
| 189 uint32_t |
| 190 UanPdp::GetNTaps (void) const |
| 191 { |
| 192 return m_taps.size (); |
| 193 } |
| 194 |
| 195 Time |
| 196 UanPdp::GetResolution (void) const |
| 197 { |
| 198 return m_resolution; |
| 199 } |
| 200 |
| 201 std::complex<double> |
| 202 UanPdp::SumTapsFromMaxC (Time delay, Time duration) const |
| 203 { |
| 204 if (m_resolution <= Seconds (0)) |
| 205 NS_FATAL_ERROR ("Attempted to sum taps over time interval in UanPdp with res
olution=0"); |
| 206 |
| 207 uint32_t numTaps = (uint32_t) (duration.GetSeconds () / (double) m_resolution
.GetSeconds () + 0.5); |
| 208 double maxAmp = -1; |
| 209 uint32_t maxTapIndex; |
| 210 |
| 211 for (uint32_t i=0;i<GetNTaps ();i++) |
| 212 { |
| 213 if (abs (m_taps[i].GetAmp ()) > maxAmp) |
| 214 { |
| 215 maxAmp = abs (m_taps[i].GetAmp ()); |
| 216 maxTapIndex = i; |
| 217 } |
| 218 } |
| 219 uint32_t start = maxTapIndex + delay.GetSeconds ()/m_resolution.GetSeconds (); |
| 220 uint32_t end = std::min (start + numTaps, GetNTaps ()); |
| 221 std::complex<double> sum=0; |
| 222 for (uint32_t i=start; i < end; i++) |
| 223 { |
| 224 sum += m_taps[i].GetAmp (); |
| 225 } |
| 226 return sum; |
| 227 } |
| 228 double |
| 229 UanPdp::SumTapsFromMaxNc (Time delay, Time duration) const |
| 230 { |
| 231 if (m_resolution <= Seconds (0)) |
| 232 NS_FATAL_ERROR ("Attempted to sum taps over time interval in UanPdp with res
olution=0"); |
| 233 |
| 234 uint32_t numTaps = (uint32_t) (duration.GetSeconds () / (double) m_resolution
.GetSeconds () + 0.5); |
| 235 double maxAmp = -1; |
| 236 uint32_t maxTapIndex; |
| 237 |
| 238 for (uint32_t i=0;i<GetNTaps ();i++) |
| 239 { |
| 240 if (abs (m_taps[i].GetAmp ()) > maxAmp) |
| 241 { |
| 242 maxAmp = abs (m_taps[i].GetAmp ()); |
| 243 maxTapIndex = i; |
| 244 } |
| 245 } |
| 246 |
| 247 |
| 248 uint32_t start = maxTapIndex + delay.GetSeconds ()/m_resolution.GetSeconds (); |
| 249 uint32_t end = std::min (start + numTaps, GetNTaps ()); |
| 250 double sum=0; |
| 251 for (uint32_t i=start; i < end; i++) |
| 252 |
| 253 { |
| 254 sum += abs (m_taps[i].GetAmp ()); |
| 255 } |
| 256 return sum; |
| 257 } |
| 258 double |
| 259 UanPdp::SumTapsNc (Time begin, Time end) const |
| 260 { |
| 261 if (m_resolution <= Seconds (0)) |
| 262 NS_FATAL_ERROR ("Attempted to sum taps over time interval in UanPdp with res
olution=0"); |
| 263 |
| 264 uint32_t stIndex = (uint32_t) (begin.GetSeconds () / m_resolution.GetSeconds (
) + 0.5); |
| 265 uint32_t endIndex = (uint32_t) (end.GetSeconds () / m_resolution.GetSeconds ()
+ 0.5); |
| 266 |
| 267 endIndex = std::min (endIndex, GetNTaps ()); |
| 268 double sum=0; |
| 269 for (uint32_t i=stIndex;i < endIndex;i++) |
| 270 { |
| 271 sum += abs (m_taps[i].GetAmp ()); |
| 272 } |
| 273 return sum; |
| 274 |
| 275 } |
| 276 |
| 277 |
| 278 |
| 279 std::complex<double> |
| 280 UanPdp::SumTapsC (Time begin, Time end) const |
| 281 { |
| 282 if (m_resolution <= Seconds (0)) |
| 283 NS_FATAL_ERROR ("Attempted to sum taps over time interval in UanPdp with res
olution=0"); |
| 284 |
| 285 uint32_t stIndex = (uint32_t) (begin.GetSeconds () / m_resolution.GetSeconds (
) + 0.5); |
| 286 uint32_t endIndex = (uint32_t) (end.GetSeconds () / m_resolution.GetSeconds ()
+ 0.5); |
| 287 |
| 288 endIndex = std::min (endIndex, GetNTaps ()); |
| 289 |
| 290 std::complex<double> sum=0; |
| 291 for (uint32_t i=stIndex;i < endIndex;i++) |
| 292 { |
| 293 sum += m_taps[i].GetAmp (); |
| 294 } |
| 295 return sum; |
| 296 } |
| 297 |
| 298 UanPdp |
| 299 UanPdp::CreateImpulsePdp (void) |
| 300 { |
| 301 UanPdp pdp; |
| 302 pdp.SetResolution (Seconds (0)); |
| 303 pdp.SetTap (1.0,0); |
| 304 return pdp; |
| 305 } |
| 306 |
| 307 } |
OLD | NEW |