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 "ns3/log.h"
23 #include "yans-error-rate-model.h"
24 #include "wifi-utils.h"
25 #include "wifi-phy.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::DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const
183 {
184  NS_LOG_FUNCTION (this << mode << txVector << snr << nbits << +numRxAntennas << field << staId);
186  {
187  uint64_t phyRate;
188  if ((txVector.IsMu () && (staId == SU_STA_ID)) || (mode != txVector.GetMode ()))
189  {
190  phyRate = mode.GetPhyRate (txVector.GetChannelWidth () >= 40 ? 20 : txVector.GetChannelWidth ()); //This is the PHY header
191  }
192  else
193  {
194  phyRate = mode.GetPhyRate (txVector, staId);
195  }
196  if (mode.GetConstellationSize () == 2)
197  {
198  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
199  {
200  return GetFecBpskBer (snr,
201  nbits,
202  txVector.GetChannelWidth () * 1000000, //signal spread
203  phyRate, //PHY rate
204  10, //dFree
205  11); //adFree
206  }
207  else
208  {
209  return GetFecBpskBer (snr,
210  nbits,
211  txVector.GetChannelWidth () * 1000000, //signal spread
212  phyRate, //PHY rate
213  5, //dFree
214  8); //adFree
215  }
216  }
217  else if (mode.GetConstellationSize () == 4)
218  {
219  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
220  {
221  return GetFecQamBer (snr,
222  nbits,
223  txVector.GetChannelWidth () * 1000000, //signal spread
224  phyRate, //PHY rate
225  4, //m
226  10, //dFree
227  11, //adFree
228  0); //adFreePlusOne
229  }
230  else
231  {
232  return GetFecQamBer (snr,
233  nbits,
234  txVector.GetChannelWidth () * 1000000, //signal spread
235  phyRate, //PHY rate
236  4, //m
237  5, //dFree
238  8, //adFree
239  31); //adFreePlusOne
240  }
241  }
242  else if (mode.GetConstellationSize () == 16)
243  {
244  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
245  {
246  return GetFecQamBer (snr,
247  nbits,
248  txVector.GetChannelWidth () * 1000000, //signal spread
249  phyRate, //PHY rate
250  16, //m
251  10, //dFree
252  11, //adFree
253  0); //adFreePlusOne
254  }
255  else
256  {
257  return GetFecQamBer (snr,
258  nbits,
259  txVector.GetChannelWidth () * 1000000, //signal spread
260  phyRate, //PHY rate
261  16, //m
262  5, //dFree
263  8, //adFree
264  31); //adFreePlusOne
265  }
266  }
267  else if (mode.GetConstellationSize () == 64)
268  {
269  if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
270  {
271  return GetFecQamBer (snr,
272  nbits,
273  txVector.GetChannelWidth () * 1000000, //signal spread
274  phyRate, //PHY rate
275  64, //m
276  6, //dFree
277  1, //adFree
278  16); //adFreePlusOne
279  }
280  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
281  {
282  //Table B.32 in Pâl Frenger et al., "Multi-rate Convolutional Codes".
283  return GetFecQamBer (snr,
284  nbits,
285  txVector.GetChannelWidth () * 1000000, //signal spread
286  phyRate, //PHY rate
287  64, //m
288  4, //dFree
289  14, //adFree
290  69); //adFreePlusOne
291  }
292  else
293  {
294  return GetFecQamBer (snr,
295  nbits,
296  txVector.GetChannelWidth () * 1000000, //signal spread
297  phyRate, //PHY rate
298  64, //m
299  5, //dFree
300  8, //adFree
301  31); //adFreePlusOne
302  }
303  }
304  else if (mode.GetConstellationSize () == 256)
305  {
306  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
307  {
308  return GetFecQamBer (snr,
309  nbits,
310  txVector.GetChannelWidth () * 1000000, // signal spread
311  phyRate, //PHY rate
312  256, // m
313  4, // dFree
314  14, // adFree
315  69 // adFreePlusOne
316  );
317  }
318  else
319  {
320  return GetFecQamBer (snr,
321  nbits,
322  txVector.GetChannelWidth () * 1000000, // signal spread
323  phyRate, //PHY rate
324  256, // m
325  5, // dFree
326  8, // adFree
327  31 // adFreePlusOne
328  );
329  }
330  }
331  else if (mode.GetConstellationSize () == 1024)
332  {
333  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
334  {
335  return GetFecQamBer (snr,
336  nbits,
337  txVector.GetChannelWidth () * 1000000, // signal spread
338  phyRate, //PHY rate
339  1024, // m
340  4, // dFree
341  14, // adFree
342  69 // adFreePlusOne
343  );
344  }
345  else
346  {
347  return GetFecQamBer (snr,
348  nbits,
349  txVector.GetChannelWidth () * 1000000, // signal spread
350  phyRate, //PHY rate
351  1024, // m
352  5, // dFree
353  8, // adFree
354  31 // adFreePlusOne
355  );
356  }
357  }
358  else if (mode.GetConstellationSize () == 4096)
359  {
360  if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
361  {
362  return GetFecQamBer (snr,
363  nbits,
364  txVector.GetChannelWidth () * 1000000, // signal spread
365  mode.GetPhyRate (txVector), //PHY rate
366  4096, // m
367  4, // dFree
368  14, // adFree
369  69 // adFreePlusOne
370  );
371  }
372  else
373  {
374  return GetFecQamBer (snr,
375  nbits,
376  txVector.GetChannelWidth () * 1000000, // signal spread
377  mode.GetPhyRate (txVector), //PHY rate
378  4096, // m
379  5, // dFree
380  8, // adFree
381  31 // adFreePlusOne
382  );
383  }
384  }
385  }
386  return 0;
387 }
388 
389 } //namespace ns3
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::YansErrorRateModel::GetBpskBer
double GetBpskBer(double snr, uint32_t signalSpread, uint64_t phyRate) const
Return BER of BPSK with the given parameters.
Definition: yans-error-rate-model.cc:49
ns3::YansErrorRateModel
Model the error rate for different modulations.
Definition: yans-error-rate-model.h:54
NS_OBJECT_ENSURE_REGISTERED
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
NS_ASSERT
#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
ns3::WIFI_MOD_CLASS_ERP_OFDM
@ WIFI_MOD_CLASS_ERP_OFDM
ERP-OFDM (18.4)
Definition: wifi-phy-common.h:128
min
#define min(a, b)
Definition: 80211b.c:42
ns3::WIFI_CODE_RATE_5_6
const uint16_t WIFI_CODE_RATE_5_6
5/6 coding rate
Definition: wifi-phy-common.h:61
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::WifiMode::GetCodeRate
WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:108
ns3::WifiMode::GetModulationClass
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:159
ns3::WifiTxVector
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Definition: wifi-tx-vector.h:71
wifi-phy.h
ns3::YansErrorRateModel::CalculatePd
double CalculatePd(double ber, unsigned int d) const
Definition: yans-error-rate-model.cc:124
ns3::YansErrorRateModel::DoGetChunkSuccessRate
double DoGetChunkSuccessRate(WifiMode mode, const WifiTxVector &txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const override
A pure virtual method that must be implemented in the subclass.
Definition: yans-error-rate-model.cc:182
ns3::TypeId::SetParent
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
ns3::YansErrorRateModel::CalculatePdEven
double CalculatePdEven(double ber, unsigned int d) const
Definition: yans-error-rate-model.cc:107
ns3::WifiMode
represent a single transmission mode
Definition: wifi-mode.h:48
bianchi11ax.k
int k
Definition: bianchi11ax.py:129
ns3::YansErrorRateModel::GetFecBpskBer
double GetFecBpskBer(double snr, uint64_t nbits, uint32_t signalSpread, uint64_t phyRate, uint32_t dFree, uint32_t adFree) const
Definition: yans-error-rate-model.cc:140
ns3::YansErrorRateModel::GetFecQamBer
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
Definition: yans-error-rate-model.cc:158
NS_LOG_INFO
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
ns3::YansErrorRateModel::YansErrorRateModel
YansErrorRateModel()
Definition: yans-error-rate-model.cc:44
ns3::WIFI_CODE_RATE_2_3
const uint16_t WIFI_CODE_RATE_2_3
2/3 coding rate
Definition: wifi-phy-common.h:59
SU_STA_ID
#define SU_STA_ID
Definition: wifi-mode.h:32
ns3::ErrorRateModel
the interface for Wifi's error models
Definition: error-rate-model.h:35
ns3::WifiTxVector::GetChannelWidth
uint16_t GetChannelWidth(void) const
Definition: wifi-tx-vector.cc:154
ns3::WifiMode::GetPhyRate
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:73
ns3::WifiPpduField
WifiPpduField
The type of PPDU field (grouped for convenience)
Definition: wifi-phy-common.h:171
ns3::WifiTxVector::IsMu
bool IsMu(void) const
Return true if this TX vector is used for a multi-user transmission.
Definition: wifi-tx-vector.cc:370
ns3::YansErrorRateModel::CalculatePdOdd
double CalculatePdOdd(double ber, unsigned int d) const
Definition: yans-error-rate-model.cc:92
ns3::WIFI_CODE_RATE_1_2
const uint16_t WIFI_CODE_RATE_1_2
1/2 coding rate
Definition: wifi-phy-common.h:58
wifi-utils.h
yans-error-rate-model.h
ns3::YansErrorRateModel::GetQamBer
double GetQamBer(double snr, unsigned int m, uint32_t signalSpread, uint64_t phyRate) const
Return BER of QAM-m with the given parameters.
Definition: yans-error-rate-model.cc:60
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::YansErrorRateModel::Binomial
double Binomial(uint32_t k, double p, uint32_t n) const
Return Binomial distribution for a given k, p, and n.
Definition: yans-error-rate-model.cc:85
ns3::YansErrorRateModel::Factorial
uint32_t Factorial(uint32_t k) const
Return k!
Definition: yans-error-rate-model.cc:73
ns3::YansErrorRateModel::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: yans-error-rate-model.cc:34
sample-rng-plot.n
n
Definition: sample-rng-plot.py:37
ns3::WifiTxVector::GetMode
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
Definition: wifi-tx-vector.cc:112
ns3::WifiMode::GetConstellationSize
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:115