fn_sort_index.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 fn_sort_index
00017 //! @{
00018 
00019 
00020 
00021 
00022 template<typename T1, typename T2>
00023 struct arma_sort_index_packet_ascend
00024   {
00025   T1 val;
00026   T2 index;
00027   };
00028 
00029 
00030 
00031 template<typename T1, typename T2>
00032 struct arma_sort_index_packet_descend
00033   {
00034   T1 val;
00035   T2 index;
00036   };
00037 
00038 
00039 
00040 template<typename T1, typename T2>
00041 inline
00042 bool
00043 operator< (const arma_sort_index_packet_ascend<T1,T2>& A, const arma_sort_index_packet_ascend<T1,T2>& B)
00044   {
00045   return A.val < B.val;
00046   }
00047 
00048 
00049 
00050 template<typename T1, typename T2>
00051 inline
00052 bool
00053 operator< (const arma_sort_index_packet_descend<T1,T2>& A, const arma_sort_index_packet_descend<T1,T2>& B)
00054   {
00055   return A.val > B.val;
00056   }
00057 
00058 
00059 
00060 template<typename umat_elem_type, typename packet_type, typename eT>
00061 void
00062 inline
00063 sort_index_helper(umat_elem_type* out_mem, std::vector<packet_type>& packet_vec, const eT* in_mem)
00064   {
00065   arma_extra_debug_sigprint();
00066   
00067   const u32 n_elem = packet_vec.size();
00068   
00069   for(u32 i=0; i<n_elem; ++i)
00070     {
00071     packet_vec[i].val   = in_mem[i];
00072     packet_vec[i].index = i;
00073     }
00074   
00075   std::sort( packet_vec.begin(), packet_vec.end() );
00076   
00077   for(u32 i=0; i<n_elem; ++i)
00078     {
00079     out_mem[i] = packet_vec[i].index;
00080     }
00081   }
00082 
00083 
00084 
00085 template<typename T>
00086 struct sort_index_result_type_deducer
00087   {
00088   typedef umat out_type;
00089   };
00090   
00091 
00092 
00093 //template<>
00094 template<typename eT>
00095 struct sort_index_result_type_deducer< Col<eT> >
00096   {
00097   typedef ucolvec out_type;
00098   };
00099 
00100 
00101 
00102 //template<>
00103 template<typename eT>
00104 struct sort_index_result_type_deducer< Row<eT> >
00105   {
00106   typedef urowvec out_type;
00107   };
00108 
00109 
00110 
00111 template<typename T1>
00112 inline
00113 typename sort_index_result_type_deducer<T1>::out_type
00114 sort_index(const Base_vec<typename T1::elem_type,T1>& X, const u32 sort_type = 0)
00115   {
00116   arma_extra_debug_sigprint();
00117   
00118   typedef typename T1::elem_type eT;
00119   
00120   arma_type_check< is_complex<eT>::value == true>::apply();
00121   
00122   const unwrap<T1> tmp(X.get_ref());
00123   const Mat<eT>& A = tmp.M;
00124   
00125   arma_debug_check( (A.is_vec() == false), "sort_index(): internal error: expected a vector");
00126   
00127   typedef typename sort_index_result_type_deducer<T1>::out_type out_type;
00128   typedef typename out_type::elem_type out_elem_type;
00129   
00130   out_type out(A.n_elem);
00131   
00132   
00133   if(sort_type == 0)
00134     {
00135     std::vector< arma_sort_index_packet_ascend<eT,out_elem_type> > packet_vec(A.n_elem);
00136     
00137     sort_index_helper(out.memptr(), packet_vec, A.mem);
00138     
00139     return out;
00140     }
00141   else
00142     {
00143     std::vector< arma_sort_index_packet_descend<eT,out_elem_type> > packet_vec(A.n_elem);
00144     
00145     sort_index_helper(out.memptr(), packet_vec, A.mem);
00146     
00147     return out;
00148     }
00149   
00150   }
00151 
00152 
00153 //! @}