unique.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include "unique.h"
  2. #include "sort.h"
  3. #include "IndexComparison.h"
  4. #include "SortableRow.h"
  5. #include "sortrows.h"
  6. #include "list_to_matrix.h"
  7. #include <algorithm>
  8. #include <iostream>
  9. #include <map>
  10. template <typename T>
  11. IGL_INLINE void igl::unique(
  12. const std::vector<T> & A,
  13. std::vector<T> & C,
  14. std::vector<size_t> & IA,
  15. std::vector<size_t> & IC)
  16. {
  17. using namespace std;
  18. std::vector<size_t> IM;
  19. std::vector<T> sortA;
  20. igl::sort(A,true,sortA,IM);
  21. // Original unsorted index map
  22. IA.resize(sortA.size());
  23. for(int i=0;i<(int)sortA.size();i++)
  24. {
  25. IA[i] = i;
  26. }
  27. IA.erase(
  28. std::unique(
  29. IA.begin(),
  30. IA.end(),
  31. igl::IndexEquals<const std::vector<T>& >(sortA)),IA.end());
  32. IC.resize(A.size());
  33. {
  34. int j = 0;
  35. for(int i = 0;i<(int)sortA.size();i++)
  36. {
  37. if(sortA[IA[j]] != sortA[i])
  38. {
  39. j++;
  40. }
  41. IC[IM[i]] = j;
  42. }
  43. }
  44. C.resize(IA.size());
  45. // Reindex IA according to IM
  46. for(int i = 0;i<(int)IA.size();i++)
  47. {
  48. IA[i] = IM[IA[i]];
  49. C[i] = A[IA[i]];
  50. }
  51. }
  52. // Obsolete slow version converting to vectors
  53. // template <typename DerivedA, typename DerivedIA, typename DerivedIC>
  54. // IGL_INLINE void igl::unique_rows(
  55. // const Eigen::PlainObjectBase<DerivedA>& A,
  56. // Eigen::PlainObjectBase<DerivedA>& C,
  57. // Eigen::PlainObjectBase<DerivedIA>& IA,
  58. // Eigen::PlainObjectBase<DerivedIC>& IC)
  59. // {
  60. // using namespace std;
  61. //
  62. // typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
  63. // vector<SortableRow<RowVector> > rows;
  64. // rows.resize(A.rows());
  65. // // Loop over rows
  66. // for(int i = 0;i<A.rows();i++)
  67. // {
  68. // RowVector ri = A.row(i);
  69. // rows[i] = SortableRow<RowVector>(ri);
  70. // }
  71. // vector<SortableRow<RowVector> > vC;
  72. //
  73. // // unique on rows
  74. // vector<size_t> vIA;
  75. // vector<size_t> vIC;
  76. // unique(rows,vC,vIA,vIC);
  77. //
  78. // // Convert to eigen
  79. // C.resize(vC.size(),A.cols());
  80. // IA.resize(vIA.size(),1);
  81. // IC.resize(vIC.size(),1);
  82. // for(int i = 0;i<C.rows();i++)
  83. // {
  84. // C.row(i) = vC[i].data;
  85. // IA(i) = vIA[i];
  86. // }
  87. // for(int i = 0;i<A.rows();i++)
  88. // {
  89. // IC(i) = vIC[i];
  90. // }
  91. // }
  92. // Obsolete
  93. // template <typename DerivedA, typename DerivedIA, typename DerivedIC>
  94. // IGL_INLINE void igl::unique_rows_many(
  95. // const Eigen::PlainObjectBase<DerivedA>& A,
  96. // Eigen::PlainObjectBase<DerivedA>& C,
  97. // Eigen::PlainObjectBase<DerivedIA>& IA,
  98. // Eigen::PlainObjectBase<DerivedIC>& IC)
  99. // {
  100. // using namespace std;
  101. // // frequency map
  102. // typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
  103. // IC.resize(A.rows(),1);
  104. // map<SortableRow<RowVector>, int> fm;
  105. // const int m = A.rows();
  106. // for(int i = 0;i<m;i++)
  107. // {
  108. // RowVector ri = A.row(i);
  109. // if(fm.count(SortableRow<RowVector>(ri)) == 0)
  110. // {
  111. // fm[SortableRow<RowVector>(ri)] = i;
  112. // }
  113. // IC(i) = fm[SortableRow<RowVector>(ri)];
  114. // }
  115. // IA.resize(fm.size(),1);
  116. // Eigen::VectorXi RIA(m);
  117. // C.resize(fm.size(),A.cols());
  118. // {
  119. // int i = 0;
  120. // for(typename map<SortableRow<RowVector > , int >::const_iterator fit = fm.begin();
  121. // fit != fm.end();
  122. // fit++)
  123. // {
  124. // IA(i) = fit->second;
  125. // RIA(fit->second) = i;
  126. // C.row(i) = fit->first.data;
  127. // i++;
  128. // }
  129. // }
  130. // // IC should index C
  131. // for(int i = 0;i<m;i++)
  132. // {
  133. // IC(i) = RIA(IC(i));
  134. // }
  135. // }
  136. template <typename DerivedA, typename DerivedIA, typename DerivedIC>
  137. IGL_INLINE void igl::unique_rows(
  138. const Eigen::PlainObjectBase<DerivedA>& A,
  139. Eigen::PlainObjectBase<DerivedA>& C,
  140. Eigen::PlainObjectBase<DerivedIA>& IA,
  141. Eigen::PlainObjectBase<DerivedIC>& IC)
  142. {
  143. using namespace std;
  144. using namespace igl;
  145. using namespace Eigen;
  146. VectorXi IM;
  147. Eigen::PlainObjectBase<DerivedA> sortA;
  148. sortrows(A,true,sortA,IM);
  149. vector<int> vIA(sortA.rows());
  150. for(int i=0;i<(int)sortA.rows();i++)
  151. {
  152. vIA[i] = i;
  153. }
  154. vIA.erase(
  155. std::unique(
  156. vIA.begin(),
  157. vIA.end(),
  158. igl::IndexRowEquals<const Eigen::PlainObjectBase<DerivedA> &>(sortA)),vIA.end());
  159. IC.resize(A.rows(),1);
  160. {
  161. int j = 0;
  162. for(int i = 0;i<(int)sortA.rows();i++)
  163. {
  164. if(sortA.row(vIA[j]) != sortA.row(i))
  165. {
  166. j++;
  167. }
  168. IC(IM(i,0),0) = j;
  169. }
  170. }
  171. C.resize(vIA.size(),A.cols());
  172. IA.resize(vIA.size(),1);
  173. // Reindex IA according to IM
  174. for(int i = 0;i<(int)vIA.size();i++)
  175. {
  176. IA(i,0) = IM(vIA[i],0);
  177. C.row(i) = A.row(IA(i,0));
  178. }
  179. }
  180. #ifndef IGL_HEADER_ONLY
  181. 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> >&);
  182. 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> >&);
  183. 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> >&);
  184. 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> >&);
  185. 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> >&);
  186. template void igl::unique_rows<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  187. #endif