repdiag.cpp 1.7 KB

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