User Manual, Developers Guide and API Documentation

Weibull.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WNS/distribution/Weibull.hpp>
00029 
00030 using namespace wns::distribution;
00031 
00032 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00033     Weibull,
00034     Distribution,
00035     "Weibull",
00036     wns::PyConfigViewCreator);
00037 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00038     Weibull,
00039     Distribution,
00040     "Weibull",
00041     wns::distribution::RNGConfigCreator);
00042 
00043 Weibull::Weibull(double scale, double shape, wns::rng::RNGen* rng) :
00044   Distribution(rng)
00045 {
00046   assert((scale > 0.0) && (shape > 0.0));
00047   scale_ = scale;
00048   shape_ = shape;
00049 
00050   mean_ = scale_ * gamma(1 + (1 / shape_));
00051   variance_ = pow(scale_, 2) * gamma( 1 + (2 / shape_)) - pow(mean_, 2);
00052 }
00053 
00054 Weibull::Weibull(const pyconfig::View& config) :
00055   Distribution(),
00056   shape_(config.get<double>("shape")),
00057   scale_(config.get<double>("scale"))
00058 {
00059   assert((scale_ > 0) && (shape_ > 0));
00060 
00061   mean_ = scale_ * gamma(1 + (1 / shape_));
00062   variance_ = pow(scale_, 2) * gamma( 1 + (2 / shape_)) - pow(mean_, 2);
00063 }
00064 
00065 
00066 Weibull::Weibull(wns::rng::RNGen* rng, const pyconfig::View& config) :
00067   Distribution(),
00068   shape_(config.get<double>("shape")),
00069   scale_(config.get<double>("scale"))
00070 {
00071   assert((scale_ > 0) && (shape_ > 0));
00072 
00073   mean_ = scale_ * gamma(1 + (1 / shape_));
00074   variance_ = pow(scale_, 2) * gamma( 1 + (2 / shape_)) - pow(mean_, 2);
00075 }
00076 
00077 Weibull::~Weibull()
00078 {
00079 }
00080 
00081 /* - Parameters:
00082       1. Scale (notation: alpha or lambda )
00083       2. Shape (notation: k or beta)
00084   - Sources:
00085       1. Algorithm in this method is described here:
00086          http://en.wikipedia.org/wiki/Weibull_distribution#Generating_Weibull-distributed_random_variates
00087       2. http://de.wikipedia.org/wiki/Weibull-Verteilung
00088       3 .http://en.wikipedia.org/wiki/Gamma_function
00089 */
00090 
00091 double
00092 Weibull::operator()()
00093 {
00094   /* generates uniform random value between (0,1) */
00095   uniDis = new wns::distribution::Uniform(0.0, 1.0);
00096   double uniRandomValue = (*uniDis)();
00097 
00098   double x = scale_ * pow((-1) * log(uniRandomValue), 1 / shape_);
00099 
00100   return x;
00101 }
00102 
00103 double
00104 Weibull::getMean() const
00105 {
00106   return mean_;
00107 }
00108 
00109 /*
00110   This method implements the gamma function
00111   source: http://www.crbond.com/download/gamma.cpp
00112 */
00113 double
00114 Weibull::gamma(double x)
00115 {
00116   int i,k,m;
00117   double ga,gr,z;
00118   double r = 1.0;
00119 
00120    static double g[] = {
00121      1.0,
00122      0.5772156649015329,
00123      -0.6558780715202538,
00124      -0.420026350340952e-1,
00125      0.1665386113822915,
00126      -0.421977345555443e-1,
00127      -0.9621971527877e-2,
00128      0.7218943246663e-2,
00129      -0.11651675918591e-2,
00130      -0.2152416741149e-3,
00131      0.1280502823882e-3,
00132      -0.201348547807e-4,
00133      -0.12504934821e-5,
00134      0.1133027232e-5,
00135      -0.2056338417e-6,
00136      0.6116095e-8,
00137      0.50020075e-8,
00138      -0.11812746e-8,
00139      0.1043427e-9,
00140      0.77823e-11,
00141      -0.36968e-11,
00142      0.51e-12,
00143      -0.206e-13,
00144      -0.54e-14,
00145      0.14e-14};
00146 
00147    if (x > 171.0) {
00148      /* This value is an overflow flag. */
00149      return 1e308;
00150    }
00151 
00152    if (x == (int)x) {
00153      if (x > 0.0) {
00154        /* use factorial */
00155        ga = 1.0;
00156        for (i=2;i<x;i++) {
00157      ga *= i;
00158        }
00159      }
00160      else
00161        ga = 1e308;
00162    }
00163    else {
00164      if (fabs(x) > 1.0) {
00165        z = fabs(x);
00166        m = (int)z;
00167        r = 1.0;
00168        for (k=1;k<=m;k++) {
00169      r *= (z-k);
00170        }
00171        z -= m;
00172      }
00173      else
00174        z = x;
00175      gr = g[24];
00176      for (k=23;k>=0;k--) {
00177        gr = gr*z+g[k];
00178      }
00179      ga = 1.0/(gr*z);
00180      if (fabs(x) > 1.0) {
00181        ga *= r;
00182        if (x < 0.0) {
00183      ga = -M_PI/(x*ga*sin(M_PI*x));
00184        }
00185      }
00186    }
00187    return ga;
00188 }
00189 
00190 
00191 std::string
00192 Weibull::paramString() const
00193 {
00194     std::ostringstream tmp;
00195     tmp << "Weibull(shape = " << shape_ << ", scale = " << scale_
00196         << ", mean = " << mean_ << ", variance = " << variance_ << ")";
00197     return tmp.str();
00198 }

Generated on Sat May 26 03:31:36 2012 for openWNS by  doxygen 1.5.5