10#ifndef EIGEN_CHOLMODSUPPORT_H
11#define EIGEN_CHOLMODSUPPORT_H
17template<
typename Scalar>
struct cholmod_configure_matrix;
19template<>
struct cholmod_configure_matrix<double> {
20 template<
typename CholmodType>
21 static void run(CholmodType& mat) {
22 mat.xtype = CHOLMOD_REAL;
23 mat.dtype = CHOLMOD_DOUBLE;
27template<>
struct cholmod_configure_matrix<std::complex<double> > {
28 template<
typename CholmodType>
29 static void run(CholmodType& mat) {
30 mat.xtype = CHOLMOD_COMPLEX;
31 mat.dtype = CHOLMOD_DOUBLE;
57template<
typename _Scalar,
int _Options,
typename _Index>
61 res.nzmax = mat.nonZeros();
62 res.nrow = mat.rows();;
63 res.ncol = mat.cols();
64 res.p = mat.outerIndexPtr();
65 res.i = mat.innerIndexPtr();
66 res.x = mat.valuePtr();
69 if(mat.isCompressed())
77 res.nz = mat.innerNonZeroPtr();
83 if (internal::is_same<_Index,int>::value)
85 res.itype = CHOLMOD_INT;
87 else if (internal::is_same<_Index,SuiteSparse_long>::value)
89 res.itype = CHOLMOD_LONG;
93 eigen_assert(
false &&
"Index type not supported yet");
97 internal::cholmod_configure_matrix<_Scalar>::run(res);
104template<
typename _Scalar,
int _Options,
typename _Index>
107 cholmod_sparse res = viewAsCholmod(mat.const_cast_derived());
113template<
typename _Scalar,
int _Options,
typename _Index,
unsigned int UpLo>
116 cholmod_sparse res = viewAsCholmod(mat.matrix().const_cast_derived());
118 if(UpLo==
Upper) res.stype = 1;
119 if(UpLo==
Lower) res.stype = -1;
126template<
typename Derived>
129 EIGEN_STATIC_ASSERT((internal::traits<Derived>::Flags&
RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
130 typedef typename Derived::Scalar Scalar;
133 res.nrow = mat.rows();
134 res.ncol = mat.cols();
135 res.nzmax = res.nrow * res.ncol;
136 res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride();
137 res.x = (
void*)(mat.derived().data());
140 internal::cholmod_configure_matrix<Scalar>::run(res);
147template<
typename Scalar,
int Flags,
typename Index>
151 (cm.nrow, cm.ncol,
static_cast<Index*
>(cm.p)[cm.ncol],
152 static_cast<Index*
>(cm.p),
static_cast<Index*
>(cm.i),
static_cast<Scalar*
>(cm.x) );
156 CholmodAuto, CholmodSimplicialLLt, CholmodSupernodalLLt, CholmodLDLt
165template<
typename _MatrixType,
int _UpLo,
typename Derived>
166class CholmodBase : internal::noncopyable
169 typedef _MatrixType MatrixType;
170 enum { UpLo = _UpLo };
171 typedef typename MatrixType::Scalar Scalar;
172 typedef typename MatrixType::RealScalar RealScalar;
173 typedef MatrixType CholMatrixType;
174 typedef typename MatrixType::Index Index;
179 : m_cholmodFactor(0), m_info(
Success), m_isInitialized(
false)
181 EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
182 m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
183 cholmod_start(&m_cholmod);
186 CholmodBase(
const MatrixType& matrix)
187 : m_cholmodFactor(0), m_info(
Success), m_isInitialized(
false)
189 EIGEN_STATIC_ASSERT((internal::is_same<double,RealScalar>::value), CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY);
190 m_shiftOffset[0] = m_shiftOffset[1] = 0.0;
191 cholmod_start(&m_cholmod);
198 cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
199 cholmod_finish(&m_cholmod);
202 inline Index cols()
const {
return m_cholmodFactor->n; }
203 inline Index rows()
const {
return m_cholmodFactor->n; }
205 Derived& derived() {
return *
static_cast<Derived*
>(
this); }
206 const Derived& derived()
const {
return *
static_cast<const Derived*
>(
this); }
215 eigen_assert(m_isInitialized &&
"Decomposition is not initialized.");
231 template<
typename Rhs>
232 inline const internal::solve_retval<CholmodBase, Rhs>
235 eigen_assert(m_isInitialized &&
"LLT is not initialized.");
236 eigen_assert(rows()==b.rows()
237 &&
"CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b");
238 return internal::solve_retval<CholmodBase, Rhs>(*
this, b.derived());
245 template<
typename Rhs>
246 inline const internal::sparse_solve_retval<CholmodBase, Rhs>
249 eigen_assert(m_isInitialized &&
"LLT is not initialized.");
250 eigen_assert(rows()==b.
rows()
251 &&
"CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b");
252 return internal::sparse_solve_retval<CholmodBase, Rhs>(*
this, b.
derived());
265 cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
268 cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
269 m_cholmodFactor = cholmod_analyze(&A, &m_cholmod);
271 this->m_isInitialized =
true;
273 m_analysisIsOk =
true;
274 m_factorizationIsOk =
false;
285 eigen_assert(m_analysisIsOk &&
"You must first call analyzePattern()");
286 cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
287 cholmod_factorize_p(&A, m_shiftOffset, 0, 0, m_cholmodFactor, &m_cholmod);
291 m_factorizationIsOk =
true;
296 cholmod_common&
cholmod() {
return m_cholmod; }
298 #ifndef EIGEN_PARSED_BY_DOXYGEN
300 template<
typename Rhs,
typename Dest>
303 eigen_assert(m_factorizationIsOk &&
"The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
304 const Index size = m_cholmodFactor->n;
305 EIGEN_UNUSED_VARIABLE(size);
306 eigen_assert(size==b.rows());
309 Rhs& b_ref(b.const_cast_derived());
310 cholmod_dense b_cd = viewAsCholmod(b_ref);
311 cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod);
318 cholmod_free_dense(&x_cd, &m_cholmod);
322 template<
typename RhsScalar,
int RhsOptions,
typename RhsIndex,
typename DestScalar,
int DestOptions,
typename DestIndex>
323 void _solve(
const SparseMatrix<RhsScalar,RhsOptions,RhsIndex> &b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest)
const
325 eigen_assert(m_factorizationIsOk &&
"The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
326 const Index size = m_cholmodFactor->n;
327 EIGEN_UNUSED_VARIABLE(size);
328 eigen_assert(size==b.rows());
331 cholmod_sparse b_cs = viewAsCholmod(b);
332 cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod);
338 dest = viewAsEigen<DestScalar,DestOptions,DestIndex>(*x_cs);
339 cholmod_free_sparse(&x_cs, &m_cholmod);
355 m_shiftOffset[0] = double(offset);
359 template<
typename Stream>
360 void dumpMemory(Stream& )
364 mutable cholmod_common m_cholmod;
365 cholmod_factor* m_cholmodFactor;
366 double m_shiftOffset[2];
367 mutable ComputationInfo m_info;
368 bool m_isInitialized;
369 int m_factorizationIsOk;
393template<
typename _MatrixType,
int _UpLo = Lower>
394class CholmodSimplicialLLT :
public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT<_MatrixType, _UpLo> >
396 typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT> Base;
397 using Base::m_cholmod;
401 typedef _MatrixType MatrixType;
403 CholmodSimplicialLLT() : Base() { init(); }
405 CholmodSimplicialLLT(
const MatrixType& matrix) : Base()
411 ~CholmodSimplicialLLT() {}
415 m_cholmod.final_asis = 0;
416 m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
417 m_cholmod.final_ll = 1;
442template<
typename _MatrixType,
int _UpLo = Lower>
443class CholmodSimplicialLDLT :
public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT<_MatrixType, _UpLo> >
445 typedef CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT> Base;
446 using Base::m_cholmod;
450 typedef _MatrixType MatrixType;
452 CholmodSimplicialLDLT() : Base() { init(); }
454 CholmodSimplicialLDLT(
const MatrixType& matrix) : Base()
460 ~CholmodSimplicialLDLT() {}
464 m_cholmod.final_asis = 1;
465 m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
489template<
typename _MatrixType,
int _UpLo = Lower>
490class CholmodSupernodalLLT :
public CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT<_MatrixType, _UpLo> >
492 typedef CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT> Base;
493 using Base::m_cholmod;
497 typedef _MatrixType MatrixType;
499 CholmodSupernodalLLT() : Base() { init(); }
501 CholmodSupernodalLLT(
const MatrixType& matrix) : Base()
507 ~CholmodSupernodalLLT() {}
511 m_cholmod.final_asis = 1;
512 m_cholmod.supernodal = CHOLMOD_SUPERNODAL;
538template<
typename _MatrixType,
int _UpLo = Lower>
539class CholmodDecomposition :
public CholmodBase<_MatrixType, _UpLo, CholmodDecomposition<_MatrixType, _UpLo> >
541 typedef CholmodBase<_MatrixType, _UpLo, CholmodDecomposition> Base;
542 using Base::m_cholmod;
546 typedef _MatrixType MatrixType;
548 CholmodDecomposition() : Base() { init(); }
550 CholmodDecomposition(
const MatrixType& matrix) : Base()
556 ~CholmodDecomposition() {}
558 void setMode(CholmodMode mode)
563 m_cholmod.final_asis = 1;
564 m_cholmod.supernodal = CHOLMOD_AUTO;
566 case CholmodSimplicialLLt:
567 m_cholmod.final_asis = 0;
568 m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
569 m_cholmod.final_ll = 1;
571 case CholmodSupernodalLLt:
572 m_cholmod.final_asis = 1;
573 m_cholmod.supernodal = CHOLMOD_SUPERNODAL;
576 m_cholmod.final_asis = 1;
577 m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
586 m_cholmod.final_asis = 1;
587 m_cholmod.supernodal = CHOLMOD_AUTO;
593template<
typename _MatrixType,
int _UpLo,
typename Derived,
typename Rhs>
594struct solve_retval<
CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
595 : solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
598 EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
600 template<
typename Dest>
void evalTo(Dest& dst)
const
602 dec()._solve(rhs(),dst);
606template<
typename _MatrixType,
int _UpLo,
typename Derived,
typename Rhs>
607struct sparse_solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
608 : sparse_solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
610 typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec;
611 EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
613 template<
typename Dest>
void evalTo(Dest& dst)
const
615 dec()._solve(rhs(),dst);
The base class for the direct Cholesky factorization of Cholmod.
Definition CholmodSupport.h:167
Derived & compute(const MatrixType &matrix)
Definition CholmodSupport.h:220
void factorize(const MatrixType &matrix)
Definition CholmodSupport.h:283
cholmod_common & cholmod()
Definition CholmodSupport.h:296
Derived & setShift(const RealScalar &offset)
Definition CholmodSupport.h:353
const internal::solve_retval< CholmodBase, Rhs > solve(const MatrixBase< Rhs > &b) const
Definition CholmodSupport.h:233
void analyzePattern(const MatrixType &matrix)
Definition CholmodSupport.h:261
ComputationInfo info() const
Reports whether previous computation was successful.
Definition CholmodSupport.h:213
const internal::sparse_solve_retval< CholmodBase, Rhs > solve(const SparseMatrixBase< Rhs > &b) const
Definition CholmodSupport.h:247
Sparse matrix.
Definition MappedSparseMatrix.h:33
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:50
static ConstMapType Map(const Scalar *data)
Definition PlainObjectBase.h:505
Base class of any sparse matrices or sparse expressions.
Definition SparseMatrixBase.h:34
Index rows() const
Definition SparseMatrixBase.h:160
A versatible sparse matrix representation.
Definition SparseMatrix.h:87
Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix.
Definition SparseSelfAdjointView.h:51
ComputationInfo
Definition Constants.h:374
@ NumericalIssue
Definition Constants.h:378
@ Success
Definition Constants.h:376
@ Upper
Definition Constants.h:169
@ Lower
Definition Constants.h:167
const unsigned int RowMajorBit
Definition Constants.h:53
Derived & derived()
Definition EigenBase.h:34