User Manual, Developers Guide and API Documentation

ErrorProbability.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * WiFiMac                                                                    *
00003  * This file is part of openWNS (open Wireless Network Simulator)
00004  * _____________________________________________________________________________
00005  *
00006  * Copyright (C) 2004-2007
00007  * Chair of Communication Networks (ComNets)
00008  * Kopernikusstr. 16, D-52074 Aachen, Germany
00009  * phone: ++49-241-80-27910,
00010  * fax: ++49-241-80-22242
00011  * email: info@openwns.org
00012  * www: http://www.openwns.org
00013  * _____________________________________________________________________________
00014  *
00015  * openWNS is free software; you can redistribute it and/or modify it under the
00016  * terms of the GNU Lesser General Public License version 2 as published by the
00017  * Free Software Foundation;
00018  *
00019  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00020  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00021  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00022  * details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00026  *
00027  ******************************************************************************/
00028 
00029 #include <WIFIMAC/management/protocolCalculatorPlugins/ErrorProbability.hpp>
00030 
00031 #include <WNS/Ttos.hpp>
00032 #include <WNS/simulator/Time.hpp>
00033 
00034 #include <cmath>
00035 #include <algorithm>
00036 
00037 using namespace wifimac::management::protocolCalculatorPlugins;
00038 
00039 ErrorProbability::ErrorProbability()
00040 {
00041 
00042 }
00043 
00044 double
00045 ErrorProbability::getPER(std::vector<wns::Ratio> snr,
00046                          Bit packetLength,
00047                          wifimac::convergence::PhyMode phyMode) const
00048 {
00049     // if the packet length is unknown, one symbol is assumed
00050     if(packetLength == 0)
00051     {
00052         packetLength = phyMode.getDataBitsPerSymbol();
00053     }
00054 
00055     double cyclicPrefixReduction = 0.0;
00056     if(phyMode.getGuardIntervalDuration() == 0.8e-6)
00057     {
00058         cyclicPrefixReduction = 0.8;
00059     }
00060     if(phyMode.getGuardIntervalDuration() == 0.4e-6)
00061     {
00062         cyclicPrefixReduction = 0.9;
00063     }
00064     assure(cyclicPrefixReduction > 0, "Unknown guard interval");
00065 
00066     double bitSuccessRate = 1.0;
00067 
00068     std::vector<wifimac::convergence::MCS> v = phyMode.getSpatialStreams();
00069     assure(v.size() > 0, "Must have at least one spatial stream");
00070     assure(v.size() == snr.size(), "Number of spatial streams and SNRs must match");
00071 
00072     std::vector<wns::Ratio>::const_iterator itSNR = snr.begin();
00073     std::vector<wifimac::convergence::MCS>::const_iterator itV = v.begin();
00074 
00075     for(;
00076         itSNR != snr.end(), itV != v.end();
00077         ++itSNR, ++itV)
00078     {
00079         double snr = itSNR->get_factor() * cyclicPrefixReduction;
00080 
00081         double ser = 0.0;
00082         double ber = 0.0;
00083 
00084         if(itV->getModulation() == "BPSK")
00085         {
00086             ser = Q(sqrt(2*snr));
00087             ber = ser;
00088         }
00089         else if(itV->getModulation() == "QPSK")
00090         {
00091             ser = 2.0 * Q(sqrt(snr)) * (1.0 - 0.5 * Q(sqrt(snr)));
00092             ber = 0.5 * ser;
00093         }
00094         else if(itV->getModulation() == "QAM16")
00095         {
00096             double P_sqrt16 = 3.0/2.0 * Q(sqrt((3.0/15.0) * snr));
00097             ser = 1 - pow((1 - P_sqrt16), 2);
00098             ber = ser / 4.0;
00099         }
00100         else if(itV->getModulation() == "QAM64")
00101         {
00102             double P_sqrt64 = 7.0/4.0 * Q(sqrt((3.0/63.0) * snr));
00103             ser = 1 - pow((1 - P_sqrt64), 2);
00104             ber = ser / 6.0;
00105         }
00106 
00107         bitSuccessRate *= (1.0 - ber);
00108 
00109         assure((bitSuccessRate >= 0.0 and bitSuccessRate <= 1.0) and
00110                (ber >= 0.0 and ber <= 1.0) and
00111                (ser >= 0.0 and ser <= 1.0),
00112                "Calculated error probabilities are not valid");
00113     }
00114 
00115     double ber = (1.0 - bitSuccessRate);
00116     double u = 0.0;
00117 
00118     // only the first coding rate is taken
00119     if(phyMode.getSpatialStreams()[0].getRate() ==  "1/2")
00120     {
00121         u = std::min(1.0, Pu12(ber));
00122     }
00123     else if(phyMode.getSpatialStreams()[0].getRate() == "2/3")
00124     {
00125         u = std::min(1.0, Pu23(ber));
00126     }
00127     else if(phyMode.getSpatialStreams()[0].getRate() == "3/4")
00128     {
00129         u = std::min(1.0, Pu34(ber));
00130     }
00131     else if(phyMode.getSpatialStreams()[0].getRate() == "5/6")
00132     {
00133         u = std::min(1.0, Pu56(ber));
00134     }
00135 
00136     double per = 1.0 - pow(1.0 - u, static_cast<double>(packetLength));
00137 
00138     assure((per >= 0.0 and per <= 1.0) and
00139            (u >= 0.0 and u <= 1.0),
00140            "Calculated error probabilities are not valid");
00141 
00142     return per;
00143 }
00144 
00145 double
00146 ErrorProbability::getPER(wns::Ratio postSNR,
00147                          Bit packetLength,
00148                          wifimac::convergence::PhyMode phyMode) const
00149 {
00150     std::vector<wns::Ratio> snr(phyMode.getNumberOfSpatialStreams(), postSNR);
00151     return(this->getPER(snr, packetLength, phyMode));
00152 }
00153 
00154 double
00155 ErrorProbability::Pd(double p, double d) const
00156 {
00157     // Chernoff - Approximation
00158     return (pow(4*p*(1-p), d/2));
00159 }
00160 
00161 double
00162 ErrorProbability::Pu12(double rawBer) const
00163 {
00164     return( 11 * Pd(rawBer,10) +
00165             38 * Pd(rawBer,12) +
00166             193 * Pd(rawBer, 14) +
00167             1331 * Pd(rawBer, 16) +
00168             7275 * Pd(rawBer, 18) +
00169             40406 * Pd(rawBer, 20) +
00170             234969 * Pd(rawBer, 22) );
00171 }
00172 
00173 double
00174 ErrorProbability::Pu23(double rawBer) const
00175 {
00176     return( Pd(rawBer,6) +
00177             16 * Pd(rawBer, 7) +
00178             48 * Pd(rawBer, 8) +
00179             158 * Pd(rawBer, 9) +
00180             642 * Pd(rawBer, 10) +
00181             2435 * Pd(rawBer, 11) +
00182             6174 * Pd(rawBer, 12) +
00183             34705 * Pd(rawBer, 13) +
00184             131585 * Pd(rawBer, 14) +
00185             499608 * Pd(rawBer, 15));
00186 }
00187 
00188 double
00189 ErrorProbability::Pu34(double rawBer) const
00190 {
00191     return( 8 * Pd(rawBer, 5) +
00192             31 * Pd(rawBer, 6) +
00193             160 * Pd(rawBer, 7) +
00194             892 * Pd(rawBer, 8) +
00195             4512 * Pd(rawBer, 9) +
00196             23307 * Pd(rawBer, 10) +
00197             121077 * Pd(rawBer, 11) +
00198             625059 * Pd(rawBer, 12) +
00199             3234886 * Pd(rawBer, 13) +
00200             16753077 * Pd(rawBer, 14));
00201 }
00202 
00203 double
00204 ErrorProbability::Pu56(double rawBer) const
00205 {
00206     return( 14 * Pd(rawBer, 4) +
00207             69 * Pd(rawBer, 5) +
00208             654 * Pd(rawBer, 6) +
00209             4996 * Pd(rawBer, 7) +
00210             39677 * Pd(rawBer, 8) +
00211             314973 * Pd(rawBer, 9) +
00212             2503576 * Pd(rawBer, 10) +
00213             19875546 * Pd(rawBer, 11));
00214 }
00215 
00216 double
00217 ErrorProbability::Q(double x) const
00218 {
00219     return( erfc(x/sqrt(2.0)) /  2.0);
00220 }
00221 

Generated on Sun May 27 03:32:12 2012 for openWNS by  doxygen 1.5.5