Stats.hpp

Go to the documentation of this file.
00001 #pragma ident "$Id: Stats.hpp 2254 2010-01-25 20:34:48Z btolman $"
00002 
00008 #ifndef INCLUDE_GPSTK_STATS_HPP
00009 #define INCLUDE_GPSTK_STATS_HPP
00010 
00011 //============================================================================
00012 //
00013 //  This file is part of GPSTk, the GPS Toolkit.
00014 //
00015 //  The GPSTk is free software; you can redistribute it and/or modify
00016 //  it under the terms of the GNU Lesser General Public License as published
00017 //  by the Free Software Foundation; either version 2.1 of the License, or
00018 //  any later version.
00019 //
00020 //  The GPSTk is distributed in the hope that it will be useful,
00021 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 //  GNU Lesser General Public License for more details.
00024 //
00025 //  You should have received a copy of the GNU Lesser General Public
00026 //  License along with GPSTk; if not, write to the Free Software Foundation,
00027 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028 //  
00029 //  Copyright 2004, The University of Texas at Austin
00030 //
00031 //============================================================================
00032 
00033 #include "MiscMath.hpp"
00034 #include "Vector.hpp"
00035 #include "Exception.hpp"
00036 
00037 namespace gpstk
00038 {
00041  
00049    template <class T>
00050    class Stats
00051    {
00052    public:
00054       explicit Stats() { n=0; weighted=false; }
00055 
00057       Stats(Vector<T>& X, Vector<T>& W)
00058       {
00059          n = 0;
00060          weighted = false;
00061          Add(X,W);
00062       }
00063 
00065       inline void Reset(void) { n=0; weighted=false; W=T(); }
00066 
00068       inline unsigned int N(void) const { return n; }
00069 
00071       inline T Minimum(void) const { if(n) return min; else return T(); }
00072 
00074       inline T Maximum(void) const { if(n) return max; else return T(); }
00075 
00077       inline T Average(void) const
00078       {
00079          if(n == 0) return T();
00080          return ave;
00081       }
00082 
00084       inline T Variance(void) const
00085       {
00086          if(n <= 1) return T();
00087          return (T(n)*var/T(n-1));
00088       }
00089 
00091       inline T StdDev(void) const
00092       {
00093          if(n <= 1) return T();
00094          return SQRT(Variance());
00095       }
00096 
00098       inline T Normalization(void) const { return W; }
00099 
00101       inline bool Weighted(void) const { return weighted; }
00102 
00104       void Add(const T& x, const T& wt_in=T())
00105       {
00106          T wt(ABS(wt_in));
00107          if(wt != T()) { weighted=true; }
00108 
00109          if(n == 0) {
00110             min = max = ave = x;
00111             var = T();
00112             W = T();
00113          }
00114          else {
00115             if(x < min) min=x;
00116             if(x > max) max=x;
00117          }
00118 
00119          if(weighted) {
00120             if(W+wt > T(1.e-10))     // if W+wt=0, nothing yet has had non-zero weight
00121                ave += (x-ave)*(wt/(W+wt));
00122             if(n > 0 && W > 1.e-10)
00123                var = (W/(W+wt))*var + (x-ave)*(x-ave)*(wt/W);
00124             W += wt;
00125          }
00126          else {
00127             ave += (x-ave)/T(n+1);
00128             if(n > 0)
00129                var = T(n)*var/T(n+1) + (x-ave)*(x-ave)/T(n);
00130          }
00131 
00132          n++;
00133       }
00134 
00137       inline void Add(Vector<T>& X, Vector<T> w = Vector<T>())
00138       {
00139          if(w.size() > 0 && w.size() < X.size()) {
00140             Exception e("Inconsistent input: weight vector short");
00141             GPSTK_THROW(e);
00142          }
00143 
00144          size_t i;
00145          if(w.size() > 0) 
00146             for(i=0; i<X.size(); i++) Add(X(i),w(i));
00147          else
00148             for(i=0; i<X.size(); i++) Add(X(i));
00149       }
00150 
00153       void Subtract(const T x, const T wt_in=T())
00154       {
00155          if(n == 0) return;
00156          if(weighted) {
00157             if(W > T(1.e-10)) {
00158                T wt(ABS(wt_in));
00159                if(W-wt > T(1.e-10))
00160                   var = (var - (wt/(W-wt))*(x-ave)*(x-ave)) * (W/(W-wt));
00161                else
00162                   var = T();
00163                ave = (ave - wt*x/W)*W/(W-wt);
00164                W -= wt;
00165             }
00166             else { ave = var = W = T(); }
00167          }
00168          else {
00169             if(n > 1)
00170                var = (var - (x-ave)*(x-ave)/T(n-1))*T(n)/(T(n)-T(1));
00171             else
00172                var = T();
00173             ave = T(n)*(ave - x/T(n))/(T(n)-T(1));
00174          }
00175          n--;
00176       }
00177 
00179       inline void Subtract(Vector<T>& X)
00180       {
00181          for(size_t i=0; i<X.size(); i++) Subtract(X(i));
00182       }
00183 
00186       void Load(unsigned int in_n, T in_min, T in_max, T in_ave, T in_var,
00187                   bool wtd=false, T norm=1.0)
00188       {
00189          n = in_n;
00190          min = in_min;
00191          max = in_max;
00192          var = in_var;
00193          ave = in_ave;
00194          weighted = wtd;
00195          W = norm;
00196       }
00197       
00201       Stats<T>& operator+=(const Stats<T>& S)
00202       {
00203          if(S.n == 0) return *this;
00204          if(n==0) { *this = S; return *this; }
00205          if((weighted && !S.weighted) || (!weighted && S.weighted)) {
00206             Exception e("Stats::operator+= : operands have inconsistent weighting");
00207             GPSTK_THROW(e);
00208          }
00209 
00210          if(S.min < min) min=S.min;
00211          if(S.max > max) max=S.max;
00212 
00213          T newave, newvar;
00214          if(weighted) {
00215             if(W + S.W > T(1.e-10)) {
00216                newave = W*ave + S.W*S.ave;
00217                newvar = W*var + S.W*S.var + W*ave*ave + S.W*S.ave*S.ave;
00218                W += S.W;
00219                ave = newave/W;
00220                //var = (newvar-W*ave*ave)/W;
00221                var = newvar/W -ave*ave;
00222             }
00223          }
00224          else {
00225             newave = T(n)*ave + T(S.n)*S.ave;
00226             newvar = T(n)*var + T(S.n)*S.var + T(n)*ave*ave + T(S.n)*S.ave*S.ave;
00227             ave = newave/T(n+S.n);
00228             //var = (newvar-T(n+S.n)*ave*ave)/T(n+S.n);
00229             var = newvar/T(n+S.n) - ave*ave;
00230          }
00231          n += S.n;
00232 
00233          return *this;
00234 
00235       }  // end Stats operator+=
00236 
00238 
00239    private:
00241       unsigned int n;
00242 
00244       T min;
00245 
00247       T max;
00248 
00250       T ave;
00251 
00253       T var;
00254 
00256       T W;
00257 
00259       bool weighted;
00260 
00261    }; // end class Stats
00262 
00264    template <class T>
00265    std::ostream& operator<<(std::ostream& s, const Stats<T>& ST) 
00266    {
00267       std::ofstream savefmt;
00268       savefmt.copyfmt(s);
00269       s << " N       = " << ST.N() << (ST.Weighted() ? " ":" not") << " weighted\n";
00270       s << " Minimum = "; s.copyfmt(savefmt); s << ST.Minimum();
00271       s << " Maximum = "; s.copyfmt(savefmt); s << ST.Maximum() << "\n";
00272       s << " Average = "; s.copyfmt(savefmt); s << ST.Average();
00273       s << " Std Dev = "; s.copyfmt(savefmt); s << ST.StdDev();
00274       s << " Variance = "; s.copyfmt(savefmt); s << ST.Variance(); // temp
00275       return s;
00276    }
00277 
00285    template <class T>
00286    class TwoSampleStats
00287    {
00288    public:
00290       TwoSampleStats() { n=0; }
00291 
00293       TwoSampleStats(Vector<T>& X, Vector<T>& Y)
00294       {
00295          n = 0;
00296          Add(X,Y);
00297       }
00298 
00300       void Add(const T& X, const T& Y)
00301       {
00302          if(n == 0) {
00303             sumx = sumy = sumx2 = sumy2 = sumxy = T();
00304             xmin = xmax = X;
00305             ymin = ymax = Y;
00306             scalex = scaley = T(1);
00307          }
00308          if(scalex==T(1) && X!=T()) scalex=ABS(X);
00309          if(scaley==T(1) && Y!=T()) scaley=ABS(Y);
00310          sumx += X/scalex;
00311          sumy += Y/scaley;
00312          sumx2 += (X/scalex)*(X/scalex);
00313          sumy2 += (Y/scaley)*(Y/scaley);
00314          sumxy += (X/scalex)*(Y/scaley);
00315          if(X < xmin) xmin=X;
00316          if(X > xmax) xmax=X;
00317          if(Y < ymin) ymin=Y;
00318          if(Y > ymax) ymax=Y;
00319          n++;
00320       }
00321 
00323       void Add(const Vector<T>& X, const Vector<T>& Y)
00324       {
00325          size_t m = (X.size() < Y.size() ? X.size() : Y.size());
00326          if(m==0) return;
00327          for(size_t i=0; i<m; i++) Add(X(i),Y(i));
00328       }
00329 
00330       void Subtract(const T& X, const T& Y)
00331       {
00332          if(n == 1) {
00333             sumx = sumy = sumx2 = sumy2 = sumxy = T();
00334             xmin = xmax = T();
00335             ymin = ymax = T();
00336             scalex = scaley = T(1);
00337             return;
00338          }
00339 
00340          sumx -= X/scalex;
00341          sumy -= Y/scaley;
00342          sumx2 -= (X/scalex)*(X/scalex);
00343          sumy2 -= (Y/scaley)*(Y/scaley);
00344          sumxy -= (X/scalex)*(Y/scaley);
00345          n--;
00346       }
00347 
00348       void Subtract(const Vector<T>& X, const Vector<T>& Y)
00349       {
00350          size_t m=(X.size()<Y.size()?X.size():Y.size());
00351          if(m==0) return;
00352          for(size_t i=0; i<m; i++) Subtract(X(i),Y(i));
00353       }
00354 
00356       inline void Reset(void) { n=0; }
00357 
00359       inline unsigned int N(void) const { return n; }
00361       inline T MinimumX(void) const { if(n) return xmin; else return T(); }
00363       inline T MaximumX(void) const { if(n) return xmax; else return T(); }
00365       inline T MinimumY(void) const { if(n) return ymin; else return T(); }
00367       inline T MaximumY(void) const { if(n) return ymax; else return T(); }
00368 
00370       inline T AverageX(void) const
00371          { if(n>0) return (scalex*sumx/T(n)); else return T(); }
00372 
00374       inline T AverageY(void) const
00375          { if(n>0) return (scaley*sumy/T(n)); else return T(); }
00376 
00378       inline T VarianceX(void) const
00379       {
00380          if(n>1) return scalex*scalex*(sumx2-sumx*sumx/T(n))/T(n-1);
00381          else return T();
00382       }
00383 
00385       inline T VarianceY(void) const
00386       {
00387          if(n>1) return scaley*scaley*(sumy2-sumy*sumy/T(n))/T(n-1);
00388          else return T();
00389       }
00390 
00392       inline T StdDevX(void) const { return SQRT(VarianceX()); }
00393 
00395       inline T StdDevY(void) const { return SQRT(VarianceY()); }
00396 
00398       inline T Slope(void) const
00399       {
00400          if(n>0)
00401             return ((scaley/scalex)*(sumxy-sumx*sumy/T(n))/(sumx2-sumx*sumx/T(n)));
00402          else
00403             return T();
00404       }
00405 
00407       inline T Intercept(void) const
00408       {
00409          if(n>0)
00410             return (AverageY()-Slope()*AverageX());
00411          else
00412             return T();
00413       }
00414 
00416       inline T SigmaSlope(void) const
00417       {
00418          if(n>2)
00419             return (SigmaYX()/(StdDevX()*SQRT(T(n-1))));
00420          else
00421             return T();
00422       }
00423 
00425       inline T Correlation(void) const
00426       {
00427          if(n>1)
00428          {
00429             return ( scalex * scaley * (sumxy-sumx*sumy/T(n))
00430                / (StdDevX()*StdDevY()*T(n-1)) );
00431          }
00432          else
00433             return T();
00434       }
00435 
00437       inline T SigmaYX(void) const
00438       {
00439          if(n>2)
00440          {
00441             return (StdDevY() * SQRT(T(n-1)/T(n-2))
00442                   * SQRT(T(1)-Correlation()*Correlation()) );
00443          }
00444          else return T();
00445       }
00446 
00450       TwoSampleStats<T>& operator+=(TwoSampleStats<T>& S)
00451       {
00452          if(n + S.n == 0) return *this;
00453          if(S.xmin < xmin) xmin=S.xmin;
00454          if(S.xmax > xmax) xmax=S.xmax;
00455          if(S.ymin < ymin) ymin=S.ymin;
00456          if(S.ymax > ymax) ymax=S.ymax;
00457          sumx += S.scalex*S.sumx/scalex;
00458          sumy += S.scaley*S.sumy/scaley;
00459          sumx2 += (S.scalex/scalex)*(S.scalex/scalex)*S.sumx2;
00460          sumy2 += (S.scaley/scaley)*(S.scaley/scaley)*S.sumy2;
00461          sumxy += (S.scalex/scalex)*(S.scaley/scaley)*S.sumxy;
00462          n += S.n;
00463          return *this;
00464       }  // end TwoSampleStats operator+=
00465 
00466    private:
00468       unsigned int n;
00469       T xmin, xmax, ymin, ymax, scalex, scaley;
00470       T sumx, sumy, sumx2, sumy2, sumxy;
00471 
00472    }; // end class TwoSampleStats
00473 
00475    template <class T>
00476    std::ostream& operator<<(std::ostream& s, const TwoSampleStats<T>& TSS) 
00477    {
00478       std::ofstream savefmt;
00479       savefmt.copyfmt(s);
00480       s << " N           = " << TSS.N() << "\n";
00481       s << " Minimum:  X = "; s.copyfmt(savefmt); s << TSS.MinimumX();
00482       s << "  Y = "; s.copyfmt(savefmt); s << TSS.MinimumY() << "\n";
00483       s << " Maximum:  X = "; s.copyfmt(savefmt); s << TSS.MaximumX();
00484       s << "  Y = "; s.copyfmt(savefmt); s << TSS.MaximumY() << "\n";
00485       s << " Average:  X = "; s.copyfmt(savefmt); s << TSS.AverageX();
00486       s << "  Y = "; s.copyfmt(savefmt); s << TSS.AverageY() << "\n";
00487       s << " Std Dev:  X = "; s.copyfmt(savefmt); s << TSS.StdDevX();
00488       s << "  Y = "; s.copyfmt(savefmt); s << TSS.StdDevY() << "\n";
00489       s << " Variance: X = "; s.copyfmt(savefmt); s << TSS.VarianceX();
00490       s << "  Y = "; s.copyfmt(savefmt); s << TSS.VarianceY() << "\n";
00491       s << " Intercept = "; s.copyfmt(savefmt); s << TSS.Intercept();
00492       s << "  Slope = "; s.copyfmt(savefmt); s << TSS.Slope();
00493       s << " with uncertainty = "; s.copyfmt(savefmt); s << TSS.SigmaSlope() << "\n";
00494       s << " Conditional uncertainty (sigma y given x) = ";
00495       s.copyfmt(savefmt); s << TSS.SigmaYX();
00496       s << "  Correlation = "; s.copyfmt(savefmt); s << TSS.Correlation();
00497       return s;
00498    }
00499 
00501    template <class T>
00502    inline T median(const Vector<T>& v)
00503    {
00504       if(v.size()==0) return T();
00505       if(v.size()==1) return v(0);
00506       if(v.size()==2) return (v(0)+v(1))/T(2);
00507       // insert sort
00508       int i,j;
00509       T x;
00510       Vector<T> w(v);
00511       for(i=0; i<v.size(); i++) {
00512          x = w[i] = v(i);
00513          j = i-1;
00514          while(j>=0 && x<w[j]) {
00515             w[j+1] = w[j];
00516             j--;
00517          }
00518          w[j+1] = x;
00519       }
00520       if(v.size() % 2)
00521          x=w[(v.size()+1)/2-1];
00522       else
00523          x=(w[v.size()/2-1]+w[v.size()/2])/T(2);
00524 
00525       return x;
00526    }  // end median(Vector)
00527 
00529    template <class T>
00530    inline T median(const std::vector<T>& v)
00531    {
00532       if(v.size()==0) return T();
00533       if(v.size()==1) return v[0];
00534       if(v.size()==2) return (v[0]+v[1])/T(2);
00535       // insert sort
00536       int i,j;
00537       T x;
00538       std::vector<T> w(v);
00539       for(i=0; i<v.size(); i++) {
00540          x = w[i] = v[i];
00541          j = i-1;
00542          while(j>=0 && x<w[j]) {
00543             w[j+1] = w[j];
00544             j--;
00545          }
00546          w[j+1] = x;
00547       }
00548       if(v.size() % 2)
00549          x=w[(v.size()+1)/2-1];
00550       else
00551          x=(w[v.size()/2-1]+w[v.size()/2])/T(2);
00552 
00553       return x;
00554    }  // end median(Vector)
00555 
00557 
00558 }  // namespace
00559 
00560 #endif

Generated on Thu Sep 9 03:30:56 2010 for GPS ToolKit Software Library by  doxygen 1.3.9.1