setdiff.cpp 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 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 "setdiff.h"
  9. #include "LinSpaced.h"
  10. #include "list_to_matrix.h"
  11. #include "sort.h"
  12. #include "unique.h"
  13. template <
  14. typename DerivedA,
  15. typename DerivedB,
  16. typename DerivedC,
  17. typename DerivedIA>
  18. IGL_INLINE void igl::setdiff(
  19. const Eigen::DenseBase<DerivedA> & A,
  20. const Eigen::DenseBase<DerivedB> & B,
  21. Eigen::PlainObjectBase<DerivedC> & C,
  22. Eigen::PlainObjectBase<DerivedIA> & IA)
  23. {
  24. using namespace Eigen;
  25. using namespace std;
  26. // boring base cases
  27. if(A.size() == 0)
  28. {
  29. C.resize(0,1);
  30. IA.resize(0,1);
  31. }
  32. if(B.size() == 0)
  33. {
  34. C.resize(A.size(),1);
  35. int k = 0;
  36. for(int j = 0;j<A.cols();j++)
  37. {
  38. for(int i = 0;i<A.rows();i++)
  39. {
  40. C(k++) = A(i,j);
  41. }
  42. }
  43. assert(k == C.size());
  44. // Have to use << instead of = because Eigen's PlainObjectBase is annoying
  45. IA << igl::LinSpaced<Eigen::Matrix<typename DerivedIA::Scalar,Eigen::Dynamic,1> >(
  46. C.size(),0,C.size()-1);
  47. }
  48. // Get rid of any duplicates
  49. typedef Matrix<typename DerivedA::Scalar,Dynamic,1> VectorA;
  50. typedef Matrix<typename DerivedB::Scalar,Dynamic,1> VectorB;
  51. VectorA uA;
  52. VectorB uB;
  53. typedef DerivedIA IAType;
  54. IAType uIA,uIuA,uIB,uIuB;
  55. unique(A,uA,uIA,uIuA);
  56. unique(B,uB,uIB,uIuB);
  57. // Sort both
  58. VectorA sA;
  59. VectorB sB;
  60. IAType sIA,sIB;
  61. sort(uA,1,true,sA,sIA);
  62. sort(uB,1,true,sB,sIB);
  63. vector<typename DerivedB::Scalar> vC;
  64. vector<typename DerivedIA::Scalar> vIA;
  65. int bi = 0;
  66. // loop over sA
  67. bool past = false;
  68. for(int a = 0;a<sA.size();a++)
  69. {
  70. while(!past && sA(a)>sB(bi))
  71. {
  72. bi++;
  73. past = bi>=sB.size();
  74. }
  75. if(past || sA(a)<sB(bi))
  76. {
  77. // then sA(a) did not appear in sB
  78. vC.push_back(sA(a));
  79. vIA.push_back(uIA(sIA(a)));
  80. }
  81. }
  82. list_to_matrix(vC,C);
  83. list_to_matrix(vIA,IA);
  84. }
  85. #ifdef IGL_STATIC_LIBRARY
  86. // Explicit template instantiation
  87. // generated by autoexplicit.sh
  88. template void igl::setdiff<Eigen::Matrix<int, -1, 2, 0, -1, 2>, 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::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, Eigen::DenseBase<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> >&);
  89. template void igl::setdiff<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::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::DenseBase<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> >&);
  90. template void igl::setdiff<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::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::DenseBase<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> >&);
  91. template void igl::setdiff<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::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::DenseBase<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> >&);
  92. #endif