op_median_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 
00018 
00019 template<typename eT>
00020 arma_inline
00021 eT
00022 op_median::robust_mean(const eT A, const eT B)
00023   {
00024   return A + (B - A)/eT(2);
00025   }
00026 
00027 
00028 
00030 template<typename eT>
00031 inline 
00032 eT
00033 op_median::direct_median(std::vector<eT>& X)
00034   {
00035   arma_extra_debug_sigprint();
00036   
00037   const uword n_elem = X.size();
00038   const uword half   = n_elem/2;
00039   
00040   std::sort(X.begin(), X.end());
00041   
00042   if((n_elem % 2) == 0)
00043     {
00044     return op_median::robust_mean(X[half-1], X[half]);
00045     }
00046   else
00047     {
00048     return X[half];
00049     }
00050   }
00051 
00052 
00053 
00054 template<typename eT>
00055 inline 
00056 eT
00057 op_median::direct_median(const eT* X, const uword n_elem)
00058   {
00059   arma_extra_debug_sigprint();
00060   
00061   std::vector<eT> tmp(X, X+n_elem);
00062   
00063   return op_median::direct_median(tmp);
00064   }
00065 
00066 
00067 
00068 template<typename eT>
00069 inline 
00070 eT
00071 op_median::direct_median(const subview<eT>& X)
00072   {
00073   arma_extra_debug_sigprint();
00074   
00075   const uword X_n_elem = X.n_elem;
00076   
00077   std::vector<eT> tmp(X_n_elem);
00078   
00079   for(uword i=0; i<X_n_elem; ++i)
00080     {
00081     tmp[i] = X[i];
00082     }
00083   
00084   return op_median::direct_median(tmp);
00085   }
00086 
00087 
00088 
00089 template<typename eT>
00090 inline 
00091 eT
00092 op_median::direct_median(const diagview<eT>& X)
00093   {
00094   arma_extra_debug_sigprint();
00095   
00096   const uword X_n_elem = X.n_elem;
00097   
00098   std::vector<eT> tmp(X_n_elem);
00099   
00100   for(uword i=0; i<X_n_elem; ++i)
00101     {
00102     tmp[i] = X[i];
00103     }
00104   
00105   return op_median::direct_median(tmp);
00106   }
00107 
00108 
00109 
00114 template<typename T1>
00115 inline
00116 void
00117 op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in)
00118   {
00119   arma_extra_debug_sigprint();
00120   
00121   typedef typename T1::elem_type eT;
00122   
00123   const unwrap_check<T1> tmp(in.m, out);
00124   const Mat<eT>&     X = tmp.M;
00125   
00126   const uword X_n_rows = X.n_rows;
00127   const uword X_n_cols = X.n_cols;
00128   
00129   const uword dim = in.aux_uword_a;
00130   arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
00131   
00132   if(dim == 0)  // in each column
00133     {
00134     arma_extra_debug_print("op_median::apply(), dim = 0");
00135     
00136     arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
00137 
00138     out.set_size(1, X_n_cols);
00139     
00140     std::vector<eT> tmp_vec(X_n_rows);
00141       
00142     for(uword col=0; col<X_n_cols; ++col)
00143       {
00144       const eT* colmem = X.colptr(col);
00145       
00146       for(uword row=0; row<X_n_rows; ++row)
00147         {
00148         tmp_vec[row] = colmem[row];
00149         }
00150       
00151       out[col] = op_median::direct_median(tmp_vec);
00152       }
00153     }
00154   else
00155   if(dim == 1)  // in each row
00156     {
00157     arma_extra_debug_print("op_median::apply(), dim = 1");
00158     
00159     arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
00160 
00161     out.set_size(X_n_rows, 1);
00162     
00163     std::vector<eT> tmp_vec(X_n_cols);
00164       
00165     for(uword row=0; row<X_n_rows; ++row)
00166       {
00167       for(uword col=0; col<X_n_cols; ++col)
00168         {
00169         tmp_vec[col] = X.at(row,col);
00170         }
00171       
00172       out[row] =  op_median::direct_median(tmp_vec);
00173       }
00174     }
00175   }
00176 
00177 
00178 
00179 template<typename T>
00180 arma_inline
00181 std::complex<T>
00182 op_median::robust_mean(const std::complex<T>& A, const std::complex<T>& B)
00183   {
00184   return A + (B - A)/T(2);
00185   }
00186 
00187 
00188 
00189 template<typename T>
00190 inline 
00191 void
00192 op_median::direct_cx_median_index
00193   (
00194   uword& out_index1, 
00195   uword& out_index2, 
00196   std::vector< arma_cx_median_packet<T> >& X
00197   )
00198   {
00199   arma_extra_debug_sigprint();
00200   
00201   const uword n_elem = X.size();
00202   const uword half   = n_elem/2;
00203   
00204   std::sort(X.begin(), X.end());
00205   
00206   if((n_elem % 2) == 0)
00207     {
00208     out_index1 = X[half-1].index;
00209     out_index2 = X[half  ].index;
00210     }
00211   else
00212     {
00213     out_index1 = X[half].index;
00214     out_index2 = out_index1;
00215     }
00216   }
00217 
00218 
00219 
00220 template<typename T>
00221 inline 
00222 void
00223 op_median::direct_cx_median_index
00224   (
00225   uword& out_index1, 
00226   uword& out_index2, 
00227   const std::complex<T>* X, 
00228   const uword n_elem
00229   )
00230   {
00231   arma_extra_debug_sigprint();
00232   
00233   std::vector< arma_cx_median_packet<T> > tmp(n_elem);
00234   
00235   for(uword i=0; i<n_elem; ++i)
00236     {
00237     tmp[i].val   = std::abs(X[i]);
00238     tmp[i].index = i;
00239     }
00240   
00241   op_median::direct_cx_median_index(out_index1, out_index2, tmp);
00242   }
00243 
00244 
00245 
00246 template<typename T>
00247 inline 
00248 void
00249 op_median::direct_cx_median_index
00250   (
00251   uword& out_index1, 
00252   uword& out_index2, 
00253   const subview< std::complex<T> >&X
00254   )
00255   {
00256   arma_extra_debug_sigprint();
00257   
00258   const uword n_elem = X.n_elem;
00259   
00260   std::vector< arma_cx_median_packet<T> > tmp(n_elem);
00261   
00262   for(uword i=0; i<n_elem; ++i)
00263     {
00264     tmp[i].val   = std::abs(X[i]);
00265     tmp[i].index = i;
00266     }
00267   
00268   op_median::direct_cx_median_index(out_index1, out_index2, tmp);
00269   }
00270 
00271 
00272 
00273 template<typename T>
00274 inline 
00275 void
00276 op_median::direct_cx_median_index
00277   (
00278   uword& out_index1, 
00279   uword& out_index2, 
00280   const diagview< std::complex<T> >&X
00281   )
00282   {
00283   arma_extra_debug_sigprint();
00284   
00285   const uword n_elem = X.n_elem;
00286   
00287   std::vector< arma_cx_median_packet<T> > tmp(n_elem);
00288   
00289   for(uword i=0; i<n_elem; ++i)
00290     {
00291     tmp[i].val   = std::abs(X[i]);
00292     tmp[i].index = i;
00293     }
00294   
00295   op_median::direct_cx_median_index(out_index1, out_index2, tmp);
00296   }
00297 
00298 
00299 
00301 template<typename T, typename T1>
00302 inline
00303 void
00304 op_median::apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in)
00305   {
00306   arma_extra_debug_sigprint();
00307   
00308   typedef typename std::complex<T> eT;
00309   
00310   arma_type_check(( is_same_type<eT, typename T1::elem_type>::value == false ));
00311   
00312   const unwrap_check<T1> tmp(in.m, out);
00313   const Mat<eT>&     X = tmp.M;
00314   
00315   const uword X_n_rows = X.n_rows;
00316   const uword X_n_cols = X.n_cols;
00317   
00318   const uword dim = in.aux_uword_a;
00319   arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
00320   
00321   if(dim == 0)  // in each column
00322     {
00323     arma_extra_debug_print("op_median::apply(), dim = 0");
00324     
00325     arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
00326 
00327     out.set_size(1, X_n_cols);
00328     
00329     std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_rows);
00330     
00331     for(uword col=0; col<X_n_cols; ++col)
00332       {
00333       const eT* colmem = X.colptr(col);
00334       
00335       for(uword row=0; row<X_n_rows; ++row)
00336         {
00337         tmp_vec[row].val   = std::abs(colmem[row]);
00338         tmp_vec[row].index = row;
00339         }
00340       
00341       uword index1;
00342       uword index2;
00343       op_median::direct_cx_median_index(index1, index2, tmp_vec);
00344         
00345       out[col] = op_median::robust_mean(colmem[index1], colmem[index2]);
00346       }
00347     }
00348   else
00349   if(dim == 1)  // in each row
00350     {
00351     arma_extra_debug_print("op_median::apply(), dim = 1");
00352     
00353     arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
00354 
00355     out.set_size(X_n_rows, 1);
00356     
00357     std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_cols);
00358     
00359     for(uword row=0; row<X_n_rows; ++row)
00360       {
00361       for(uword col=0; col<X_n_cols; ++col)
00362         {
00363         tmp_vec[col].val   = std::abs(X.at(row,col));
00364         tmp_vec[row].index = col;
00365         }
00366       
00367       uword index1;
00368       uword index2;
00369       op_median::direct_cx_median_index(index1, index2, tmp_vec);
00370       
00371       out[row] = op_median::robust_mean( X.at(row,index1), X.at(row,index2) );
00372       }
00373     }
00374   }
00375 
00376 
00377 
00379 


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