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