slice_into.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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 "slice_into.h"
  9. #include "colon.h"
  10. #include "sort.h"
  11. // Bug in unsupported/Eigen/SparseExtra needs iostream first
  12. #include <iostream>
  13. #include <unsupported/Eigen/SparseExtra>
  14. template <typename T, typename DerivedR, typename DerivedC>
  15. IGL_INLINE void igl::slice_into(
  16. const Eigen::SparseMatrix<T>& X,
  17. const Eigen::MatrixBase<DerivedR> & R,
  18. const Eigen::MatrixBase<DerivedC> & C,
  19. Eigen::SparseMatrix<T>& Y)
  20. {
  21. const int xm = X.rows();
  22. const int xn = X.cols();
  23. assert(R.size() == xm);
  24. assert(C.size() == xn);
  25. const int ym = Y.rows();
  26. const int yn = Y.cols();
  27. assert(R.minCoeff() >= 0);
  28. assert(R.maxCoeff() < ym);
  29. assert(C.minCoeff() >= 0);
  30. assert(C.maxCoeff() < yn);
  31. std::vector<bool> in_R(Y.rows());
  32. for(int r = 0;r<R.size();r++) { in_R[R(r)] = true; }
  33. // Rebuild each column in C
  34. for(int c = 0;c<C.size();c++)
  35. {
  36. int k = C(c);
  37. Eigen::SparseVector<T> Yk = Y.col(k);
  38. // implicit zeros
  39. for(typename Eigen::SparseMatrix<T>::InnerIterator yit(Y, k);yit;++yit)
  40. {
  41. if(in_R[yit.row()]){ Yk.coeffRef(yit.row()) = 0; }
  42. }
  43. // explicit values
  44. for(typename Eigen::SparseMatrix<T>::InnerIterator xit(X, c);xit;++xit)
  45. {
  46. // row in X
  47. int r = xit.row();
  48. // row in Y
  49. int s = R(r);
  50. Yk.coeffRef(s) = xit.value();
  51. }
  52. Y.col(k) = Yk;
  53. }
  54. }
  55. template <typename DerivedX, typename DerivedY, typename DerivedR, typename DerivedC>
  56. IGL_INLINE void igl::slice_into(
  57. const Eigen::MatrixBase<DerivedX> & X,
  58. const Eigen::MatrixBase<DerivedR> & R,
  59. const Eigen::MatrixBase<DerivedC> & C,
  60. Eigen::PlainObjectBase<DerivedY> & Y)
  61. {
  62. int xm = X.rows();
  63. int xn = X.cols();
  64. assert(R.size() == xm);
  65. assert(C.size() == xn);
  66. const int ym = Y.rows();
  67. const int yn = Y.cols();
  68. assert(R.minCoeff() >= 0);
  69. assert(R.maxCoeff() < ym);
  70. assert(C.minCoeff() >= 0);
  71. assert(C.maxCoeff() < yn);
  72. // Build reindexing maps for columns and rows, -1 means not in map
  73. Eigen::Matrix<typename DerivedR::Scalar,Eigen::Dynamic,1> RI;
  74. RI.resize(xm);
  75. for(int i = 0;i<xm;i++)
  76. {
  77. for(int j = 0;j<xn;j++)
  78. {
  79. Y(int(R(i)),int(C(j))) = X(i,j);
  80. }
  81. }
  82. }
  83. template <typename MatX, typename MatY, typename DerivedR>
  84. IGL_INLINE void igl::slice_into(
  85. const MatX & X,
  86. const Eigen::MatrixBase<DerivedR> & R,
  87. const int dim,
  88. MatY& Y)
  89. {
  90. Eigen::Matrix<typename MatX::Scalar, Eigen::Dynamic, 1> C;
  91. switch(dim)
  92. {
  93. case 1:
  94. assert(R.size() == X.rows());
  95. // boring base case
  96. if(X.cols() == 0)
  97. {
  98. return;
  99. }
  100. igl::colon(0,X.cols()-1,C);
  101. return slice_into(X,R,C,Y);
  102. case 2:
  103. assert(R.size() == X.cols());
  104. // boring base case
  105. if(X.rows() == 0)
  106. {
  107. return;
  108. }
  109. igl::colon(0,X.rows()-1,C);
  110. return slice_into(X,C,R,Y);
  111. default:
  112. assert(false && "Unsupported dimension");
  113. return;
  114. }
  115. }
  116. template <typename DerivedX, typename DerivedR, typename DerivedY>
  117. IGL_INLINE void igl::slice_into(
  118. const Eigen::MatrixBase<DerivedX> & X,
  119. const Eigen::MatrixBase<DerivedR> & R,
  120. Eigen::PlainObjectBase<DerivedY> & Y)
  121. {
  122. // phony column indices
  123. Eigen::Matrix<typename DerivedR::Scalar, Eigen::Dynamic, 1> C;
  124. C.resize(1);
  125. C(0) = 0;
  126. return igl::slice_into(X,R,C,Y);
  127. }
  128. #ifdef IGL_STATIC_LIBRARY
  129. // Explicit template instantiation
  130. // generated by autoexplicit.sh
  131. template void igl::slice_into<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> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
  132. // generated by autoexplicit.sh
  133. template void igl::slice_into<double, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<double, 0, int>&);
  134. template void igl::slice_into<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::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  135. template void igl::slice_into<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -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::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  136. template void igl::slice_into<double, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::SparseMatrix<double, 0, int>&);
  137. template void igl::slice_into<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  138. template void igl::slice_into<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  139. template void igl::slice_into<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<double, -1, -1, 0, -1, -1> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::Matrix<double, -1, -1, 0, -1, -1>&);
  140. template void igl::slice_into<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<double, -1, 1, 0, -1, 1> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
  141. template void igl::slice_into<Eigen::SparseMatrix<double, 0, int>, Eigen::SparseMatrix<double, 0, int>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::SparseMatrix<double, 0, int> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::SparseMatrix<double, 0, int>&);
  142. template void igl::slice_into<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::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  143. template void igl::slice_into<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::MatrixWrapper<Eigen::Array<int, -1, 1, 0, -1, 1> > >(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::MatrixBase<Eigen::MatrixWrapper<Eigen::Array<int, -1, 1, 0, -1, 1> > > const&, int, Eigen::Matrix<double, -1, 1, 0, -1, 1>&);
  144. #endif