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 <bitset>
24 #include "ns3/log.h"
25 #include "nist-error-rate-model.h"
26 #include "wifi-tx-vector.h"
27 
28 namespace ns3 {
29 
30 NS_LOG_COMPONENT_DEFINE ("NistErrorRateModel");
31 
32 NS_OBJECT_ENSURE_REGISTERED (NistErrorRateModel);
33 
34 TypeId
36 {
37  static TypeId tid = TypeId ("ns3::NistErrorRateModel")
39  .SetGroupName ("Wifi")
40  .AddConstructor<NistErrorRateModel> ()
41  ;
42  return tid;
43 }
44 
46 {
47 }
48 
49 double
51 {
52  NS_LOG_FUNCTION (this << snr);
53  double z = std::sqrt (snr);
54  double ber = 0.5 * erfc (z);
55  NS_LOG_INFO ("bpsk snr=" << snr << " ber=" << ber);
56  return ber;
57 }
58 
59 double
61 {
62  NS_LOG_FUNCTION (this << snr);
63  double z = std::sqrt (snr / 2.0);
64  double ber = 0.5 * erfc (z);
65  NS_LOG_INFO ("qpsk snr=" << snr << " ber=" << ber);
66  return ber;
67 }
68 
69 double
70 NistErrorRateModel::GetQamBer (uint16_t constellationSize, double snr) const
71 {
72  NS_LOG_FUNCTION (this << constellationSize << snr);
73  NS_ASSERT (std::bitset<16> (constellationSize).count () == 1); //constellationSize has to be a power of 2
74  double z = std::sqrt (snr / ((2 * (constellationSize - 1)) / 3));
75  uint8_t bitsPerSymbol = std::sqrt (constellationSize);
76  double ber = ((bitsPerSymbol - 1) / (bitsPerSymbol * std::log2 (bitsPerSymbol))) * erfc (z);
77  NS_LOG_INFO (constellationSize << "-QAM: snr=" << snr << " ber=" << ber);
78  return ber;
79 }
80 
81 double
82 NistErrorRateModel::GetFecBpskBer (double snr, uint64_t nbits, uint8_t bValue) const
83 {
84  NS_LOG_FUNCTION (this << snr << nbits << +bValue);
85  double ber = GetBpskBer (snr);
86  if (ber == 0.0)
87  {
88  return 1.0;
89  }
90  double pe = CalculatePe (ber, bValue);
91  pe = std::min (pe, 1.0);
92  double pms = std::pow (1 - pe, nbits);
93  return pms;
94 }
95 
96 double
97 NistErrorRateModel::GetFecQpskBer (double snr, uint64_t nbits, uint8_t bValue) const
98 {
99  NS_LOG_FUNCTION (this << snr << nbits << +bValue);
100  double ber = GetQpskBer (snr);
101  if (ber == 0.0)
102  {
103  return 1.0;
104  }
105  double pe = CalculatePe (ber, bValue);
106  pe = std::min (pe, 1.0);
107  double pms = std::pow (1 - pe, nbits);
108  return pms;
109 }
110 
111 double
112 NistErrorRateModel::CalculatePe (double p, uint8_t bValue) const
113 {
114  NS_LOG_FUNCTION (this << p << +bValue);
115  double D = std::sqrt (4.0 * p * (1.0 - p));
116  double pe = 1.0;
117  if (bValue == 1)
118  {
119  //code rate 1/2, use table 3.1.1
120  pe = 0.5 * (36.0 * std::pow (D, 10)
121  + 211.0 * std::pow (D, 12)
122  + 1404.0 * std::pow (D, 14)
123  + 11633.0 * std::pow (D, 16)
124  + 77433.0 * std::pow (D, 18)
125  + 502690.0 * std::pow (D, 20)
126  + 3322763.0 * std::pow (D, 22)
127  + 21292910.0 * std::pow (D, 24)
128  + 134365911.0 * std::pow (D, 26));
129  }
130  else if (bValue == 2)
131  {
132  //code rate 2/3, use table 3.1.2
133  pe = 1.0 / (2.0 * bValue) *
134  (3.0 * std::pow (D, 6)
135  + 70.0 * std::pow (D, 7)
136  + 285.0 * std::pow (D, 8)
137  + 1276.0 * std::pow (D, 9)
138  + 6160.0 * std::pow (D, 10)
139  + 27128.0 * std::pow (D, 11)
140  + 117019.0 * std::pow (D, 12)
141  + 498860.0 * std::pow (D, 13)
142  + 2103891.0 * std::pow (D, 14)
143  + 8784123.0 * std::pow (D, 15));
144  }
145  else if (bValue == 3)
146  {
147  //code rate 3/4, use table 3.1.2
148  pe = 1.0 / (2.0 * bValue) *
149  (42.0 * std::pow (D, 5)
150  + 201.0 * std::pow (D, 6)
151  + 1492.0 * std::pow (D, 7)
152  + 10469.0 * std::pow (D, 8)
153  + 62935.0 * std::pow (D, 9)
154  + 379644.0 * std::pow (D, 10)
155  + 2253373.0 * std::pow (D, 11)
156  + 13073811.0 * std::pow (D, 12)
157  + 75152755.0 * std::pow (D, 13)
158  + 428005675.0 * std::pow (D, 14));
159  }
160  else if (bValue == 5)
161  {
162  //code rate 5/6, use table V from D. Haccoun and G. Begin, "High-Rate Punctured Convolutional Codes
163  //for Viterbi Sequential Decoding", IEEE Transactions on Communications, Vol. 32, Issue 3, pp.315-319.
164  pe = 1.0 / (2.0 * bValue) *
165  (92.0 * std::pow (D, 4.0)
166  + 528.0 * std::pow (D, 5.0)
167  + 8694.0 * std::pow (D, 6.0)
168  + 79453.0 * std::pow (D, 7.0)
169  + 792114.0 * std::pow (D, 8.0)
170  + 7375573.0 * std::pow (D, 9.0)
171  + 67884974.0 * std::pow (D, 10.0)
172  + 610875423.0 * std::pow (D, 11.0)
173  + 5427275376.0 * std::pow (D, 12.0)
174  + 47664215639.0 * std::pow (D, 13.0));
175  }
176  else
177  {
178  NS_ASSERT (false);
179  }
180  return pe;
181 }
182 
183 double
184 NistErrorRateModel::GetFecQamBer (uint16_t constellationSize, double snr, uint64_t nbits, uint8_t bValue) const
185 {
186  NS_LOG_FUNCTION (this << constellationSize << snr << nbits << +bValue);
187  double ber = GetQamBer (constellationSize, snr);
188  if (ber == 0.0)
189  {
190  return 1.0;
191  }
192  double pe = CalculatePe (ber, bValue);
193  pe = std::min (pe, 1.0);
194  double pms = std::pow (1 - pe, nbits);
195  return pms;
196 }
197 
198 uint8_t
200 {
201  switch (codeRate)
202  {
203  case WIFI_CODE_RATE_3_4:
204  return 3;
205  case WIFI_CODE_RATE_2_3:
206  return 2;
207  case WIFI_CODE_RATE_1_2:
208  return 1;
209  case WIFI_CODE_RATE_5_6:
210  return 5;
212  default:
213  NS_FATAL_ERROR ("Unknown code rate");
214  break;
215  }
216  return 0;
217 }
218 
219 double
220 NistErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, const WifiTxVector& txVector, double snr, uint64_t nbits, uint8_t numRxAntennas, WifiPpduField field, uint16_t staId) const
221 {
222  NS_LOG_FUNCTION (this << mode << snr << nbits << +numRxAntennas << field << staId);
224  {
225  if (mode.GetConstellationSize () == 2)
226  {
227  return GetFecBpskBer (snr, nbits, GetBValue (mode.GetCodeRate ()));
228  }
229  else if (mode.GetConstellationSize () == 4)
230  {
231  return GetFecQpskBer (snr, nbits, GetBValue (mode.GetCodeRate ()));
232  }
233  else
234  {
235  return GetFecQamBer (mode.GetConstellationSize (), snr, nbits, GetBValue (mode.GetCodeRate ()));
236  }
237  }
238  return 0;
239 }
240 
241 } //namespace ns3
#define min(a, b)
Definition: 80211b.c:42
the interface for Wifi's error models
A model for the error rate for different modulations.
double GetQamBer(uint16_t constellationSize, double snr) const
Return BER of QAM for a given constellation size at the given SNR.
double GetBpskBer(double snr) const
Return BER of BPSK at the given SNR.
double GetFecBpskBer(double snr, uint64_t nbits, uint8_t bValue) const
Return BER of BPSK at the given SNR after applying FEC.
double CalculatePe(double p, uint8_t bValue) const
Return the coded BER for the given p and b.
static TypeId GetTypeId(void)
Get the type ID.
double GetFecQpskBer(double snr, uint64_t nbits, uint8_t bValue) const
Return BER of QPSK at the given SNR after applying FEC.
double GetFecQamBer(uint16_t constellationSize, double snr, uint64_t nbits, uint8_t bValue) const
Return BER of QAM for a given constellation size at the given SNR after applying FEC.
uint8_t GetBValue(WifiCodeRate codeRate) const
Return the bValue such that coding rate = bValue / (bValue + 1).
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.
double GetQpskBer(double snr) const
Return BER of QPSK at the given SNR.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
represent a single transmission mode
Definition: wifi-mode.h:48
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:133
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:177
WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:126
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#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_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#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:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
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.
const uint16_t WIFI_CODE_RATE_UNDEFINED
undefined coding rate
const uint16_t WIFI_CODE_RATE_3_4
3/4 coding rate
const uint16_t WIFI_CODE_RATE_1_2
1/2 coding rate
const uint16_t WIFI_CODE_RATE_2_3
2/3 coding rate
uint16_t WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
const uint16_t WIFI_CODE_RATE_5_6
5/6 coding rate