op_var_meat.hpp
Go to the documentation of this file.
00001 // Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
00002 // Copyright (C) 2009-2011 Conrad Sanderson
00003 // 
00004 // This file is part of the Armadillo C++ library.
00005 // It is provided without any warranty of fitness
00006 // for any purpose. You can redistribute this file
00007 // and/or modify it under the terms of the GNU
00008 // Lesser General Public License (LGPL) as published
00009 // by the Free Software Foundation, either version 3
00010 // of the License or (at your option) any later version.
00011 // (see http://www.opensource.org/licenses for more info)
00012 
00013 
00016 
00017 
00019 template<typename eT>
00020 inline
00021 eT
00022 op_var::direct_var(const eT* const X, const uword n_elem, const uword norm_type)
00023   {
00024   arma_extra_debug_sigprint();
00025   
00026   if(n_elem >= 2)
00027     {
00028     const eT acc1 = op_mean::direct_mean(X, n_elem);
00029     
00030     eT acc2 = eT(0);
00031     eT acc3 = eT(0);
00032     
00033     uword i,j;
00034     
00035     for(i=0, j=1; j<n_elem; i+=2, j+=2)
00036       {
00037       const eT Xi = X[i];
00038       const eT Xj = X[j];
00039       
00040       const eT tmpi = acc1 - Xi;
00041       const eT tmpj = acc1 - Xj;
00042       
00043       acc2 += tmpi*tmpi + tmpj*tmpj;
00044       acc3 += tmpi      + tmpj;
00045       }
00046     
00047     if(i < n_elem)
00048       {
00049       const eT Xi = X[i];
00050       
00051       const eT tmpi = acc1 - Xi;
00052       
00053       acc2 += tmpi*tmpi;
00054       acc3 += tmpi;
00055       }
00056     
00057     const eT norm_val = (norm_type == 0) ? eT(n_elem-1) : eT(n_elem);
00058     const eT var_val  = (acc2 - acc3*acc3/eT(n_elem)) / norm_val;
00059     
00060     return arma_isfinite(var_val) ? var_val : op_var::direct_var_robust(X, n_elem, norm_type);
00061     }
00062   else
00063     {
00064     return eT(0);
00065     }
00066   }
00067 
00068 
00069 
00071 template<typename T>
00072 inline
00073 T
00074 op_var::direct_var(const std::complex<T>* const X, const uword n_elem, const uword norm_type)
00075   {
00076   arma_extra_debug_sigprint();
00077   
00078   typedef typename std::complex<T> eT;
00079   
00080   if(n_elem >= 2)
00081     {
00082     const eT acc1 = op_mean::direct_mean(X, n_elem);
00083     
00084     T  acc2 =  T(0);
00085     eT acc3 = eT(0);
00086     
00087     for(uword i=0; i<n_elem; ++i)
00088       {
00089       const eT tmp = acc1 - X[i];
00090       
00091       acc2 += std::norm(tmp);
00092       acc3 += tmp;
00093       }
00094     
00095     const T norm_val = (norm_type == 0) ? T(n_elem-1) : T(n_elem);
00096     const T var_val  = (acc2 - std::norm(acc3)/T(n_elem)) / norm_val;
00097     
00098     return arma_isfinite(var_val) ? var_val : op_var::direct_var_robust(X, n_elem, norm_type);
00099     }
00100   else
00101     {
00102     return T(0);
00103     }
00104   }
00105 
00106 
00107 
00109 template<typename eT>
00110 inline 
00111 typename get_pod_type<eT>::result
00112 op_var::direct_var(const subview_row<eT>& X, const uword norm_type)
00113   {
00114   arma_extra_debug_sigprint();
00115   
00116   const uword n_elem = X.n_elem;
00117   
00118   podarray<eT> tmp(n_elem);
00119   
00120   eT* tmp_mem = tmp.memptr();
00121   
00122   for(uword i=0; i<n_elem; ++i)
00123     {
00124     tmp_mem[i] = X[i];
00125     }
00126   
00127   return op_var::direct_var(tmp_mem, n_elem, norm_type);
00128   }
00129 
00130 
00131 
00133 template<typename eT>
00134 inline 
00135 typename get_pod_type<eT>::result
00136 op_var::direct_var(const subview_col<eT>& X, const uword norm_type)
00137   {
00138   arma_extra_debug_sigprint();
00139   
00140   return op_var::direct_var(X.colptr(0), X.n_elem, norm_type);
00141   }
00142 
00143 
00144 
00146 template<typename eT>
00147 inline 
00148 typename get_pod_type<eT>::result
00149 op_var::direct_var(const diagview<eT>& X, const uword norm_type)
00150   {
00151   arma_extra_debug_sigprint();
00152   
00153   const uword n_elem = X.n_elem;
00154   
00155   podarray<eT> tmp(n_elem);
00156   
00157   eT* tmp_mem = tmp.memptr();
00158   
00159   for(uword i=0; i<n_elem; ++i)
00160     {
00161     tmp_mem[i] = X[i];
00162     }
00163   
00164   return op_var::direct_var(tmp_mem, n_elem, norm_type);
00165   }
00166 
00167 
00168 
00173 template<typename T1>
00174 inline
00175 void
00176 op_var::apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_var>& in)
00177   {
00178   arma_extra_debug_sigprint();
00179   
00180   typedef typename T1::elem_type  in_eT;
00181   typedef typename T1::pod_type  out_eT;
00182   
00183   const unwrap_check_mixed<T1> tmp(in.m, out);
00184   const Mat<in_eT>&        X = tmp.M;
00185   
00186   const uword norm_type = in.aux_uword_a;
00187   const uword dim       = in.aux_uword_b;
00188   
00189   arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
00190   arma_debug_check( (dim > 1),       "var(): incorrect usage. dim must be 0 or 1"      );
00191   
00192   const uword X_n_rows = X.n_rows;
00193   const uword X_n_cols = X.n_cols;
00194   
00195   if(dim == 0)
00196     {
00197     arma_extra_debug_print("op_var::apply(), dim = 0");
00198     
00199     arma_debug_check( (X_n_rows == 0), "var(): given object has zero rows" );
00200 
00201     out.set_size(1, X_n_cols);
00202     
00203     out_eT* out_mem = out.memptr();
00204     
00205     for(uword col=0; col<X_n_cols; ++col)
00206       {
00207       out_mem[col] = op_var::direct_var( X.colptr(col), X_n_rows, norm_type );
00208       }
00209     }
00210   else
00211   if(dim == 1)
00212     {
00213     arma_extra_debug_print("op_var::apply(), dim = 1");
00214     
00215     arma_debug_check( (X_n_cols == 0), "var(): given object has zero columns" );
00216 
00217     out.set_size(X_n_rows, 1);
00218     
00219     podarray<in_eT> tmp(X_n_cols);
00220     
00221     in_eT*  tmp_mem = tmp.memptr();
00222     out_eT* out_mem = out.memptr();
00223     
00224     for(uword row=0; row<X_n_rows; ++row)
00225       {
00226       tmp.copy_row(X, row);
00227       
00228       out_mem[row] = op_var::direct_var( tmp_mem, X_n_cols, norm_type );
00229       }
00230     }
00231   }
00232 
00233 
00234 
00236 template<typename eT>
00237 inline
00238 eT
00239 op_var::direct_var_robust(const eT* const X, const uword n_elem, const uword norm_type)
00240   {
00241   arma_extra_debug_sigprint();
00242   
00243   if(n_elem > 1)
00244     {
00245     eT r_mean = X[0];
00246     eT r_var  = eT(0);
00247     
00248     for(uword i=1; i<n_elem; ++i)
00249       {
00250       const eT tmp      = X[i] - r_mean;
00251       const eT i_plus_1 = eT(i+1);
00252       
00253       r_var  = eT(i-1)/eT(i) * r_var + (tmp*tmp)/i_plus_1;
00254       
00255       r_mean = r_mean + tmp/i_plus_1;
00256       }
00257     
00258     return (norm_type == 0) ? r_var : (eT(n_elem-1)/eT(n_elem)) * r_var;
00259     }
00260   else
00261     {
00262     return eT(0);
00263     }
00264   }
00265 
00266 
00267 
00269 template<typename T>
00270 inline
00271 T
00272 op_var::direct_var_robust(const std::complex<T>* const X, const uword n_elem, const uword norm_type)
00273   {
00274   arma_extra_debug_sigprint();
00275   
00276   typedef typename std::complex<T> eT;
00277   
00278   if(n_elem > 1)
00279     {
00280     eT r_mean = X[0];
00281      T r_var  = T(0);
00282     
00283     for(uword i=1; i<n_elem; ++i)
00284       {
00285       const eT tmp      = X[i] - r_mean;
00286       const  T i_plus_1 = T(i+1);
00287       
00288       r_var  = T(i-1)/T(i) * r_var + std::norm(tmp)/i_plus_1;
00289       
00290       r_mean = r_mean + tmp/i_plus_1;
00291       }
00292     
00293     return (norm_type == 0) ? r_var : (T(n_elem-1)/T(n_elem)) * r_var;
00294     }
00295   else
00296     {
00297     return T(0);
00298     }
00299   }
00300 
00301 
00302 
00304 


armadillo_matrix
Author(s): Conrad Sanderson - NICTA (www.nicta.com.au), (Wrapper by Sjoerd van den Dries)
autogenerated on Tue Jan 7 2014 11:42:05