unique.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. #include <map>
  9. template <typename T>
  10. IGL_INLINE void igl::unique(
  11. const std::vector<T> & A,
  12. std::vector<T> & C,
  13. std::vector<size_t> & IA,
  14. std::vector<size_t> & IC)
  15. {
  16. using namespace std;
  17. std::vector<size_t> IM;
  18. std::vector<T> sortA;
  19. igl::sort(A,true,sortA,IM);
  20. // Original unsorted index map
  21. IA.resize(sortA.size());
  22. for(int i=0;i<(int)sortA.size();i++)
  23. {
  24. IA[i] = i;
  25. }
  26. IA.erase(
  27. std::unique(
  28. IA.begin(),
  29. IA.end(),
  30. igl::IndexEquals<const std::vector<T>& >(sortA)),IA.end());
  31. IC.resize(A.size());
  32. {
  33. int j = 0;
  34. for(int i = 0;i<(int)sortA.size();i++)
  35. {
  36. if(sortA[IA[j]] != sortA[i])
  37. {
  38. j++;
  39. }
  40. IC[IM[i]] = j;
  41. }
  42. }
  43. C.resize(IA.size());
  44. // Reindex IA according to IM
  45. for(int i = 0;i<(int)IA.size();i++)
  46. {
  47. IA[i] = IM[IA[i]];
  48. C[i] = A[IA[i]];
  49. }
  50. }
  51. template <typename DerivedA, typename DerivedIA, typename DerivedIC>
  52. IGL_INLINE void igl::unique_rows(
  53. const Eigen::PlainObjectBase<DerivedA>& A,
  54. Eigen::PlainObjectBase<DerivedA>& C,
  55. Eigen::PlainObjectBase<DerivedIA>& IA,
  56. Eigen::PlainObjectBase<DerivedIC>& IC)
  57. {
  58. using namespace std;
  59. typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
  60. vector<SortableRow<RowVector> > rows;
  61. rows.resize(A.rows());
  62. // Loop over rows
  63. for(int i = 0;i<A.rows();i++)
  64. {
  65. RowVector ri = A.row(i);
  66. rows[i] = SortableRow<RowVector>(ri);
  67. }
  68. vector<SortableRow<RowVector> > vC;
  69. // unique on rows
  70. vector<size_t> vIA;
  71. vector<size_t> vIC;
  72. unique(rows,vC,vIA,vIC);
  73. // Convert to eigen
  74. C.resize(vC.size(),A.cols());
  75. IA.resize(vIA.size(),1);
  76. IC.resize(vIC.size(),1);
  77. for(int i = 0;i<C.rows();i++)
  78. {
  79. C.row(i) = vC[i].data;
  80. IA(i) = vIA[i];
  81. }
  82. for(int i = 0;i<A.rows();i++)
  83. {
  84. IC(i) = vIC[i];
  85. }
  86. }
  87. template <typename DerivedA, typename DerivedIA, typename DerivedIC>
  88. IGL_INLINE void igl::unique_rows_many(
  89. const Eigen::PlainObjectBase<DerivedA>& A,
  90. Eigen::PlainObjectBase<DerivedA>& C,
  91. Eigen::PlainObjectBase<DerivedIA>& IA,
  92. Eigen::PlainObjectBase<DerivedIC>& IC)
  93. {
  94. using namespace std;
  95. // frequency map
  96. typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
  97. IC.resize(A.rows(),1);
  98. map<SortableRow<RowVector>, int> fm;
  99. const int m = A.rows();
  100. for(int i = 0;i<m;i++)
  101. {
  102. RowVector ri = A.row(i);
  103. if(fm.count(SortableRow<RowVector>(ri)) == 0)
  104. {
  105. fm[SortableRow<RowVector>(ri)] = i;
  106. }
  107. IC(i) = fm[SortableRow<RowVector>(ri)];
  108. }
  109. IA.resize(fm.size(),1);
  110. Eigen::VectorXi RIA(m);
  111. C.resize(fm.size(),A.cols());
  112. {
  113. int i = 0;
  114. for(typename map<SortableRow<RowVector > , int >::const_iterator fit = fm.begin();
  115. fit != fm.end();
  116. fit++)
  117. {
  118. IA(i) = fit->second;
  119. RIA(fit->second) = i;
  120. C.row(i) = fit->first.data;
  121. i++;
  122. }
  123. }
  124. // IC should index C
  125. for(int i = 0;i<m;i++)
  126. {
  127. IC(i) = RIA(IC(i));
  128. }
  129. }
  130. #ifndef IGL_HEADER_ONLY
  131. 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> >&);
  132. 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> >&);
  133. 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> >&);
  134. 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> >&);
  135. 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> >&);
  136. template void igl::unique_rows_many<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> >&);
  137. template void igl::unique_rows_many<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> >&);
  138. #endif