invert_diag.cpp 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. #include "invert_diag.h"
  2. template <typename T>
  3. IGL_INLINE void igl::invert_diag(
  4. const Eigen::SparseMatrix<T>& X,
  5. Eigen::SparseMatrix<T>& Y)
  6. {
  7. #ifndef NDEBUG
  8. typename Eigen::SparseVector<T> dX = X.diagonal().sparseView();
  9. // Check that there are no zeros along the diagonal
  10. assert(dX.nonZeros() == dX.size());
  11. #endif
  12. // http://www.alecjacobson.com/weblog/?p=2552
  13. if(&Y != &X)
  14. {
  15. Y = X;
  16. }
  17. // Iterate over outside
  18. for(int k=0; k<Y.outerSize(); ++k)
  19. {
  20. // Iterate over inside
  21. for(typename Eigen::SparseMatrix<T>::InnerIterator it (Y,k); it; ++it)
  22. {
  23. if(it.col() == it.row())
  24. {
  25. T v = it.value();
  26. assert(v != 0);
  27. v = ((T)1.0)/v;
  28. Y.coeffRef(it.row(),it.col()) = v;
  29. }
  30. }
  31. }
  32. }
  33. #ifndef IGL_HEADER_ONLY
  34. // Explicit template specialization
  35. template void igl::invert_diag<double>(Eigen::SparseMatrix<double, 0, int> const&, Eigen::SparseMatrix<double, 0, int>&);
  36. template void igl::invert_diag<float>(Eigen::SparseMatrix<float, 0, int> const&, Eigen::SparseMatrix<float, 0, int>&);
  37. #endif