A Discrete-Event Network Simulator
API
nist-error-rate-model.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 The Boeing Company
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  * Authors: Gary Pei <guangyu.pei@boeing.com>
19  * Sébastien Deronne <sebastien.deronne@gmail.com>
20  */
21 
22 #include <cmath>
23 #include "nist-error-rate-model.h"
24 #include "wifi-phy.h"
25 #include "ns3/log.h"
26 
27 namespace ns3 {
28 
29 NS_LOG_COMPONENT_DEFINE ("NistErrorRateModel");
30 
31 NS_OBJECT_ENSURE_REGISTERED (NistErrorRateModel);
32 
33 TypeId
35 {
36  static TypeId tid = TypeId ("ns3::NistErrorRateModel")
38  .SetGroupName ("Wifi")
39  .AddConstructor<NistErrorRateModel> ()
40  ;
41  return tid;
42 }
43 
45 {
46 }
47 
48 double
50 {
51  NS_LOG_FUNCTION (this << snr);
52  double z = std::sqrt (snr);
53  double ber = 0.5 * erfc (z);
54  NS_LOG_INFO ("bpsk snr=" << snr << " ber=" << ber);
55  return ber;
56 }
57 
58 double
60 {
61  NS_LOG_FUNCTION (this << snr);
62  double z = std::sqrt (snr / 2.0);
63  double ber = 0.5 * erfc (z);
64  NS_LOG_INFO ("qpsk snr=" << snr << " ber=" << ber);
65  return ber;
66 }
67 
68 double
70 {
71  NS_LOG_FUNCTION (this << snr);
72  double z = std::sqrt (snr / (5.0 * 2.0));
73  double ber = 0.75 * 0.5 * erfc (z);
74  NS_LOG_INFO ("16-Qam" << " snr=" << snr << " ber=" << ber);
75  return ber;
76 }
77 
78 double
80 {
81  NS_LOG_FUNCTION (this << snr);
82  double z = std::sqrt (snr / (21.0 * 2.0));
83  double ber = 7.0 / 12.0 * 0.5 * erfc (z);
84  NS_LOG_INFO ("64-Qam" << " snr=" << snr << " ber=" << ber);
85  return ber;
86 }
87 double
89 {
90  NS_LOG_FUNCTION (this << snr);
91  double z = std::sqrt (snr / (85.0 * 2.0));
92  double ber = 15.0 / 32.0 * 0.5 * erfc (z);
93  NS_LOG_INFO ("256-Qam" << " snr=" << snr << " ber=" << ber);
94  return ber;
95 }
96 
97 double
98 NistErrorRateModel::GetFecBpskBer (double snr, uint32_t nbits,
99  uint32_t bValue) const
100 {
101  NS_LOG_FUNCTION (this << snr << nbits << bValue);
102  double ber = GetBpskBer (snr);
103  if (ber == 0.0)
104  {
105  return 1.0;
106  }
107  double pe = CalculatePe (ber, bValue);
108  pe = std::min (pe, 1.0);
109  double pms = std::pow (1 - pe, (double)nbits);
110  return pms;
111 }
112 
113 double
114 NistErrorRateModel::GetFecQpskBer (double snr, uint32_t nbits,
115  uint32_t bValue) const
116 {
117  NS_LOG_FUNCTION (this << snr << nbits << bValue);
118  double ber = GetQpskBer (snr);
119  if (ber == 0.0)
120  {
121  return 1.0;
122  }
123  double pe = CalculatePe (ber, bValue);
124  pe = std::min (pe, 1.0);
125  double pms = std::pow (1 - pe, (double)nbits);
126  return pms;
127 }
128 
129 double
130 NistErrorRateModel::CalculatePe (double p, uint32_t bValue) const
131 {
132  NS_LOG_FUNCTION (this << p << bValue);
133  double D = std::sqrt (4.0 * p * (1.0 - p));
134  double pe = 1.0;
135  if (bValue == 1)
136  {
137  //code rate 1/2, use table 3.1.1
138  pe = 0.5 * (36.0 * std::pow (D, 10)
139  + 211.0 * std::pow (D, 12)
140  + 1404.0 * std::pow (D, 14)
141  + 11633.0 * std::pow (D, 16)
142  + 77433.0 * std::pow (D, 18)
143  + 502690.0 * std::pow (D, 20)
144  + 3322763.0 * std::pow (D, 22)
145  + 21292910.0 * std::pow (D, 24)
146  + 134365911.0 * std::pow (D, 26));
147  }
148  else if (bValue == 2)
149  {
150  //code rate 2/3, use table 3.1.2
151  pe = 1.0 / (2.0 * bValue) *
152  (3.0 * std::pow (D, 6)
153  + 70.0 * std::pow (D, 7)
154  + 285.0 * std::pow (D, 8)
155  + 1276.0 * std::pow (D, 9)
156  + 6160.0 * std::pow (D, 10)
157  + 27128.0 * std::pow (D, 11)
158  + 117019.0 * std::pow (D, 12)
159  + 498860.0 * std::pow (D, 13)
160  + 2103891.0 * std::pow (D, 14)
161  + 8784123.0 * std::pow (D, 15));
162  }
163  else if (bValue == 3)
164  {
165  //code rate 3/4, use table 3.1.2
166  pe = 1.0 / (2.0 * bValue) *
167  (42.0 * std::pow (D, 5)
168  + 201.0 * std::pow (D, 6)
169  + 1492.0 * std::pow (D, 7)
170  + 10469.0 * std::pow (D, 8)
171  + 62935.0 * std::pow (D, 9)
172  + 379644.0 * std::pow (D, 10)
173  + 2253373.0 * std::pow (D, 11)
174  + 13073811.0 * std::pow (D, 12)
175  + 75152755.0 * std::pow (D, 13)
176  + 428005675.0 * std::pow (D, 14));
177  }
178  else if (bValue == 5)
179  {
180  //code rate 5/6, use table V from D. Haccoun and G. Begin, "High-Rate Punctured Convolutional Codes
181  //for Viterbi Sequential Decoding", IEEE Transactions on Communications, Vol. 32, Issue 3, pp.315-319.
182  pe = 1.0 / (2.0 * bValue) *
183  (92.0 * std::pow (D, 4.0)
184  + 528.0 * std::pow (D, 5.0)
185  + 8694.0 * std::pow (D, 6.0)
186  + 79453.0 * std::pow (D, 7.0)
187  + 792114.0 * std::pow (D, 8.0)
188  + 7375573.0 * std::pow (D, 9.0)
189  + 67884974.0 * std::pow (D, 10.0)
190  + 610875423.0 * std::pow (D, 11.0)
191  + 5427275376.0 * std::pow (D, 12.0)
192  + 47664215639.0 * std::pow (D, 13.0));
193  }
194  else
195  {
196  NS_ASSERT (false);
197  }
198  return pe;
199 }
200 
201 double
202 NistErrorRateModel::GetFec16QamBer (double snr, uint32_t nbits,
203  uint32_t bValue) const
204 {
205  NS_LOG_FUNCTION (this << snr << nbits << bValue);
206  double ber = Get16QamBer (snr);
207  if (ber == 0.0)
208  {
209  return 1.0;
210  }
211  double pe = CalculatePe (ber, bValue);
212  pe = std::min (pe, 1.0);
213  double pms = std::pow (1 - pe, static_cast<double> (nbits));
214  return pms;
215 }
216 
217 double
218 NistErrorRateModel::GetFec64QamBer (double snr, uint32_t nbits,
219  uint32_t bValue) const
220 {
221  NS_LOG_FUNCTION (this << snr << nbits << bValue);
222  double ber = Get64QamBer (snr);
223  if (ber == 0.0)
224  {
225  return 1.0;
226  }
227  double pe = CalculatePe (ber, bValue);
228  pe = std::min (pe, 1.0);
229  double pms = std::pow (1 - pe, static_cast<double> (nbits));
230  return pms;
231 }
232 
233 double
234 NistErrorRateModel::GetFec256QamBer (double snr, uint32_t nbits,
235  uint32_t bValue) const
236 {
237  NS_LOG_FUNCTION (this << snr << nbits << bValue);
238  double ber = Get256QamBer (snr);
239  if (ber == 0.0)
240  {
241  return 1.0;
242  }
243  double pe = CalculatePe (ber, bValue);
244  pe = std::min (pe, 1.0);
245  double pms = std::pow (1 - pe, static_cast<double> (nbits));
246  return pms;
247 }
248 
249 double
250 NistErrorRateModel::GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
251 {
252  NS_LOG_FUNCTION (this << mode << txVector.GetMode () << snr << nbits);
257  {
258  if (mode.GetConstellationSize () == 2)
259  {
260  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
261  {
262  return GetFecBpskBer (snr,
263  nbits,
264  1); //b value
265  }
266  else
267  {
268  return GetFecBpskBer (snr,
269  nbits,
270  3); //b value
271  }
272  }
273  else if (mode.GetConstellationSize () == 4)
274  {
275  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
276  {
277  return GetFecQpskBer (snr,
278  nbits,
279  1); //b value
280  }
281  else
282  {
283  return GetFecQpskBer (snr,
284  nbits,
285  3); //b value
286  }
287  }
288  else if (mode.GetConstellationSize () == 16)
289  {
290  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
291  {
292  return GetFec16QamBer (snr,
293  nbits,
294  1); //b value
295  }
296  else
297  {
298  return GetFec16QamBer (snr,
299  nbits,
300  3); //b value
301  }
302  }
303  else if (mode.GetConstellationSize () == 64)
304  {
305  if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
306  {
307  return GetFec64QamBer (snr,
308  nbits,
309  2); //b value
310  }
311  else if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
312  {
313  return GetFec64QamBer (snr,
314  nbits,
315  5); //b value
316  }
317  else
318  {
319  return GetFec64QamBer (snr,
320  nbits,
321  3); //b value
322  }
323  }
324  else if (mode.GetConstellationSize () == 256)
325  {
326  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
327  {
328  return GetFec256QamBer (snr,
329  nbits,
330  5 // b value
331  );
332  }
333  else
334  {
335  return GetFec256QamBer (snr,
336  nbits,
337  3 // b value
338  );
339  }
340  }
341  }
343  {
344  switch (mode.GetDataRate (20, 0, 1))
345  {
346  case 1000000:
348  case 2000000:
350  case 5500000:
352  case 11000000:
354  default:
355  NS_ASSERT ("undefined DSSS/HR-DSSS datarate");
356  }
357  }
358  return 0;
359 }
360 
361 } //namespace ns3
double GetQpskBer(double snr) const
Return BER of QPSK at the given SNR.
static double GetDsssDqpskCck11SuccessRate(double sinr, uint32_t nbits)
Return the chunk success rate of the differential encoded QPSK for 11Mbps data rate.
static TypeId GetTypeId(void)
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
ERP-OFDM PHY (19.5)
Definition: wifi-mode.h:58
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
#define min(a, b)
Definition: 80211b.c:44
enum WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:379
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
static double GetDsssDqpskSuccessRate(double sinr, uint32_t nbits)
Return the chunk success rate of the differential encoded QPSK.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
VHT PHY (Clause 22)
Definition: wifi-mode.h:64
HR/DSSS PHY (Clause 18)
Definition: wifi-mode.h:52
double GetFec64QamBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of QAM64 at the given SNR after applying FEC.
double GetFec16QamBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of QAM16 at the given SNR after applying FEC.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
double GetFec256QamBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of QAM256 at the given SNR after applying FEC.
the interface for Wifi's error models
double CalculatePe(double p, uint32_t bValue) const
Return the coded BER for the given p and b.
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:289
virtual double GetChunkSuccessRate(WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
A pure virtual method that must be implemented in the subclass.
enum WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:237
double Get16QamBer(double snr) const
Return BER of QAM16 at the given SNR.
HT PHY (Clause 20)
Definition: wifi-mode.h:62
A model for the error rate for different modulations.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint64_t GetDataRate(uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
Definition: wifi-mode.cc:109
double GetFecQpskBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of QPSK at the given SNR after applying FEC.
double Get64QamBer(double snr) const
Return BER of QAM64 at the given SNR.
double Get256QamBer(double snr) const
Return BER of QAM256 at the given SNR.
static double GetDsssDqpskCck5_5SuccessRate(double sinr, uint32_t nbits)
Return the chunk success rate of the differential encoded QPSK for 5.5Mbps data rate.
OFDM PHY (Clause 17)
Definition: wifi-mode.h:60
double GetFecBpskBer(double snr, uint32_t nbits, uint32_t bValue) const
Return BER of BPSK at the given SNR after applying FEC.
static double GetDsssDbpskSuccessRate(double sinr, uint32_t nbits)
Return the chunk success rate of the differential BPSK.
WifiMode GetMode(void) const
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
DSSS PHY (Clause 15)
Definition: wifi-mode.h:50
double GetBpskBer(double snr) const
Return BER of BPSK at the given SNR.