repmat.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #ifndef IGL_REPMAT_H
  2. #define IGL_REPMAT_H
  3. #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
  4. #include <Eigen/Dense>
  5. #include <Eigen/Sparse>
  6. namespace igl
  7. {
  8. // Ideally this is a super overloaded function that behaves just like
  9. // matlab's repmat
  10. // Replicate and tile a matrix
  11. //
  12. // Templates:
  13. // T should be a eigen matrix primitive type like int or double
  14. // Inputs:
  15. // A m by n input matrix
  16. // r number of row-direction copies
  17. // c number of col-direction copies
  18. // Outputs:
  19. // B r*m by c*n output matrix
  20. //
  21. template <typename T,const int W, const int H>
  22. inline void repmat(
  23. const Eigen::Matrix<T,W,H> & A,
  24. const int r,
  25. const int c,
  26. Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & B);
  27. template <typename T>
  28. inline void repmat(
  29. const Eigen::SparseMatrix<T> & A,
  30. const int r,
  31. const int c,
  32. Eigen::SparseMatrix<T> & B);
  33. }
  34. // Implementation
  35. template <typename T,const int W, const int H>
  36. inline void igl::repmat(
  37. const Eigen::Matrix<T,W,H> & A,
  38. const int r,
  39. const int c,
  40. Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & B)
  41. {
  42. assert(r>0);
  43. assert(c>0);
  44. // Make room for output
  45. B.resize(r*A.rows(),c*A.cols());
  46. // copy tiled blocks
  47. for(int i = 0;i<r;i++)
  48. {
  49. for(int j = 0;j<c;j++)
  50. {
  51. B.block(i*A.rows(),j*A.cols(),A.rows(),A.cols()) = A;
  52. }
  53. }
  54. }
  55. template <typename T>
  56. inline void igl::repmat(
  57. const Eigen::SparseMatrix<T> & A,
  58. const int r,
  59. const int c,
  60. Eigen::SparseMatrix<T> & B)
  61. {
  62. assert(r>0);
  63. assert(c>0);
  64. B.resize(r*A.rows(),c*A.cols());
  65. B.reserve(r*c*A.nonZeros());
  66. for(int i = 0;i<r;i++)
  67. {
  68. for(int j = 0;j<c;j++)
  69. {
  70. // Loop outer level
  71. for (int k=0; k<A.outerSize(); ++k)
  72. {
  73. // loop inner level
  74. for (typename Eigen::SparseMatrix<T>::InnerIterator it(A,k); it; ++it)
  75. {
  76. B.insert(i*A.rows()+it.row(),j*A.cols() + it.col()) = it.value();
  77. }
  78. }
  79. }
  80. }
  81. B.finalize();
  82. }
  83. #endif