CholmodSupport.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_CHOLMODSUPPORT_H
11 #define EIGEN_CHOLMODSUPPORT_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 template<typename Scalar, typename CholmodType>
18 void cholmod_configure_matrix(CholmodType& mat)
19 {
21  {
22  mat.xtype = CHOLMOD_REAL;
23  mat.dtype = CHOLMOD_SINGLE;
24  }
26  {
27  mat.xtype = CHOLMOD_REAL;
28  mat.dtype = CHOLMOD_DOUBLE;
29  }
30  else if (internal::is_same<Scalar,std::complex<float> >::value)
31  {
32  mat.xtype = CHOLMOD_COMPLEX;
33  mat.dtype = CHOLMOD_SINGLE;
34  }
35  else if (internal::is_same<Scalar,std::complex<double> >::value)
36  {
37  mat.xtype = CHOLMOD_COMPLEX;
38  mat.dtype = CHOLMOD_DOUBLE;
39  }
40  else
41  {
42  eigen_assert(false && "Scalar type not supported by CHOLMOD");
43  }
44 }
45 
46 } // namespace internal
47 
51 template<typename _Scalar, int _Options, typename _Index>
53 {
54  cholmod_sparse res;
55  res.nzmax = mat.nonZeros();
56  res.nrow = mat.rows();;
57  res.ncol = mat.cols();
58  res.p = mat.outerIndexPtr();
59  res.i = mat.innerIndexPtr();
60  res.x = mat.valuePtr();
61  res.sorted = 1;
62  if(mat.isCompressed())
63  {
64  res.packed = 1;
65  }
66  else
67  {
68  res.packed = 0;
69  res.nz = mat.innerNonZeroPtr();
70  }
71 
72  res.dtype = 0;
73  res.stype = -1;
74 
76  {
77  res.itype = CHOLMOD_INT;
78  }
80  {
81  res.itype = CHOLMOD_LONG;
82  }
83  else
84  {
85  eigen_assert(false && "Index type not supported yet");
86  }
87 
88  // setup res.xtype
89  internal::cholmod_configure_matrix<_Scalar>(res);
90 
91  res.stype = 0;
92 
93  return res;
94 }
95 
96 template<typename _Scalar, int _Options, typename _Index>
97 const cholmod_sparse viewAsCholmod(const SparseMatrix<_Scalar,_Options,_Index>& mat)
98 {
99  cholmod_sparse res = viewAsCholmod(mat.const_cast_derived());
100  return res;
101 }
102 
105 template<typename _Scalar, int _Options, typename _Index, unsigned int UpLo>
107 {
108  cholmod_sparse res = viewAsCholmod(mat.matrix().const_cast_derived());
109 
110  if(UpLo==Upper) res.stype = 1;
111  if(UpLo==Lower) res.stype = -1;
112 
113  return res;
114 }
115 
118 template<typename Derived>
120 {
121  EIGEN_STATIC_ASSERT((internal::traits<Derived>::Flags&RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
122  typedef typename Derived::Scalar Scalar;
123 
124  cholmod_dense res;
125  res.nrow = mat.rows();
126  res.ncol = mat.cols();
127  res.nzmax = res.nrow * res.ncol;
128  res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride();
129  res.x = (void*)(mat.derived().data());
130  res.z = 0;
131 
132  internal::cholmod_configure_matrix<Scalar>(res);
133 
134  return res;
135 }
136 
139 template<typename Scalar, int Flags, typename Index>
141 {
143  (cm.nrow, cm.ncol, static_cast<Index*>(cm.p)[cm.ncol],
144  static_cast<Index*>(cm.p), static_cast<Index*>(cm.i),static_cast<Scalar*>(cm.x) );
145 }
146 
149 };
150 
151 
157 template<typename _MatrixType, int _UpLo, typename Derived>
159 {
160  public:
161  typedef _MatrixType MatrixType;
162  enum { UpLo = _UpLo };
163  typedef typename MatrixType::Scalar Scalar;
164  typedef typename MatrixType::RealScalar RealScalar;
165  typedef MatrixType CholMatrixType;
166  typedef typename MatrixType::Index Index;
167 
168  public:
169 
171  : m_cholmodFactor(0), m_info(Success), m_isInitialized(false)
172  {
173  cholmod_start(&m_cholmod);
174  }
175 
176  CholmodBase(const MatrixType& matrix)
177  : m_cholmodFactor(0), m_info(Success), m_isInitialized(false)
178  {
179  m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0);
180  cholmod_start(&m_cholmod);
181  compute(matrix);
182  }
183 
185  {
186  if(m_cholmodFactor)
187  cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
188  cholmod_finish(&m_cholmod);
189  }
190 
191  inline Index cols() const { return m_cholmodFactor->n; }
192  inline Index rows() const { return m_cholmodFactor->n; }
193 
194  Derived& derived() { return *static_cast<Derived*>(this); }
195  const Derived& derived() const { return *static_cast<const Derived*>(this); }
196 
203  {
204  eigen_assert(m_isInitialized && "Decomposition is not initialized.");
205  return m_info;
206  }
207 
209  Derived& compute(const MatrixType& matrix)
210  {
211  analyzePattern(matrix);
212  factorize(matrix);
213  return derived();
214  }
215 
220  template<typename Rhs>
222  solve(const MatrixBase<Rhs>& b) const
223  {
224  eigen_assert(m_isInitialized && "LLT is not initialized.");
225  eigen_assert(rows()==b.rows()
226  && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b");
227  return internal::solve_retval<CholmodBase, Rhs>(*this, b.derived());
228  }
229 
234  template<typename Rhs>
236  solve(const SparseMatrixBase<Rhs>& b) const
237  {
238  eigen_assert(m_isInitialized && "LLT is not initialized.");
239  eigen_assert(rows()==b.rows()
240  && "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b");
242  }
243 
250  void analyzePattern(const MatrixType& matrix)
251  {
252  if(m_cholmodFactor)
253  {
254  cholmod_free_factor(&m_cholmodFactor, &m_cholmod);
255  m_cholmodFactor = 0;
256  }
257  cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
258  m_cholmodFactor = cholmod_analyze(&A, &m_cholmod);
259 
260  this->m_isInitialized = true;
261  this->m_info = Success;
262  m_analysisIsOk = true;
263  m_factorizationIsOk = false;
264  }
265 
272  void factorize(const MatrixType& matrix)
273  {
274  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
275  cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView<UpLo>());
276  cholmod_factorize_p(&A, m_shiftOffset, 0, 0, m_cholmodFactor, &m_cholmod);
277 
278  // If the factorization failed, minor is the column at which it did. On success minor == n.
279  this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue);
280  m_factorizationIsOk = true;
281  }
282 
285  cholmod_common& cholmod() { return m_cholmod; }
286 
287  #ifndef EIGEN_PARSED_BY_DOXYGEN
288 
289  template<typename Rhs,typename Dest>
290  void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
291  {
292  eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
293  const Index size = m_cholmodFactor->n;
294  EIGEN_UNUSED_VARIABLE(size);
295  eigen_assert(size==b.rows());
296 
297  // note: cd stands for Cholmod Dense
298  Rhs& b_ref(b.const_cast_derived());
299  cholmod_dense b_cd = viewAsCholmod(b_ref);
300  cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod);
301  if(!x_cd)
302  {
303  this->m_info = NumericalIssue;
304  }
305  // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.)
306  dest = Matrix<Scalar,Dest::RowsAtCompileTime,Dest::ColsAtCompileTime>::Map(reinterpret_cast<Scalar*>(x_cd->x),b.rows(),b.cols());
307  cholmod_free_dense(&x_cd, &m_cholmod);
308  }
309 
311  template<typename RhsScalar, int RhsOptions, typename RhsIndex, typename DestScalar, int DestOptions, typename DestIndex>
313  {
314  eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
315  const Index size = m_cholmodFactor->n;
316  EIGEN_UNUSED_VARIABLE(size);
317  eigen_assert(size==b.rows());
318 
319  // note: cs stands for Cholmod Sparse
320  cholmod_sparse b_cs = viewAsCholmod(b);
321  cholmod_sparse* x_cs = cholmod_spsolve(CHOLMOD_A, m_cholmodFactor, &b_cs, &m_cholmod);
322  if(!x_cs)
323  {
324  this->m_info = NumericalIssue;
325  }
326  // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.)
327  dest = viewAsEigen<DestScalar,DestOptions,DestIndex>(*x_cs);
328  cholmod_free_sparse(&x_cs, &m_cholmod);
329  }
330  #endif // EIGEN_PARSED_BY_DOXYGEN
331 
332 
342  Derived& setShift(const RealScalar& offset)
343  {
344  m_shiftOffset[0] = offset;
345  return derived();
346  }
347 
348  template<typename Stream>
349  void dumpMemory(Stream& /*s*/)
350  {}
351 
352  protected:
353  mutable cholmod_common m_cholmod;
354  cholmod_factor* m_cholmodFactor;
355  RealScalar m_shiftOffset[2];
360 };
361 
380 template<typename _MatrixType, int _UpLo = Lower>
381 class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLLT<_MatrixType, _UpLo> >
382 {
384  using Base::m_cholmod;
385 
386  public:
387 
388  typedef _MatrixType MatrixType;
389 
390  CholmodSimplicialLLT() : Base() { init(); }
391 
392  CholmodSimplicialLLT(const MatrixType& matrix) : Base()
393  {
394  init();
395  compute(matrix);
396  }
397 
399  protected:
400  void init()
401  {
402  m_cholmod.final_asis = 0;
403  m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
404  m_cholmod.final_ll = 1;
405  }
406 };
407 
408 
427 template<typename _MatrixType, int _UpLo = Lower>
428 class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimplicialLDLT<_MatrixType, _UpLo> >
429 {
431  using Base::m_cholmod;
432 
433  public:
434 
435  typedef _MatrixType MatrixType;
436 
437  CholmodSimplicialLDLT() : Base() { init(); }
438 
439  CholmodSimplicialLDLT(const MatrixType& matrix) : Base()
440  {
441  init();
442  compute(matrix);
443  }
444 
446  protected:
447  void init()
448  {
449  m_cholmod.final_asis = 1;
450  m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
451  }
452 };
453 
472 template<typename _MatrixType, int _UpLo = Lower>
473 class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSupernodalLLT<_MatrixType, _UpLo> >
474 {
476  using Base::m_cholmod;
477 
478  public:
479 
480  typedef _MatrixType MatrixType;
481 
482  CholmodSupernodalLLT() : Base() { init(); }
483 
484  CholmodSupernodalLLT(const MatrixType& matrix) : Base()
485  {
486  init();
487  compute(matrix);
488  }
489 
491  protected:
492  void init()
493  {
494  m_cholmod.final_asis = 1;
495  m_cholmod.supernodal = CHOLMOD_SUPERNODAL;
496  }
497 };
498 
519 template<typename _MatrixType, int _UpLo = Lower>
520 class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecomposition<_MatrixType, _UpLo> >
521 {
523  using Base::m_cholmod;
524 
525  public:
526 
527  typedef _MatrixType MatrixType;
528 
529  CholmodDecomposition() : Base() { init(); }
530 
531  CholmodDecomposition(const MatrixType& matrix) : Base()
532  {
533  init();
534  compute(matrix);
535  }
536 
538 
539  void setMode(CholmodMode mode)
540  {
541  switch(mode)
542  {
543  case CholmodAuto:
544  m_cholmod.final_asis = 1;
545  m_cholmod.supernodal = CHOLMOD_AUTO;
546  break;
548  m_cholmod.final_asis = 0;
549  m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
550  m_cholmod.final_ll = 1;
551  break;
553  m_cholmod.final_asis = 1;
554  m_cholmod.supernodal = CHOLMOD_SUPERNODAL;
555  break;
556  case CholmodLDLt:
557  m_cholmod.final_asis = 1;
558  m_cholmod.supernodal = CHOLMOD_SIMPLICIAL;
559  break;
560  default:
561  break;
562  }
563  }
564  protected:
565  void init()
566  {
567  m_cholmod.final_asis = 1;
568  m_cholmod.supernodal = CHOLMOD_AUTO;
569  }
570 };
571 
572 namespace internal {
573 
574 template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs>
575 struct solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
576  : solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
577 {
579  EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
580 
581  template<typename Dest> void evalTo(Dest& dst) const
582  {
583  dec()._solve(rhs(),dst);
584  }
585 };
586 
587 template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs>
588 struct sparse_solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
589  : sparse_solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
590 {
593 
594  template<typename Dest> void evalTo(Dest& dst) const
595  {
596  dec()._solve(rhs(),dst);
597  }
598 };
599 
600 } // end namespace internal
601 
602 } // end namespace Eigen
603 
604 #endif // EIGEN_CHOLMODSUPPORT_H
Index cols() const
void setMode(CholmodMode mode)
Index rows() const
CholmodBase< _MatrixType, _UpLo, CholmodSupernodalLLT > Base
Index cols() const
Definition: SparseMatrix.h:121
CholmodBase< _MatrixType, _UpLo, CholmodDecomposition > Base
A versatible sparse matrix representation.
Definition: SparseMatrix.h:85
cholmod_factor * m_cholmodFactor
void factorize(const MatrixType &matrix)
const Derived & derived() const
#define EIGEN_UNUSED_VARIABLE(var)
_MatrixType MatrixType
Definition: LDLT.h:16
Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix.
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
Definition: StaticAssert.h:111
CholmodBase(const MatrixType &matrix)
A supernodal Cholesky (LLT) factorization and solver based on Cholmod.
MatrixType CholMatrixType
CholmodDecomposition(const MatrixType &matrix)
const unsigned int RowMajorBit
Definition: Constants.h:53
Index nonZeros() const
Definition: SparseMatrix.h:246
CholmodBase< _MatrixType, _UpLo, CholmodSimplicialLDLT > Base
const Index * outerIndexPtr() const
Definition: SparseMatrix.h:149
cholmod_common & cholmod()
MappedSparseMatrix< Scalar, Flags, Index > viewAsEigen(cholmod_sparse &cm)
Base class of any sparse matrices or sparse expressions.
cholmod_sparse viewAsCholmod(SparseMatrix< _Scalar, _Options, _Index > &mat)
void dumpMemory(Stream &)
void analyzePattern(const MatrixType &matrix)
void _solve(const SparseMatrix< RhsScalar, RhsOptions, RhsIndex > &b, SparseMatrix< DestScalar, DestOptions, DestIndex > &dest) const
CholmodBase< _MatrixType, _UpLo, CholmodSimplicialLLT > Base
A general Cholesky factorization and solver based on Cholmod.
#define EIGEN_MAKE_SPARSE_SOLVE_HELPERS(DecompositionType, Rhs)
Definition: SparseSolve.h:71
The base class for the direct Cholesky factorization of Cholmod.
ComputationInfo info() const
Reports whether previous computation was successful.
A simplicial direct Cholesky (LLT) factorization and solver based on Cholmod.
void cholmod_configure_matrix(CholmodType &mat)
const internal::solve_retval< CholmodBase, Rhs > solve(const MatrixBase< Rhs > &b) const
bool isCompressed() const
Definition: SparseMatrix.h:116
MatrixType::RealScalar RealScalar
MatrixType::Index Index
A simplicial direct Cholesky (LDLT) factorization and solver based on Cholmod.
Derived & compute(const MatrixType &matrix)
const Derived & derived() const
Derived & setShift(const RealScalar &offset)
void _solve(const MatrixBase< Rhs > &b, MatrixBase< Dest > &dest) const
cholmod_common m_cholmod
MatrixType::Scalar Scalar
ComputationInfo m_info
CholmodSimplicialLLT(const MatrixType &matrix)
const Index * innerIndexPtr() const
Definition: SparseMatrix.h:140
#define EIGEN_MAKE_SOLVE_HELPERS(DecompositionType, Rhs)
Definition: Solve.h:61
CholmodSupernodalLLT(const MatrixType &matrix)
#define eigen_assert(x)
const Scalar * valuePtr() const
Definition: SparseMatrix.h:131
ComputationInfo
Definition: Constants.h:374
const internal::sparse_solve_retval< CholmodBase, Rhs > solve(const SparseMatrixBase< Rhs > &b) const
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
Index rows() const
Definition: SparseMatrix.h:119
const Index * innerNonZeroPtr() const
Definition: SparseMatrix.h:158
CholmodSimplicialLDLT(const MatrixType &matrix)
SparseMatrix< _Scalar, _Options, _Index > & const_cast_derived() const


tuw_aruco
Author(s): Lukas Pfeifhofer
autogenerated on Mon Jun 10 2019 15:40:46