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