sortrows.cpp 4.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "sortrows.h"
  9. #include "get_seconds.h"
  10. #include "SortableRow.h"
  11. #include "sort.h"
  12. #include "colon.h"
  13. #include "IndexComparison.h"
  14. #include <vector>
  15. // Obsolete slower version converst to vector
  16. //template <typename DerivedX, typename DerivedIX>
  17. //IGL_INLINE void igl::sortrows(
  18. // const Eigen::PlainObjectBase<DerivedX>& X,
  19. // const bool ascending,
  20. // Eigen::PlainObjectBase<DerivedX>& Y,
  21. // Eigen::PlainObjectBase<DerivedIX>& IX)
  22. //{
  23. // using namespace std;
  24. // using namespace Eigen;
  25. // typedef Eigen::Matrix<typename DerivedX::Scalar, Eigen::Dynamic, 1> RowVector;
  26. // vector<SortableRow<RowVector> > rows;
  27. // rows.resize(X.rows());
  28. // // Loop over rows
  29. // for(int i = 0;i<X.rows();i++)
  30. // {
  31. // RowVector ri = X.row(i);
  32. // rows[i] = SortableRow<RowVector>(ri);
  33. // }
  34. // vector<SortableRow<RowVector> > sorted;
  35. // std::vector<size_t> index_map;
  36. // // Perform sort on rows
  37. // igl::sort(rows,ascending,sorted,index_map);
  38. // // Resize output
  39. // Y.resize(X.rows(),X.cols());
  40. // IX.resize(X.rows(),1);
  41. // // Convert to eigen
  42. // for(int i = 0;i<X.rows();i++)
  43. // {
  44. // Y.row(i) = sorted[i].data;
  45. // IX(i,0) = index_map[i];
  46. // }
  47. //}
  48. template <typename DerivedX, typename DerivedIX>
  49. IGL_INLINE void igl::sortrows(
  50. const Eigen::PlainObjectBase<DerivedX>& X,
  51. const bool ascending,
  52. Eigen::PlainObjectBase<DerivedX>& Y,
  53. Eigen::PlainObjectBase<DerivedIX>& IX)
  54. {
  55. // This is already 2x faster than matlab's builtin `sortrows`. I have tried
  56. // implementing a "multiple-pass" sort on each column, but see no performance
  57. // improvement.
  58. using namespace std;
  59. using namespace Eigen;
  60. // Resize output
  61. Y.resize(X.rows(),X.cols());
  62. IX.resize(X.rows(),1);
  63. for(int i = 0;i<X.rows();i++)
  64. {
  65. IX(i) = i;
  66. }
  67. std::sort(
  68. IX.data(),
  69. IX.data()+IX.size(),
  70. igl::IndexRowLessThan<const Eigen::PlainObjectBase<DerivedX> & >(X));
  71. // if not ascending then reverse
  72. if(!ascending)
  73. {
  74. std::reverse(IX.data(),IX.data()+IX.size());
  75. }
  76. for(int i = 0;i<X.rows();i++)
  77. {
  78. Y.row(i) = X.row(IX(i));
  79. }
  80. }
  81. #ifdef IGL_STATIC_LIBRARY
  82. template void igl::sortrows<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&, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  83. template void igl::sortrows<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&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  84. template void igl::sortrows<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&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  85. template void igl::sortrows<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  86. template void igl::sortrows<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  87. template void igl::sortrows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  88. template void igl::sortrows<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&, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  89. #endif