unique.cpp 10 KB

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