![]() |
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. 16, 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/evaluation/statistics/pdf.hpp> 00029 00030 #include <cmath> 00031 #include <iomanip> 00032 #include <climits> 00033 #include <cfloat> 00034 00035 using namespace wns::evaluation::statistics; 00036 00037 STATIC_FACTORY_REGISTER_WITH_CREATOR(PDF, 00038 StatEvalInterface, 00039 "openwns.evaluation.statistics.PDF", 00040 wns::PyConfigViewCreator); 00041 00042 PDF::PDF(double minXValue, 00043 double maxXValue, 00044 unsigned long int resolution, 00045 scaleType scaleType, 00046 formatType format, 00047 std::string name, 00048 std::string description) 00049 : StatEval(format, name, description), 00050 minXValue_(minXValue), 00051 maxXValue_(maxXValue), 00052 resolution_(resolution), 00053 scaleType_(scaleType), 00054 values_(resolution_+1, 0), 00055 underFlows_(0), 00056 overFlows_(0) 00057 { 00058 assure(minXValue_ < maxXValue_, 00059 "Wrong min/max values. min=" << minXValue_ << ", max="<<maxXValue_); 00060 assure(resolution_ > 0, "Resolution must be >0, but is " << resolution_); 00061 } 00062 00063 PDF::PDF(const wns::pyconfig::View& config) 00064 : StatEval(config), 00065 minXValue_(config.get<double>("minXValue")), 00066 maxXValue_(config.get<double>("maxXValue")), 00067 resolution_(config.get<int>("resolution")), 00068 scaleType_(config.get<std::string>("xScaleType") == "logarithmical" ? logarithmical : linear), 00069 values_(resolution_+1, 0), 00070 underFlows_(0), 00071 overFlows_(0) 00072 { 00073 assure(minXValue_ < maxXValue_, 00074 "Wrong min/max values. min=" << minXValue_ << ", max="<<maxXValue_); 00075 assure(resolution_ > 0, "Resolution must be >0, but is " << resolution_); 00076 } 00077 00078 00080 00081 PDF::PDF(const PDF& other) 00082 : StatEval(other), 00083 minXValue_(0.0), 00084 maxXValue_(1.0), 00085 resolution_(100), 00086 scaleType_(linear), 00087 values_(), 00088 underFlows_(0), 00089 overFlows_(0) 00090 { 00091 // Copy all internal data 00092 minXValue_ = other.minXValue_; 00093 maxXValue_ = other.maxXValue_; 00094 resolution_ = other.resolution_; 00095 scaleType_ = other.scaleType_; 00096 values_ = other.values_; 00097 name_ = other.name_; 00098 desc_ = other.desc_; 00099 } 00100 00101 PDF::~PDF() 00102 { 00103 } 00104 00105 void 00106 PDF::print(std::ostream& stream) const 00107 { 00108 std::string errorString; 00109 errorString = "I/O Error: Can't dump PDF results"; 00110 00111 printBanner(stream, 00112 (std::string) (prefix_ + " Evaluation: PDF"), 00113 errorString); 00114 00115 if (!stream) 00116 { 00117 throw(wns::Exception(errorString)); 00118 } 00119 00120 std::string prefix = (prefix_ + " "); 00121 00122 std::string separator; 00123 00124 unsigned long int i = 0; 00125 00126 unsigned long int numTrials = 0; 00127 00128 double x = 0.0; 00129 double f = 0.0; 00130 double g = 0.0; 00131 double p = 0.0; 00132 00133 separator = prefix + "-------------------------------------"; 00134 separator += "----------------------"; 00135 00136 stream << std::resetiosflags(std::ios::fixed) 00137 << std::resetiosflags(std::ios::scientific) 00138 << std::resetiosflags(std::ios::right) 00139 << std::setiosflags(std::ios::left) 00140 << std::setiosflags(std::ios::dec) 00141 << std::setprecision(7) 00142 << std::setw(6) 00143 00144 << separator << std::endl << prefix 00145 << "PDF statistics " << std::endl << prefix 00146 << " Left border of x-axis: " 00147 << minXValue_ 00148 << std::endl << prefix 00149 << " Right border of x-axis: " 00150 << maxXValue_ 00151 << std::endl << prefix 00152 << " Resolution of x-axis: " 00153 << resolution_ 00154 << std::endl 00155 << separator 00156 << std::endl; 00157 00158 stream << prefix 00159 << "PDF data " << std::endl << prefix 00160 << " Underflows: " 00161 << underFlows_ << std::endl; 00162 00163 stream << prefix 00164 << " Underflows in percent: " 00165 << ((numTrials_ > 0) ? (double)(underFlows_) / 00166 (double)numTrials_ : 0.0) 00167 << std::endl; 00168 00169 stream << prefix 00170 << " Overflows: " 00171 << (overFlows_) << std::endl; 00172 00173 stream << prefix 00174 << " Overflows in percent: " 00175 << ((numTrials_ > 0) ? 00176 (double)(overFlows_) / 00177 (double)numTrials_ : 0.0) << std::endl; 00178 00179 stream << separator 00180 << std::endl << prefix 00181 << "Percentiles" << std::endl; 00182 00183 for (int ii=1; ii <= 100; ++ii) 00184 { 00185 stream << prefix; this->printPercentile( ii, stream); 00186 } 00187 00188 stream << separator 00189 << std::endl << prefix << std::endl << prefix 00190 << "x_n F(x_n) G(x_n) P(x_n-1 < X n" 00191 << std::endl << prefix 00192 << " =P(X<=x_n) =P(X>x_n) AND X <= x_n)" 00193 << std::endl << prefix << std::endl 00194 << (format_ == fixed ? setiosflags(std::ios::fixed) : 00195 setiosflags(std::ios::scientific)); 00196 00197 00198 if (!stream) 00199 { 00200 throw(wns::Exception(errorString)); 00201 } 00202 00203 // Handle the normal intervals 00204 for (i = 0, numTrials = underFlows_; 00205 i <= resolution_; ++i) 00206 { 00207 // Normal interval 00208 x = getAbscissa(i); 00209 numTrials += values_.at(i); 00210 00211 if (numTrials_ != 0) 00212 { 00213 f = double(numTrials) / double(numTrials_); 00214 assert(0.0 <= f && f <= 1.0); 00215 g = 1.0 - f; 00216 p = double(values_.at(i)) / double(numTrials_); 00217 } 00218 else 00219 { 00220 f = g = p = 0.0; 00221 } 00222 00223 stream << resetiosflags(std::ios::right) 00224 << setiosflags(std::ios::left) 00225 << std::setw(15) 00226 << x 00227 << resetiosflags(std::ios::left) 00228 << setiosflags(std::ios::right) 00229 << std::setw(14) 00230 << f 00231 << " " 00232 << std::setw(14) 00233 << g 00234 << " " 00235 << std::setw(14) 00236 << p 00237 << " " 00238 << std::setw(4) 00239 << i 00240 << std::endl; 00241 if (!stream) 00242 { 00243 throw(wns::Exception(errorString)); 00244 } 00245 } 00246 00247 stream << separator; 00248 00249 if (!stream) 00250 { 00251 throw(wns::Exception(errorString)); 00252 } 00253 } 00254 00255 void 00256 PDF::put(double value) 00257 { 00258 StatEval::put(value); 00259 00260 value *= scalingFactor_; 00261 00262 // Underflow? 00263 if (value < minXValue_) 00264 { 00265 ++underFlows_; 00266 } 00267 // Overflow? 00268 else if (value > maxXValue_) 00269 { 00270 ++overFlows_; 00271 } 00272 else 00273 { 00274 values_.at(this->getIndex(value))++; 00275 } 00276 } 00277 00278 00279 unsigned long int 00280 PDF::getIndex(double value) const 00281 { 00282 assert((value >= minXValue_ && value <= maxXValue_) && "Huge, Fat Error!"); 00283 00284 if (this->scaleType_ == PDF::linear) 00285 { 00286 return (unsigned long int)( 00287 ceil((value - minXValue_) * double(resolution_) / 00288 (maxXValue_ - minXValue_))); 00289 } 00290 else if (this->scaleType_ == PDF::logarithmical) 00291 { 00292 double logXMin = log10(minXValue_); 00293 double logXMax = log10(maxXValue_); 00294 double logValue = log10(value); 00295 double logXStep = (logXMax - logXMin)/double(resolution_); 00296 00297 return (unsigned long int)( ceil ((logValue - logXMin)/logXStep) ); 00298 } 00299 00300 throw wns::Exception("Unknown scaleType in PDF!"); 00301 return 0; 00302 } 00303 00304 void 00305 PDF::reset() 00306 { 00307 StatEval::reset(); 00308 values_ = std::vector<int>(resolution_ + 1); 00309 } 00310 00311 double 00312 PDF::getAbscissa(unsigned long int index) const 00313 { 00314 if (this->scaleType_ == PDF::linear) 00315 { 00316 return minXValue_ 00317 + (maxXValue_ - minXValue_) * double(index) / double(resolution_); 00318 } 00319 else if (this->scaleType_ == PDF::logarithmical) 00320 { 00321 double logXMin = log10(minXValue_); 00322 double logXMax = log10(maxXValue_); 00323 double logXStep = (logXMax - logXMin)/double(resolution_); 00324 return double(pow(10, logXMin + double(index) * logXStep)); 00325 } 00326 else 00327 { 00328 throw wns::Exception("Unknown scaleType in PDF!"); 00329 } 00330 } 00331 00332 double 00333 PDF::getPercentile(int p) const 00334 { 00335 assert(p>0 && "Percentile has to be greater than 0!"); 00336 00337 if (numTrials_ == 0) 00338 return 0.0; 00339 00340 double P = double(p)/100.0; 00341 00342 if ( P<= double(underFlows_)/double(numTrials_) ) 00343 throw PercentileUnderFlow(); 00344 00345 if ( P > 1.0 - double(overFlows_)/double(numTrials_) ) 00346 throw PercentileOverFlow(); 00347 00348 double x = 0.0; 00349 double F = 0.0; 00350 double dummy1 = 0.0; 00351 double dummy2 = 0.0; 00352 double tmpF = 0.0; 00353 double tmpX = 0.0; 00354 00355 this->getResult(0, x, F, dummy1, dummy2); 00356 00357 if (F >= P) 00358 throw PercentileUnderFlow(); 00359 00360 for (unsigned int ii = 1; ii <= resolution_; ++ii) 00361 { 00362 this->getResult(ii, tmpX, tmpF, dummy1, dummy2); 00363 00364 if (F<P && tmpF >= P) 00365 { 00366 if (tmpF == 1.0) 00367 tmpX = maxValue_; 00368 00369 return x + (tmpX-x) / (tmpF-F) * (P-F); 00370 } 00371 00372 F = tmpF; 00373 x = tmpX; 00374 } 00375 00376 throw wns::Exception("This point should never be reached"); 00377 } 00378 00379 void 00380 PDF::printPercentile(int p, std::ostream& stream) const 00381 { 00382 std::stringstream ss; 00383 00384 ss << " P" 00385 << std::setiosflags(std::ios::right) << std::setfill('0') << std::setw(2) 00386 << p << ": "; 00387 00388 try 00389 { 00390 ss << std::setiosflags(std::ios::dec) << std::setprecision(7) << std::setw(6) 00391 << std::setiosflags(std::ios::fixed) << this->getPercentile(p); 00392 } 00393 catch (PercentileUnderFlow) 00394 { 00395 ss << "NaN"; 00396 } 00397 catch (PercentileOverFlow) 00398 { 00399 ss << "NaN"; 00400 } 00401 stream << ss.str() << std::endl; 00402 } 00403 00404 00405 void 00406 PDF::getResult(unsigned long int index, 00407 double& abscissa, 00408 double& F, 00409 double& G, 00410 double& P) const 00411 { 00412 unsigned long int i; 00413 unsigned long int numTrials = underFlows_; 00414 00415 assert(resolution_); 00416 00417 if (numTrials_ == 0) 00418 { 00419 abscissa = 0.0; 00420 F = 0.0; 00421 G = 0.0; 00422 P = 0.0; 00423 return; 00424 } 00425 00426 for (i = 0; i <= index; i++) 00427 { 00428 numTrials += values_.at(i); 00429 } 00430 abscissa = getAbscissa(index); 00431 F = double(numTrials) / double(numTrials_); 00432 assert(0.0 <= F && F <= 1.0); 00433 G = 1.0 - F; 00434 P = double(values_.at(index)) / double(numTrials_); 00435 } 00436 00437
1.5.5