Scythe-1.0.3
stat.h
Go to the documentation of this file.
00001 /* 
00002  * Scythe Statistical Library Copyright (C) 2000-2002 Andrew D. Martin
00003  * and Kevin M. Quinn; 2002-present Andrew D. Martin, Kevin M. Quinn,
00004  * and Daniel Pemstein.  All Rights Reserved.
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify under the terms of the GNU General Public License as
00008  * published by Free Software Foundation; either version 2 of the
00009  * License, or (at your option) any later version.  See the text files
00010  * COPYING and LICENSE, distributed with this source code, for further
00011  * information.
00012  * --------------------------------------------------------------------
00013  *  scythestat/stat.h
00014  *
00015  */
00016 
00028 #ifndef SCYTHE_STAT_H
00029 #define SCYTHE_STAT_H
00030 
00031 #ifdef SCYTHE_COMPILE_DIRECT
00032 #include "matrix.h"
00033 #include "algorithm.h"
00034 #include "error.h"
00035 #else
00036 #include "scythestat/matrix.h"
00037 #include "scythestat/algorithm.h"
00038 #include "scythestat/error.h"
00039 #endif
00040 
00041 #include <numeric>
00042 #include <set>
00043 
00044 
00045 namespace scythe {
00046 
00047   namespace {
00048     typedef unsigned int uint;
00049   }
00050 
00051 /* A macro for defining column versions of a function.  That is,
00052  * when expanded, this macro produces general and default template
00053  * functions that compute function NAME on each column in a matrix and
00054  * return a row vector with the results.  We use this to generate
00055  * column versions of every function in this header file.
00056  */
00057 #define SCYTHE_STATMETH_COL(NAME)                                     \
00058   template <matrix_order RO, matrix_style RS, typename T,             \
00059             matrix_order PO, matrix_style PS>                         \
00060   Matrix<T,RO,RS>                                                     \
00061   NAME ## c (const Matrix<T,PO,PS>& A)                                \
00062   {                                                                   \
00063     Matrix<T,RO,RS> res (1, A.cols(), false);                         \
00064                                                                       \
00065     for (uint j = 0; j < A.cols(); ++j)                               \
00066       res[j] = NAME(A(_, j));                                         \
00067                                                                       \
00068     return res;                                                       \
00069   }                                                                   \
00070                                                                       \
00071   template <typename T, matrix_order O, matrix_style S>               \
00072   Matrix<T,O,Concrete>                                                \
00073   NAME ## c (const Matrix<T,O,S>& A)                                  \
00074   {                                                                   \
00075     return NAME ## c<O,Concrete>(A);                                  \
00076   }         
00077 
00078 
00079   /* Calculate the sum of a Matrix */
00080   
00095   template <typename T, matrix_order PO, matrix_style PS>
00096   T
00097   sum (const Matrix<T,PO,PS> &A)
00098   {
00099     return (std::accumulate(A.begin_f(), A.end_f(), (T) 0));
00100   }
00101 
00102   /* Calculate the sum of each column in a Matrix */
00103    
00118   SCYTHE_STATMETH_COL(sum)
00119   
00120   /* Calculate the product of a Matrix */
00121   
00122    
00135   template <typename T, matrix_order PO, matrix_style PS>
00136   T
00137   prod (const Matrix<T,PO,PS> &A)
00138   {
00139     return std::accumulate(A.begin_f(), A.end_f(), (T) 1, 
00140                            std::multiplies<T> ());
00141   }
00142 
00143   /* Calculate the product of each column of a matrix */
00144   
00159   SCYTHE_STATMETH_COL(prod)
00160   
00161   /* Calculate the mean of a Matrix */
00162     
00163    
00178   template <typename T, matrix_order PO, matrix_style PS>
00179   T
00180   mean (const Matrix<T,PO,PS> &A)
00181   {
00182     return (std::accumulate(A.begin_f(), A.end_f(), (T) 0) / A.size());
00183   }
00184 
00185   /* Calculate the mean of each column of a Matrix */
00186   
00203   SCYTHE_STATMETH_COL(mean)
00204   
00205   /* Calculate the median of a matrix.  Uses a sort but I'll implement
00206    * the randomized alg when I figure out how to generalize it to
00207    * even-length lists
00208    */
00209    
00210    
00223   template <typename T, matrix_order PO, matrix_style PS>
00224   T
00225   median (const Matrix<T,PO,PS> &A)
00226   {
00227     Matrix<T, PO, Concrete> temp(A);
00228     uint n = temp.size();
00229 
00230     sort(temp.begin(), temp.end());
00231     if (n % 2 == 0)
00232       return ((temp[n / 2] + temp[n / 2 - 1]) / 2);
00233     else
00234       return temp[(uint) ::floor(n / 2)];
00235   }
00236 
00237   /* Calculate the median of each column of a matrix */
00238   
00253   SCYTHE_STATMETH_COL(median)
00254 
00255   /* Calculate the mode of a matrix */
00256   
00257    
00270   template <typename T, matrix_order PO, matrix_style PS>
00271   T
00272   mode (const Matrix<T,PO,PS> &A)
00273   {
00274     Matrix<T, PO, Concrete> temp(A);
00275     
00276     sort(temp.begin(), temp.end());
00277 
00278     T last = temp[0];
00279     uint cnt = 1;
00280     T cur_max = temp[0];
00281     uint max_cnt = 1;
00282     
00283     for (uint i = 1; i < temp.size(); ++i) {
00284       if (last == temp[i]) {
00285         ++cnt;
00286       } else {
00287         last = temp[i];
00288         cnt = 1;
00289       }
00290       if (cnt > max_cnt) {
00291         max_cnt = cnt;
00292         cur_max = temp[i];
00293       }
00294     }
00295 
00296     return cur_max;
00297   }
00298 
00313   SCYTHE_STATMETH_COL(mode)
00314 
00315   /* Calculate the variance of a Matrix */
00316 
00317   /* A functor that encapsulates a single variance calculation step.
00318    * Also used by skew and kurtosis. */
00319   namespace {
00320     template <typename T, typename T2>
00321     struct var_step : std::binary_function<T, T, T>
00322     {
00323       T constant_;
00324       T2 divisor_;
00325       T exponent_;
00326       var_step (T c, T2 d, T e) : constant_ (c), divisor_ (d),
00327                                     exponent_ (e) {}
00328       T operator() (T last, T x) const
00329       {
00330         return (last + std::pow(constant_ - x, exponent_) / divisor_);
00331       }
00332     };
00333   }
00334   
00347   template <typename T, matrix_order PO, matrix_style PS>
00348   T
00349   var (const Matrix<T,PO,PS> &A)
00350   {
00351     return var(A, mean(A));
00352   }
00353 
00354   /* Calculate the variances of each column of a Matrix. */
00355   
00369   SCYTHE_STATMETH_COL(var)
00370 
00371  
00385   template <typename T, matrix_order PO, matrix_style PS>
00386   T
00387   var (const Matrix<T,PO,PS> &A, T mu)
00388   {
00389     return std::accumulate(A.begin_f(), A.end_f(), (T) 0, 
00390                          var_step<T, uint> (mu, A.size() - 1, 2));
00391   }
00392   
00393   /* Calculate the standard deviation of a Matrix (not std cause of namespace std:: */
00394   
00408   template <typename T, matrix_order PO, matrix_style PS>
00409   T
00410   sd (const Matrix<T,PO,PS> &A)
00411   {
00412     return std::sqrt(var(A));
00413   }
00414   
00415   /* Calculate the standard deviation of each column of a Matrix */
00428   SCYTHE_STATMETH_COL(sd)
00429 
00430   
00444   template <typename T, matrix_order PO, matrix_style PS>
00445   T
00446   sd (const Matrix<T,PO,PS> &A, T mu)
00447   {
00448     return std::sqrt(var(A, mu));
00449   }
00450 
00451   /* Calculate the skew of a Matrix */
00452 
00464   template <typename T, matrix_order PO, matrix_style PS>
00465   T
00466   skew (const Matrix<T,PO,PS> &A)
00467   {
00468     T mu = mean(A);
00469     T sde = sd(A, mu);
00470     return std::accumulate(A.begin_f(), A.end_f(), (T) 0, 
00471               var_step<T, T> (mu, A.size() * std::pow(sde, 3), 3));
00472   }
00473 
00474   /* Calculate the skew of each column of a Matrix. */
00475   
00487   SCYTHE_STATMETH_COL(skew)
00488   
00489   /* Calculate the kurtosis of a Matrix */
00490     
00491    
00501   template <typename T, matrix_order PO, matrix_style PS>
00502   T
00503   kurtosis (const Matrix<T,PO,PS> &A)
00504   {
00505     T mu = mean(A);
00506     T sde = sd(A, mu);
00507     return (std::accumulate(A.begin_f(), A.end_f(), (T) 0, 
00508               var_step<T, T> (mu, A.size() * std::pow(sde, 4), 4))
00509             - 3);
00510   }
00511   
00512   /* Calculate the kurtosis of each column of a Matrix. */
00513   
00525   SCYTHE_STATMETH_COL(kurtosis)
00526 
00527   /* Calculates the maximum element in a Matrix */
00540   template <typename T, matrix_order PO, matrix_style PS>
00541   T
00542   max (const Matrix<T,PO,PS> &A)
00543   {
00544     return *(max_element(A.begin_f(), A.end_f()));
00545   }
00546 
00558   SCYTHE_STATMETH_COL(max)
00559 
00560   /* Calculates the minimum element in a Matrix */
00561   
00562   
00572   template <typename T, matrix_order PO, matrix_style PS>
00573   T
00574   min (const Matrix<T,PO,PS> &A)
00575   {
00576     return *(min_element(A.begin_f(), A.end_f()));
00577   }
00578   
00590   SCYTHE_STATMETH_COL(min)
00591 
00592   /* Find the index of the max element */  
00593   
00605   template <typename T, matrix_order PO, matrix_style PS>
00606   unsigned int
00607   maxind (const Matrix<T,PO,PS> &A)
00608   {
00609     return (max_element(A.begin_f(), A.end_f())).get_index();
00610   }
00611   
00623   SCYTHE_STATMETH_COL(maxind)
00624   
00625   /* Find the index of the min element */
00626   
00627   
00638   template <typename T, matrix_order PO, matrix_style PS>
00639   unsigned int
00640   minind (const Matrix<T,PO,PS> &A)
00641   {
00642     return (min_element(A.begin_f(), A.end_f())).get_index();
00643   }
00644 
00655   SCYTHE_STATMETH_COL(minind)
00656 
00657 } // end namespace scythe
00658 
00659 
00660 #endif /* SCYTHE_STAT_H */