running_stat_meat.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2009 NICTA
00002 // 
00003 // Authors:
00004 // - Conrad Sanderson (conradsand at ieee dot org)
00005 // 
00006 // This file is part of the Armadillo C++ library.
00007 // It is provided without any warranty of fitness
00008 // for any purpose. You can redistribute this file
00009 // and/or modify it under the terms of the GNU
00010 // Lesser General Public License (LGPL) as published
00011 // by the Free Software Foundation, either version 3
00012 // of the License or (at your option) any later version.
00013 // (see http://www.opensource.org/licenses for more info)
00014 
00015 
00016 //! \addtogroup running_stat
00017 //! @{
00018 
00019 
00020 
00021 template<typename eT>
00022 inline
00023 arma_counter<eT>::~arma_counter()
00024   {
00025   arma_extra_debug_sigprint_this(this);
00026   }
00027 
00028 
00029 
00030 template<typename eT>
00031 inline
00032 arma_counter<eT>::arma_counter()
00033   : d_count( eT(0))
00034   , i_count(u32(0))
00035   {
00036   arma_extra_debug_sigprint_this(this);
00037   }
00038 
00039 
00040 
00041 template<typename eT>
00042 inline
00043 const arma_counter<eT>& 
00044 arma_counter<eT>::operator++()
00045   {
00046   const u32 max_val = 0xffffffff;
00047   
00048   if(i_count < max_val)
00049     {
00050     i_count++;
00051     }
00052   else
00053     {
00054     d_count += eT(max_val);
00055     i_count =  1;
00056     }
00057   
00058   return *this;
00059   }
00060 
00061 
00062 
00063 template<typename eT>
00064 inline
00065 void
00066 arma_counter<eT>::operator++(int)
00067   {
00068   operator++();
00069   }
00070 
00071 
00072 
00073 template<typename eT>
00074 inline
00075 void
00076 arma_counter<eT>::reset()
00077   {
00078   d_count =  eT(0);
00079   i_count = u32(0);
00080   }
00081 
00082 
00083 
00084 template<typename eT>
00085 inline
00086 eT
00087 arma_counter<eT>::value()
00088 const
00089   {
00090   return d_count + eT(i_count);
00091   }
00092 
00093 
00094 
00095 template<typename eT>
00096 inline
00097 eT
00098 arma_counter<eT>::value_plus_1()
00099 const
00100   {
00101   const u32 max_val = 0xffffffff;
00102   
00103   if(i_count < max_val)
00104     {
00105     return d_count + eT(i_count + 1);
00106     }
00107   else
00108     {
00109     return d_count + eT(max_val) + eT(1);
00110     }
00111   }
00112 
00113 
00114 
00115 template<typename eT>
00116 inline
00117 eT
00118 arma_counter<eT>::value_minus_1()
00119 const
00120   {
00121   if(i_count > 0)
00122     {
00123     return d_count + eT(i_count - 1);
00124     }
00125   else
00126     {
00127     return d_count - eT(1);
00128     }
00129   }
00130 
00131 
00132 
00133 //
00134 
00135 
00136 
00137 template<typename eT>
00138 running_stat<eT>::~running_stat()
00139   {
00140   arma_extra_debug_sigprint_this(this);
00141   }
00142 
00143 
00144 
00145 template<typename eT>
00146 running_stat<eT>::running_stat()
00147   : r_mean      (                          eT(0))
00148   , r_var       (typename running_stat<eT>::T(0))
00149   , min_val     (                          eT(0))
00150   , max_val     (                          eT(0))
00151   , min_val_norm(typename running_stat<eT>::T(0))
00152   , max_val_norm(typename running_stat<eT>::T(0))
00153   {
00154   arma_extra_debug_sigprint_this(this);
00155   }
00156 
00157 
00158 
00159 //! update statistics to reflect new sample
00160 template<typename eT>
00161 inline
00162 void
00163 running_stat<eT>::operator() (const typename running_stat<eT>::T sample)
00164   {
00165   arma_extra_debug_sigprint();
00166   
00167   arma_check( (arma_isfinite(sample) == false), "running_stat: non-finite sample given" );
00168 
00169   running_stat_aux::update_stats(*this, sample);
00170   }
00171 
00172 
00173 
00174 //! update statistics to reflect new sample (version for complex numbers)
00175 template<typename eT>
00176 inline
00177 void
00178 running_stat<eT>::operator() (const std::complex< typename running_stat<eT>::T >& sample)
00179   {
00180   arma_extra_debug_sigprint();
00181   
00182   isnt_same_type<eT, std::complex< typename running_stat<eT>::T > >::check();
00183   
00184   arma_check( (arma_isfinite(sample) == false), "running_stat: non-finite sample given" );
00185   
00186   running_stat_aux::update_stats(*this, sample);
00187   }
00188 
00189 
00190 
00191 //! set all statistics to zero
00192 template<typename eT>
00193 inline
00194 void
00195 running_stat<eT>::reset()
00196   {
00197   arma_extra_debug_sigprint();
00198   
00199   typedef typename running_stat<eT>::T T;
00200   
00201   counter.reset();
00202   
00203   r_mean       = eT(0);
00204   r_var        =  T(0);
00205   
00206   min_val      = eT(0);
00207   max_val      = eT(0);
00208   
00209   min_val_norm =  T(0);
00210   max_val_norm =  T(0);
00211   }
00212 
00213 
00214 
00215 //! mean or average value
00216 template<typename eT>
00217 inline
00218 eT
00219 running_stat<eT>::mean()
00220 const
00221   {
00222   arma_extra_debug_sigprint();
00223   
00224   return r_mean;
00225   }
00226 
00227 
00228 
00229 //! variance
00230 template<typename eT>
00231 inline
00232 typename running_stat<eT>::T
00233 running_stat<eT>::var(const u32 norm_type)
00234 const
00235   {
00236   arma_extra_debug_sigprint();
00237   
00238   const T N = counter.value();
00239   
00240   if(N > T(1))
00241     {
00242     if(norm_type == 0)
00243       {
00244       return r_var;
00245       }
00246     else
00247       {
00248       const T N_minus_1 = counter.value_minus_1();
00249       return (N_minus_1/N) * r_var;
00250       }
00251     }
00252   else
00253     {
00254     return T(0);
00255     }
00256   }
00257 
00258 
00259 
00260 //! standard deviation
00261 template<typename eT>
00262 inline
00263 typename running_stat<eT>::T
00264 running_stat<eT>::stddev(const u32 norm_type)
00265 const
00266   {
00267   arma_extra_debug_sigprint();
00268 
00269   return std::sqrt( (*this).var(norm_type) );
00270   }
00271 
00272 
00273 
00274 //! minimum value
00275 template<typename eT>
00276 inline
00277 eT
00278 running_stat<eT>::min()
00279 const
00280   {
00281   arma_extra_debug_sigprint();
00282   
00283   return min_val;
00284   }
00285 
00286 
00287 
00288 //! maximum value
00289 template<typename eT>
00290 inline
00291 eT
00292 running_stat<eT>::max()
00293 const
00294   {
00295   arma_extra_debug_sigprint();
00296 
00297   return max_val;
00298   }
00299 
00300 
00301 
00302 //! update statistics to reflect new sample
00303 template<typename eT>
00304 inline
00305 void
00306 running_stat_aux::update_stats(running_stat<eT>& x, const eT sample)
00307   {
00308   arma_extra_debug_sigprint();
00309   
00310   typedef typename running_stat<eT>::T T;
00311   
00312   const T N = x.counter.value();
00313   
00314   if(N > T(0))
00315     {
00316     if(sample < x.min_val)
00317       {
00318       x.min_val = sample;
00319       }
00320     
00321     if(sample > x.max_val)
00322       {
00323       x.max_val = sample;
00324       }
00325     
00326     const T  N_plus_1   = x.counter.value_plus_1();
00327     const T  N_minus_1  = x.counter.value_minus_1();
00328     
00329     // note: variance has to be updated before the mean
00330     
00331     const eT tmp = sample - x.r_mean;
00332     
00333     x.r_var  = N_minus_1/N * x.r_var + (tmp*tmp)/N_plus_1;
00334     
00335     x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1;
00336     //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1;
00337     //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1;
00338     }
00339   else
00340     {
00341     x.r_mean  = sample;
00342     x.min_val = sample;
00343     x.max_val = sample;
00344     
00345     // r_var is initialised to zero
00346     // in the constructor and reset()
00347     }
00348   
00349   x.counter++;
00350   }
00351 
00352 
00353 
00354 //! update statistics to reflect new sample (version for complex numbers)
00355 template<typename T>
00356 inline
00357 void
00358 running_stat_aux::update_stats(running_stat< std::complex<T> >& x, const T sample)
00359   {
00360   arma_extra_debug_sigprint();
00361 
00362   running_stat_aux::update_stats(x, std::complex<T>(sample));
00363   }
00364 
00365 
00366 
00367 //! alter statistics to reflect new sample (version for complex numbers)
00368 template<typename T>
00369 inline
00370 void
00371 running_stat_aux::update_stats(running_stat< std::complex<T> >& x, const std::complex<T>& sample)
00372   {
00373   arma_extra_debug_sigprint();
00374   
00375   typedef typename std::complex<T> eT;
00376   
00377   const T sample_norm = std::norm(sample);
00378   const T N           = x.counter.value();
00379   
00380   if(N > T(0))
00381     {
00382     if(sample_norm < x.min_val_norm)
00383       {
00384       x.min_val_norm = sample_norm;
00385       x.min_val      = sample;
00386       }
00387     
00388     if(sample_norm > x.max_val_norm)
00389       {
00390       x.max_val_norm = sample_norm;
00391       x.max_val      = sample;
00392       }
00393     
00394     const T  N_plus_1   = x.counter.value_plus_1();
00395     const T  N_minus_1  = x.counter.value_minus_1();
00396     
00397     x.r_var = N_minus_1/N * x.r_var + std::norm(sample - x.r_mean)/N_plus_1;
00398     
00399     x.r_mean = x.r_mean + (sample - x.r_mean)/N_plus_1;
00400     //x.r_mean = (N/N_plus_1)*x.r_mean + sample/N_plus_1;
00401     //x.r_mean = (x.r_mean + sample/N) * N/N_plus_1;
00402     }
00403   else
00404     {
00405     x.r_mean       = sample;
00406     x.min_val      = sample;
00407     x.max_val      = sample;
00408     x.min_val_norm = sample_norm;
00409     x.max_val_norm = sample_norm;
00410     
00411     // r_var is initialised to zero
00412     // in the constructor and reset()
00413     }
00414   
00415   x.counter++;
00416   }
00417 
00418 
00419 
00420 //! @}