unique.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "unique.h"
  2. #include "sort.h"
  3. #include "IndexComparison.h"
  4. #include "SortableRow.h"
  5. #include "list_to_matrix.h"
  6. #include <algorithm>
  7. #include <iostream>
  8. template <typename T>
  9. IGL_INLINE void igl::unique(
  10. const std::vector<T> & A,
  11. std::vector<T> & C,
  12. std::vector<size_t> & IA,
  13. std::vector<size_t> & IC)
  14. {
  15. using namespace std;
  16. std::vector<size_t> IM;
  17. std::vector<T> sortA;
  18. igl::sort(A,true,sortA,IM);
  19. // Original unsorted index map
  20. IA.resize(sortA.size());
  21. for(int i=0;i<(int)sortA.size();i++)
  22. {
  23. IA[i] = i;
  24. }
  25. IA.erase(
  26. std::unique(
  27. IA.begin(),
  28. IA.end(),
  29. igl::IndexEquals<const std::vector<T>& >(sortA)),IA.end());
  30. IC.resize(A.size());
  31. {
  32. int j = 0;
  33. for(int i = 0;i<(int)sortA.size();i++)
  34. {
  35. if(sortA[IA[j]] != sortA[i])
  36. {
  37. j++;
  38. }
  39. IC[IM[i]] = j;
  40. }
  41. }
  42. C.resize(IA.size());
  43. // Reindex IA according to IM
  44. for(int i = 0;i<(int)IA.size();i++)
  45. {
  46. IA[i] = IM[IA[i]];
  47. C[i] = A[IA[i]];
  48. }
  49. }
  50. template <typename DerivedA, typename DerivedIA, typename DerivedIC>
  51. IGL_INLINE void igl::unique_rows(
  52. const Eigen::PlainObjectBase<DerivedA>& A,
  53. Eigen::PlainObjectBase<DerivedA>& C,
  54. Eigen::PlainObjectBase<DerivedIA>& IA,
  55. Eigen::PlainObjectBase<DerivedIC>& IC)
  56. {
  57. using namespace std;
  58. typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
  59. vector<SortableRow<RowVector> > rows;
  60. rows.resize(A.rows());
  61. // Loop over rows
  62. for(int i = 0;i<A.rows();i++)
  63. {
  64. RowVector ri = A.row(i);
  65. rows[i] = SortableRow<RowVector>(ri);
  66. }
  67. vector<SortableRow<RowVector> > vC;
  68. // unique on rows
  69. vector<size_t> vIA;
  70. vector<size_t> vIC;
  71. unique(rows,vC,vIA,vIC);
  72. // Convert to eigen
  73. C.resize(vC.size(),A.cols());
  74. IA.resize(vIA.size(),1);
  75. IC.resize(vIC.size(),1);
  76. for(int i = 0;i<C.rows();i++)
  77. {
  78. C.row(i) = vC[i].data;
  79. IA(i) = vIA[i];
  80. }
  81. for(int i = 0;i<A.rows();i++)
  82. {
  83. IC(i) = vIC[i];
  84. }
  85. }
  86. #ifndef IGL_HEADER_ONLY
  87. template void igl::unique<int>(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&, std::vector<size_t, std::allocator<size_t> >&, std::vector<size_t, std::allocator<size_t> >&);
  88. template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, 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&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  89. template void igl::unique_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  90. template void igl::unique_rows<Eigen::Matrix<int, -1, -1, 0, -1, -1>, 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&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  91. #endif