A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
yans-error-rate-model.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include <cmath>
22 
23 #include "yans-error-rate-model.h"
24 #include "wifi-phy.h"
25 #include "ns3/log.h"
26 
27 NS_LOG_COMPONENT_DEFINE ("YansErrorRateModel");
28 
29 namespace ns3 {
30 
31 NS_OBJECT_ENSURE_REGISTERED (YansErrorRateModel);
32 
33 TypeId
34 YansErrorRateModel::GetTypeId (void)
35 {
36  static TypeId tid = TypeId ("ns3::YansErrorRateModel")
37  .SetParent<ErrorRateModel> ()
38  .AddConstructor<YansErrorRateModel> ()
39  ;
40  return tid;
41 }
42 
43 YansErrorRateModel::YansErrorRateModel ()
44 {
45 }
46 
47 double
48 YansErrorRateModel::Log2 (double val) const
49 {
50  return std::log (val) / std::log (2.0);
51 }
52 double
53 YansErrorRateModel::GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const
54 {
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 double
62 YansErrorRateModel::GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const
63 {
64  double EbNo = snr * signalSpread / phyRate;
65  double z = std::sqrt ((1.5 * Log2 (m) * EbNo) / (m - 1.0));
66  double z1 = ((1.0 - 1.0 / std::sqrt (m)) * erfc (z));
67  double z2 = 1 - std::pow ((1 - z1), 2.0);
68  double ber = z2 / Log2 (m);
69  NS_LOG_INFO ("Qam m=" << m << " rate=" << phyRate << " snr=" << snr << " ber=" << ber);
70  return ber;
71 }
72 uint32_t
73 YansErrorRateModel::Factorial (uint32_t k) const
74 {
75  uint32_t fact = 1;
76  while (k > 0)
77  {
78  fact *= k;
79  k--;
80  }
81  return fact;
82 }
83 double
84 YansErrorRateModel::Binomial (uint32_t k, double p, uint32_t n) const
85 {
86  double retval = Factorial (n) / (Factorial (k) * Factorial (n - k)) * std::pow (p, static_cast<double> (k)) * std::pow (1 - p, static_cast<double> (n - k));
87  return retval;
88 }
89 double
90 YansErrorRateModel::CalculatePdOdd (double ber, unsigned int d) const
91 {
92  NS_ASSERT ((d % 2) == 1);
93  unsigned int dstart = (d + 1) / 2;
94  unsigned int dend = d;
95  double pd = 0;
96 
97  for (unsigned int i = dstart; i < dend; i++)
98  {
99  pd += Binomial (i, ber, d);
100  }
101  return pd;
102 }
103 double
104 YansErrorRateModel::CalculatePdEven (double ber, unsigned int d) const
105 {
106  NS_ASSERT ((d % 2) == 0);
107  unsigned int dstart = d / 2 + 1;
108  unsigned int dend = d;
109  double pd = 0;
110 
111  for (unsigned int i = dstart; i < dend; i++)
112  {
113  pd += Binomial (i, ber, d);
114  }
115  pd += 0.5 * Binomial (d / 2, ber, d);
116 
117  return pd;
118 }
119 
120 double
121 YansErrorRateModel::CalculatePd (double ber, unsigned int d) const
122 {
123  double pd;
124  if ((d % 2) == 0)
125  {
126  pd = CalculatePdEven (ber, d);
127  }
128  else
129  {
130  pd = CalculatePdOdd (ber, d);
131  }
132  return pd;
133 }
134 
135 double
136 YansErrorRateModel::GetFecBpskBer (double snr, double nbits,
137  uint32_t signalSpread, uint32_t phyRate,
138  uint32_t dFree, uint32_t adFree) const
139 {
140  double ber = GetBpskBer (snr, signalSpread, phyRate);
141  if (ber == 0.0)
142  {
143  return 1.0;
144  }
145  double pd = CalculatePd (ber, dFree);
146  double pmu = adFree * pd;
147  pmu = std::min (pmu, 1.0);
148  double pms = std::pow (1 - pmu, nbits);
149  return pms;
150 }
151 
152 double
153 YansErrorRateModel::GetFecQamBer (double snr, uint32_t nbits,
154  uint32_t signalSpread,
155  uint32_t phyRate,
156  uint32_t m, uint32_t dFree,
157  uint32_t adFree, uint32_t adFreePlusOne) const
158 {
159  double ber = GetQamBer (snr, m, signalSpread, phyRate);
160  if (ber == 0.0)
161  {
162  return 1.0;
163  }
164  /* first term */
165  double pd = CalculatePd (ber, dFree);
166  double pmu = adFree * pd;
167  /* second term */
168  pd = CalculatePd (ber, dFree + 1);
169  pmu += adFreePlusOne * pd;
170  pmu = std::min (pmu, 1.0);
171  double pms = std::pow (1 - pmu, static_cast<double> (nbits));
172  return pms;
173 }
174 
175 double
176 YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
177 {
178  if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
179  || mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM)
180  {
181  if (mode.GetConstellationSize () == 2)
182  {
183  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
184  {
185  return GetFecBpskBer (snr,
186  nbits,
187  mode.GetBandwidth (), // signal spread
188  mode.GetPhyRate (), // phy rate
189  10, // dFree
190  11 // adFree
191  );
192  }
193  else
194  {
195  return GetFecBpskBer (snr,
196  nbits,
197  mode.GetBandwidth (), // signal spread
198  mode.GetPhyRate (), // phy rate
199  5, // dFree
200  8 // adFree
201  );
202  }
203  }
204  else if (mode.GetConstellationSize () == 4)
205  {
206  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
207  {
208  return GetFecQamBer (snr,
209  nbits,
210  mode.GetBandwidth (), // signal spread
211  mode.GetPhyRate (), // phy rate
212  4, // m
213  10, // dFree
214  11, // adFree
215  0 // adFreePlusOne
216  );
217  }
218  else
219  {
220  return GetFecQamBer (snr,
221  nbits,
222  mode.GetBandwidth (), // signal spread
223  mode.GetPhyRate (), // phy rate
224  4, // m
225  5, // dFree
226  8, // adFree
227  31 // adFreePlusOne
228  );
229  }
230  }
231  else if (mode.GetConstellationSize () == 16)
232  {
233  if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
234  {
235  return GetFecQamBer (snr,
236  nbits,
237  mode.GetBandwidth (), // signal spread
238  mode.GetPhyRate (), // phy rate
239  16, // m
240  10, // dFree
241  11, // adFree
242  0 // adFreePlusOne
243  );
244  }
245  else
246  {
247  return GetFecQamBer (snr,
248  nbits,
249  mode.GetBandwidth (), // signal spread
250  mode.GetPhyRate (), // phy rate
251  16, // m
252  5, // dFree
253  8, // adFree
254  31 // adFreePlusOne
255  );
256  }
257  }
258  else if (mode.GetConstellationSize () == 64)
259  {
260  if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
261  {
262  return GetFecQamBer (snr,
263  nbits,
264  mode.GetBandwidth (), // signal spread
265  mode.GetPhyRate (), // phy rate
266  64, // m
267  6, // dFree
268  1, // adFree
269  16 // adFreePlusOne
270  );
271  }
272  else
273  {
274  return GetFecQamBer (snr,
275  nbits,
276  mode.GetBandwidth (), // signal spread
277  mode.GetPhyRate (), // phy rate
278  64, // m
279  5, // dFree
280  8, // adFree
281  31 // adFreePlusOne
282  );
283  }
284  }
285  }
286  else if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS)
287  {
288  switch (mode.GetDataRate ())
289  {
290  case 1000000:
291  return DsssErrorRateModel::GetDsssDbpskSuccessRate (snr, nbits);
292  case 2000000:
293  return DsssErrorRateModel::GetDsssDqpskSuccessRate (snr, nbits);
294  case 5500000:
295  return DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (snr, nbits);
296  case 11000000:
297  return DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (snr, nbits);
298  }
299  }
300  return 0;
301 }
302 
303 } // namespace ns3
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_LOG_INFO(msg)
Definition: log.h:264