![]() |
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/stateval.hpp> 00029 00030 #include <WNS/pyconfig/View.hpp> 00031 #include <WNS/simulator/ISimulator.hpp> 00032 #include <WNS/Exception.hpp> 00033 00034 #include <iomanip> 00035 #include <climits> 00036 #include <cfloat> 00037 #include <cmath> 00038 00039 using namespace std; 00040 00041 using namespace wns::evaluation::statistics; 00042 00043 STATIC_FACTORY_REGISTER_WITH_CREATOR(StatEval, 00044 StatEvalInterface, 00045 "wns.evaluation.statistics.StatEval", 00046 wns::PyConfigViewCreator); 00047 00048 StatEval::StatEval(formatType format, 00049 std::string name, 00050 std::string desc) 00051 : minValue_(DBL_MAX), 00052 maxValue_(-DBL_MAX), 00053 numTrials_(0), 00054 sum_(0.0), 00055 squareSum_(0.0), 00056 cubeSum_(0.0), 00057 format_(format), 00058 name_(name), 00059 desc_(desc), 00060 prefix_("#"), 00061 scalingFactor_(1.0) 00062 { 00063 } 00064 00065 00066 StatEval::StatEval(const wns::pyconfig::View& config) : 00067 minValue_(DBL_MAX), 00068 maxValue_(-DBL_MAX), 00069 numTrials_(0), 00070 sum_(0.0), 00071 squareSum_(0.0), 00072 cubeSum_(0.0), 00073 format_((config.get<std::string>("format")=="scientific") ? StatEval::scientific : StatEval::fixed), 00074 name_(config.get<std::string>("name")), 00075 desc_(config.get<std::string>("description")), 00076 prefix_(config.get<std::string>("prefix")), 00077 scalingFactor_(config.get<double>("scalingFactor")) 00078 {} 00079 00080 StatEval::~StatEval() 00081 {} 00082 00083 00084 void 00085 StatEval::print(std::ostream& stream) const 00086 { 00087 this->printBanner(stream, 00088 std::string(prefix_ + " Evaluation: StatEval"), 00089 std::string("I/O Error: Can't dump StatEval results")); 00090 } 00091 00092 void 00093 StatEval::printLog(std::ostream&) 00094 { 00095 } 00096 00097 void 00098 StatEval::put(double xI) 00099 { 00100 xI *= scalingFactor_; 00101 00102 if(xI > maxValue_) 00103 maxValue_ = xI; 00104 if(xI < minValue_) 00105 minValue_ = xI; 00106 00107 double tmp = xI; 00108 sum_ += tmp; 00109 tmp *= xI; 00110 squareSum_ += tmp; 00111 tmp *= xI; 00112 cubeSum_ += tmp; 00113 00114 ++numTrials_; 00115 } 00116 00117 double 00118 StatEval::mean() const 00119 { 00120 return numTrials_ ? sum_ / (double)numTrials_ : 0.0; 00121 } 00122 00123 double 00124 StatEval::variance() const 00125 { 00126 double theMean; 00127 00128 if (numTrials_ > 1) 00129 { 00130 theMean = mean(); 00131 assert((sqrt(DBL_MAX) > fabs(theMean))); 00132 00133 double square_mean = theMean * theMean; 00134 00135 assert(DBL_MAX / square_mean > (double)numTrials_); 00136 double sum_square = (double)numTrials_ * square_mean; 00137 00138 return ::max((squareSum_ - sum_square) / 00139 ((double)numTrials_ - 1.0) , 0.0); 00140 00141 } 00142 else 00143 { 00144 return 0.0; 00145 } 00146 } 00147 00148 00149 double 00150 StatEval::relativeVariance() const 00151 { 00152 double theMean = mean(); 00153 00154 if (fabs(theMean) > getMaxError<double>()) 00155 { 00156 assert((sqrt(DBL_MAX) > fabs(theMean))); 00157 return (variance() / (theMean * theMean)); 00158 } 00159 else 00160 { 00161 return 0.0; 00162 } 00163 } 00164 00165 double 00166 StatEval::coeffOfVariation() const 00167 { 00168 double relVar = relativeVariance(); 00169 00170 return relVar > 0.0 ? sqrt(relVar): 0.0; 00171 } 00172 00173 double 00174 StatEval::M2() const 00175 { 00176 return (numTrials_) ? 00177 (squareSum_ / (double) numTrials_) : 0.0 ; 00178 } 00179 00180 double 00181 StatEval::M3() const 00182 { 00183 return (numTrials_) ? 00184 (cubeSum_ / (double) numTrials_) : 0.0 ; 00185 } 00186 00187 double 00188 StatEval::Z3() const 00189 { 00190 double m1 = mean(); 00191 double m2 = M2(); 00192 double m3 = M3(); 00193 00194 assert(DBL_MAX / 2.0 / fabs(m1) / fabs(m1) > fabs(m1)); 00195 00196 double twoM1Cube = 2.0 * m1 * m1 * m1; 00197 00198 assert(DBL_MAX / 3.0 / fabs(m1) > 3.0 * fabs(m2)); 00199 00200 double threeM1M2 = 3.0 * m1 * m2; 00201 00202 if (m3 > 0.0) 00203 { 00204 // m3 - three_m1_2 > -DBL_MAX, as m3 > 0 00205 // m3 - three_m1_2 < DBL_MAX 00206 assert(threeM1M2 > - ( DBL_MAX - m3)); 00207 } 00208 else 00209 { 00210 // m3 - threeM1M2 < DBL_MAX, as m3 < 0 00211 // m3 - threeM1M2 > -DBL_MAX 00212 // - threeM1M2 > -DBL_MAX - m3 00213 assert(- threeM1M2 > -DBL_MAX - m3); 00214 } 00215 if (twoM1Cube > 0.0) 00216 { 00217 assert(m3 - threeM1M2 < DBL_MAX - twoM1Cube); 00218 } 00219 else 00220 { 00221 assert(m3 - threeM1M2 > -DBL_MAX - twoM1Cube); 00222 } 00223 00224 return m3 - threeM1M2 + twoM1Cube; 00225 } 00226 00227 double 00228 StatEval::skewness() const 00229 { 00230 double var = variance(); 00231 assert(sqrt(var) < pow(DBL_MAX, 1.0/3.0)); 00232 00233 return (var > getMaxError<double>()) ? Z3() / (var * sqrt(var)) : 0.0; 00234 } 00235 00236 double 00237 StatEval::deviation() const 00238 { 00239 double var = variance(); 00240 return (var > getMaxError<double>()) ? sqrt(var) : 0.0; 00241 } 00242 00243 double 00244 StatEval::relativeDeviation() const 00245 { 00246 double m1 = mean(); 00247 double var = variance(); 00248 00249 return ((fabs(m1) > getMaxError<double>()) && 00250 (var > getMaxError<double>())) ? sqrt(var) / m1 : 0.0; 00251 } 00252 00253 unsigned long int 00254 StatEval::trials() const 00255 { 00256 return numTrials_; 00257 } 00258 00259 double 00260 StatEval::min() const 00261 { 00262 return minValue_; 00263 } 00264 00265 double 00266 StatEval::max() const 00267 { 00268 return maxValue_; 00269 } 00270 00271 void 00272 StatEval::reset() 00273 { 00274 numTrials_ = 0; 00275 sum_ = 0; 00276 squareSum_ = 0; 00277 cubeSum_ = 0; 00278 minValue_ = DBL_MAX; 00279 maxValue_ = -DBL_MAX; 00280 } 00281 00282 const std::string& 00283 StatEval::getName() const 00284 { 00285 return name_; 00286 } 00287 00288 const std::string& 00289 StatEval::getDesc() const 00290 { 00291 return desc_; 00292 } 00293 00294 void 00295 StatEval::setFormat(formatType format) 00296 { 00297 format_ = format; 00298 } 00299 00300 StatEval::formatType 00301 StatEval::getFormat() const 00302 { 00303 return format_; 00304 } 00305 00306 StatEval::statEvalType 00307 StatEval::mapToStatEvalType(std::string statTypeName) 00308 00309 { 00310 StatEval::statEvalType statType; 00311 00312 00313 if (statTypeName == std::string("LREF")) 00314 { 00315 statType = StatEval::lref; 00316 } 00317 else if (statTypeName == std::string("LREG")) 00318 { 00319 statType = StatEval::lreg; 00320 } 00321 else if (statTypeName == std::string("PLREF")) 00322 { 00323 statType = StatEval::plref; 00324 } 00325 else if (statTypeName == std::string("PLREG")) 00326 { 00327 statType = StatEval::plreg; 00328 } 00329 else if (statTypeName == std::string("Moments")) 00330 { 00331 statType = StatEval::moments; 00332 } 00333 else if (statTypeName == std::string("PMoments")) 00334 { 00335 statType = StatEval::pmoments; 00336 } 00337 else if (statTypeName == std::string("BatchMns")) 00338 { 00339 statType = StatEval::batchMns; 00340 } 00341 else if (statTypeName == std::string("PBatchMns")) 00342 { 00343 statType = StatEval::pbatchMns; 00344 } 00345 else if (statTypeName == std::string("Histogrm")) 00346 { 00347 statType = StatEval::histogrm; 00348 } 00349 else if (statTypeName == std::string("PHistogrm")) 00350 { 00351 statType = StatEval::phistogrm; 00352 } 00353 else if (statTypeName == std::string("DLREF")) 00354 { 00355 statType = StatEval::dlref; 00356 } 00357 else if (statTypeName == std::string("DLREG")) 00358 { 00359 statType = StatEval::dlreg; 00360 } 00361 else if (statTypeName == std::string("DLREP")) 00362 { 00363 statType = StatEval::dlrep; 00364 } 00365 else if (statTypeName == std::string("PDLREF")) 00366 { 00367 statType = StatEval::pdlref; 00368 } 00369 else if (statTypeName == std::string("PDLREG")) 00370 { 00371 statType = StatEval::pdlreg; 00372 } 00373 else if (statTypeName == std::string("PDLREP")) 00374 { 00375 statType = StatEval::pdlrep; 00376 } 00377 else if (statTypeName == std::string("DLREF_NONEQUI")) 00378 { 00379 statType = StatEval::dlref_nonequi; 00380 } 00381 else if (statTypeName == std::string("DLREG_NONEQUI")) 00382 { 00383 statType = StatEval::dlreg_nonequi; 00384 } 00385 else if (statTypeName == std::string("DLREP_NONEQUI")) 00386 { 00387 statType = StatEval::dlrep_nonequi; 00388 } 00389 else if (statTypeName == std::string("PDLREF_NONEQUI")) 00390 { 00391 statType = StatEval::pdlref_nonequi; 00392 } 00393 else if (statTypeName == std::string("PDLREG_NONEQUI")) 00394 { 00395 statType = StatEval::pdlreg_nonequi; 00396 } 00397 else if (statTypeName == std::string("PDLREP_NONEQUI")) 00398 { 00399 statType = StatEval::pdlrep_nonequi; 00400 } 00401 else if (statTypeName == std::string("PDF")) 00402 { 00403 statType = StatEval::pdf; 00404 } 00405 else if (statTypeName == std::string("PPDF")) 00406 { 00407 statType = StatEval::ppdf; 00408 } 00409 else if (statTypeName == std::string("Log")) 00410 { 00411 statType = StatEval::logeval; 00412 } 00413 else if (statTypeName == std::string("PLog")) 00414 { 00415 statType = StatEval::plogeval; 00416 } 00417 else if (statTypeName == std::string("ProbeText")) 00418 { 00419 statType = StatEval::probetext; 00420 } 00421 else if (statTypeName == std::string("PProbeText")) 00422 { 00423 statType = StatEval::pprobetext; 00424 } 00425 else 00426 { 00427 throw wns::Exception("StatEval: Unknown type '" + statTypeName + "'!"); 00428 } 00429 00430 return statType; 00431 } 00432 00433 std::string 00434 StatEval::mapEvalTypeToString(statEvalType statType) 00435 { 00436 00437 switch(statType) 00438 { 00439 case StatEval::lref: 00440 case StatEval::plref: 00441 00442 return std::string("LREF"); 00443 break; 00444 case StatEval::lreg: 00445 case StatEval::plreg: 00446 00447 return std::string("LREG"); 00448 break; 00449 00450 case StatEval::moments: 00451 case StatEval::pmoments: 00452 00453 return std::string("Mom"); 00454 break; 00455 00456 case StatEval::batchMns: 00457 case StatEval::pbatchMns: 00458 00459 return std::string("BaM"); 00460 break; 00461 00462 case StatEval::histogrm: 00463 case StatEval::phistogrm: 00464 00465 return std::string("His"); 00466 break; 00467 00468 case StatEval::dlref: 00469 case StatEval::pdlref: 00470 case StatEval::dlref_nonequi: 00471 case StatEval::pdlref_nonequi: 00472 00473 return std::string("DLREF"); 00474 break; 00475 00476 case StatEval::dlreg: 00477 case StatEval::pdlreg: 00478 case StatEval::dlreg_nonequi: 00479 case StatEval::pdlreg_nonequi: 00480 00481 return std::string("DLREG"); 00482 break; 00483 00484 case StatEval::dlrep: 00485 case StatEval::pdlrep: 00486 case StatEval::dlrep_nonequi: 00487 case StatEval::pdlrep_nonequi: 00488 00489 return std::string("DLREP"); 00490 break; 00491 00492 case StatEval::pdf: 00493 case StatEval::ppdf: 00494 00495 return std::string("PDF"); 00496 break; 00497 00498 case StatEval::logeval: 00499 case StatEval::plogeval: 00500 00501 return std::string("Log"); 00502 break; 00503 00504 case StatEval::probetext: 00505 case StatEval::pprobetext: 00506 00507 return std::string("Text"); 00508 break; 00509 00510 default: 00511 00512 throw wns::Exception("StatEval: Unknown type"); 00513 break; 00514 } 00515 00516 } 00517 00518 void 00519 StatEval::printBanner(ostream& stream, 00520 std::string probeTypeDesc, 00521 std::string errorString) const 00522 { 00523 std::string prefix(prefix_ + " "); 00524 00525 std::string separator = prefix + "-------------------------------------"; 00526 separator += "--------------------------------------\n"; 00527 00528 stream << prefix + " PROBE RESULTS (THIS IS A MAGIC LINE)" 00529 << endl 00530 << separator 00531 << probeTypeDesc 00532 << endl 00533 << separator 00534 << prefix+ " Name: " 00535 << getName() 00536 << endl 00537 << prefix + " Description: " 00538 << getDesc() 00539 << endl 00540 << separator; 00541 if (!stream) 00542 { 00543 throw(wns::Exception(errorString)); 00544 } 00545 00546 stream << prefix + " Evaluation terminated successfully!" 00547 << endl 00548 << separator; 00549 if (!stream) 00550 { 00551 throw(wns::Exception(errorString)); 00552 } 00553 00554 stream << resetiosflags(ios::fixed) 00555 << resetiosflags(ios::scientific) 00556 << resetiosflags(ios::right) 00557 << setiosflags(ios::left) 00558 << setiosflags(ios::dec) 00559 << setprecision(7) 00560 << setw(6) 00561 << (format_ == fixed ? setiosflags(ios::fixed) : 00562 setiosflags(ios::scientific)) 00563 << prefix + " Common Statistics " << endl 00564 00565 00566 00567 << prefix + " Minimum: "; 00568 if (!stream) 00569 { 00570 throw(wns::Exception(errorString)); 00571 } 00572 if (minValue_ == DBL_MAX) 00573 { 00574 stream << "+infinity"; 00575 } 00576 else 00577 { 00578 stream << minValue_; 00579 } 00580 00581 00582 stream << endl 00583 << prefix + " Maximum: "; 00584 if (!stream) 00585 { 00586 throw(wns::Exception(errorString)); 00587 } 00588 if (maxValue_ == -DBL_MAX) 00589 { 00590 stream << "-infinity"; 00591 } 00592 else 00593 { 00594 stream << maxValue_; 00595 } 00596 if (!stream) 00597 { 00598 throw(wns::Exception(errorString)); 00599 } 00600 00601 00602 stream << endl 00603 << prefix + " Trials: " 00604 << numTrials_ 00605 << endl 00606 00607 00608 << prefix + " Mean: "; 00609 if (!stream) 00610 { 00611 throw(wns::Exception(errorString)); 00612 } 00613 if (mean() == DBL_MAX) 00614 { 00615 stream << "+infinity"; 00616 } 00617 else 00618 { 00619 stream << mean(); 00620 } 00621 if (!stream) 00622 { 00623 throw(wns::Exception(errorString)); 00624 } 00625 00626 00627 stream << endl << prefix << endl 00628 << prefix + " Variance: " 00629 << variance() 00630 << endl; 00631 00632 if (!stream) 00633 { 00634 throw(wns::Exception(errorString)); 00635 } 00636 00637 00638 stream << prefix + " Relative variance: " 00639 << relativeVariance() 00640 << endl; 00641 00642 if (!stream) 00643 { 00644 throw(wns::Exception(errorString)); 00645 } 00646 00647 00648 stream << prefix + " Coefficient of variation: " 00649 << coeffOfVariation() 00650 << endl; 00651 00652 if (!stream) 00653 { 00654 throw(wns::Exception(errorString)); 00655 } 00656 00657 00658 00659 stream << prefix + " Standard deviation: " 00660 << deviation() 00661 << endl; 00662 00663 if (!stream) 00664 { 00665 throw(wns::Exception(errorString)); 00666 } 00667 00668 00669 stream << prefix + " Relative standard deviation: " 00670 << relativeDeviation() 00671 << endl; 00672 00673 if (!stream) 00674 { 00675 throw(wns::Exception(errorString)); 00676 } 00677 00678 00679 stream << prefix << endl 00680 << prefix + " Skewness: " 00681 << skewness() 00682 << endl; 00683 00684 if (!stream) 00685 { 00686 throw(wns::Exception(errorString)); 00687 } 00688 00689 00690 stream << prefix << endl 00691 << prefix + " 2nd moment: " 00692 << M2() 00693 << endl; 00694 00695 if (!stream) 00696 { 00697 throw(wns::Exception(errorString)); 00698 } 00699 00700 00701 stream << prefix + " 3rd moment: " 00702 << M3() 00703 << endl; 00704 00705 if (!stream) 00706 { 00707 throw(wns::Exception(errorString)); 00708 } 00709 00710 00711 stream << prefix << endl 00712 << prefix + " Sum of all values: " 00713 << sum_ 00714 << endl; 00715 00716 if (!stream) 00717 { 00718 throw(wns::Exception(errorString)); 00719 } 00720 00721 00722 stream << prefix + " (Sum of all values)^2: " 00723 << squareSum_ 00724 << endl; 00725 00726 if (!stream) 00727 { 00728 throw(wns::Exception(errorString)); 00729 } 00730 00731 00732 stream << prefix + " (Sum of all values)^3: " 00733 << cubeSum_ 00734 << endl; 00735 00736 if (!stream) 00737 { 00738 throw(wns::Exception(errorString)); 00739 } 00740 00741 00742 } 00743
1.5.5