sort.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "sort.h"
  2. #include <algorithm>
  3. #include "reorder.h"
  4. template <typename DerivedX, typename DerivedIX>
  5. IGL_INLINE void igl::sort(
  6. const Eigen::PlainObjectBase<DerivedX>& X,
  7. const int dim,
  8. const bool ascending,
  9. Eigen::PlainObjectBase<DerivedX>& Y,
  10. Eigen::PlainObjectBase<DerivedIX>& IX)
  11. {
  12. using namespace Eigen;
  13. // dim must be 2 or 1
  14. assert(dim == 1 || dim == 2);
  15. // Resize output
  16. Y.resize(X.rows(),X.cols());
  17. IX.resize(X.rows(),X.cols());
  18. // idea is to process each column (or row) as a std vector
  19. // get number of columns (or rows)
  20. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  21. // get number of rows (or columns)
  22. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  23. // loop over columns (or rows)
  24. for(int i = 0; i<num_outer;i++)
  25. {
  26. // Unsorted index map for this column (or row)
  27. std::vector<size_t> index_map(num_inner);
  28. std::vector<double> data(num_inner);
  29. for(int j = 0;j<num_inner;j++)
  30. {
  31. if(dim == 1)
  32. {
  33. data[j] = (double) X(j,i);
  34. }else
  35. {
  36. data[j] = (double) X(i,j);
  37. }
  38. }
  39. // sort this column (or row)
  40. igl::sort( data, ascending, data, index_map);
  41. // Copy into Y and IX
  42. for(int j = 0;j<num_inner;j++)
  43. {
  44. if(dim == 1)
  45. {
  46. Y(j,i) = data[j];
  47. IX(j,i) = index_map[j];
  48. }else
  49. {
  50. Y(i,j) = data[j];
  51. IX(i,j) = index_map[j];
  52. }
  53. }
  54. }
  55. }
  56. // Comparison struct used by sort
  57. // http://bytes.com/topic/c/answers/132045-sort-get-index
  58. namespace igl{
  59. template<class T> struct index_cmp
  60. {
  61. index_cmp(const T arr) : arr(arr) {}
  62. bool operator()(const size_t a, const size_t b) const
  63. {
  64. return arr[a] < arr[b];
  65. }
  66. const T arr;
  67. };
  68. }
  69. template <class T>
  70. IGL_INLINE void igl::sort(
  71. const std::vector<T> & unsorted,
  72. const bool ascending,
  73. std::vector<T> & sorted,
  74. std::vector<size_t> & index_map)
  75. {
  76. // Original unsorted index map
  77. index_map.resize(unsorted.size());
  78. for(size_t i=0;i<unsorted.size();i++)
  79. {
  80. index_map[i] = i;
  81. }
  82. // Sort the index map, using unsorted for comparison
  83. std::sort(
  84. index_map.begin(),
  85. index_map.end(),
  86. igl::index_cmp<const std::vector<T>& >(unsorted));
  87. // if not ascending then reverse
  88. if(!ascending)
  89. {
  90. std::reverse(index_map.begin(),index_map.end());
  91. }
  92. // make space for output without clobbering
  93. sorted.resize(unsorted.size());
  94. // reorder unsorted into sorted using index map
  95. igl::reorder(unsorted,index_map,sorted);
  96. }
  97. #ifndef IGL_HEADER_ONLY
  98. // Explicit template specialization
  99. // generated by autoexplicit.sh
  100. template void igl::sort<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  101. #endif