statistics.h

Go to the documentation of this file.
00001 ///
00002 /// \file  statistics.h
00003 /// \brief Classes for descriptive statistics
00004 ///
00005 /// This header file provides two statistical classes: Statistic and
00006 /// SimpleStatistic. As the names suggest, Statistic is more complete. It 
00007 /// includes methods for standard deviation and coefficient of variation
00008 /// as well as mean and variance. It can also calculate statistics on 
00009 /// ratios (using ratio.h)
00010 ///
00011 /// \author Kent Holsinger
00012 /// \date   2004-06-26
00013 ///
00014 
00015 // This file is part of MCMC++, a library for constructing C++ programs
00016 // that implement MCMC analyses of Bayesian statistical models.
00017 // Copyright (c) 2004-2006 Kent E. Holsinger
00018 //
00019 // MCMC++ is free software; you can redistribute it and/or modify
00020 // it under the terms of the GNU General Public License as published by
00021 // the Free Software Foundation; either version 2 of the License, or
00022 // (at your option) any later version.
00023 //
00024 // MCMC++ is distributed in the hope that it will be useful,
00025 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027 // GNU General Public License for more details.
00028 //
00029 // You should have received a copy of the GNU General Public License
00030 // along with MCMC++; if not, write to the Free Software
00031 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00032 //
00033 
00034 #if !defined(__STATISTI_H)
00035 #define __STATISTI_H
00036 
00037 // standard includes
00038 #include <iostream>
00039 // boost includes
00040 #include <boost/type_traits.hpp>
00041 // local includes
00042 #include "mcmc++/ratio.h"
00043 
00044 
00045 namespace keh { // to make sure that we avoid collisions
00046 
00047   /// Base template for Accumulate (used only for definition
00048   ///
00049   template <bool U, class T>
00050   class Accumulate;
00051   
00052   /// Designed for use with a vector<T>, where a method in T is called
00053   /// before this constructor to provide an implementation of operator* that
00054   /// returns an appropriate member from T (one that can be converted via
00055   /// default conversions to a double)
00056   ///
00057   template <class T>
00058   class Accumulate<false, T> {
00059   public:
00060     /// Constructor
00061     ///
00062     /// \param x     vector of values
00063     /// \param sum   sum of values
00064     /// \param sumsq sum of squared values
00065     /// \param n     number of values, i.e., length of the vector
00066     ///
00067     /// The constructor is useful because of its side effects, namely 
00068     /// sum, sumsq, and n are adjusted and are accesible from the calling
00069     /// function
00070     ///
00071     Accumulate(std::vector<T>& x, double& sum, double& sumsq, 
00072                unsigned long& n)
00073     {
00074       sum = sumsq = 0.0;
00075       typedef typename std::vector<T>::const_iterator iter;
00076       iter begin = x.begin();
00077       iter end = x.end();
00078       for (iter i = begin; i != end; ++i) {
00079         double value = **i;
00080         sum += value;
00081         sumsq += sqr(value);
00082       }
00083       n = x.size();
00084     }
00085   private:
00086     static double sqr(const double x) {
00087       return x*x;
00088     }
00089   };
00090   
00091   /// Specialization of Accumulate for arithmetic types
00092   ///
00093   template <class T>
00094   class Accumulate<true, T> {
00095   public:
00096     /// Constructor
00097     ///
00098     /// \param x     vector of values
00099     /// \param sum   sum of values
00100     /// \param sumsq sum of squared values
00101     /// \param n     number of values, i.e., length of the vector
00102     ///
00103     /// The constructor is useful because of its side effects, namely 
00104     /// sum, sumsq, and n are adjusted and are accesible from the calling
00105     /// function
00106     ///
00107     Accumulate(std::vector<T>& x, double& sum, double& sumsq, 
00108                unsigned long& n) 
00109     {
00110       n = x.size();
00111       sum = sumsq = 0.0;
00112       typedef typename std::vector<T>::const_iterator iter;
00113       iter end = x.end();
00114       for (iter i = x.begin(); i != end; ++i) {
00115         double value = *i;
00116         sum += value;
00117         sumsq += sqr(value);
00118       }
00119     }
00120   private:
00121     static double sqr(const double x) {
00122       return x*x;
00123     }
00124 
00125   };
00126 
00127 } // end of namespace keh
00128 
00129 class Statistic {
00130   double sum;
00131   double lsum; // lower sum used only for ratios
00132   double sumSq;
00133   double lsumSq; // lower sum of squares used only for ratios
00134   double mean;
00135   double variance;
00136   double stddev;
00137   double cv;
00138   long n;
00139   int dirty;
00140   void CalcMean(void);
00141   void CalcVariance(void);
00142   void CalcStdDev(void) {
00143     stddev = (variance <= 0.0 ? 0.0 : sqrt(variance));
00144   }
00145   void CalcCV(void) {
00146     cv = (mean == 0.0 ? 0.0 : stddev/mean);
00147   }
00148   void CalcAll(void);
00149 
00150 public:
00151   Statistic(void);
00152   void Add(double);
00153   void Add(ratio);
00154   /// returns sample size
00155   ///
00156   long N(void) {
00157     return n;
00158   }
00159   /// returns sum of sample values
00160   ///
00161   double Sum(void) {
00162     return sum;
00163   }
00164   /// returns sum of squared sample values
00165   ///
00166   double SumSq(void) {
00167     return sumSq;
00168   }
00169   double Mean(void);
00170   double Variance(void);
00171   double StdDev(void);
00172   double CV(void);
00173   Statistic& operator +=(double v);
00174   Statistic& operator +=(ratio r);
00175   friend std::ostream& operator <<(std::ostream&, Statistic&);
00176 };
00177 
00178 class SimpleStatistic {
00179 public:
00180   SimpleStatistic(void);
00181 
00182   /// Constructor -- initialize with a vector.
00183   ///
00184   /// May be used with any vector having an iterator that can produce a
00185   /// double. This may be a simple vector<double> (or any other vector 
00186   /// whose elements can be converted to double by default conversions,
00187   /// but it could also be a vector<T>, where a method in T is called 
00188   /// before this constructor to provide an implementation of operator* 
00189   /// that returns an appropriate member from T (one that can be converted 
00190   /// via default conversions to a double).
00191   ///
00192   /// \param x   The vector to use in calculations
00193   ///
00194   template <class T>
00195   SimpleStatistic(std::vector<T>& x) {
00196     keh::Accumulate<boost::is_arithmetic<T>::value, T> 
00197       stats(x, sum_, sumsq_, n_);
00198   }
00199   void Add(double x);
00200   double Mean(void) const;
00201   double Variance(void) const;
00202   double StdDev(void) const;
00203   void Clear(void);
00204 
00205 private:
00206   double sqr(const double x) const;
00207 
00208   double sum_;
00209   double sumsq_;
00210   unsigned long n_;
00211 
00212 };
00213 
00214 #endif
00215 
00216 // Local Variables: //
00217 // mode: c++ //
00218 // End: //

Generated on Tue Mar 27 16:03:38 2007 for mcmc by  doxygen 1.5.1