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"
26#include "wifi-tx-vector.h"
27
28namespace ns3 {
29
30NS_LOG_COMPONENT_DEFINE ("NistErrorRateModel");
31
32NS_OBJECT_ENSURE_REGISTERED (NistErrorRateModel);
33
34TypeId
36{
37 static TypeId tid = TypeId ("ns3::NistErrorRateModel")
39 .SetGroupName ("Wifi")
40 .AddConstructor<NistErrorRateModel> ()
41 ;
42 return tid;
43}
44
46{
47}
48
49double
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
59double
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
69double
70NistErrorRateModel::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
81double
82NistErrorRateModel::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
96double
97NistErrorRateModel::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
111double
112NistErrorRateModel::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
183double
184NistErrorRateModel::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
198uint8_t
200{
201 switch (codeRate)
202 {
204 return 3;
206 return 2;
208 return 1;
210 return 5;
212 default:
213 NS_FATAL_ERROR ("Unknown code rate");
214 break;
215 }
216 return 0;
217}
218
219double
220NistErrorRateModel::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