A Discrete-Event Network Simulator
API
yans-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) 2005,2006 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  * Sébastien Deronne <sebastien.deronne@gmail.com>
20  */
21 
22 #include "yans-error-rate-model.h"
23 #include "wifi-utils.h"
24 #include "wifi-phy.h"
25 #include "ns3/log.h"
26 
27 namespace ns3 {
28 
29 NS_LOG_COMPONENT_DEFINE ("YansErrorRateModel");
30 
31 NS_OBJECT_ENSURE_REGISTERED (YansErrorRateModel);
32 
33 TypeId
35 {
36  static TypeId tid = TypeId ("ns3::YansErrorRateModel")
38  .SetGroupName ("Wifi")
39  .AddConstructor<YansErrorRateModel> ()
40  ;
41  return tid;
42 }
43 
45 {
46 }
47 
48 double
49 YansErrorRateModel::GetBpskBer (double snr, uint32_t signalSpread, uint64_t phyRate) const
50 {
51  NS_LOG_FUNCTION (this << snr << signalSpread << phyRate);
52  double EbNo = snr * signalSpread / phyRate;
53  double z = std::sqrt (EbNo);
54  double ber = 0.5 * erfc (z);
55  NS_LOG_INFO ("bpsk snr=" << snr << " ber=" << ber);
56  return ber;
57 }
58 
59 double
60 YansErrorRateModel::GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint64_t phyRate) const
61 {
62  NS_LOG_FUNCTION (this << snr << m << signalSpread << phyRate);
63  double EbNo = snr * signalSpread / phyRate;
64  double z = std::sqrt ((1.5 * Log2 (m) * EbNo) / (m - 1.0));
65  double z1 = ((1.0 - 1.0 / std::sqrt (m)) * erfc (z));
66  double z2 = 1 - std::pow ((1 - z1), 2);
67  double ber = z2 / Log2 (m);
68  NS_LOG_INFO ("Qam m=" << m << " rate=" << phyRate << " snr=" << snr << " ber=" << ber);
69  return ber;
70 }
71 
72 uint32_t
74 {
75  uint32_t fact = 1;
76  while (k > 0)
77  {
78  fact *= k;
79  k--;
80  }
81  return fact;
82 }
83 
84 double
85 YansErrorRateModel::Binomial (uint32_t k, double p, uint32_t n) const
86 {
87  double retval = Factorial (n) / (Factorial (k) * Factorial (n - k)) * std::pow (p, static_cast<double> (k)) * std::pow (1 - p, static_cast<double> (n - k));
88  return retval;
89 }
90 
91 double
92 YansErrorRateModel::CalculatePdOdd (double ber, unsigned int d) const
93 {
94  NS_ASSERT ((d % 2) == 1);
95  unsigned int dstart = (d + 1) / 2;
96  unsigned int dend = d;
97  double pd = 0;
98 
99  for (unsigned int i = dstart; i < dend; i++)
100  {
101  pd += Binomial (i, ber, d);
102  }
103  return pd;
104 }
105 
106 double
107 YansErrorRateModel::CalculatePdEven (double ber, unsigned int d) const
108 {
109  NS_ASSERT ((d % 2) == 0);
110  unsigned int dstart = d / 2 + 1;
111  unsigned int dend = d;
112  double pd = 0;
113 
114  for (unsigned int i = dstart; i < dend; i++)
115  {
116  pd += Binomial (i, ber, d);
117  }
118  pd += 0.5 * Binomial (d / 2, ber, d);
119 
120  return pd;
121 }
122 
123 double
124 YansErrorRateModel::CalculatePd (double ber, unsigned int d) const
125 {
126  NS_LOG_FUNCTION (this << ber << d);
127  double pd;
128  if ((d % 2) == 0)
129  {
130  pd = CalculatePdEven (ber, d);
131  }
132  else
133  {
134  pd = CalculatePdOdd (ber, d);
135  }
136  return pd;
137 }
138 
139 double
140 YansErrorRateModel::GetFecBpskBer (double snr, uint64_t nbits,
141  uint32_t signalSpread, uint64_t phyRate,
142  uint32_t dFree, uint32_t adFree) const
143 {
144  NS_LOG_FUNCTION (this << snr << nbits << signalSpread << phyRate << dFree << adFree);
145  double ber = GetBpskBer (snr, signalSpread, phyRate);
146  if (ber == 0.0)
147  {
148  return 1.0;
149  }
150  double pd = CalculatePd (ber, dFree);
151  double pmu = adFree * pd;
152  pmu = std::min (pmu, 1.0);
153  double pms = std::pow (1 - pmu, nbits);
154  return pms;
155 }
156 
157 double
158 YansErrorRateModel::GetFecQamBer (double snr, uint64_t nbits,
159  uint32_t signalSpread,
160  uint64_t phyRate,
161  uint32_t m, uint32_t dFree,
162  uint32_t adFree, uint32_t adFreePlusOne) const
163 {
164  NS_LOG_FUNCTION (this << snr << nbits << signalSpread << phyRate << m << dFree << adFree << adFreePlusOne);
165  double ber = GetQamBer (snr, m, signalSpread, phyRate);
166  if (ber == 0.0)
167  {
168  return 1.0;
169  }
170  /* first term */
171  double pd = CalculatePd (ber, dFree);
172  double pmu = adFree * pd;
173  /* second term */
174  pd = CalculatePd (ber, dFree + 1);
175  pmu += adFreePlusOne * pd;
176  pmu = std::min (pmu, 1.0);
177  double pms = std::pow (1 - pmu, nbits);
178  return pms;
179 }
180 
181 double
182 YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint64_t nbits) const
183 {
184  NS_LOG_FUNCTION (this << mode << txVector.GetMode () << snr << nbits);
190  {
191  if (mode.GetConstellationSize () == 2)
192  {
193  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
194  {
195  return GetFecBpskBer (snr,
196  nbits,
197  txVector.GetChannelWidth () * 1000000, //signal spread
198  mode.GetPhyRate (txVector), //phy rate
199  10, //dFree
200  11); //adFree
201  }
202  else
203  {
204  return GetFecBpskBer (snr,
205  nbits,
206  txVector.GetChannelWidth () * 1000000, //signal spread
207  mode.GetPhyRate (txVector), //phy rate
208  5, //dFree
209  8); //adFree
210  }
211  }
212  else if (mode.GetConstellationSize () == 4)
213  {
214  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
215  {
216  return GetFecQamBer (snr,
217  nbits,
218  txVector.GetChannelWidth () * 1000000, //signal spread
219  mode.GetPhyRate (txVector), //phy rate
220  4, //m
221  10, //dFree
222  11, //adFree
223  0); //adFreePlusOne
224  }
225  else
226  {
227  return GetFecQamBer (snr,
228  nbits,
229  txVector.GetChannelWidth () * 1000000, //signal spread
230  mode.GetPhyRate (txVector), //phy rate
231  4, //m
232  5, //dFree
233  8, //adFree
234  31); //adFreePlusOne
235  }
236  }
237  else if (mode.GetConstellationSize () == 16)
238  {
239  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
240  {
241  return GetFecQamBer (snr,
242  nbits,
243  txVector.GetChannelWidth () * 1000000, //signal spread
244  mode.GetPhyRate (txVector), //phy rate
245  16, //m
246  10, //dFree
247  11, //adFree
248  0); //adFreePlusOne
249  }
250  else
251  {
252  return GetFecQamBer (snr,
253  nbits,
254  txVector.GetChannelWidth () * 1000000, //signal spread
255  mode.GetPhyRate (txVector), //phy rate
256  16, //m
257  5, //dFree
258  8, //adFree
259  31); //adFreePlusOne
260  }
261  }
262  else if (mode.GetConstellationSize () == 64)
263  {
264  if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
265  {
266  return GetFecQamBer (snr,
267  nbits,
268  txVector.GetChannelWidth () * 1000000, //signal spread
269  mode.GetPhyRate (txVector), //phy rate
270  64, //m
271  6, //dFree
272  1, //adFree
273  16); //adFreePlusOne
274  }
275  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
276  {
277  //Table B.32 in Pâl Frenger et al., "Multi-rate Convolutional Codes".
278  return GetFecQamBer (snr,
279  nbits,
280  txVector.GetChannelWidth () * 1000000, //signal spread
281  mode.GetPhyRate (txVector), //phy rate
282  64, //m
283  4, //dFree
284  14, //adFree
285  69); //adFreePlusOne
286  }
287  else
288  {
289  return GetFecQamBer (snr,
290  nbits,
291  txVector.GetChannelWidth () * 1000000, //signal spread
292  mode.GetPhyRate (txVector), //phy rate
293  64, //m
294  5, //dFree
295  8, //adFree
296  31); //adFreePlusOne
297  }
298  }
299  else if (mode.GetConstellationSize () == 256)
300  {
301  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
302  {
303  return GetFecQamBer (snr,
304  nbits,
305  txVector.GetChannelWidth () * 1000000, // signal spread
306  mode.GetPhyRate (txVector), //phy rate
307  256, // m
308  4, // dFree
309  14, // adFree
310  69 // adFreePlusOne
311  );
312  }
313  else
314  {
315  return GetFecQamBer (snr,
316  nbits,
317  txVector.GetChannelWidth () * 1000000, // signal spread
318  mode.GetPhyRate (txVector), //phy rate
319  256, // m
320  5, // dFree
321  8, // adFree
322  31 // adFreePlusOne
323  );
324  }
325  }
326  else if (mode.GetConstellationSize () == 1024)
327  {
328  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
329  {
330  return GetFecQamBer (snr,
331  nbits,
332  txVector.GetChannelWidth () * 1000000, // signal spread
333  mode.GetPhyRate (txVector), //phy rate
334  1024, // m
335  4, // dFree
336  14, // adFree
337  69 // adFreePlusOne
338  );
339  }
340  else
341  {
342  return GetFecQamBer (snr,
343  nbits,
344  txVector.GetChannelWidth () * 1000000, // signal spread
345  mode.GetPhyRate (txVector), //phy rate
346  1024, // m
347  5, // dFree
348  8, // adFree
349  31 // adFreePlusOne
350  );
351  }
352  }
353  }
355  {
356  switch (mode.GetDataRate (20))
357  {
358  case 1000000:
360  case 2000000:
362  case 5500000:
364  case 11000000:
366  default:
367  NS_ASSERT ("undefined DSSS/HR-DSSS datarate");
368  }
369  }
370  return 0;
371 }
372 
373 } //namespace ns3
static TypeId GetTypeId(void)
Get the type ID.
double CalculatePdEven(double ber, unsigned int d) const
double CalculatePd(double ber, unsigned int d) const
#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:54
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:45
#define min(a, b)
Definition: 80211b.c:44
#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
double CalculatePdOdd(double ber, unsigned int d) const
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:277
VHT PHY (Clause 22)
Definition: wifi-mode.h:60
HR/DSSS PHY (Clause 18)
Definition: wifi-mode.h:48
double GetFecBpskBer(double snr, uint64_t nbits, uint32_t signalSpread, uint64_t phyRate, uint32_t dFree, uint32_t adFree) const
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
static double GetDsssDbpskSuccessRate(double sinr, uint64_t nbits)
Return the chunk success rate of the differential BPSK.
the interface for Wifi's error models
uint8_t GetChannelWidth(void) const
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:393
Model the error rate for different modulations.
uint64_t GetDataRate(uint8_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:143
HT PHY (Clause 20)
Definition: wifi-mode.h:58
double GetBpskBer(double snr, uint32_t signalSpread, uint64_t phyRate) const
Return BER of BPSK with the given parameters.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual double GetChunkSuccessRate(WifiMode mode, WifiTxVector txVector, double snr, uint64_t nbits) const
A pure virtual method that must be implemented in the subclass.
static double GetDsssDqpskCck5_5SuccessRate(double sinr, uint64_t nbits)
Return the chunk success rate of the differential encoded QPSK for 5.5Mbps data rate.
uint32_t Factorial(uint32_t k) const
Return k!
uint64_t GetPhyRate(uint8_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:96
OFDM PHY (Clause 17)
Definition: wifi-mode.h:56
double Binomial(uint32_t k, double p, uint32_t n) const
Return Binomial distribution for a given k, p, and n.
double GetFecQamBer(double snr, uint64_t nbits, uint32_t signalSpread, uint64_t phyRate, uint32_t m, uint32_t dfree, uint32_t adFree, uint32_t adFreePlusOne) const
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:487
static double GetDsssDqpskSuccessRate(double sinr, uint64_t nbits)
Return the chunk success rate of the differential encoded QPSK.
WifiMode GetMode(void) const
SpectrumValue Log2(const SpectrumValue &arg)
double GetQamBer(double snr, unsigned int m, uint32_t signalSpread, uint64_t phyRate) const
Return BER of QAM-m with the given parameters.
a unique identifier for an interface.
Definition: type-id.h:58
WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:317
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
HE PHY (Clause 26)
Definition: wifi-mode.h:62
DSSS PHY (Clause 15)
Definition: wifi-mode.h:46
static double GetDsssDqpskCck11SuccessRate(double sinr, uint64_t nbits)
Return the chunk success rate of the differential encoded QPSK for 11Mbps data rate.