sort.cpp 2.7 KB

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