A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
nist-error-rate-model.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 The Boeing Company
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: Gary Pei <guangyu.pei@boeing.com>
18 * Sébastien Deronne <sebastien.deronne@gmail.com>
19 */
20
22
23#include "wifi-tx-vector.h"
24
25#include "ns3/log.h"
26
27#include <bitset>
28#include <cmath>
29
30namespace ns3
31{
32
33NS_LOG_COMPONENT_DEFINE("NistErrorRateModel");
34
35NS_OBJECT_ENSURE_REGISTERED(NistErrorRateModel);
36
37TypeId
39{
40 static TypeId tid = TypeId("ns3::NistErrorRateModel")
42 .SetGroupName("Wifi")
43 .AddConstructor<NistErrorRateModel>();
44 return tid;
45}
46
48{
49}
50
51double
53{
54 NS_LOG_FUNCTION(this << snr);
55 double z = std::sqrt(snr);
56 double ber = 0.5 * erfc(z);
57 NS_LOG_INFO("bpsk snr=" << snr << " ber=" << ber);
58 return ber;
59}
60
61double
63{
64 NS_LOG_FUNCTION(this << snr);
65 double z = std::sqrt(snr / 2.0);
66 double ber = 0.5 * erfc(z);
67 NS_LOG_INFO("qpsk snr=" << snr << " ber=" << ber);
68 return ber;
69}
70
71double
72NistErrorRateModel::GetQamBer(uint16_t constellationSize, double snr) const
73{
74 NS_LOG_FUNCTION(this << constellationSize << snr);
75 NS_ASSERT(std::bitset<16>(constellationSize).count() ==
76 1); // constellationSize has to be a power of 2
77 double z = std::sqrt(snr / ((2 * (constellationSize - 1)) / 3));
78 uint8_t bitsPerSymbol = std::sqrt(constellationSize);
79 double ber = ((bitsPerSymbol - 1) / (bitsPerSymbol * std::log2(bitsPerSymbol))) * erfc(z);
80 NS_LOG_INFO(constellationSize << "-QAM: snr=" << snr << " ber=" << ber);
81 return ber;
82}
83
84double
85NistErrorRateModel::GetFecBpskBer(double snr, uint64_t nbits, uint8_t bValue) const
86{
87 NS_LOG_FUNCTION(this << snr << nbits << +bValue);
88 double ber = GetBpskBer(snr);
89 if (ber == 0.0)
90 {
91 return 1.0;
92 }
93 double pe = CalculatePe(ber, bValue);
94 pe = std::min(pe, 1.0);
95 double pms = std::pow(1 - pe, nbits);
96 return pms;
97}
98
99double
100NistErrorRateModel::GetFecQpskBer(double snr, uint64_t nbits, uint8_t bValue) const
101{
102 NS_LOG_FUNCTION(this << snr << nbits << +bValue);
103 double ber = GetQpskBer(snr);
104 if (ber == 0.0)
105 {
106 return 1.0;
107 }
108 double pe = CalculatePe(ber, bValue);
109 pe = std::min(pe, 1.0);
110 double pms = std::pow(1 - pe, nbits);
111 return pms;
112}
113
114double
115NistErrorRateModel::CalculatePe(double p, uint8_t bValue) const
116{
117 NS_LOG_FUNCTION(this << p << +bValue);
118 double D = std::sqrt(4.0 * p * (1.0 - p));
119 double pe = 1.0;
120 if (bValue == 1)
121 {
122 // code rate 1/2, use table 3.1.1
123 pe = 0.5 * (36.0 * std::pow(D, 10) + 211.0 * std::pow(D, 12) + 1404.0 * std::pow(D, 14) +
124 11633.0 * std::pow(D, 16) + 77433.0 * std::pow(D, 18) +
125 502690.0 * std::pow(D, 20) + 3322763.0 * std::pow(D, 22) +
126 21292910.0 * std::pow(D, 24) + 134365911.0 * std::pow(D, 26));
127 }
128 else if (bValue == 2)
129 {
130 // code rate 2/3, use table 3.1.2
131 pe = 1.0 / (2.0 * bValue) *
132 (3.0 * std::pow(D, 6) + 70.0 * std::pow(D, 7) + 285.0 * std::pow(D, 8) +
133 1276.0 * std::pow(D, 9) + 6160.0 * std::pow(D, 10) + 27128.0 * std::pow(D, 11) +
134 117019.0 * std::pow(D, 12) + 498860.0 * std::pow(D, 13) +
135 2103891.0 * std::pow(D, 14) + 8784123.0 * std::pow(D, 15));
136 }
137 else if (bValue == 3)
138 {
139 // code rate 3/4, use table 3.1.2
140 pe = 1.0 / (2.0 * bValue) *
141 (42.0 * std::pow(D, 5) + 201.0 * std::pow(D, 6) + 1492.0 * std::pow(D, 7) +
142 10469.0 * std::pow(D, 8) + 62935.0 * std::pow(D, 9) + 379644.0 * std::pow(D, 10) +
143 2253373.0 * std::pow(D, 11) + 13073811.0 * std::pow(D, 12) +
144 75152755.0 * std::pow(D, 13) + 428005675.0 * std::pow(D, 14));
145 }
146 else if (bValue == 5)
147 {
148 // code rate 5/6, use table V from D. Haccoun and G. Begin, "High-Rate Punctured
149 // Convolutional Codes for Viterbi Sequential Decoding", IEEE Transactions on
150 // Communications, Vol. 32, Issue 3, pp.315-319.
151 pe = 1.0 / (2.0 * bValue) *
152 (92.0 * std::pow(D, 4.0) + 528.0 * std::pow(D, 5.0) + 8694.0 * std::pow(D, 6.0) +
153 79453.0 * std::pow(D, 7.0) + 792114.0 * std::pow(D, 8.0) +
154 7375573.0 * std::pow(D, 9.0) + 67884974.0 * std::pow(D, 10.0) +
155 610875423.0 * std::pow(D, 11.0) + 5427275376.0 * std::pow(D, 12.0) +
156 47664215639.0 * std::pow(D, 13.0));
157 }
158 else
159 {
160 NS_ASSERT(false);
161 }
162 return pe;
163}
164
165double
166NistErrorRateModel::GetFecQamBer(uint16_t constellationSize,
167 double snr,
168 uint64_t nbits,
169 uint8_t bValue) const
170{
171 NS_LOG_FUNCTION(this << constellationSize << snr << nbits << +bValue);
172 double ber = GetQamBer(constellationSize, snr);
173 if (ber == 0.0)
174 {
175 return 1.0;
176 }
177 double pe = CalculatePe(ber, bValue);
178 pe = std::min(pe, 1.0);
179 double pms = std::pow(1 - pe, nbits);
180 return pms;
181}
182
183uint8_t
185{
186 switch (codeRate)
187 {
189 return 3;
191 return 2;
193 return 1;
195 return 5;
197 default:
198 NS_FATAL_ERROR("Unknown code rate");
199 break;
200 }
201 return 0;
202}
203
204double
206 const WifiTxVector& txVector,
207 double snr,
208 uint64_t nbits,
209 uint8_t numRxAntennas,
210 WifiPpduField field,
211 uint16_t staId) const
212{
213 NS_LOG_FUNCTION(this << mode << snr << nbits << +numRxAntennas << field << staId);
215 {
216 if (mode.GetConstellationSize() == 2)
217 {
218 return GetFecBpskBer(snr, nbits, GetBValue(mode.GetCodeRate()));
219 }
220 else if (mode.GetConstellationSize() == 4)
221 {
222 return GetFecQpskBer(snr, nbits, GetBValue(mode.GetCodeRate()));
223 }
224 else
225 {
227 snr,
228 nbits,
229 GetBValue(mode.GetCodeRate()));
230 }
231 }
232 return 0;
233}
234
235} // namespace ns3
the interface for Wifi's error models
A model for the error rate for different modulations.
static TypeId GetTypeId()
Get the type ID.
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.
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:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
represent a single transmission mode
Definition: wifi-mode.h:50
uint16_t GetConstellationSize() const
Definition: wifi-mode.cc:141
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
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...
#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_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#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.
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