slice.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include "slice.h"
  2. #include <vector>
  3. template <typename T>
  4. IGL_INLINE void igl::slice(
  5. const Eigen::SparseMatrix<T>& X,
  6. const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  7. const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
  8. Eigen::SparseMatrix<T>& Y)
  9. {
  10. int xm = X.rows();
  11. int xn = X.cols();
  12. int ym = R.size();
  13. int yn = C.size();
  14. // special case when R or C is empty
  15. if(ym == 0 || yn == 0)
  16. {
  17. Y.resize(ym,yn);
  18. return;
  19. }
  20. assert(R.minCoeff() >= 0);
  21. assert(R.maxCoeff() < xm);
  22. assert(C.minCoeff() >= 0);
  23. assert(C.maxCoeff() < xn);
  24. // Build reindexing maps for columns and rows, -1 means not in map
  25. std::vector<std::vector<int> > RI;
  26. RI.resize(xm);
  27. for(int i = 0;i<ym;i++)
  28. {
  29. RI[R(i)].push_back(i);
  30. }
  31. std::vector<std::vector<int> > CI;
  32. CI.resize(xn);
  33. // initialize to -1
  34. for(int i = 0;i<yn;i++)
  35. {
  36. CI[C(i)].push_back(i);
  37. }
  38. // Resize output
  39. Eigen::DynamicSparseMatrix<T, Eigen::RowMajor> dyn_Y(ym,yn);
  40. // Take a guess at the number of nonzeros (this assumes uniform distribution
  41. // not banded or heavily diagonal)
  42. dyn_Y.reserve((X.nonZeros()/(X.rows()*X.cols())) * (ym*yn));
  43. // Iterate over outside
  44. for(int k=0; k<X.outerSize(); ++k)
  45. {
  46. // Iterate over inside
  47. for(typename Eigen::SparseMatrix<T>::InnerIterator it (X,k); it; ++it)
  48. {
  49. std::vector<int>::iterator rit, cit;
  50. for(rit = RI[it.row()].begin();rit != RI[it.row()].end(); rit++)
  51. {
  52. for(cit = CI[it.col()].begin();cit != CI[it.col()].end(); cit++)
  53. {
  54. dyn_Y.coeffRef(*rit,*cit) = it.value();
  55. }
  56. }
  57. }
  58. }
  59. Y = Eigen::SparseMatrix<T>(dyn_Y);
  60. }
  61. template <typename DerivedX>
  62. IGL_INLINE void igl::slice(
  63. const Eigen::PlainObjectBase<DerivedX> & X,
  64. const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  65. const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
  66. Eigen::PlainObjectBase<DerivedX> & Y)
  67. {
  68. int xm = X.rows();
  69. int xn = X.cols();
  70. int ym = R.size();
  71. int yn = C.size();
  72. // special case when R or C is empty
  73. if(ym == 0 || yn == 0)
  74. {
  75. Y.resize(ym,yn);
  76. return;
  77. }
  78. assert(R.minCoeff() >= 0);
  79. assert(R.maxCoeff() < xm);
  80. assert(C.minCoeff() >= 0);
  81. assert(C.maxCoeff() < xn);
  82. // Resize output
  83. Y.resize(ym,yn);
  84. // loop over output rows, then columns
  85. for(int i = 0;i<ym;i++)
  86. {
  87. for(int j = 0;j<yn;j++)
  88. {
  89. Y(i,j) = X(R(i),C(j));
  90. }
  91. }
  92. }
  93. template <typename DerivedX>
  94. IGL_INLINE void igl::slice(
  95. const Eigen::PlainObjectBase<DerivedX> & X,
  96. const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  97. Eigen::PlainObjectBase<DerivedX> & Y)
  98. {
  99. // phony column indices
  100. Eigen::Matrix<int,Eigen::Dynamic,1> C;
  101. C.resize(1);
  102. C(0) = 0;
  103. return igl::slice(X,R,C,Y);
  104. }
  105. #ifndef IGL_HEADER_ONLY
  106. // Explicit template specialization
  107. // generated by autoexplicit.sh
  108. template void igl::slice<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  109. // generated by autoexplicit.sh
  110. template void igl::slice<Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
  111. // generated by autoexplicit.sh
  112. template void igl::slice<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  113. // generated by autoexplicit.sh
  114. template void igl::slice<Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> >&);
  115. // generated by autoexplicit.sh
  116. template void igl::slice<double>(Eigen::SparseMatrix<double, 0, int> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, Eigen::SparseMatrix<double, 0, int>&);
  117. #endif