2008-10-05 13:38:38 +00:00
// This file is part of Eigen, a lightweight C++ template library
2009-05-22 20:25:33 +02:00
// for linear algebra.
2008-10-05 13:38:38 +00:00
//
2010-10-26 15:48:33 +02:00
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
2008-10-05 13:38:38 +00:00
//
2012-07-13 14:42:47 -04:00
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
2008-10-05 13:38:38 +00:00
# ifndef EIGEN_CHOLMODSUPPORT_H
# define EIGEN_CHOLMODSUPPORT_H
2012-04-15 11:06:28 +01:00
namespace Eigen {
2010-10-25 10:15:22 -04:00
namespace internal {
2010-10-27 14:31:23 +02:00
2008-12-27 18:13:29 +00:00
template < typename Scalar , typename CholmodType >
2010-10-25 10:15:22 -04:00
void cholmod_configure_matrix ( CholmodType & mat )
2008-10-05 13:38:38 +00:00
{
2010-10-26 15:48:33 +02:00
if ( internal : : is_same < Scalar , float > : : value )
2008-10-05 13:38:38 +00:00
{
2008-12-27 18:13:29 +00:00
mat . xtype = CHOLMOD_REAL ;
2010-05-19 16:49:05 +02:00
mat . dtype = CHOLMOD_SINGLE ;
2008-10-05 13:38:38 +00:00
}
2010-10-26 15:48:33 +02:00
else if ( internal : : is_same < Scalar , double > : : value )
2008-10-05 13:38:38 +00:00
{
2008-12-27 18:13:29 +00:00
mat . xtype = CHOLMOD_REAL ;
2010-05-19 16:49:05 +02:00
mat . dtype = CHOLMOD_DOUBLE ;
2008-10-05 13:38:38 +00:00
}
2010-10-26 15:48:33 +02:00
else if ( internal : : is_same < Scalar , std : : complex < float > > : : value )
2008-10-05 13:38:38 +00:00
{
2008-12-27 18:13:29 +00:00
mat . xtype = CHOLMOD_COMPLEX ;
2010-05-19 16:49:05 +02:00
mat . dtype = CHOLMOD_SINGLE ;
2008-10-05 13:38:38 +00:00
}
2010-10-26 15:48:33 +02:00
else if ( internal : : is_same < Scalar , std : : complex < double > > : : value )
2008-10-05 13:38:38 +00:00
{
2008-12-27 18:13:29 +00:00
mat . xtype = CHOLMOD_COMPLEX ;
2010-05-19 16:49:05 +02:00
mat . dtype = CHOLMOD_DOUBLE ;
2008-10-05 13:38:38 +00:00
}
else
{
2010-10-25 10:15:22 -04:00
eigen_assert ( false & & " Scalar type not supported by CHOLMOD " ) ;
2008-10-05 13:38:38 +00:00
}
2008-12-27 18:13:29 +00:00
}
2010-10-26 15:48:33 +02:00
} // namespace internal
/** Wraps the Eigen sparse matrix \a mat into a Cholmod sparse matrix object.
* Note that the data are shared .
*/
2014-12-04 22:48:53 +01:00
template < typename _Scalar , int _Options , typename _StorageIndex >
cholmod_sparse viewAsCholmod ( SparseMatrix < _Scalar , _Options , _StorageIndex > & mat )
2008-12-27 18:13:29 +00:00
{
cholmod_sparse res ;
2010-06-18 11:28:30 +02:00
res . nzmax = mat . nonZeros ( ) ;
res . nrow = mat . rows ( ) ; ;
res . ncol = mat . cols ( ) ;
2011-12-04 12:19:26 +01:00
res . p = mat . outerIndexPtr ( ) ;
res . i = mat . innerIndexPtr ( ) ;
res . x = mat . valuePtr ( ) ;
2013-10-17 00:03:00 +02:00
res . z = 0 ;
2010-04-09 13:37:05 +02:00
res . sorted = 1 ;
2011-12-10 23:08:10 +01:00
if ( mat . isCompressed ( ) )
2011-12-10 22:53:31 +01:00
{
res . packed = 1 ;
2013-10-17 00:03:00 +02:00
res . nz = 0 ;
2011-12-10 22:53:31 +01:00
}
else
{
res . packed = 0 ;
res . nz = mat . innerNonZeroPtr ( ) ;
}
2010-04-09 13:37:05 +02:00
res . dtype = 0 ;
res . stype = - 1 ;
2010-10-26 15:48:33 +02:00
2014-12-04 22:48:53 +01:00
if ( internal : : is_same < _StorageIndex , int > : : value )
2008-10-05 13:38:38 +00:00
{
2010-10-26 15:48:33 +02:00
res . itype = CHOLMOD_INT ;
2008-10-05 13:38:38 +00:00
}
2015-10-12 16:20:12 +02:00
else if ( internal : : is_same < _StorageIndex , SuiteSparse_long > : : value )
2012-11-12 15:20:37 +01:00
{
res . itype = CHOLMOD_LONG ;
}
2008-10-05 13:38:38 +00:00
else
2010-10-26 15:48:33 +02:00
{
2012-11-12 15:20:37 +01:00
eigen_assert ( false & & " Index type not supported yet " ) ;
2010-10-26 15:48:33 +02:00
}
// setup res.xtype
internal : : cholmod_configure_matrix < _Scalar > ( res ) ;
res . stype = 0 ;
return res ;
}
2010-10-27 14:31:23 +02:00
template < typename _Scalar , int _Options , typename _Index >
const cholmod_sparse viewAsCholmod ( const SparseMatrix < _Scalar , _Options , _Index > & mat )
{
cholmod_sparse res = viewAsCholmod ( mat . const_cast_derived ( ) ) ;
return res ;
}
2010-10-26 15:48:33 +02:00
/** Returns a view of the Eigen sparse matrix \a mat as Cholmod sparse matrix.
* The data are not copied but shared . */
template < typename _Scalar , int _Options , typename _Index , unsigned int UpLo >
2014-10-07 18:29:28 +02:00
cholmod_sparse viewAsCholmod ( const SparseSelfAdjointView < const SparseMatrix < _Scalar , _Options , _Index > , UpLo > & mat )
2010-10-26 15:48:33 +02:00
{
cholmod_sparse res = viewAsCholmod ( mat . matrix ( ) . const_cast_derived ( ) ) ;
if ( UpLo = = Upper ) res . stype = 1 ;
if ( UpLo = = Lower ) res . stype = - 1 ;
2008-10-05 13:38:38 +00:00
return res ;
}
2010-10-26 15:48:33 +02:00
/** Returns a view of the Eigen \b dense matrix \a mat as Cholmod dense matrix.
* The data are not copied but shared . */
2008-12-27 18:13:29 +00:00
template < typename Derived >
2010-10-26 15:48:33 +02:00
cholmod_dense viewAsCholmod ( MatrixBase < Derived > & mat )
2008-12-27 18:13:29 +00:00
{
2010-10-26 15:48:33 +02:00
EIGEN_STATIC_ASSERT ( ( internal : : traits < Derived > : : Flags & RowMajorBit ) = = 0 , THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES ) ;
2008-12-27 18:13:29 +00:00
typedef typename Derived : : Scalar Scalar ;
cholmod_dense res ;
res . nrow = mat . rows ( ) ;
res . ncol = mat . cols ( ) ;
res . nzmax = res . nrow * res . ncol ;
2010-02-25 21:01:52 -05:00
res . d = Derived : : IsVectorAtCompileTime ? mat . derived ( ) . size ( ) : mat . derived ( ) . outerStride ( ) ;
2013-06-24 17:24:32 +02:00
res . x = ( void * ) ( mat . derived ( ) . data ( ) ) ;
2008-12-27 18:13:29 +00:00
res . z = 0 ;
2010-10-26 15:48:33 +02:00
internal : : cholmod_configure_matrix < Scalar > ( res ) ;
2008-12-27 18:13:29 +00:00
return res ;
}
2010-10-26 15:48:33 +02:00
/** Returns a view of the Cholmod sparse matrix \a cm as an Eigen sparse matrix.
* The data are not copied but shared . */
2014-12-04 22:48:53 +01:00
template < typename Scalar , int Flags , typename StorageIndex >
MappedSparseMatrix < Scalar , Flags , StorageIndex > viewAsEigen ( cholmod_sparse & cm )
2008-10-05 13:38:38 +00:00
{
2014-12-04 22:48:53 +01:00
return MappedSparseMatrix < Scalar , Flags , StorageIndex >
( cm . nrow , cm . ncol , static_cast < StorageIndex * > ( cm . p ) [ cm . ncol ] ,
static_cast < StorageIndex * > ( cm . p ) , static_cast < StorageIndex * > ( cm . i ) , static_cast < Scalar * > ( cm . x ) ) ;
2008-10-05 13:38:38 +00:00
}
2010-10-26 15:48:33 +02:00
enum CholmodMode {
CholmodAuto , CholmodSimplicialLLt , CholmodSupernodalLLt , CholmodLDLt
} ;
2010-10-04 20:56:54 +02:00
2012-06-04 13:24:41 +02:00
2011-11-28 16:36:37 +01:00
/** \ingroup CholmodSupport_Module
2012-06-04 13:24:41 +02:00
* \ class CholmodBase
* \ brief The base class for the direct Cholesky factorization of Cholmod
* \ sa class CholmodSupernodalLLT , class CholmodSimplicialLDLT , class CholmodSimplicialLLT
2010-10-26 15:48:33 +02:00
*/
2012-06-04 13:24:41 +02:00
template < typename _MatrixType , int _UpLo , typename Derived >
2014-09-01 15:00:19 +02:00
class CholmodBase : public SparseSolverBase < Derived >
2010-10-04 20:56:54 +02:00
{
2014-09-01 15:00:19 +02:00
protected :
typedef SparseSolverBase < Derived > Base ;
using Base : : derived ;
using Base : : m_isInitialized ;
2010-10-04 20:56:54 +02:00
public :
typedef _MatrixType MatrixType ;
2010-10-26 15:48:33 +02:00
enum { UpLo = _UpLo } ;
typedef typename MatrixType : : Scalar Scalar ;
typedef typename MatrixType : : RealScalar RealScalar ;
typedef MatrixType CholMatrixType ;
2014-12-04 22:48:53 +01:00
typedef typename MatrixType : : StorageIndex StorageIndex ;
2010-10-04 20:56:54 +02:00
2010-10-26 15:48:33 +02:00
public :
2012-06-04 13:24:41 +02:00
CholmodBase ( )
2014-09-01 15:00:19 +02:00
: m_cholmodFactor ( 0 ) , m_info ( Success )
2010-10-04 20:56:54 +02:00
{
2013-10-17 00:03:00 +02:00
m_shiftOffset [ 0 ] = m_shiftOffset [ 1 ] = RealScalar ( 0.0 ) ;
2010-10-04 20:56:54 +02:00
cholmod_start ( & m_cholmod ) ;
}
2014-09-23 14:28:23 +02:00
explicit CholmodBase ( const MatrixType & matrix )
2014-09-01 15:00:19 +02:00
: m_cholmodFactor ( 0 ) , m_info ( Success )
2010-10-04 20:56:54 +02:00
{
2012-07-04 18:46:14 +02:00
m_shiftOffset [ 0 ] = m_shiftOffset [ 1 ] = RealScalar ( 0.0 ) ;
2010-10-04 20:56:54 +02:00
cholmod_start ( & m_cholmod ) ;
compute ( matrix ) ;
}
2012-06-04 13:24:41 +02:00
~ CholmodBase ( )
2010-10-04 20:56:54 +02:00
{
2010-10-26 15:48:33 +02:00
if ( m_cholmodFactor )
2010-10-04 20:56:54 +02:00
cholmod_free_factor ( & m_cholmodFactor , & m_cholmod ) ;
cholmod_finish ( & m_cholmod ) ;
}
2010-10-26 15:48:33 +02:00
2014-12-04 22:48:53 +01:00
inline StorageIndex cols ( ) const { return internal : : convert_index < StorageIndex , Index > ( m_cholmodFactor - > n ) ; }
inline StorageIndex rows ( ) const { return internal : : convert_index < StorageIndex , Index > ( m_cholmodFactor - > n ) ; }
2010-10-26 15:48:33 +02:00
2010-10-26 16:47:47 +02:00
/** \brief Reports whether previous computation was successful.
*
* \ returns \ c Success if computation was succesful ,
* \ c NumericalIssue if the matrix . appears to be negative .
*/
ComputationInfo info ( ) const
{
eigen_assert ( m_isInitialized & & " Decomposition is not initialized. " ) ;
return m_info ;
}
2010-10-04 20:56:54 +02:00
2010-10-26 15:48:33 +02:00
/** Computes the sparse Cholesky decomposition of \a matrix */
2012-06-04 13:24:41 +02:00
Derived & compute ( const MatrixType & matrix )
2010-10-26 15:48:33 +02:00
{
analyzePattern ( matrix ) ;
factorize ( matrix ) ;
2012-06-04 13:24:41 +02:00
return derived ( ) ;
2010-10-26 15:48:33 +02:00
}
2013-10-17 00:03:00 +02:00
/** Performs a symbolic decomposition on the sparsity pattern of \a matrix.
2010-10-26 15:48:33 +02:00
*
* This function is particularly useful when solving for several problems having the same structure .
*
* \ sa factorize ( )
*/
void analyzePattern ( const MatrixType & matrix )
{
if ( m_cholmodFactor )
{
cholmod_free_factor ( & m_cholmodFactor , & m_cholmod ) ;
m_cholmodFactor = 0 ;
}
cholmod_sparse A = viewAsCholmod ( matrix . template selfadjointView < UpLo > ( ) ) ;
m_cholmodFactor = cholmod_analyze ( & A , & m_cholmod ) ;
this - > m_isInitialized = true ;
this - > m_info = Success ;
m_analysisIsOk = true ;
m_factorizationIsOk = false ;
}
/** Performs a numeric decomposition of \a matrix
*
2013-10-17 00:03:00 +02:00
* The given matrix must have the same sparsity pattern as the matrix on which the symbolic decomposition has been performed .
2010-10-26 15:48:33 +02:00
*
* \ sa analyzePattern ( )
*/
void factorize ( const MatrixType & matrix )
{
eigen_assert ( m_analysisIsOk & & " You must first call analyzePattern() " ) ;
cholmod_sparse A = viewAsCholmod ( matrix . template selfadjointView < UpLo > ( ) ) ;
2012-07-04 18:46:14 +02:00
cholmod_factorize_p ( & A , m_shiftOffset , 0 , 0 , m_cholmodFactor , & m_cholmod ) ;
2010-10-26 15:48:33 +02:00
2012-07-04 18:46:14 +02:00
// If the factorization failed, minor is the column at which it did. On success minor == n.
this - > m_info = ( m_cholmodFactor - > minor = = m_cholmodFactor - > n ? Success : NumericalIssue ) ;
2010-10-26 15:48:33 +02:00
m_factorizationIsOk = true ;
}
/** Returns a reference to the Cholmod's configuration structure to get a full control over the performed operations.
* See the Cholmod user guide for details . */
cholmod_common & cholmod ( ) { return m_cholmod ; }
2010-10-26 16:47:47 +02:00
# ifndef EIGEN_PARSED_BY_DOXYGEN
2010-10-26 15:48:33 +02:00
/** \internal */
template < typename Rhs , typename Dest >
2014-09-01 15:00:19 +02:00
void _solve_impl ( const MatrixBase < Rhs > & b , MatrixBase < Dest > & dest ) const
2010-10-26 15:48:33 +02:00
{
eigen_assert ( m_factorizationIsOk & & " The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric() " ) ;
const Index size = m_cholmodFactor - > n ;
2012-07-04 18:46:14 +02:00
EIGEN_UNUSED_VARIABLE ( size ) ;
2010-10-26 15:48:33 +02:00
eigen_assert ( size = = b . rows ( ) ) ;
// note: cd stands for Cholmod Dense
2013-06-24 17:24:32 +02:00
Rhs & b_ref ( b . const_cast_derived ( ) ) ;
cholmod_dense b_cd = viewAsCholmod ( b_ref ) ;
2010-10-26 15:48:33 +02:00
cholmod_dense * x_cd = cholmod_solve ( CHOLMOD_A , m_cholmodFactor , & b_cd , & m_cholmod ) ;
if ( ! x_cd )
{
this - > m_info = NumericalIssue ;
2015-02-18 11:26:25 +01:00
return ;
2010-10-26 15:48:33 +02:00
}
2013-10-17 00:03:00 +02:00
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
2010-10-27 14:31:23 +02:00
dest = Matrix < Scalar , Dest : : RowsAtCompileTime , Dest : : ColsAtCompileTime > : : Map ( reinterpret_cast < Scalar * > ( x_cd - > x ) , b . rows ( ) , b . cols ( ) ) ;
2010-10-26 15:48:33 +02:00
cholmod_free_dense ( & x_cd , & m_cholmod ) ;
}
2010-10-26 16:47:47 +02:00
2010-10-27 14:31:23 +02:00
/** \internal */
template < typename RhsScalar , int RhsOptions , typename RhsIndex , typename DestScalar , int DestOptions , typename DestIndex >
2014-09-01 15:00:19 +02:00
void _solve_impl ( const SparseMatrix < RhsScalar , RhsOptions , RhsIndex > & b , SparseMatrix < DestScalar , DestOptions , DestIndex > & dest ) const
2010-10-27 14:31:23 +02:00
{
eigen_assert ( m_factorizationIsOk & & " The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric() " ) ;
const Index size = m_cholmodFactor - > n ;
2013-06-09 21:03:32 +02:00
EIGEN_UNUSED_VARIABLE ( size ) ;
2010-10-27 14:31:23 +02:00
eigen_assert ( size = = b . rows ( ) ) ;
// note: cs stands for Cholmod Sparse
cholmod_sparse b_cs = viewAsCholmod ( b ) ;
cholmod_sparse * x_cs = cholmod_spsolve ( CHOLMOD_A , m_cholmodFactor , & b_cs , & m_cholmod ) ;
if ( ! x_cs )
{
this - > m_info = NumericalIssue ;
2015-02-18 11:26:25 +01:00
return ;
2010-10-27 14:31:23 +02:00
}
2013-10-17 00:03:00 +02:00
// TODO optimize this copy by swapping when possible (be careful with alignment, etc.)
2010-10-27 14:31:23 +02:00
dest = viewAsEigen < DestScalar , DestOptions , DestIndex > ( * x_cs ) ;
cholmod_free_sparse ( & x_cs , & m_cholmod ) ;
}
2010-10-26 16:47:47 +02:00
# endif // EIGEN_PARSED_BY_DOXYGEN
2010-11-18 10:30:52 +01:00
2012-07-04 18:46:14 +02:00
/** Sets the shift parameter that will be used to adjust the diagonal coefficients during the numerical factorization.
*
* During the numerical factorization , an offset term is added to the diagonal coefficients : \ n
* \ c d_ii = \ a offset + \ c d_ii
*
* The default is \ a offset = 0.
*
* \ returns a reference to \ c * this .
*/
Derived & setShift ( const RealScalar & offset )
{
m_shiftOffset [ 0 ] = offset ;
return derived ( ) ;
}
2010-11-18 10:30:52 +01:00
template < typename Stream >
2013-06-24 17:24:32 +02:00
void dumpMemory ( Stream & /*s*/ )
2010-11-18 10:30:52 +01:00
{ }
2012-06-04 13:24:41 +02:00
2010-10-04 20:56:54 +02:00
protected :
mutable cholmod_common m_cholmod ;
cholmod_factor * m_cholmodFactor ;
2012-07-04 18:46:14 +02:00
RealScalar m_shiftOffset [ 2 ] ;
2010-10-26 16:47:47 +02:00
mutable ComputationInfo m_info ;
2010-10-26 15:48:33 +02:00
int m_factorizationIsOk ;
int m_analysisIsOk ;
2012-06-04 13:24:41 +02:00
} ;
/** \ingroup CholmodSupport_Module
* \ class CholmodSimplicialLLT
* \ brief A simplicial direct Cholesky ( LLT ) factorization and solver based on Cholmod
*
* This class allows to solve for A . X = B sparse linear problems via a simplicial LL ^ T Cholesky factorization
* using the Cholmod library .
2013-10-17 00:03:00 +02:00
* This simplicial variant is equivalent to Eigen ' s built - in SimplicialLLT class . Therefore , it has little practical interest .
* The sparse matrix A must be selfadjoint and positive definite . The vectors or matrices
2012-06-04 13:24:41 +02:00
* X and B can be either dense or sparse .
*
* \ tparam _MatrixType the type of the sparse matrix A , it must be a SparseMatrix < >
* \ tparam _UpLo the triangular part that will be used for the computations . It can be Lower
* or Upper . Default is Lower .
*
2015-10-08 10:50:39 +02:00
* \ implsparsesolverconcept
*
2012-06-04 13:24:41 +02:00
* This class supports all kind of SparseMatrix < > : row or column major ; upper , lower , or both ; compressed or non compressed .
*
* \ sa \ ref TutorialSparseDirectSolvers , class CholmodSupernodalLLT , class SimplicialLLT
*/
template < typename _MatrixType , int _UpLo = Lower >
class CholmodSimplicialLLT : public CholmodBase < _MatrixType , _UpLo , CholmodSimplicialLLT < _MatrixType , _UpLo > >
{
typedef CholmodBase < _MatrixType , _UpLo , CholmodSimplicialLLT > Base ;
using Base : : m_cholmod ;
2012-03-29 19:19:12 +02:00
2012-06-04 13:24:41 +02:00
public :
typedef _MatrixType MatrixType ;
CholmodSimplicialLLT ( ) : Base ( ) { init ( ) ; }
CholmodSimplicialLLT ( const MatrixType & matrix ) : Base ( )
{
init ( ) ;
2015-02-17 15:24:52 +01:00
this - > compute ( matrix ) ;
2012-06-04 13:24:41 +02:00
}
~ CholmodSimplicialLLT ( ) { }
protected :
void init ( )
{
m_cholmod . final_asis = 0 ;
m_cholmod . supernodal = CHOLMOD_SIMPLICIAL ;
m_cholmod . final_ll = 1 ;
}
} ;
/** \ingroup CholmodSupport_Module
* \ class CholmodSimplicialLDLT
* \ brief A simplicial direct Cholesky ( LDLT ) factorization and solver based on Cholmod
*
* This class allows to solve for A . X = B sparse linear problems via a simplicial LDL ^ T Cholesky factorization
* using the Cholmod library .
2013-10-17 00:03:00 +02:00
* This simplicial variant is equivalent to Eigen ' s built - in SimplicialLDLT class . Therefore , it has little practical interest .
* The sparse matrix A must be selfadjoint and positive definite . The vectors or matrices
2012-06-04 13:24:41 +02:00
* X and B can be either dense or sparse .
*
* \ tparam _MatrixType the type of the sparse matrix A , it must be a SparseMatrix < >
* \ tparam _UpLo the triangular part that will be used for the computations . It can be Lower
* or Upper . Default is Lower .
*
2015-10-08 10:50:39 +02:00
* \ implsparsesolverconcept
*
2012-06-04 13:24:41 +02:00
* This class supports all kind of SparseMatrix < > : row or column major ; upper , lower , or both ; compressed or non compressed .
*
* \ sa \ ref TutorialSparseDirectSolvers , class CholmodSupernodalLLT , class SimplicialLDLT
*/
template < typename _MatrixType , int _UpLo = Lower >
class CholmodSimplicialLDLT : public CholmodBase < _MatrixType , _UpLo , CholmodSimplicialLDLT < _MatrixType , _UpLo > >
{
typedef CholmodBase < _MatrixType , _UpLo , CholmodSimplicialLDLT > Base ;
using Base : : m_cholmod ;
public :
typedef _MatrixType MatrixType ;
CholmodSimplicialLDLT ( ) : Base ( ) { init ( ) ; }
CholmodSimplicialLDLT ( const MatrixType & matrix ) : Base ( )
{
init ( ) ;
2015-02-17 15:24:52 +01:00
this - > compute ( matrix ) ;
2012-06-04 13:24:41 +02:00
}
~ CholmodSimplicialLDLT ( ) { }
protected :
void init ( )
{
m_cholmod . final_asis = 1 ;
m_cholmod . supernodal = CHOLMOD_SIMPLICIAL ;
}
} ;
/** \ingroup CholmodSupport_Module
* \ class CholmodSupernodalLLT
* \ brief A supernodal Cholesky ( LLT ) factorization and solver based on Cholmod
*
* This class allows to solve for A . X = B sparse linear problems via a supernodal LL ^ T Cholesky factorization
* using the Cholmod library .
* This supernodal variant performs best on dense enough problems , e . g . , 3 D FEM , or very high order 2 D FEM .
2013-10-17 00:03:00 +02:00
* The sparse matrix A must be selfadjoint and positive definite . The vectors or matrices
2012-06-04 13:24:41 +02:00
* X and B can be either dense or sparse .
*
* \ tparam _MatrixType the type of the sparse matrix A , it must be a SparseMatrix < >
* \ tparam _UpLo the triangular part that will be used for the computations . It can be Lower
* or Upper . Default is Lower .
*
2015-10-08 10:50:39 +02:00
* \ implsparsesolverconcept
*
2012-06-04 13:24:41 +02:00
* This class supports all kind of SparseMatrix < > : row or column major ; upper , lower , or both ; compressed or non compressed .
*
* \ sa \ ref TutorialSparseDirectSolvers
*/
template < typename _MatrixType , int _UpLo = Lower >
class CholmodSupernodalLLT : public CholmodBase < _MatrixType , _UpLo , CholmodSupernodalLLT < _MatrixType , _UpLo > >
{
typedef CholmodBase < _MatrixType , _UpLo , CholmodSupernodalLLT > Base ;
using Base : : m_cholmod ;
public :
typedef _MatrixType MatrixType ;
CholmodSupernodalLLT ( ) : Base ( ) { init ( ) ; }
CholmodSupernodalLLT ( const MatrixType & matrix ) : Base ( )
{
init ( ) ;
2015-02-17 15:24:52 +01:00
this - > compute ( matrix ) ;
2012-06-04 13:24:41 +02:00
}
~ CholmodSupernodalLLT ( ) { }
protected :
void init ( )
{
m_cholmod . final_asis = 1 ;
m_cholmod . supernodal = CHOLMOD_SUPERNODAL ;
}
} ;
/** \ingroup CholmodSupport_Module
* \ class CholmodDecomposition
* \ brief A general Cholesky factorization and solver based on Cholmod
*
* This class allows to solve for A . X = B sparse linear problems via a LL ^ T or LDL ^ T Cholesky factorization
2013-10-17 00:03:00 +02:00
* using the Cholmod library . The sparse matrix A must be selfadjoint and positive definite . The vectors or matrices
2012-06-04 13:24:41 +02:00
* X and B can be either dense or sparse .
*
* This variant permits to change the underlying Cholesky method at runtime .
* On the other hand , it does not provide access to the result of the factorization .
* The default is to let Cholmod automatically choose between a simplicial and supernodal factorization .
*
* \ tparam _MatrixType the type of the sparse matrix A , it must be a SparseMatrix < >
* \ tparam _UpLo the triangular part that will be used for the computations . It can be Lower
* or Upper . Default is Lower .
*
2015-10-08 10:50:39 +02:00
* \ implsparsesolverconcept
*
2012-06-04 13:24:41 +02:00
* This class supports all kind of SparseMatrix < > : row or column major ; upper , lower , or both ; compressed or non compressed .
*
* \ sa \ ref TutorialSparseDirectSolvers
*/
template < typename _MatrixType , int _UpLo = Lower >
class CholmodDecomposition : public CholmodBase < _MatrixType , _UpLo , CholmodDecomposition < _MatrixType , _UpLo > >
{
typedef CholmodBase < _MatrixType , _UpLo , CholmodDecomposition > Base ;
using Base : : m_cholmod ;
public :
typedef _MatrixType MatrixType ;
CholmodDecomposition ( ) : Base ( ) { init ( ) ; }
CholmodDecomposition ( const MatrixType & matrix ) : Base ( )
{
init ( ) ;
2015-02-17 15:24:52 +01:00
this - > compute ( matrix ) ;
2012-06-04 13:24:41 +02:00
}
~ CholmodDecomposition ( ) { }
void setMode ( CholmodMode mode )
{
switch ( mode )
{
case CholmodAuto :
m_cholmod . final_asis = 1 ;
m_cholmod . supernodal = CHOLMOD_AUTO ;
break ;
case CholmodSimplicialLLt :
m_cholmod . final_asis = 0 ;
m_cholmod . supernodal = CHOLMOD_SIMPLICIAL ;
m_cholmod . final_ll = 1 ;
break ;
case CholmodSupernodalLLt :
m_cholmod . final_asis = 1 ;
m_cholmod . supernodal = CHOLMOD_SUPERNODAL ;
break ;
case CholmodLDLt :
m_cholmod . final_asis = 1 ;
m_cholmod . supernodal = CHOLMOD_SIMPLICIAL ;
break ;
default :
break ;
}
}
protected :
void init ( )
{
m_cholmod . final_asis = 1 ;
m_cholmod . supernodal = CHOLMOD_AUTO ;
}
2010-10-04 20:56:54 +02:00
} ;
2012-04-15 11:06:28 +01:00
} // end namespace Eigen
2010-10-04 20:56:54 +02:00
2008-10-05 13:38:38 +00:00
# endif // EIGEN_CHOLMODSUPPORT_H