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);
228  {
229  if (mode.GetConstellationSize () == 2)
230  {
231  return GetFecBpskBer (snr, nbits, GetBValue (mode.GetCodeRate ()));
232  }
233  else if (mode.GetConstellationSize () == 4)
234  {
235  return GetFecQpskBer (snr, nbits, GetBValue (mode.GetCodeRate ()));
236  }
237  else
238  {
239  return GetFecQamBer (mode.GetConstellationSize (), snr, nbits, GetBValue (mode.GetCodeRate ()));
240  }
241  }
242  return 0;
243 }
244 
245 } //namespace ns3
double GetQamBer(uint16_t constellationSize, double snr) const
Return BER of QAM for a given constellation size at the given SNR.
static TypeId GetTypeId(void)
Get the type ID.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
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
const uint16_t WIFI_CODE_RATE_2_3
2/3 coding rate
#define min(a, b)
Definition: 80211b.c:42
#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:205
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.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
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.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:47
const uint16_t WIFI_CODE_RATE_3_4
3/4 coding rate
the interface for Wifi&#39;s error models
double GetFecBpskBer(double snr, uint64_t nbits, uint8_t bValue) const
Return BER of BPSK at the given SNR after applying FEC.
uint8_t GetBValue(WifiCodeRate codeRate) const
Return the bValue such that coding rate = bValue / (bValue + 1).
WifiPpduField
The type of PPDU field (grouped for convenience)
A model for the error rate for different modulations.
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:159
const uint16_t WIFI_CODE_RATE_5_6
5/6 coding rate
uint16_t WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
double CalculatePe(double p, uint8_t bValue) const
Return the coded BER for the given p and b.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint16_t GetConstellationSize(void) const
Definition: wifi-mode.cc:115
double GetQpskBer(double snr) const
Return BER of QPSK at the given SNR.
const uint16_t WIFI_CODE_RATE_UNDEFINED
undefined coding rate
WifiCodeRate GetCodeRate(void) const
Definition: wifi-mode.cc:108
double GetBpskBer(double snr) const
Return BER of BPSK at the given SNR.
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
const uint16_t WIFI_CODE_RATE_1_2
1/2 coding rate