slice_into.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #ifndef IGL_SLICE_INTO_H
  2. #define IGL_SLICE_INTO_H
  3. namespace igl
  4. {
  5. // Act like the matlab Y(row_indices,col_indices) = X
  6. //
  7. // Inputs:
  8. // X xm by xn rhs matrix
  9. // R list of row indices
  10. // C list of column indices
  11. // Y ym by yn lhs matrix
  12. // Output:
  13. // Y ym by yn lhs matrix, same as input but Y(R,C) = X
  14. template <typename T>
  15. inline void slice_into(
  16. const Eigen::SparseMatrix<T>& X,
  17. const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  18. const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
  19. Eigen::SparseMatrix<T>& Y);
  20. template <typename T, const int W, const int H>
  21. inline void slice_into(
  22. const Eigen::Matrix<T,W,H> & X,
  23. const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  24. const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
  25. Eigen::Matrix<T,W,H> & Y);
  26. template <typename T>
  27. inline void slice_into(
  28. const Eigen::Matrix<T,Eigen::Dynamic,1> & X,
  29. const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  30. Eigen::Matrix<T,Eigen::Dynamic,1> & Y);
  31. }
  32. // Implementation
  33. template <typename T>
  34. inline void igl::slice_into(
  35. const Eigen::SparseMatrix<T>& X,
  36. const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  37. const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
  38. Eigen::SparseMatrix<T>& Y)
  39. {
  40. int xm = X.rows();
  41. int xn = X.cols();
  42. assert(R.size() == xm);
  43. assert(C.size() == xn);
  44. int ym = Y.size();
  45. int yn = Y.size();
  46. assert(R.minCoeff() >= 0);
  47. assert(R.maxCoeff() < ym);
  48. assert(C.minCoeff() >= 0);
  49. assert(C.maxCoeff() < yn);
  50. // create temporary dynamic sparse matrix
  51. Eigen::DynamicSparseMatrix<T, Eigen::RowMajor> dyn_Y(Y);
  52. // Iterate over outside
  53. for(int k=0; k<X.outerSize(); ++k)
  54. {
  55. // Iterate over inside
  56. for(typename Eigen::SparseMatrix<T>::InnerIterator it (X,k); it; ++it)
  57. {
  58. dyn_Y.coeffRef(R(it.row()),C(it.col())) = it.value();
  59. }
  60. }
  61. Y = Eigen::SparseMatrix<T>(dyn_Y);
  62. }
  63. template <typename T, const int W, const int H>
  64. inline void igl::slice_into(
  65. const Eigen::Matrix<T,W,H> & X,
  66. const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  67. const Eigen::Matrix<int,Eigen::Dynamic,1> & C,
  68. Eigen::Matrix<T,W,H> & Y)
  69. {
  70. int xm = X.rows();
  71. int xn = X.cols();
  72. assert(R.size() == xm);
  73. assert(C.size() == xn);
  74. int ym = Y.size();
  75. int yn = Y.size();
  76. assert(R.minCoeff() >= 0);
  77. assert(R.maxCoeff() < ym);
  78. assert(C.minCoeff() >= 0);
  79. assert(C.maxCoeff() < yn);
  80. // Build reindexing maps for columns and rows, -1 means not in map
  81. Eigen::Matrix<int,Eigen::Dynamic,1> RI;
  82. RI.resize(xm);
  83. for(int i = 0;i<xm;i++)
  84. {
  85. for(int j = 0;j<xn;j++)
  86. {
  87. Y(R(i),C(j)) = X(i,j);
  88. }
  89. }
  90. }
  91. template <typename T>
  92. inline void igl::slice_into(
  93. const Eigen::Matrix<T,Eigen::Dynamic,1> & X,
  94. const Eigen::Matrix<int,Eigen::Dynamic,1> & R,
  95. Eigen::Matrix<T,Eigen::Dynamic,1> & Y)
  96. {
  97. // phony column indices
  98. Eigen::Matrix<int,Eigen::Dynamic,1> C;
  99. C.resize(1);
  100. C(0) = 0;
  101. return igl::slice_into(X,R,C,Y);
  102. }
  103. #endif