2#ifdef PBAT_USE_SUITESPARSE
4#ifndef PBAT_MATH_LINALG_CHOLMOD_H
5#define PBAT_MATH_LINALG_CHOLMOD_H
8#include "PhysicsBasedAnimationToolkitExport.h"
11#include <suitesparse/cholmod.h>
23 std::is_same_v<Scalar, double>,
24 "Cholmod implementation uses double floating point coefficients");
26 std::is_same_v<CSCMatrix::StorageIndex, std::int32_t>,
27 "Cholmod implementation uses 32-bit integer indices");
29 enum class ESparseStorage {
30 SymmetricLowerTriangular = -1,
32 SymmetricUpperTriangular = 1
37 template <
class Derived>
39 Eigen::SparseCompressedBase<Derived>
const& A,
40 ESparseStorage storage = ESparseStorage::SymmetricLowerTriangular);
42 template <
class Derived>
44 Eigen::SparseCompressedBase<Derived>
const& A,
45 ESparseStorage storage = ESparseStorage::SymmetricLowerTriangular);
47 template <
class Derived>
49 Eigen::SparseCompressedBase<Derived>
const& A,
50 ESparseStorage storage = ESparseStorage::SymmetricLowerTriangular);
52 template <
class Derived>
53 bool Update(Eigen::SparseCompressedBase<Derived>
const& U);
55 template <
class Derived>
56 bool Downdate(Eigen::SparseCompressedBase<Derived>
const& U);
58 PBAT_API
MatrixX Solve(Eigen::Ref<MatrixX const>
const& B)
const;
63 template <
class Derived>
65 Eigen::SparseCompressedBase<Derived>
const& A,
66 ESparseStorage storage,
67 cholmod_sparse& cholmod_A)
const;
69 PBAT_API
void Deallocate();
71 cholmod_common mCholmodCommon;
72 cholmod_factor* mCholmodL;
75template <
class Derived>
76inline void Cholmod::Analyze(Eigen::SparseCompressedBase<Derived>
const& A, ESparseStorage storage)
79 cholmod_sparse cholmod_A{};
80 ToCholmodView(A, storage, cholmod_A);
81 mCholmodL = cholmod_analyze(&cholmod_A, &mCholmodCommon);
82 if (mCholmodL == NULL)
83 throw std::runtime_error(
"Symbolic analysis of Cholesky factor failed");
86template <
class Derived>
88Cholmod::Factorize(Eigen::SparseCompressedBase<Derived>
const& A, ESparseStorage storage)
90 if (mCholmodL == NULL)
93 cholmod_sparse cholmod_A;
94 ToCholmodView(A, storage, cholmod_A);
95 int const ec = cholmod_factorize(&cholmod_A, mCholmodL, &mCholmodCommon);
99template <
class Derived>
100inline bool Cholmod::Compute(Eigen::SparseCompressedBase<Derived>
const& A, ESparseStorage storage)
102 return Factorize(A, storage);
105template <
class Derived>
106inline bool Cholmod::Update(Eigen::SparseCompressedBase<Derived>
const& U)
108 cholmod_sparse cholmod_U{};
109 ToCholmodView(U, ESparseStorage::Unsymmetric, cholmod_U);
110 cholmod_sparse* cholmod_PU = cholmod_submatrix(
112 static_cast<std::int32_t*
>(mCholmodL->Perm) ,
113 static_cast<long long>(mCholmodL->n) ,
119 int const ec = cholmod_updown(1 , cholmod_PU, mCholmodL, &mCholmodCommon);
120 cholmod_free_sparse(&cholmod_PU, &mCholmodCommon);
124template <
class Derived>
125inline bool Cholmod::Downdate(Eigen::SparseCompressedBase<Derived>
const& U)
128 cholmod_sparse cholmod_U{};
129 ToCholmodView(U, ESparseStorage::Unsymmetric, cholmod_U);
130 cholmod_sparse* cholmod_PU = cholmod_submatrix(
132 static_cast<std::int32_t*
>(mCholmodL->Perm) ,
133 static_cast<long long>(mCholmodL->n) ,
139 int const ec = cholmod_updown(0 , cholmod_PU, mCholmodL, &mCholmodCommon);
140 cholmod_free_sparse(&cholmod_PU, &mCholmodCommon);
144template <
class Derived>
145inline void Cholmod::ToCholmodView(
146 Eigen::SparseCompressedBase<Derived>
const& A,
147 ESparseStorage storage,
148 cholmod_sparse& cholmod_A)
const
150 using ScalarType =
typename Derived::Scalar;
151 using IndexType =
typename Derived::StorageIndex;
153 std::is_same_v<ScalarType, double> || std::is_same_v<ScalarType, float>,
154 "Cholmod implementation uses double or float floating point coefficients");
156 std::is_same_v<IndexType, std::int32_t> or std::is_same_v<IndexType, std::int64_t>,
157 "Cholmod implementation uses 32-bit or 64-bit integer indices");
159 cholmod_A.nrow =
static_cast<size_t>(A.innerSize());
160 cholmod_A.ncol =
static_cast<size_t>(A.outerSize());
161 cholmod_A.nzmax =
static_cast<size_t>(A.nonZeros());
162 cholmod_A.p =
const_cast<IndexType*
>(A.outerIndexPtr());
163 cholmod_A.i =
const_cast<IndexType*
>(A.innerIndexPtr());
165 cholmod_A.x =
const_cast<ScalarType*
>(A.valuePtr());
167 cholmod_A.stype =
static_cast<std::int32_t
>(storage);
168 cholmod_A.itype = std::is_same_v<IndexType, std::int64_t> ? CHOLMOD_LONG : CHOLMOD_INT;
169 cholmod_A.xtype = CHOLMOD_REAL;
170 cholmod_A.dtype = std::is_same_v<ScalarType, double> ? CHOLMOD_DOUBLE : CHOLMOD_SINGLE;
171 cholmod_A.sorted = 1 ;
172 cholmod_A.packed = 1 ;
Linear Algebra related functionality.
Definition FilterEigenvalues.h:7
Math related functionality.
Definition Concepts.h:19
The main namespace of the library.
Definition Aliases.h:15
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic-size matrix type.
Definition Aliases.h:34