repdiag.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #ifndef IGL_REPDIAG_H
  2. #define IGL_REPDIAG_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. // REPDIAG repeat a matrix along the diagonal a certain number of times, so
  9. // that if A is a m by n matrix and we want to repeat along the diagonal d
  10. // times, we get a m*d by n*d matrix B such that:
  11. // B( (k*m+1):(k*m+1+m-1), (k*n+1):(k*n+1+n-1)) = A
  12. // for k from 0 to d-1
  13. //
  14. // Inputs:
  15. // A m by n matrix we are repeating along the diagonal. May be dense or
  16. // sparse
  17. // d number of times to repeat A along the diagonal
  18. // Outputs:
  19. // B m*d by n*d matrix with A repeated d times along the diagonal,
  20. // will be dense or sparse to match A
  21. //
  22. // Sparse version
  23. template <typename T>
  24. inline void repdiag(
  25. const Eigen::SparseMatrix<T>& A,
  26. const int d,
  27. Eigen::SparseMatrix<T>& B);
  28. // Dense version
  29. template <typename T>
  30. inline void repdiag(
  31. const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & A,
  32. const int d,
  33. Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & B);
  34. }
  35. // Implementation
  36. template <typename T>
  37. inline void igl::repdiag(
  38. const Eigen::SparseMatrix<T>& A,
  39. const int d,
  40. Eigen::SparseMatrix<T>& B)
  41. {
  42. int m = A.rows();
  43. int n = A.cols();
  44. Eigen::DynamicSparseMatrix<T, Eigen::RowMajor>
  45. dyn_B(m*d,n*d);
  46. // loop over reps
  47. for(int i=0;i<d;i++)
  48. {
  49. // Loop outer level
  50. for (int k=0; k<A.outerSize(); ++k)
  51. {
  52. // loop inner level
  53. for (typename Eigen::SparseMatrix<T>::InnerIterator it(A,k); it; ++it)
  54. {
  55. dyn_B.coeffRef(i*m+it.row(),i*n+it.col()) += it.value();
  56. }
  57. }
  58. }
  59. B = Eigen::SparseMatrix<T>(dyn_B);
  60. }
  61. template <typename T>
  62. inline void igl::repdiag(
  63. const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & A,
  64. const int d,
  65. Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & B)
  66. {
  67. int m = A.rows();
  68. int n = A.cols();
  69. B.resize(m*d,n*d);
  70. B.array() *= 0;
  71. for(int i = 0;i<d;i++)
  72. {
  73. B.block(i*m,i*n,m,n) = A;
  74. }
  75. }
  76. #endif