running_stat_meat.hpp

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