fn_sort_index.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 fn_sort_index
00018 //! @{
00019 
00020 
00021 
00022 
00023 template<typename T1, typename T2>
00024 struct arma_sort_index_packet_ascend
00025   {
00026   T1 val;
00027   T2 index;
00028   };
00029 
00030 
00031 
00032 template<typename T1, typename T2>
00033 struct arma_sort_index_packet_descend
00034   {
00035   T1 val;
00036   T2 index;
00037   };
00038 
00039 
00040 
00041 template<typename T1, typename T2>
00042 inline
00043 bool
00044 operator< (const arma_sort_index_packet_ascend<T1,T2>& A, const arma_sort_index_packet_ascend<T1,T2>& B)
00045   {
00046   return A.val < B.val;
00047   }
00048 
00049 
00050 
00051 template<typename T1, typename T2>
00052 inline
00053 bool
00054 operator< (const arma_sort_index_packet_descend<T1,T2>& A, const arma_sort_index_packet_descend<T1,T2>& B)
00055   {
00056   return A.val > B.val;
00057   }
00058 
00059 
00060 
00061 template<typename umat_elem_type, typename packet_type, typename eT>
00062 void
00063 inline
00064 sort_index_helper(umat_elem_type* out_mem, std::vector<packet_type>& packet_vec, const eT* in_mem)
00065   {
00066   arma_extra_debug_sigprint();
00067   
00068   const u32 n_elem = packet_vec.size();
00069   
00070   for(u32 i=0; i<n_elem; ++i)
00071     {
00072     packet_vec[i].val   = in_mem[i];
00073     packet_vec[i].index = i;
00074     }
00075   
00076   std::sort( packet_vec.begin(), packet_vec.end() );
00077   
00078   for(u32 i=0; i<n_elem; ++i)
00079     {
00080     out_mem[i] = packet_vec[i].index;
00081     }
00082   }
00083 
00084 
00085 
00086 template<typename T1>
00087 inline
00088 umat
00089 sort_index(const Base<typename T1::elem_type,T1>& X, const u32 sort_type = 0)
00090   {
00091   arma_extra_debug_sigprint();
00092   
00093   typedef typename T1::elem_type eT;
00094   
00095   arma_type_check< is_complex<eT>::value == true>::apply();
00096   
00097   const unwrap<T1> tmp(X.get_ref());
00098   const Mat<eT>& A = tmp.M;
00099   
00100   arma_debug_check( (A.is_vec() == false), "sort_index(): currently only handles vectors");
00101   
00102   typedef typename umat::elem_type out_elem_type;
00103   
00104   umat out(A.n_rows, A.n_cols);
00105   
00106   if(sort_type == 0)
00107     {
00108     std::vector< arma_sort_index_packet_ascend<eT,out_elem_type> > packet_vec(A.n_elem);
00109     
00110     sort_index_helper(out.memptr(), packet_vec, A.mem);
00111     }
00112   else
00113     {
00114     std::vector< arma_sort_index_packet_descend<eT,out_elem_type> > packet_vec(A.n_elem);
00115     
00116     sort_index_helper(out.memptr(), packet_vec, A.mem);
00117     }
00118   
00119   return out;
00120   }
00121 
00122 
00123 //! @}