diag.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #ifndef IGL_DIAG_H
  2. #define IGL_DIAG_H
  3. #include <Eigen/Sparse>
  4. namespace igl
  5. {
  6. // Either extracts the main diagonal of a matrix as a vector OR converts a
  7. // vector into a matrix with vector along the main diagonal. Like matlab's
  8. // diag function
  9. // Templates:
  10. // T should be a eigen sparse matrix primitive type like int or double
  11. // Inputs:
  12. // X an m by n sparse matrix
  13. // Outputs:
  14. // V a min(m,n) sparse vector
  15. template <typename T>
  16. inline void diag(
  17. const Eigen::SparseMatrix<T>& X,
  18. Eigen::SparseVector<T>& V);
  19. // Templates:
  20. // T should be a eigen sparse matrix primitive type like int or double
  21. // Inputs:
  22. // V a m sparse vector
  23. // Outputs:
  24. // X a m by m sparse matrix
  25. template <typename T>
  26. inline void diag(
  27. const Eigen::SparseVector<T>& V,
  28. Eigen::SparseMatrix<T>& X);
  29. }
  30. // Implementation
  31. #include "verbose.h"
  32. template <typename T>
  33. inline void igl::diag(
  34. const Eigen::SparseMatrix<T>& X,
  35. Eigen::SparseVector<T>& V)
  36. {
  37. // Get size of input
  38. int m = X.rows();
  39. int n = X.cols();
  40. V = Eigen::SparseVector<T>((m>n?n:m));
  41. // Iterate over outside
  42. for(int k=0; k<X.outerSize(); ++k)
  43. {
  44. // Iterate over inside
  45. for(typename Eigen::SparseMatrix<T>::InnerIterator it (X,k); it; ++it)
  46. {
  47. if(it.col() == it.row())
  48. {
  49. V.coeffRef(it.col()) += it.value();
  50. }
  51. }
  52. }
  53. }
  54. template <typename T>
  55. inline void igl::diag(
  56. const Eigen::SparseVector<T>& V,
  57. Eigen::SparseMatrix<T>& X)
  58. {
  59. // clear and resize output
  60. Eigen::DynamicSparseMatrix<T, Eigen::RowMajor> dyn_X(V.size(),V.size());
  61. // loop over non-zeros
  62. for(typename Eigen::SparseVector<T>::InnerIterator it(V); it; ++it)
  63. {
  64. dyn_X.coeffRef(it.index(),it.index()) += it.value();
  65. }
  66. X = Eigen::SparseMatrix<T>(dyn_X);
  67. }
  68. #endif