AtA_cached.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2017 Daniele Panozzo <[email protected]>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #ifndef IGL_ATA_CACHED_H
  9. #define IGL_ATA_CACHED_H
  10. #include "igl_inline.h"
  11. #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
  12. #include <Eigen/Dense>
  13. #include <Eigen/Sparse>
  14. namespace igl
  15. {
  16. /// Hold precomputed data for AtA_cached
  17. struct AtA_cached_data
  18. {
  19. /// Weights (diagonal of W)
  20. Eigen::VectorXd W;
  21. // Flatten composition rules
  22. /// @private
  23. std::vector<int> I_row;
  24. /// @private
  25. std::vector<int> I_col;
  26. /// @private
  27. std::vector<int> I_w;
  28. // For each entry of AtA, points to the beginning
  29. // of the composition rules
  30. /// @private
  31. std::vector<int> I_outer;
  32. };
  33. /// Computes At * W * A, where A is sparse and W is diagonal.
  34. ///
  35. /// Divides the construction in two phases, one for fixing the sparsity
  36. /// pattern, and one to populate it with values. Compared to evaluating it
  37. /// directly, this version is slower for the first time (since it requires a
  38. /// precomputation), but faster to the subsequent evaluations.
  39. ///
  40. /// @param[in] A m x n sparse matrix
  41. /// @param[in,out] data stores the precomputed sparsity pattern, data.W contains the optional diagonal weights (stored as a dense vector). If W is not provided, it is replaced by the identity.
  42. /// @param[out] AtA m by m matrix computed as AtA * W * A
  43. ///
  44. /// #### Example:
  45. ///
  46. /// \code{cpp}
  47. /// AtA_data = igl::AtA_cached_data();
  48. /// AtA_data.W = W;
  49. /// if (s.AtA.rows() == 0)
  50. /// igl::AtA_cached_precompute(s.A,s.AtA_data,s.AtA);
  51. /// else
  52. /// igl::AtA_cached(s.A,s.AtA_data,s.AtA);
  53. /// \endcode
  54. template <typename Scalar>
  55. IGL_INLINE void AtA_cached_precompute(
  56. const Eigen::SparseMatrix<Scalar>& A,
  57. AtA_cached_data& data,
  58. Eigen::SparseMatrix<Scalar>& AtA
  59. );
  60. /// Computes At * W * A, where A is sparse and W is diagonal precomputed into data.
  61. ///
  62. /// @param[in] A m x n sparse matrix
  63. /// @param[in] data stores the precomputed sparsity pattern, data.W contains the optional diagonal weights (stored as a dense vector). If W is not provided, it is replaced by the identity.
  64. /// @param[out] AtA m by m matrix computed as AtA * W * A
  65. template <typename Scalar>
  66. IGL_INLINE void AtA_cached(
  67. const Eigen::SparseMatrix<Scalar>& A,
  68. const AtA_cached_data& data,
  69. Eigen::SparseMatrix<Scalar>& AtA
  70. );
  71. }
  72. #ifndef IGL_STATIC_LIBRARY
  73. # include "AtA_cached.cpp"
  74. #endif
  75. #endif