running_stat_vec_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_vec
00017 //! @{
00018 
00019 
00020 
00021 template<typename eT>
00022 running_stat_vec<eT>::~running_stat_vec()
00023   {
00024   arma_extra_debug_sigprint_this(this);
00025   }
00026 
00027 
00028 
00029 template<typename eT>
00030 running_stat_vec<eT>::running_stat_vec(const bool in_calc_cov)
00031   : calc_cov(in_calc_cov)
00032   {
00033   arma_extra_debug_sigprint_this(this);
00034   }
00035 
00036 
00037 
00038 //! update statistics to reflect new sample
00039 template<typename eT>
00040 template<typename T1>
00041 inline
00042 void
00043 running_stat_vec<eT>::operator() (const Base<typename get_pod_type<eT>::pod_type, T1>& X)
00044   {
00045   arma_extra_debug_sigprint();
00046   
00047   //typedef typename get_pod_type<eT>::pod_type T;
00048   
00049   const unwrap<T1>        tmp(X.get_ref());
00050   const Mat<eT>& sample = tmp.M;
00051   
00052   arma_check( (sample.is_finite() == false), "running_stat_vec: given sample has non-finite elements" );
00053   
00054   running_stat_vec_aux::update_stats(*this, sample);
00055   }
00056 
00057 
00058 
00059 //! update statistics to reflect new sample (version for complex numbers)
00060 template<typename eT>
00061 template<typename T1>
00062 inline
00063 void
00064 running_stat_vec<eT>::operator() (const Base<std::complex<typename get_pod_type<eT>::pod_type>, T1>& X)
00065   {
00066   arma_extra_debug_sigprint();
00067   
00068   //typedef typename std::complex<typename get_pod_type<eT>::pod_type> eT;
00069   
00070   const unwrap<T1>        tmp(X.get_ref());
00071   const Mat<eT>& sample = tmp.M;
00072   
00073   arma_check( (sample.is_finite() == false), "running_stat_vec: given sample has non-finite elements" );
00074   
00075   running_stat_vec_aux::update_stats(*this, sample);
00076   }
00077 
00078 
00079 
00080 //! set all statistics to zero
00081 template<typename eT>
00082 inline
00083 void
00084 running_stat_vec<eT>::reset()
00085   {
00086   arma_extra_debug_sigprint();
00087   
00088   counter.reset();
00089   
00090   r_mean.reset();
00091   r_var.reset();
00092   r_cov.reset();
00093   
00094   min_val.reset();
00095   max_val.reset();
00096   
00097   min_val_norm.reset();
00098   max_val_norm.reset();
00099   }
00100 
00101 
00102 
00103 //! mean or average value
00104 template<typename eT>
00105 inline
00106 Mat<eT>
00107 running_stat_vec<eT>::mean()
00108   const
00109   {
00110   arma_extra_debug_sigprint();
00111   
00112   return r_mean;
00113   }
00114 
00115 
00116 
00117 //! variance
00118 template<typename eT>
00119 inline
00120 Mat<typename get_pod_type<eT>::pod_type>
00121 running_stat_vec<eT>::var(const u32 norm_type)
00122   const
00123   {
00124   arma_extra_debug_sigprint();
00125   
00126   const T N = counter.value();
00127   
00128   if(N > T(1))
00129     {
00130     if(norm_type == 0)
00131       {
00132       return r_var;
00133       }
00134     else
00135       {
00136       const T N_minus_1 = counter.value_minus_1();
00137       return (N_minus_1/N) * r_var;
00138       }
00139     }
00140   else
00141     {
00142     return zeros< Mat<typename get_pod_type<eT>::pod_type> >(r_mean.n_rows, r_mean.n_cols);
00143     }
00144   
00145   }
00146 
00147 
00148 
00149 //! standard deviation
00150 template<typename eT>
00151 inline
00152 Mat<typename get_pod_type<eT>::pod_type>
00153 running_stat_vec<eT>::stddev(const u32 norm_type)
00154   const
00155   {
00156   arma_extra_debug_sigprint();
00157   
00158   return sqrt( (*this).var(norm_type) );
00159   }
00160 
00161 
00162 
00163 //! covariance
00164 template<typename eT>
00165 inline
00166 Mat<eT>
00167 running_stat_vec<eT>::cov(const u32 norm_type)
00168   const
00169   {
00170   arma_extra_debug_sigprint();
00171   
00172   if(calc_cov == true)
00173     {
00174     const T N = counter.value();
00175     
00176     if(N > T(1))
00177       {
00178       if(norm_type == 0)
00179         {
00180         return r_cov;
00181         }
00182       else
00183         {
00184         const T N_minus_1 = counter.value_minus_1();
00185         return (N_minus_1/N) * r_cov;
00186         }
00187       }
00188     else
00189       {
00190       return zeros< Mat<eT> >(r_mean.n_rows, r_mean.n_cols);
00191       }
00192     }
00193   else
00194     {
00195     return Mat<eT>();
00196     }
00197   
00198   }
00199 
00200 
00201 
00202 //! vector with minimum values
00203 template<typename eT>
00204 inline
00205 Mat<eT>
00206 running_stat_vec<eT>::min()
00207 const
00208   {
00209   arma_extra_debug_sigprint();
00210 
00211   return min_val;
00212   }
00213 
00214 
00215 
00216 //! vector with maximum values
00217 template<typename eT>
00218 inline
00219 Mat<eT>
00220 running_stat_vec<eT>::max()
00221 const
00222   {
00223   arma_extra_debug_sigprint();
00224 
00225   return max_val;
00226   }
00227 
00228 
00229 
00230 //
00231 
00232 
00233 
00234 //! update statistics to reflect new sample
00235 template<typename eT>
00236 inline
00237 void
00238 running_stat_vec_aux::update_stats(running_stat_vec<eT>& x, const Mat<eT>& sample)
00239   {
00240   arma_extra_debug_sigprint();
00241   
00242   typedef typename running_stat_vec<eT>::T T;
00243   
00244   const T N = x.counter.value();
00245   
00246   if(N > T(0))
00247     {
00248     arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch");
00249     
00250     const u32 n_elem      = sample.n_elem;
00251     const eT* sample_mem  = sample.memptr();
00252           eT* r_mean_mem  = x.r_mean.memptr();
00253            T* r_var_mem   = x.r_var.memptr();
00254           eT* min_val_mem = x.min_val.memptr();
00255           eT* max_val_mem = x.max_val.memptr();
00256     
00257     const T  N_plus_1   = x.counter.value_plus_1();
00258     const T  N_minus_1  = x.counter.value_minus_1();
00259     
00260     if(x.calc_cov == true)
00261       {
00262       const Mat<eT> tmp1 = sample - x.r_mean;
00263       
00264       Mat<eT> tmp2;
00265       
00266       if(sample.n_cols == 1)
00267         {
00268         tmp2 = tmp1*trans(tmp1);
00269         }
00270       else
00271         {
00272         tmp2 = trans(tmp1)*tmp1;
00273         }
00274       
00275       x.r_cov *= (N_minus_1/N);
00276       x.r_cov += tmp2 / N_plus_1;
00277       }
00278     
00279     
00280     for(u32 i=0; i<n_elem; ++i)
00281       {
00282       const eT val = sample_mem[i];
00283       
00284       if(val < min_val_mem[i])
00285         {
00286         min_val_mem[i] = val;
00287         }
00288       
00289       if(val > max_val_mem[i])
00290         {
00291         max_val_mem[i] = val;
00292         }
00293         
00294       const eT r_mean_val = r_mean_mem[i];
00295       const eT tmp        = val - r_mean_val;
00296     
00297       r_var_mem[i] = N_minus_1/N * r_var_mem[i] + (tmp*tmp)/N_plus_1;
00298       
00299       r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1;
00300       }
00301     }
00302   else
00303     {
00304     arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector");
00305     
00306     x.r_mean.set_size(sample.n_rows, sample.n_cols);
00307     
00308     x.r_var.zeros(sample.n_rows, sample.n_cols);
00309     
00310     if(x.calc_cov == true)
00311       {
00312       x.r_cov.zeros(sample.n_elem, sample.n_elem);
00313       }
00314     
00315     x.min_val.set_size(sample.n_rows, sample.n_cols);
00316     x.max_val.set_size(sample.n_rows, sample.n_cols);
00317     
00318     
00319     const u32 n_elem      = sample.n_elem;
00320     const eT* sample_mem  = sample.memptr();
00321           eT* r_mean_mem  = x.r_mean.memptr();
00322           eT* min_val_mem = x.min_val.memptr();
00323           eT* max_val_mem = x.max_val.memptr();
00324           
00325     
00326     for(u32 i=0; i<n_elem; ++i)
00327       {
00328       const eT val = sample_mem[i];
00329       
00330       r_mean_mem[i]  = val;
00331       min_val_mem[i] = val;
00332       max_val_mem[i] = val;
00333       }
00334     }
00335   
00336   x.counter++;
00337   }
00338 
00339 
00340 
00341 //! update statistics to reflect new sample (version for complex numbers)
00342 template<typename T>
00343 inline
00344 void
00345 running_stat_vec_aux::update_stats(running_stat_vec< std::complex<T> >& x, const Mat<T>& sample)
00346   {
00347   arma_extra_debug_sigprint();
00348   
00349   const Mat< std::complex<T> > tmp = conv_to< Mat< std::complex<T> > >::from(sample);
00350   
00351   running_stat_vec_aux::update_stats(x, tmp);
00352   }
00353 
00354 
00355 
00356 //! alter statistics to reflect new sample (version for complex numbers)
00357 template<typename T>
00358 inline
00359 void
00360 running_stat_vec_aux::update_stats(running_stat_vec< std::complex<T> >& x, const Mat< std::complex<T> >& sample)
00361   {
00362   arma_extra_debug_sigprint();
00363   
00364   typedef typename std::complex<T> eT;
00365   
00366   const T N = x.counter.value();
00367   
00368   if(N > T(0))
00369     {
00370     arma_debug_assert_same_size(x.r_mean, sample, "running_stat_vec(): dimensionality mismatch");
00371     
00372     const u32 n_elem           = sample.n_elem;
00373     const eT* sample_mem       = sample.memptr();
00374           eT* r_mean_mem       = x.r_mean.memptr();
00375            T* r_var_mem        = x.r_var.memptr();
00376           eT* min_val_mem      = x.min_val.memptr();
00377           eT* max_val_mem      = x.max_val.memptr();
00378            T* min_val_norm_mem = x.min_val_norm.memptr();
00379            T* max_val_norm_mem = x.max_val_norm.memptr();
00380     
00381     const T  N_plus_1   = x.counter.value_plus_1();
00382     const T  N_minus_1  = x.counter.value_minus_1();
00383     
00384     if(x.calc_cov == true)
00385       {
00386       const Mat<eT> tmp1 = sample - x.r_mean;
00387       
00388       Mat<eT> tmp2;
00389       
00390       if(sample.n_cols == 1)
00391         {
00392         tmp2 = conj(tmp1)*trans(tmp1);
00393         }
00394       else
00395         {
00396         tmp2 = trans(conj(tmp1))*tmp1;
00397         }
00398       
00399       x.r_cov *= (N_minus_1/N);
00400       x.r_cov += tmp2 / N_plus_1;
00401       }
00402     
00403     
00404     for(u32 i=0; i<n_elem; ++i)
00405       {
00406       const eT& val      = sample_mem[i];
00407       const  T  val_norm = std::norm(val);
00408       
00409       if(val_norm < min_val_norm_mem[i])
00410         {
00411         min_val_norm_mem[i] = val_norm;
00412         min_val_mem[i]      = val;
00413         }
00414       
00415       if(val_norm > max_val_norm_mem[i])
00416         {
00417         max_val_norm_mem[i] = val_norm;
00418         max_val_mem[i]      = val;
00419         }
00420       
00421       const eT& r_mean_val = r_mean_mem[i];
00422       
00423       r_var_mem[i] = N_minus_1/N * r_var_mem[i] + std::norm(val - r_mean_val)/N_plus_1;
00424       
00425       r_mean_mem[i] = r_mean_val + (val - r_mean_val)/N_plus_1;
00426       }
00427     
00428     }
00429   else
00430     {
00431     arma_debug_check( (sample.is_vec() == false), "running_stat_vec(): given sample is not a vector");
00432     
00433     x.r_mean.set_size(sample.n_rows, sample.n_cols);
00434     
00435     x.r_var.zeros(sample.n_rows, sample.n_cols);
00436     
00437     if(x.calc_cov == true)
00438       {
00439       x.r_cov.zeros(sample.n_elem, sample.n_elem);
00440       }
00441     
00442     x.min_val.set_size(sample.n_rows, sample.n_cols);
00443     x.max_val.set_size(sample.n_rows, sample.n_cols);
00444     
00445     x.min_val_norm.set_size(sample.n_rows, sample.n_cols);
00446     x.max_val_norm.set_size(sample.n_rows, sample.n_cols);
00447     
00448     
00449     const u32 n_elem           = sample.n_elem;
00450     const eT* sample_mem       = sample.memptr();
00451           eT* r_mean_mem       = x.r_mean.memptr();
00452           eT* min_val_mem      = x.min_val.memptr();
00453           eT* max_val_mem      = x.max_val.memptr();
00454            T* min_val_norm_mem = x.min_val_norm.memptr();
00455            T* max_val_norm_mem = x.max_val_norm.memptr();
00456     
00457     for(u32 i=0; i<n_elem; ++i)
00458       {
00459       const eT& val      = sample_mem[i];
00460       const  T  val_norm = std::norm(val);
00461       
00462       r_mean_mem[i]  = val;
00463       min_val_mem[i] = val;
00464       max_val_mem[i] = val;
00465       
00466       min_val_norm_mem[i] = val_norm;
00467       max_val_norm_mem[i] = val_norm;
00468       }
00469     }
00470   
00471   x.counter++;
00472   }
00473 
00474 
00475 
00476 //! @}