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 template <class T>
00080 void mbl_index_sort(const vcl_vector<T>& data, vcl_vector<unsigned>& index)
00081 {
00082   mbl_index_sort_cmp2<T> c;
00083   c.data = &data;
00084 
00085   unsigned n = data.size();
00086   index.resize(n);
00087   for (unsigned i =0;i < n; ++i) index[i] = i;
00088 
00089   vcl_sort(index.begin(), index.end(), c);
00090 }
00091 
00092 //: A comparator for general index sorting.
00093 // It will take any type of index on to any sort of container
00094 // so long as T container.operator[](index) const is defined.
00095 // 
00096 // For example, a simple index sort can be done as follows.
00097 // \code
00098 //  vcl_vector data<double> (n);
00099 //  vcl_vector index<unsigned> (n/2);
00100 //  ...
00101 //  vcl_sort(index.begin(), index.end(), mbl_index_sort_cmp<double>(data));
00102 // \endcode
00103 template <class T, class INDEX=unsigned, class CONT = vcl_vector<T>,
00104   class CMP=vcl_less<T> >
00105   struct mbl_index_sort_cmp: public vcl_binary_function<INDEX, INDEX, bool>
00106 {
00107   explicit mbl_index_sort_cmp(const CONT &data, const CMP &c = CMP()):
00108     data_(data), cmp_(c) {}
00109   const CONT &data_;
00110   const CMP &cmp_;
00111   bool operator () (const INDEX &a, const INDEX &b) const
00112   {  return cmp_(data_[a], data_[b]); } 
00113 };
00114 
00115 
00116 #endif // mbl_index_sort_h_