sparse.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #ifndef IGL_SPARSE_H
  2. #define IGL_SPARSE_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. // Build a sparse matrix from list of indices and values (I,J,V), functions
  9. // like the sparse function in matlab
  10. //
  11. // Templates:
  12. // IndexVector list of indices, value should be non-negative and should
  13. // expect to be cast to an index. Must implement operator(i) to retrieve
  14. // ith element
  15. // ValueVector list of values, value should be expect to be cast to type
  16. // T. Must implement operator(i) to retrieve ith element
  17. // T should be a eigen sparse matrix primitive type like int or double
  18. // Input:
  19. // I nnz vector of row indices of non zeros entries in X
  20. // J nnz vector of column indices of non zeros entries in X
  21. // V nnz vector of non-zeros entries in X
  22. // Optional:
  23. // m number of rows
  24. // n number of cols
  25. // Outputs:
  26. // X m by n matrix of type T whose entries are to be found
  27. //
  28. template <class IndexVector, class ValueVector, typename T>
  29. inline void sparse(
  30. const IndexVector & I,
  31. const IndexVector & J,
  32. const ValueVector & V,
  33. Eigen::SparseMatrix<T>& X);
  34. template <class IndexVector, class ValueVector, typename T>
  35. inline void sparse(
  36. const IndexVector & I,
  37. const IndexVector & J,
  38. const ValueVector & V,
  39. const size_t m,
  40. const size_t n,
  41. Eigen::SparseMatrix<T>& X);
  42. }
  43. // Implementation
  44. template <class IndexVector, class ValueVector, typename T>
  45. inline void igl::sparse(
  46. const IndexVector & I,
  47. const IndexVector & J,
  48. const ValueVector & V,
  49. Eigen::SparseMatrix<T>& X)
  50. {
  51. size_t m = (size_t)I.maxCoeff()+1;
  52. size_t n = (size_t)J.maxCoeff()+1;
  53. return igl::sparse(I,J,V,m,n,X);
  54. }
  55. #include "verbose.h"
  56. template <class IndexVector, class ValueVector, typename T>
  57. inline void igl::sparse(
  58. const IndexVector & I,
  59. const IndexVector & J,
  60. const ValueVector & V,
  61. const size_t m,
  62. const size_t n,
  63. Eigen::SparseMatrix<T>& X)
  64. {
  65. assert((int)I.maxCoeff() < (int)m);
  66. assert((int)I.minCoeff() >= 0);
  67. assert((int)J.maxCoeff() < (int)n);
  68. assert((int)J.minCoeff() >= 0);
  69. assert(I.size() == J.size());
  70. assert(J.size() == V.size());
  71. // Really we just need .size() to be the same, but this is safer
  72. assert(I.rows() == J.rows());
  73. assert(J.rows() == V.rows());
  74. assert(I.cols() == J.cols());
  75. assert(J.cols() == V.cols());
  76. // number of values
  77. int nv = V.size();
  78. Eigen::DynamicSparseMatrix<T, Eigen::RowMajor> dyn_X(m,n);
  79. // over estimate the number of entries
  80. dyn_X.reserve(I.size());
  81. for(int i = 0;i < nv;i++)
  82. {
  83. dyn_X.coeffRef((int)I(i),(int)J(i)) += (T)V(i);
  84. }
  85. X = Eigen::SparseMatrix<T>(dyn_X);
  86. }
  87. #endif