sort.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "sort.h"
  2. #include "SortableRow.h"
  3. #include "reorder.h"
  4. #include "IndexComparison.h"
  5. #include <cassert>
  6. #include <algorithm>
  7. template <typename DerivedX, typename DerivedIX>
  8. IGL_INLINE void igl::sort(
  9. const Eigen::PlainObjectBase<DerivedX>& X,
  10. const int dim,
  11. const bool ascending,
  12. Eigen::PlainObjectBase<DerivedX>& Y,
  13. Eigen::PlainObjectBase<DerivedIX>& IX)
  14. {
  15. using namespace Eigen;
  16. // dim must be 2 or 1
  17. assert(dim == 1 || dim == 2);
  18. // Resize output
  19. Y.resize(X.rows(),X.cols());
  20. IX.resize(X.rows(),X.cols());
  21. // idea is to process each column (or row) as a std vector
  22. // get number of columns (or rows)
  23. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  24. // get number of rows (or columns)
  25. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  26. // loop over columns (or rows)
  27. for(int i = 0; i<num_outer;i++)
  28. {
  29. // Unsorted index map for this column (or row)
  30. std::vector<size_t> index_map(num_inner);
  31. std::vector<double> data(num_inner);
  32. for(int j = 0;j<num_inner;j++)
  33. {
  34. if(dim == 1)
  35. {
  36. data[j] = (double) X(j,i);
  37. }else
  38. {
  39. data[j] = (double) X(i,j);
  40. }
  41. }
  42. // sort this column (or row)
  43. igl::sort( data, ascending, data, 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. template <class T>
  60. IGL_INLINE void igl::sort(
  61. const std::vector<T> & unsorted,
  62. const bool ascending,
  63. std::vector<T> & sorted,
  64. std::vector<size_t> & index_map)
  65. {
  66. // Original unsorted index map
  67. index_map.resize(unsorted.size());
  68. for(size_t i=0;i<unsorted.size();i++)
  69. {
  70. index_map[i] = i;
  71. }
  72. // Sort the index map, using unsorted for comparison
  73. std::sort(
  74. index_map.begin(),
  75. index_map.end(),
  76. igl::IndexLessThan<const std::vector<T>& >(unsorted));
  77. // if not ascending then reverse
  78. if(!ascending)
  79. {
  80. std::reverse(index_map.begin(),index_map.end());
  81. }
  82. // make space for output without clobbering
  83. sorted.resize(unsorted.size());
  84. // reorder unsorted into sorted using index map
  85. igl::reorder(unsorted,index_map,sorted);
  86. }
  87. #ifndef IGL_HEADER_ONLY
  88. // Explicit template specialization
  89. // generated by autoexplicit.sh
  90. 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> >&);
  91. template void igl::sort<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  92. template void igl::sort<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > >(std::vector<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > > const&, bool, std::vector<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
  93. template void igl::sort<int>(std::vector<int, std::allocator<int> > const&, bool, std::vector<int, std::allocator<int> >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
  94. template void igl::sort<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(std::vector<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > const&, bool, std::vector<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
  95. #endif