User Manual, Developers Guide and API Documentation

pdf.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. 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 

Generated on Sun May 27 03:31:39 2012 for openWNS by  doxygen 1.5.5