A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
yans-error-rate-model.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005,2006 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  * Sébastien Deronne <sebastien.deronne@gmail.com>
19  */
20 
21 #include "yans-error-rate-model.h"
22 
23 #include "wifi-tx-vector.h"
24 #include "wifi-utils.h"
25 
26 #include "ns3/log.h"
27 
28 #include <cmath>
29 
30 namespace ns3
31 {
32 
33 NS_LOG_COMPONENT_DEFINE("YansErrorRateModel");
34 
35 NS_OBJECT_ENSURE_REGISTERED(YansErrorRateModel);
36 
37 TypeId
39 {
40  static TypeId tid = TypeId("ns3::YansErrorRateModel")
42  .SetGroupName("Wifi")
43  .AddConstructor<YansErrorRateModel>();
44  return tid;
45 }
46 
48 {
49 }
50 
51 double
52 YansErrorRateModel::GetBpskBer(double snr, uint32_t signalSpread, uint64_t phyRate) const
53 {
54  NS_LOG_FUNCTION(this << snr << signalSpread << phyRate);
55  double EbNo = snr * signalSpread / phyRate;
56  double z = std::sqrt(EbNo);
57  double ber = 0.5 * erfc(z);
58  NS_LOG_INFO("bpsk snr=" << snr << " ber=" << ber);
59  return ber;
60 }
61 
62 double
64  unsigned int m,
65  uint32_t signalSpread,
66  uint64_t phyRate) const
67 {
68  NS_LOG_FUNCTION(this << snr << m << signalSpread << phyRate);
69  double EbNo = snr * signalSpread / phyRate;
70  double z = std::sqrt((1.5 * log2(m) * EbNo) / (m - 1.0));
71  double z1 = ((1.0 - 1.0 / std::sqrt(m)) * erfc(z));
72  double z2 = 1 - std::pow((1 - z1), 2);
73  double ber = z2 / log2(m);
74  NS_LOG_INFO("Qam m=" << m << " rate=" << phyRate << " snr=" << snr << " ber=" << ber);
75  return ber;
76 }
77 
78 uint32_t
80 {
81  uint32_t fact = 1;
82  while (k > 0)
83  {
84  fact *= k;
85  k--;
86  }
87  return fact;
88 }
89 
90 double
91 YansErrorRateModel::Binomial(uint32_t k, double p, uint32_t n) const
92 {
93  double retval = Factorial(n) / (Factorial(k) * Factorial(n - k)) *
94  std::pow(p, static_cast<double>(k)) *
95  std::pow(1 - p, static_cast<double>(n - k));
96  return retval;
97 }
98 
99 double
100 YansErrorRateModel::CalculatePdOdd(double ber, unsigned int d) const
101 {
102  NS_ASSERT((d % 2) == 1);
103  unsigned int dstart = (d + 1) / 2;
104  unsigned int dend = d;
105  double pd = 0;
106 
107  for (unsigned int i = dstart; i < dend; i++)
108  {
109  pd += Binomial(i, ber, d);
110  }
111  return pd;
112 }
113 
114 double
115 YansErrorRateModel::CalculatePdEven(double ber, unsigned int d) const
116 {
117  NS_ASSERT((d % 2) == 0);
118  unsigned int dstart = d / 2 + 1;
119  unsigned int dend = d;
120  double pd = 0;
121 
122  for (unsigned int i = dstart; i < dend; i++)
123  {
124  pd += Binomial(i, ber, d);
125  }
126  pd += 0.5 * Binomial(d / 2, ber, d);
127 
128  return pd;
129 }
130 
131 double
132 YansErrorRateModel::CalculatePd(double ber, unsigned int d) const
133 {
134  NS_LOG_FUNCTION(this << ber << d);
135  double pd;
136  if ((d % 2) == 0)
137  {
138  pd = CalculatePdEven(ber, d);
139  }
140  else
141  {
142  pd = CalculatePdOdd(ber, d);
143  }
144  return pd;
145 }
146 
147 double
149  uint64_t nbits,
150  uint32_t signalSpread,
151  uint64_t phyRate,
152  uint32_t dFree,
153  uint32_t adFree) const
154 {
155  NS_LOG_FUNCTION(this << snr << nbits << signalSpread << phyRate << dFree << adFree);
156  double ber = GetBpskBer(snr, signalSpread, phyRate);
157  if (ber == 0.0)
158  {
159  return 1.0;
160  }
161  double pd = CalculatePd(ber, dFree);
162  double pmu = adFree * pd;
163  pmu = std::min(pmu, 1.0);
164  double pms = std::pow(1 - pmu, nbits);
165  return pms;
166 }
167 
168 double
170  uint64_t nbits,
171  uint32_t signalSpread,
172  uint64_t phyRate,
173  uint32_t m,
174  uint32_t dFree,
175  uint32_t adFree,
176  uint32_t adFreePlusOne) const
177 {
178  NS_LOG_FUNCTION(this << snr << nbits << signalSpread << phyRate << m << dFree << adFree
179  << adFreePlusOne);
180  double ber = GetQamBer(snr, m, signalSpread, phyRate);
181  if (ber == 0.0)
182  {
183  return 1.0;
184  }
185  /* first term */
186  double pd = CalculatePd(ber, dFree);
187  double pmu = adFree * pd;
188  /* second term */
189  pd = CalculatePd(ber, dFree + 1);
190  pmu += adFreePlusOne * pd;
191  pmu = std::min(pmu, 1.0);
192  double pms = std::pow(1 - pmu, nbits);
193  return pms;
194 }
195 
196 double
198  const WifiTxVector& txVector,
199  double snr,
200  uint64_t nbits,
201  uint8_t numRxAntennas,
202  WifiPpduField field,
203  uint16_t staId) const
204 {
205  NS_LOG_FUNCTION(this << mode << txVector << snr << nbits << +numRxAntennas << field << staId);
207  {
208  uint64_t phyRate;
209  if ((txVector.IsMu() && (staId == SU_STA_ID)) || (mode != txVector.GetMode(staId)))
210  {
211  phyRate = mode.GetPhyRate(txVector.GetChannelWidth() >= 40
212  ? 20
213  : txVector.GetChannelWidth()); // This is the PHY header
214  }
215  else
216  {
217  phyRate = mode.GetPhyRate(txVector, staId);
218  }
219  if (mode.GetConstellationSize() == 2)
220  {
221  if (mode.GetCodeRate() == WIFI_CODE_RATE_1_2)
222  {
223  return GetFecBpskBer(snr,
224  nbits,
225  txVector.GetChannelWidth() * 1000000, // signal spread
226  phyRate, // PHY rate
227  10, // dFree
228  11); // adFree
229  }
230  else
231  {
232  return GetFecBpskBer(snr,
233  nbits,
234  txVector.GetChannelWidth() * 1000000, // signal spread
235  phyRate, // PHY rate
236  5, // dFree
237  8); // adFree
238  }
239  }
240  else if (mode.GetConstellationSize() == 4)
241  {
242  if (mode.GetCodeRate() == WIFI_CODE_RATE_1_2)
243  {
244  return GetFecQamBer(snr,
245  nbits,
246  txVector.GetChannelWidth() * 1000000, // signal spread
247  phyRate, // PHY rate
248  4, // m
249  10, // dFree
250  11, // adFree
251  0); // adFreePlusOne
252  }
253  else
254  {
255  return GetFecQamBer(snr,
256  nbits,
257  txVector.GetChannelWidth() * 1000000, // signal spread
258  phyRate, // PHY rate
259  4, // m
260  5, // dFree
261  8, // adFree
262  31); // adFreePlusOne
263  }
264  }
265  else if (mode.GetConstellationSize() == 16)
266  {
267  if (mode.GetCodeRate() == WIFI_CODE_RATE_1_2)
268  {
269  return GetFecQamBer(snr,
270  nbits,
271  txVector.GetChannelWidth() * 1000000, // signal spread
272  phyRate, // PHY rate
273  16, // m
274  10, // dFree
275  11, // adFree
276  0); // adFreePlusOne
277  }
278  else
279  {
280  return GetFecQamBer(snr,
281  nbits,
282  txVector.GetChannelWidth() * 1000000, // signal spread
283  phyRate, // PHY rate
284  16, // m
285  5, // dFree
286  8, // adFree
287  31); // adFreePlusOne
288  }
289  }
290  else if (mode.GetConstellationSize() == 64)
291  {
292  if (mode.GetCodeRate() == WIFI_CODE_RATE_2_3)
293  {
294  return GetFecQamBer(snr,
295  nbits,
296  txVector.GetChannelWidth() * 1000000, // signal spread
297  phyRate, // PHY rate
298  64, // m
299  6, // dFree
300  1, // adFree
301  16); // adFreePlusOne
302  }
303  if (mode.GetCodeRate() == WIFI_CODE_RATE_5_6)
304  {
305  // Table B.32 in Pâl Frenger et al., "Multi-rate Convolutional Codes".
306  return GetFecQamBer(snr,
307  nbits,
308  txVector.GetChannelWidth() * 1000000, // signal spread
309  phyRate, // PHY rate
310  64, // m
311  4, // dFree
312  14, // adFree
313  69); // adFreePlusOne
314  }
315  else
316  {
317  return GetFecQamBer(snr,
318  nbits,
319  txVector.GetChannelWidth() * 1000000, // signal spread
320  phyRate, // PHY rate
321  64, // m
322  5, // dFree
323  8, // adFree
324  31); // adFreePlusOne
325  }
326  }
327  else if (mode.GetConstellationSize() == 256)
328  {
329  if (mode.GetCodeRate() == WIFI_CODE_RATE_5_6)
330  {
331  return GetFecQamBer(snr,
332  nbits,
333  txVector.GetChannelWidth() * 1000000, // signal spread
334  phyRate, // PHY rate
335  256, // m
336  4, // dFree
337  14, // adFree
338  69 // adFreePlusOne
339  );
340  }
341  else
342  {
343  return GetFecQamBer(snr,
344  nbits,
345  txVector.GetChannelWidth() * 1000000, // signal spread
346  phyRate, // PHY rate
347  256, // m
348  5, // dFree
349  8, // adFree
350  31 // adFreePlusOne
351  );
352  }
353  }
354  else if (mode.GetConstellationSize() == 1024)
355  {
356  if (mode.GetCodeRate() == WIFI_CODE_RATE_5_6)
357  {
358  return GetFecQamBer(snr,
359  nbits,
360  txVector.GetChannelWidth() * 1000000, // signal spread
361  phyRate, // PHY rate
362  1024, // m
363  4, // dFree
364  14, // adFree
365  69 // adFreePlusOne
366  );
367  }
368  else
369  {
370  return GetFecQamBer(snr,
371  nbits,
372  txVector.GetChannelWidth() * 1000000, // signal spread
373  phyRate, // PHY rate
374  1024, // m
375  5, // dFree
376  8, // adFree
377  31 // adFreePlusOne
378  );
379  }
380  }
381  else if (mode.GetConstellationSize() == 4096)
382  {
383  if (mode.GetCodeRate() == WIFI_CODE_RATE_5_6)
384  {
385  return GetFecQamBer(snr,
386  nbits,
387  txVector.GetChannelWidth() * 1000000, // signal spread
388  phyRate, // PHY rate
389  4096, // m
390  4, // dFree
391  14, // adFree
392  69 // adFreePlusOne
393  );
394  }
395  else
396  {
397  return GetFecQamBer(snr,
398  nbits,
399  txVector.GetChannelWidth() * 1000000, // signal spread
400  phyRate, // PHY rate
401  4096, // m
402  5, // dFree
403  8, // adFree
404  31 // adFreePlusOne
405  );
406  }
407  }
408  }
409  return 0;
410 }
411 
412 } // namespace ns3
#define min(a, b)
Definition: 80211b.c:41
the interface for Wifi's error models
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
represent a single transmission mode
Definition: wifi-mode.h:51
uint16_t GetConstellationSize() const
Definition: wifi-mode.cc:141
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
uint64_t GetPhyRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:91
WifiCodeRate GetCodeRate() const
Definition: wifi-mode.cc:134
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
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.
uint16_t GetChannelWidth() const
Model the error rate for different modulations.
double GetFecBpskBer(double snr, uint64_t nbits, uint32_t signalSpread, uint64_t phyRate, uint32_t dFree, uint32_t adFree) const
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.
static TypeId GetTypeId()
Get the type ID.
double Binomial(uint32_t k, double p, uint32_t n) const
Return Binomial distribution for a given k, p, and n.
double CalculatePdEven(double ber, unsigned int d) const
double GetQamBer(double snr, unsigned int m, uint32_t signalSpread, uint64_t phyRate) const
Return BER of QAM-m with the given parameters.
uint32_t Factorial(uint32_t k) const
Return k!
double CalculatePdOdd(double ber, unsigned int d) const
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
double CalculatePd(double ber, unsigned int d) const
double GetBpskBer(double snr, uint32_t signalSpread, uint64_t phyRate) const
Return BER of BPSK with the given parameters.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
WifiPpduField
The type of PPDU field (grouped for convenience)
@ WIFI_MOD_CLASS_ERP_OFDM
ERP-OFDM (18.4)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition: wifi-mode.h:35
@ WIFI_CODE_RATE_2_3
2/3 coding rate
@ WIFI_CODE_RATE_1_2
1/2 coding rate
@ WIFI_CODE_RATE_5_6
5/6 coding rate