contrib/mul/mbl/mbl_index_sort.h
Go to the documentation of this file.
00001 #ifndef mbl_index_sort_h_
00002 #define mbl_index_sort_h_
00003 //:
00004 // \file
00005 // \brief Algorithm to produce list of sorted data indices
00006 // \author Ian Scott
00007 
00008 #include <vcl_vector.h>
00009 #include <vcl_algorithm.h>
00010 #include <vcl_functional.h>
00011 
00012 //: Implementation class - Do No Use.
00013 template <class T>
00014 struct mbl_index_sort_cmp1
00015 {
00016   const T *data;
00017   bool operator () (const unsigned &a, const unsigned &b)
00018   {
00019     return data[a] < data[b];
00020   }
00021 };
00022 
00023 //: Sort n elements, giving the resulting order in index.
00024 //  data[index[0]] is smallest element, data[index[n-1]] is largest
00025 template <class T>
00026 void mbl_index_sort(const T* data, int n, vcl_vector<int>& index)
00027 {
00028   mbl_index_sort_cmp1<T> c;
00029   c.data = data;
00030 
00031   index.resize(n);
00032   for (int i =0;i < n; ++i) index[i] = i;
00033 
00034   vcl_sort(index.begin(), index.end(), c);
00035 }
00036 
00037 //: Sort n elements, giving the resulting order in index.
00038 //  data[index[0]] is smallest element, data[index[n-1]] is largest
00039 template <class T>
00040 void mbl_index_sort(const T* data, unsigned n, vcl_vector<unsigned>& index)
00041 {
00042   mbl_index_sort_cmp1<T> c;
00043   c.data = data;
00044 
00045   index.resize(n);
00046   for (unsigned i =0;i < n; ++i) index[i] = i;
00047 
00048   vcl_sort(index.begin(), index.end(), c);
00049 }
00050 
00051 //: Implementation class - Do No Use.
00052 template <class T>
00053 struct mbl_index_sort_cmp2
00054 {
00055   const vcl_vector<T> *data;
00056   bool operator () (const unsigned &a, const unsigned &b)
00057   {
00058     return (*data)[a] < (*data)[b];
00059   }
00060 };
00061 
00062 //: Sort n elements, giving the resulting order in index
00063 //  data[index[0]] is smallest element, data[index[n-1]] is largest
00064 template <class T>
00065 void mbl_index_sort(const vcl_vector<T>& data, vcl_vector<int>& index)
00066 {
00067   mbl_index_sort_cmp2<T> c;
00068   c.data = &data;
00069 
00070   unsigned n = data.size();
00071   index.resize(n);
00072   for (unsigned i =0;i < n; ++i) index[i] = i;
00073 
00074   vcl_sort(index.begin(), index.end(), c);
00075 }
00076 
00077 //: Sort n elements, giving the resulting order in index
00078 //  data[index[0]] is smallest element, data[index[n-1]] is largest
00079 //  \note to get a sorted list, apply sorted[i] = data[index[i]], for all i.
00080 template <class T>
00081 void mbl_index_sort(const vcl_vector<T>& data, vcl_vector<unsigned>& index)
00082 {
00083   mbl_index_sort_cmp2<T> c;
00084   c.data = &data;
00085 
00086   unsigned n = data.size();
00087   index.resize(n);
00088   for (unsigned i =0;i < n; ++i) index[i] = i;
00089 
00090   vcl_sort(index.begin(), index.end(), c);
00091 }
00092 
00093 //: A comparator for general index sorting.
00094 // It will take any type of index on to any sort of container
00095 // so long as T container.operator[](index) const is defined.
00096 // 
00097 // For example, a simple index sort can be done as follows.
00098 // \code
00099 //  vcl_vector<double> data (n);
00100 //  vcl_vector<unsigned> index (n/2);
00101 //  ...
00102 //  vcl_sort(index.begin(), index.end(), mbl_index_sort_cmp<double>(data));
00103 // \endcode
00104 template <class T, class INDEX=unsigned, class CONT = vcl_vector<T>,
00105   class CMP=vcl_less<T> >
00106   struct mbl_index_sort_cmp: public vcl_binary_function<INDEX, INDEX, bool>
00107 {
00108   explicit mbl_index_sort_cmp(const CONT &data, const CMP &c = CMP()):
00109     data_(data), cmp_(c) {}
00110   const CONT &data_;
00111   const CMP &cmp_;
00112   bool operator () (const INDEX &a, const INDEX &b) const
00113   {  return cmp_(data_[a], data_[b]); } 
00114 };
00115 
00116 
00117 #endif // mbl_index_sort_h_