repdiag.cpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include "repdiag.h"
  2. template <typename T>
  3. IGL_INLINE void igl::repdiag(
  4. const Eigen::SparseMatrix<T>& A,
  5. const int d,
  6. Eigen::SparseMatrix<T>& B)
  7. {
  8. int m = A.rows();
  9. int n = A.cols();
  10. // Should be able to *easily* do this in coherent order without
  11. // dynamicsparsematrix
  12. Eigen::DynamicSparseMatrix<T, Eigen::RowMajor>
  13. dyn_B(m*d,n*d);
  14. // Reserve enough space for new non zeros
  15. dyn_B.reserve(d*A.nonZeros());
  16. // loop over reps
  17. for(int i=0;i<d;i++)
  18. {
  19. // Loop outer level
  20. for (int k=0; k<A.outerSize(); ++k)
  21. {
  22. // loop inner level
  23. for (typename Eigen::SparseMatrix<T>::InnerIterator it(A,k); it; ++it)
  24. {
  25. dyn_B.coeffRef(i*m+it.row(),i*n+it.col()) += it.value();
  26. }
  27. }
  28. }
  29. B = Eigen::SparseMatrix<T>(dyn_B);
  30. }
  31. template <typename T>
  32. IGL_INLINE void igl::repdiag(
  33. const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & A,
  34. const int d,
  35. Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> & B)
  36. {
  37. int m = A.rows();
  38. int n = A.cols();
  39. B.resize(m*d,n*d);
  40. B.array() *= 0;
  41. for(int i = 0;i<d;i++)
  42. {
  43. B.block(i*m,i*n,m,n) = A;
  44. }
  45. }
  46. // Wrapper with B as output
  47. template <class Mat>
  48. IGL_INLINE Mat igl::repdiag(const Mat & A, const int d)
  49. {
  50. Mat B;
  51. repdiag(A,d,B);
  52. return B;
  53. }
  54. #ifndef IGL_HEADER_ONLY
  55. // Explicit template specialization
  56. // generated by autoexplicit.sh
  57. template void igl::repdiag<double>(Eigen::SparseMatrix<double, 0, int> const&, int, Eigen::SparseMatrix<double, 0, int>&);
  58. // generated by autoexplicit.sh
  59. template Eigen::SparseMatrix<double, 0, int> igl::repdiag<Eigen::SparseMatrix<double, 0, int> >(Eigen::SparseMatrix<double, 0, int> const&, int);
  60. #endif