00001 /// 00002 /// \file statistics.cpp 00003 /// \brief Classes for descriptive statistics 00004 /// 00005 /// This 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 2005-05-18 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 // local includes 00035 #include "mcmc++/statistics.h" 00036 00037 /// \class Statistic 00038 /// \brief Implements a class for summary statistics. 00039 /// 00040 /// The Statistic class allows easy calculation of summary statistics. 00041 /// When applied to ratio data the mean is the ratio of the means, and the 00042 /// variance is calculated from the ratio of the sums of squares. 00043 /// Specifically, let 00044 /// \f[ s = \frac{\sum_i x_{i,top}}{\sum_i x_{i,bottom}} \f] 00045 /// \f[ ss = \frac{\sum_i x_{i,top}^2}{\sum_i x_{i,bottom}^2} \f] 00046 /// then Mean() returns 00047 /// \f[ s/n \f] 00048 /// and Variance() returns 00049 /// \f[ (ss - (s*s)/n)/(n-1) \f] 00050 /// 00051 /// Example: 00052 /// 00053 /// \code 00054 /// Statistic stat; 00055 /// stat.Add(1.0); 00056 /// stat.Add(2.0); 00057 /// stat.Add(3.0); 00058 /// stat.Add(4.0); 00059 /// stat.Add(5.0); 00060 /// long n = stat.N(); // n = 5 00061 /// double mean = stat.Mean(); // mean = 3.000 00062 /// double variance = stat.Variance(); // variance = 2.500 00063 /// double stddev = stat.StdDev(); // stddev = 1.581 00064 /// double cv = stat.CV(); // cv = 0.527 00065 /// \endcode 00066 /// 00067 00068 /// Constructor 00069 /// 00070 /// The constructor for statistic simply initializes all internal 00071 /// values in preparation for calculating statistics. After initializtion, 00072 /// data is added with Add(). 00073 /// 00074 Statistic::Statistic(void) 00075 : sum(0.0), lsum(0.0), sumSq(0.0), lsumSq(0.0), mean(0.0), 00076 variance(0.0), stddev(0.0), cv(0.0), n(0L), dirty(0) 00077 {} 00078 00079 void 00080 Statistic::CalcMean(void) { 00081 if (lsum > 0.0) { 00082 mean = sum/lsum; 00083 } else { 00084 mean = sum/static_cast<double>(n); 00085 } 00086 } 00087 00088 void 00089 Statistic::CalcVariance(void) { 00090 double s = sum; 00091 double ss = sumSq; 00092 00093 if (lsum > 0.0) { 00094 s /= lsum; 00095 s *= static_cast<double>(n); 00096 ss /= lsumSq; 00097 ss *= static_cast<double>(n); 00098 } 00099 variance = (ss - s*s/static_cast<double>(n))/static_cast<double>(n - 1); 00100 } 00101 00102 void 00103 Statistic::CalcAll(void) { 00104 if (dirty && n > 0) 00105 CalcMean(); 00106 if (dirty && n > 1) { 00107 CalcMean(); 00108 CalcVariance(); 00109 CalcStdDev(); 00110 CalcCV(); 00111 } 00112 dirty = 0; 00113 } 00114 00115 /// Returns arithmetic mean of the data. 00116 /// 00117 double 00118 Statistic::Mean(void) { 00119 CalcAll(); 00120 return mean; 00121 } 00122 00123 /// Returns variance of the data. 00124 /// 00125 double 00126 Statistic::Variance(void) { 00127 CalcAll(); 00128 return variance; 00129 } 00130 00131 /// Returns standard deviation of the data. 00132 /// 00133 double 00134 Statistic::StdDev() { 00135 CalcAll(); 00136 return stddev; 00137 } 00138 00139 /// Returns coefficient of variation of the data. 00140 /// 00141 double 00142 Statistic::CV() { 00143 CalcAll(); 00144 return cv; 00145 } 00146 00147 /// Add a double value to the statistic. 00148 /// 00149 /// \param v The value to add 00150 /// 00151 void 00152 Statistic::Add(const double v) { 00153 sum += v; 00154 sumSq += v * v; 00155 n++; 00156 dirty = 1; 00157 } 00158 00159 /// Add a ratio to the statistic. 00160 /// 00161 /// \param r The ratio to add 00162 /// 00163 void 00164 Statistic::Add(const ratio r) { 00165 sum += r.Top(); 00166 lsum += r.Bottom(); 00167 sumSq += r.Top() * r.Top(); 00168 lsumSq += r.Bottom() * r.Bottom(); 00169 n++; 00170 dirty = 1; 00171 } 00172 00173 /// Add a double value to the statistic 00174 /// 00175 /// \param v The value to add 00176 /// 00177 Statistic& Statistic::operator +=(const double v) { 00178 Add(v); 00179 return *this; 00180 } 00181 00182 /// Add a ratio to the statistic. 00183 /// 00184 /// \param r The ratio to add 00185 /// 00186 Statistic& 00187 Statistic::operator +=(const ratio r) { 00188 Add(r); 00189 return *this; 00190 } 00191 00192 /// Stream output for Statistic. 00193 /// 00194 /// Reports sample size, mean, variance, standard deviation, and 00195 /// coefficient of variation, each preceded by a tab and appearing 00196 /// on a new line. 00197 /// 00198 /// \param out The output stream 00199 /// \param st The statistics 00200 /// 00201 std::ostream& 00202 operator <<(std::ostream& out, Statistic& st) { 00203 out << "\n\tN = " << st.N(); 00204 out << "\n\tmean = " << st.Mean(); 00205 out << "\n\tvariance = " << st.Variance(); 00206 out << "\n\tstd. dev. = " << st.StdDev(); 00207 out << "\n\tCV = " << st.CV(); 00208 return out; 00209 } 00210 00211 00212 /// \class SimpleStatistic 00213 /// \brief Implements a class for summary statistics. 00214 /// 00215 /// The SimpleStatistic class allows easy calculation of simple summary 00216 /// statistics. Unlike Statistic, it cannot be applied to ratio data. In 00217 /// addition to adding single values, with Add(), an entire vector of 00218 /// values can be added in the constructor. 00219 /// 00220 /// Example: 00221 /// 00222 /// \code 00223 /// SimpleStatistic stat; 00224 /// stat.Add(1.0); 00225 /// stat.Add(2.0); 00226 /// stat.Add(3.0); 00227 /// stat.Add(4.0); 00228 /// stat.Add(5.0); 00229 /// double mean = stat.Mean(); // mean = 3.000 00230 /// double variance = stat.Variance(); // variance = 2.500 00231 /// double stddev = stat.StdDev(); // stddev = 1.581 00232 /// stat.Clear(); // clears internal data for new calculation 00233 /// 00234 /// vector<double> x(5); 00235 /// for (int i = 0; i < 5; ++i) { 00236 /// x[i] = i; 00237 /// } 00238 /// SimpleStatistic vecStat(x); 00239 /// double mean = stat.Mean(); // mean = 3.000 00240 /// double variance = stat.Variance(); // variance = 2.500 00241 /// double stddev = stat.StdDev(); // stddev = 1.581 00242 /// \endcode 00243 /// 00244 00245 /// Default constructor. 00246 /// 00247 /// The default constructor simply initializes the internal data. 00248 /// After initializaiton, data is added with Add(). 00249 /// 00250 SimpleStatistic::SimpleStatistic(void) 00251 : sum_(0.0), sumsq_(0.0), n_(0) 00252 {} 00253 00254 /// Add a double value to the statistic. 00255 /// 00256 /// \param x Value to add 00257 /// 00258 void 00259 SimpleStatistic::Add(const double x) { 00260 sum_ += x; 00261 sumsq_ += sqr(x); 00262 n_++; 00263 } 00264 00265 /// Returns mean of the data. 00266 /// 00267 double 00268 SimpleStatistic::Mean(void) const { 00269 return sum_/n_; 00270 } 00271 00272 /// Returns variance of the data. 00273 /// 00274 double 00275 SimpleStatistic::Variance(void) const { 00276 return (sumsq_ - sqr(sum_)/n_)/(n_ - 1.0); 00277 } 00278 00279 /// Returns standard deviation of the data. 00280 /// 00281 double 00282 SimpleStatistic::StdDev(void) const { 00283 return sqrt(Variance()); 00284 } 00285 00286 /// Re-initializes internal data for new calculations. 00287 /// 00288 void 00289 SimpleStatistic::Clear(void) { 00290 sum_ = sumsq_ = 0.0; 00291 n_ = 0; 00292 } 00293 00294 double 00295 SimpleStatistic::sqr(const double x) const { 00296 return x*x; 00297 } 00298 00299 00300 00301 00302 00303 00304
1.5.1