op_min_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 op_min
00018 //! @{
00019 
00020 
00021 //! Find the minimum value in an array
00022 template<typename eT>
00023 inline 
00024 eT
00025 op_min::direct_min(const eT* const X, const u32 n_elem)
00026   {
00027   arma_extra_debug_sigprint();
00028   
00029   eT min_val = X[0];
00030   
00031   for(u32 i=1; i<n_elem; ++i)
00032     {
00033     const eT tmp_val = X[i];
00034     
00035     if(tmp_val < min_val)
00036       {
00037       min_val = tmp_val;
00038       }
00039     }
00040   
00041   return min_val;
00042   }
00043 
00044 
00045 
00046 //! find the minimum value in a subview
00047 template<typename eT>
00048 inline 
00049 eT
00050 op_min::direct_min(const subview<eT>& X)
00051   {
00052   arma_extra_debug_sigprint();
00053   
00054   eT min_val = X[0];
00055   
00056   for(u32 i=1; i<X.n_elem; ++i)
00057     {
00058     eT tmp_val = X[i];
00059     
00060     if(tmp_val < min_val)
00061       {
00062       min_val = tmp_val;
00063       }
00064     }
00065   
00066   return min_val;
00067   }
00068 
00069 
00070 
00071 //! find the minimum value in a diagview
00072 template<typename eT>
00073 inline 
00074 eT
00075 op_min::direct_min(const diagview<eT>& X)
00076   {
00077   arma_extra_debug_sigprint();
00078   
00079   eT min_val = X[0];
00080   
00081   for(u32 i=1; i<X.n_elem; ++i)
00082     {
00083     eT tmp_val = X[i];
00084     
00085     if(tmp_val < min_val)
00086       {
00087       min_val = tmp_val;
00088       }
00089     }
00090   
00091   return min_val;
00092   }
00093 
00094 
00095 
00096 //! \brief
00097 //! For each row or for each column, find the minimum value.
00098 //! The result is stored in a dense matrix that has either one column or one row.
00099 //! The dimension, for which the minima are found, is set via the min() function.
00100 template<typename T1>
00101 inline void op_min::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_min>& in)
00102   {
00103   arma_extra_debug_sigprint();
00104   
00105   typedef typename T1::elem_type eT;
00106   
00107   const unwrap_check<T1> tmp(in.m, out);
00108   const Mat<eT>& X = tmp.M;
00109   
00110   arma_debug_check( (X.n_elem == 0), "min(): given matrix has no elements" );
00111   
00112   const u32 dim = in.aux_u32_a;
00113   arma_debug_check( (dim > 1), "min(): incorrect usage. dim must be 0 or 1");
00114   
00115   
00116   if(dim == 0)  // column-wise min
00117     {
00118     arma_extra_debug_print("op_min::apply(), dim = 0");
00119     
00120     out.set_size(1, X.n_cols);
00121     
00122     for(u32 col=0; col<X.n_cols; ++col)
00123       {
00124       out[col] = op_min::direct_min( X.colptr(col), X.n_rows );
00125       }
00126     }
00127   else
00128   if(dim == 1)  // row-wise min
00129     {
00130     arma_extra_debug_print("op_min::apply(), dim = 1");
00131     
00132     out.set_size(X.n_rows, 1);
00133     
00134     for(u32 row=0; row<X.n_rows; ++row)
00135       {
00136       eT min_val = X.at(row,0);
00137       
00138       for(u32 col=1; col<X.n_cols; ++col)
00139         {
00140         const eT tmp_val = X.at(row,col);
00141         
00142         if(tmp_val < min_val)
00143           {
00144           min_val = tmp_val;
00145           }
00146         }
00147       
00148       out[row] = min_val;
00149       
00150       }
00151     
00152     }
00153   
00154   }
00155 
00156 
00157 
00158 //! Find the minimum value in an array (version for complex numbers)
00159 template<typename T>
00160 inline 
00161 std::complex<T>
00162 op_min::direct_min(const std::complex<T>* const X, const u32 n_elem)
00163   {
00164   arma_extra_debug_sigprint();
00165   
00166   u32 index   = 0;
00167   T   min_val = std::abs(X[index]);
00168   
00169   for(u32 i=1; i<n_elem; ++i)
00170     {
00171     const T tmp_val = std::abs(X[i]);
00172     
00173     if(tmp_val < min_val)
00174       {
00175       min_val = tmp_val;
00176       index   = i;
00177       }
00178     }
00179   
00180   return X[index];
00181   }
00182 
00183 
00184 
00185 //! Find the minimum value in a subview (version for complex numbers)
00186 template<typename T>
00187 inline 
00188 std::complex<T>
00189 op_min::direct_min(const subview< std::complex<T> >& X)
00190   {
00191   arma_extra_debug_sigprint();
00192   
00193   u32 index   = 0;
00194   T   min_val = std::abs(X[index]);
00195   
00196   for(u32 i=1; i<X.n_elem; ++i)
00197     {
00198     const T tmp_val = std::abs(X[i]);
00199     
00200     if(tmp_val < min_val)
00201       {
00202       min_val = tmp_val;
00203       index   = i;
00204       }
00205     }
00206   
00207   return X[index];
00208   }
00209 
00210 
00211 
00212 //! Find the minimum value in a diagview (version for complex numbers)
00213 template<typename T>
00214 inline 
00215 std::complex<T>
00216 op_min::direct_min(const diagview< std::complex<T> >& X)
00217   {
00218   arma_extra_debug_sigprint();
00219   
00220   u32 index   = 0;
00221   T   min_val = std::abs(X[index]);
00222   
00223   for(u32 i=1; i<X.n_elem; ++i)
00224     {
00225     const T tmp_val = std::abs(X[i]);
00226     
00227     if(tmp_val < min_val)
00228       {
00229       min_val = tmp_val;
00230       index   = i;
00231       }
00232     }
00233   
00234   return X[index];
00235   }
00236 
00237 
00238 
00239 //! Implementation for complex numbers
00240 template<typename T, typename T1>
00241 inline void op_min::apply(Mat< std::complex<T> >& out, const Op<T1,op_min>& in)
00242   {
00243   arma_extra_debug_sigprint();
00244   
00245   typedef typename std::complex<T> eT;
00246   isnt_same_type<eT, typename T1::elem_type>::check();
00247   
00248   const unwrap_check<T1> tmp(in.m, out);
00249   const Mat<eT>& X = tmp.M;
00250   
00251   arma_debug_check( (X.n_elem == 0), "min(): given matrix has no elements" );
00252   
00253   const u32 dim = in.aux_u32_a;
00254   arma_debug_check( (dim > 1), "min(): incorrect usage. dim must be 0 or 1");
00255   
00256   
00257   if(dim == 0)  // column-wise min
00258     {
00259     arma_extra_debug_print("op_min::apply(), dim = 0");
00260     
00261     out.set_size(1, X.n_cols);
00262     
00263     for(u32 col=0; col<X.n_cols; ++col)
00264       {
00265       out[col] = op_min::direct_min( X.colptr(col), X.n_rows );
00266       }
00267     }
00268   else
00269   if(dim == 1)  // row-wise min
00270     {
00271     arma_extra_debug_print("op_min::apply(), dim = 1");
00272     
00273     out.set_size(X.n_rows, 1);
00274     
00275     for(u32 row=0; row<X.n_rows; ++row)
00276       {
00277       u32 index   = 0;
00278       T   min_val = std::abs(X.at(row,index));
00279       
00280       for(u32 col=1; col<X.n_cols; ++col)
00281         {
00282         const T tmp_val = std::abs(X.at(row,col));
00283         
00284         if(tmp_val < min_val)
00285           {
00286           min_val = tmp_val;
00287           index   = col;
00288           }
00289         }
00290       
00291       out[row] = X.at(row,index);
00292       }
00293     
00294     }
00295   
00296   }
00297 
00298 
00299 
00300 //! @}