![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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 }
1.5.5