2011-12-05 14:52:21 +07:00
/*
Copyright ( c ) 2011 , Intel Corporation . All rights reserved .
Redistribution and use in source and binary forms , with or without modification ,
are permitted provided that the following conditions are met :
* Redistributions of source code must retain the above copyright notice , this
list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution .
* Neither the name of Intel Corporation nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS " AND
ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Content : Eigen bindings to Intel ( R ) MKL PARDISO
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
# ifndef EIGEN_PARDISOSUPPORT_H
# define EIGEN_PARDISOSUPPORT_H
2012-02-04 14:20:56 +01:00
template < typename _MatrixType > class PardisoLU ;
template < typename _MatrixType , int Options = Upper > class PardisoLLT ;
template < typename _MatrixType , int Options = Upper > class PardisoLDLT ;
2011-12-05 14:52:21 +07:00
namespace internal
{
template < typename Index >
struct pardiso_run_selector
{
2012-02-04 14:20:56 +01:00
static Index run ( _MKL_DSS_HANDLE_t pt , Index maxfct , Index mnum , Index type , Index phase , Index n , void * a ,
Index * ia , Index * ja , Index * perm , Index nrhs , Index * iparm , Index msglvl , void * b , void * x )
2011-12-05 14:52:21 +07:00
{
Index error = 0 ;
: : pardiso ( pt , & maxfct , & mnum , & type , & phase , & n , a , ia , ja , perm , & nrhs , iparm , & msglvl , b , x , & error ) ;
return error ;
}
} ;
template < >
struct pardiso_run_selector < long long int >
{
typedef long long int Index ;
2012-02-04 14:20:56 +01:00
static Index run ( _MKL_DSS_HANDLE_t pt , Index maxfct , Index mnum , Index type , Index phase , Index n , void * a ,
Index * ia , Index * ja , Index * perm , Index nrhs , Index * iparm , Index msglvl , void * b , void * x )
2011-12-05 14:52:21 +07:00
{
Index error = 0 ;
: : pardiso_64 ( pt , & maxfct , & mnum , & type , & phase , & n , a , ia , ja , perm , & nrhs , iparm , & msglvl , b , x , & error ) ;
return error ;
}
} ;
2012-02-04 14:20:56 +01:00
template < class Pardiso > struct pardiso_traits ;
2011-12-05 14:52:21 +07:00
template < typename _MatrixType >
struct pardiso_traits < PardisoLU < _MatrixType > >
{
typedef _MatrixType MatrixType ;
typedef typename _MatrixType : : Scalar Scalar ;
typedef typename _MatrixType : : RealScalar RealScalar ;
typedef typename _MatrixType : : Index Index ;
} ;
template < typename _MatrixType >
struct pardiso_traits < PardisoLLT < _MatrixType > >
{
typedef _MatrixType MatrixType ;
typedef typename _MatrixType : : Scalar Scalar ;
typedef typename _MatrixType : : RealScalar RealScalar ;
typedef typename _MatrixType : : Index Index ;
} ;
template < typename _MatrixType >
struct pardiso_traits < PardisoLDLT < _MatrixType > >
{
typedef _MatrixType MatrixType ;
typedef typename _MatrixType : : Scalar Scalar ;
typedef typename _MatrixType : : RealScalar RealScalar ;
typedef typename _MatrixType : : Index Index ;
} ;
}
template < class Derived >
class PardisoImpl
{
public :
typedef typename internal : : pardiso_traits < Derived > : : MatrixType MatrixType ;
typedef typename internal : : pardiso_traits < Derived > : : Scalar Scalar ;
typedef typename internal : : pardiso_traits < Derived > : : RealScalar RealScalar ;
typedef typename internal : : pardiso_traits < Derived > : : Index Index ;
typedef Matrix < Scalar , Dynamic , 1 > VectorType ;
typedef Matrix < Index , 1 , MatrixType : : ColsAtCompileTime > IntRowVectorType ;
typedef Matrix < Index , MatrixType : : RowsAtCompileTime , 1 > IntColVectorType ;
enum {
ScalarIsComplex = NumTraits < Scalar > : : IsComplex
} ;
2012-02-04 14:20:56 +01:00
PardisoImpl ( )
2011-12-05 14:52:21 +07:00
{
eigen_assert ( ( sizeof ( Index ) > = sizeof ( _INTEGER_t ) & & sizeof ( Index ) < = 8 ) & & " Non-supported index type " ) ;
2012-02-04 14:20:56 +01:00
m_iparm . setZero ( ) ;
2011-12-05 14:52:21 +07:00
m_msglvl = 0 ; /* No output */
m_initialized = false ;
}
~ PardisoImpl ( )
{
pardisoRelease ( ) ;
}
inline Index cols ( ) const { return m_matrix . cols ( ) ; }
inline Index rows ( ) const { return m_matrix . rows ( ) ; }
/** \brief Reports whether previous computation was successful.
*
* \ returns \ c Success if computation was succesful ,
2012-02-04 14:20:56 +01:00
* \ c NumericalIssue if the matrix appears to be negative .
2011-12-05 14:52:21 +07:00
*/
ComputationInfo info ( ) const
{
eigen_assert ( m_initialized & & " Decomposition is not initialized. " ) ;
return m_info ;
}
2012-02-04 14:20:56 +01:00
/** \warning for advanced usage only.
* \ returns a reference to the parameter array controlling PARDISO .
* See the PARDISO manual to know how to use it . */
Array < Index , 64 , 1 > & pardisoParameterArray ( )
2011-12-05 14:52:21 +07:00
{
2012-02-04 14:20:56 +01:00
return m_param ;
2011-12-05 14:52:21 +07:00
}
Derived & compute ( const MatrixType & matrix ) ;
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
*
* \ sa compute ( )
*/
template < typename Rhs >
inline const internal : : solve_retval < PardisoImpl , Rhs >
2012-02-04 14:20:56 +01:00
solve ( const MatrixBase < Rhs > & b ) const
2011-12-05 14:52:21 +07:00
{
2012-02-04 14:20:56 +01:00
eigen_assert ( m_initialized & & " Pardiso solver is not initialized. " ) ;
2011-12-05 14:52:21 +07:00
eigen_assert ( rows ( ) = = b . rows ( )
& & " PardisoImpl::solve(): invalid number of rows of the right hand side matrix b " ) ;
2012-02-04 14:20:56 +01:00
return internal : : solve_retval < PardisoImpl , Rhs > ( * this , b . derived ( ) ) ;
}
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
*
* \ sa compute ( )
*/
template < typename Rhs >
inline const internal : : sparse_solve_retval < PardisoImpl , Rhs >
solve ( const SparseMatrixBase < Rhs > & b ) const
{
eigen_assert ( m_initialized & & " Pardiso solver is not initialized. " ) ;
eigen_assert ( rows ( ) = = b . rows ( )
& & " PardisoImpl::solve(): invalid number of rows of the right hand side matrix b " ) ;
return internal : : sparse_solve_retval < PardisoImpl , Rhs > ( * this , b . derived ( ) ) ;
2011-12-05 14:52:21 +07:00
}
Derived & derived ( )
{
return * static_cast < Derived * > ( this ) ;
}
const Derived & derived ( ) const
{
return * static_cast < const Derived * > ( this ) ;
}
template < typename BDerived , typename XDerived >
2012-02-04 14:20:56 +01:00
bool _solve ( const MatrixBase < BDerived > & b , MatrixBase < XDerived > & x ) const ;
/** \internal */
template < typename Rhs , typename DestScalar , int DestOptions , typename DestIndex >
void _solve_sparse ( const Rhs & b , SparseMatrix < DestScalar , DestOptions , DestIndex > & dest ) const
{
eigen_assert ( m_matrix . rows ( ) = = b . rows ( ) ) ;
// we process the sparse rhs per block of NbColsAtOnce columns temporarily stored into a dense matrix.
static const int NbColsAtOnce = 4 ;
int rhsCols = b . cols ( ) ;
int size = b . rows ( ) ;
Eigen : : Matrix < DestScalar , Dynamic , Dynamic > tmp ( size , rhsCols ) ;
for ( int k = 0 ; k < rhsCols ; k + = NbColsAtOnce )
{
int actualCols = std : : min < int > ( rhsCols - k , NbColsAtOnce ) ;
tmp . leftCols ( actualCols ) = b . middleCols ( k , actualCols ) ;
tmp . leftCols ( actualCols ) = derived ( ) . solve ( tmp . leftCols ( actualCols ) ) ;
dest . middleCols ( k , actualCols ) = tmp . leftCols ( actualCols ) . sparseView ( ) ;
}
}
2011-12-05 14:52:21 +07:00
protected :
void pardisoRelease ( )
{
if ( m_initialized ) // Factorization ran at least once
{
internal : : pardiso_run_selector < Index > : : run ( m_pt , 1 , 1 , m_type , - 1 , m_matrix . rows ( ) , NULL , NULL , NULL , m_perm . data ( ) , 0 ,
2012-02-04 14:20:56 +01:00
m_iparm . data ( ) , m_msglvl , NULL , NULL ) ;
m_iparm . setZero ( ) ;
2011-12-05 14:52:21 +07:00
}
}
2012-02-04 14:20:56 +01:00
void pardisoInit ( int type )
{
m_type = type ;
bool symmetric = abs ( m_type ) < 10 ;
m_iparm [ 0 ] = 1 ; /* No solver default */
m_iparm [ 1 ] = 3 ; // use Metis for the ordering
/* Numbers of processors, value of OMP_NUM_THREADS */
m_iparm [ 2 ] = 1 ;
m_iparm [ 3 ] = 0 ; /* No iterative-direct algorithm */
m_iparm [ 4 ] = 0 ; /* No user fill-in reducing permutation */
m_iparm [ 5 ] = 0 ; /* Write solution into x */
m_iparm [ 6 ] = 0 ; /* Not in use */
m_iparm [ 7 ] = 2 ; /* Max numbers of iterative refinement steps */
m_iparm [ 8 ] = 0 ; /* Not in use */
m_iparm [ 9 ] = 13 ; /* Perturb the pivot elements with 1E-13 */
m_iparm [ 10 ] = symmetric ? 0 : 1 ; /* Use nonsymmetric permutation and scaling MPS */
m_iparm [ 11 ] = 0 ; /* Not in use */
m_iparm [ 12 ] = symmetric ? 0 : 1 ; /* Maximum weighted matching algorithm is switched-off (default for symmetric). Try m_iparm[12] = 1 in case of inappropriate accuracy */
m_iparm [ 13 ] = 0 ; /* Output: Number of perturbed pivots */
m_iparm [ 14 ] = 0 ; /* Not in use */
m_iparm [ 15 ] = 0 ; /* Not in use */
m_iparm [ 16 ] = 0 ; /* Not in use */
m_iparm [ 17 ] = - 1 ; /* Output: Number of nonzeros in the factor LU */
m_iparm [ 18 ] = - 1 ; /* Output: Mflops for LU factorization */
m_iparm [ 19 ] = 0 ; /* Output: Numbers of CG Iterations */
m_iparm [ 20 ] = 0 ; /* 1x1 pivoting */
m_iparm [ 26 ] = 0 ; /* No matrix checker */
m_iparm [ 27 ] = ( sizeof ( RealScalar ) = = 4 ) ? 1 : 0 ;
m_iparm [ 34 ] = 0 ; /* Fortran indexing */
m_iparm [ 59 ] = 1 ; /* Automatic switch between In-Core and Out-of-Core modes */
}
2011-12-05 14:52:21 +07:00
protected :
// cached data to reduce reallocation, etc.
ComputationInfo m_info ;
2012-02-04 14:20:56 +01:00
bool m_initialized , m_succeeded ;
2011-12-05 14:52:21 +07:00
Index m_type , m_msglvl ;
mutable void * m_pt [ 64 ] ;
2012-02-04 14:20:56 +01:00
mutable Array < Index , 64 , 1 > m_iparm ;
2011-12-05 14:52:21 +07:00
mutable SparseMatrix < Scalar , RowMajor > m_matrix ;
mutable IntColVectorType m_perm ;
} ;
template < class Derived >
Derived & PardisoImpl < Derived > : : compute ( const MatrixType & a )
{
Index n = a . rows ( ) , i ;
eigen_assert ( a . rows ( ) = = a . cols ( ) ) ;
pardisoRelease ( ) ;
memset ( m_pt , 0 , sizeof ( m_pt ) ) ;
m_initialized = true ;
2012-02-04 14:20:56 +01:00
bool symmetric = abs ( m_type ) < 10 ;
m_iparm [ 10 ] = symmetric ? 0 : 1 ; /* Use nonsymmetric permutation and scaling MPS */
m_iparm [ 12 ] = symmetric ? 0 : 1 ; /* Maximum weighted matching algorithm is switched-off (default for symmetric). Try m_iparm[12] = 1 in case of inappropriate accuracy */
2011-12-05 14:52:21 +07:00
m_perm . resize ( n ) ;
m_matrix = a ;
/* Convert to Fortran-style indexing */
for ( i = 0 ; i < = m_matrix . rows ( ) ; + + i )
2012-02-04 14:20:56 +01:00
+ + m_matrix . outerIndexPtr ( ) [ i ] ;
2011-12-05 14:52:21 +07:00
for ( i = 0 ; i < m_matrix . nonZeros ( ) ; + + i )
2012-02-04 14:20:56 +01:00
+ + m_matrix . innerIndexPtr ( ) [ i ] ;
2011-12-05 14:52:21 +07:00
2012-02-04 14:20:56 +01:00
Index error = internal : : pardiso_run_selector < Index > : : run ( m_pt , 1 , 1 , m_type , 12 , n ,
m_matrix . valuePtr ( ) , m_matrix . outerIndexPtr ( ) , m_matrix . innerIndexPtr ( ) ,
m_perm . data ( ) , 0 , m_iparm . data ( ) , m_msglvl , NULL , NULL ) ;
2011-12-05 14:52:21 +07:00
switch ( error )
{
case 0 :
m_succeeded = true ;
m_info = Success ;
return derived ( ) ;
case - 4 :
case - 7 :
m_info = NumericalIssue ;
break ;
default :
m_info = InvalidInput ;
}
m_succeeded = false ;
return derived ( ) ;
}
template < class Base >
template < typename BDerived , typename XDerived >
bool PardisoImpl < Base > : : _solve ( const MatrixBase < BDerived > & b ,
2012-02-04 14:20:56 +01:00
MatrixBase < XDerived > & x ) const
2011-12-05 14:52:21 +07:00
{
if ( m_iparm [ 0 ] = = 0 ) // Factorization was not computed
return false ;
Index n = m_matrix . rows ( ) ;
Index nrhs = b . cols ( ) ;
eigen_assert ( n = = b . rows ( ) ) ;
eigen_assert ( ( ( MatrixBase < BDerived > : : Flags & RowMajorBit ) = = 0 | | nrhs = = 1 ) & & " Row-major right hand sides are not supported " ) ;
eigen_assert ( ( ( MatrixBase < XDerived > : : Flags & RowMajorBit ) = = 0 | | nrhs = = 1 ) & & " Row-major matrices of unknowns are not supported " ) ;
eigen_assert ( ( ( nrhs = = 1 ) | | b . outerStride ( ) = = b . rows ( ) ) ) ;
2012-02-04 14:20:56 +01:00
//x.derived().resizeLike(b);
2011-12-05 14:52:21 +07:00
2012-02-04 14:20:56 +01:00
// switch (transposed) {
// case SvNoTrans : m_iparm[11] = 0 ; break;
// case SvTranspose : m_iparm[11] = 2 ; break;
// case SvAdjoint : m_iparm[11] = 1 ; break;
// default:
// //std::cerr << "Eigen: transposition option \"" << transposed << "\" not supported by the PARDISO backend\n";
// m_iparm[11] = 0;
// }
2011-12-05 14:52:21 +07:00
2012-02-04 14:20:56 +01:00
Index error = internal : : pardiso_run_selector < Index > : : run ( m_pt , 1 , 1 , m_type , 33 , n ,
m_matrix . valuePtr ( ) , m_matrix . outerIndexPtr ( ) , m_matrix . innerIndexPtr ( ) ,
m_perm . data ( ) , nrhs , m_iparm . data ( ) , m_msglvl , const_cast < Scalar * > ( & b ( 0 , 0 ) ) , & x ( 0 , 0 ) ) ;
2011-12-05 14:52:21 +07:00
return error = = 0 ;
}
2011-12-09 16:52:37 +01:00
/** \ingroup PARDISOSupport_Module
* \ class PardisoLU
* \ brief A sparse direct LU factorization and solver based on the PARDISO library
*
* This class allows to solve for A . X = B sparse linear problems via a direct LU factorization
* using the Intel MKL PARDISO library . The sparse matrix A must be squared and invertible .
* The vectors or matrices X and B can be either dense or sparse .
*
* \ tparam _MatrixType the type of the sparse matrix A , it must be a SparseMatrix < >
*
* \ sa \ ref TutorialSparseDirectSolvers
*/
2011-12-05 14:52:21 +07:00
template < typename MatrixType >
class PardisoLU : public PardisoImpl < PardisoLU < MatrixType > >
{
protected :
typedef PardisoImpl < PardisoLU < MatrixType > > Base ;
typedef typename Base : : Scalar Scalar ;
typedef typename Base : : RealScalar RealScalar ;
2012-02-04 14:20:56 +01:00
using Base : : pardisoInit ;
2011-12-05 14:52:21 +07:00
public :
using Base : : compute ;
using Base : : solve ;
2012-02-04 14:20:56 +01:00
PardisoLU ( )
: Base ( )
2011-12-05 14:52:21 +07:00
{
2012-02-04 14:20:56 +01:00
pardisoInit ( Base : : ScalarIsComplex ? 13 : 11 ) ;
2011-12-05 14:52:21 +07:00
}
2012-02-04 14:20:56 +01:00
PardisoLU ( const MatrixType & matrix )
: Base ( )
2011-12-05 14:52:21 +07:00
{
2012-02-04 14:20:56 +01:00
pardisoInit ( Base : : ScalarIsComplex ? 13 : 11 ) ;
2011-12-05 14:52:21 +07:00
compute ( matrix ) ;
}
} ;
2011-12-09 16:52:37 +01:00
/** \ingroup PARDISOSupport_Module
* \ class PardisoLLT
* \ brief A sparse direct Cholesky ( LLT ) factorization and solver based on the PARDISO library
*
* This class allows to solve for A . X = B sparse linear problems via a LL ^ T Cholesky factorization
* using the Intel MKL PARDISO library . The sparse matrix A must be selfajoint and positive definite .
* The vectors or matrices X and B can be either dense or sparse .
*
2012-02-04 14:20:56 +01:00
* \ tparam MatrixType the type of the sparse matrix A , it must be a SparseMatrix < >
* \ tparam UpLo can be any bitwise combination of Upper , Lower . The default is Upper , meaning only the upper triangular part has to be used .
* Upper | Lower can be used to tell both triangular parts can be used as input .
2011-12-09 16:52:37 +01:00
*
* \ sa \ ref TutorialSparseDirectSolvers
*/
2012-02-04 14:20:56 +01:00
template < typename MatrixType , int _UpLo >
class PardisoLLT : public PardisoImpl < PardisoLLT < MatrixType , _UpLo > >
2011-12-05 14:52:21 +07:00
{
protected :
typedef PardisoImpl < PardisoLLT < MatrixType > > Base ;
typedef typename Base : : Scalar Scalar ;
typedef typename Base : : RealScalar RealScalar ;
2012-02-04 14:20:56 +01:00
using Base : : pardisoInit ;
2011-12-05 14:52:21 +07:00
public :
2012-02-04 14:20:56 +01:00
enum { UpLo = _UpLo } ;
2011-12-05 14:52:21 +07:00
using Base : : compute ;
using Base : : solve ;
2012-02-04 14:20:56 +01:00
PardisoLLT ( )
: Base ( )
2011-12-05 14:52:21 +07:00
{
2012-02-04 14:20:56 +01:00
pardisoInit ( Base : : ScalarIsComplex ? 4 : 2 ) ;
2011-12-05 14:52:21 +07:00
}
2012-02-04 14:20:56 +01:00
PardisoLLT ( const MatrixType & matrix )
: Base ( )
2011-12-05 14:52:21 +07:00
{
2012-02-04 14:20:56 +01:00
pardisoInit ( Base : : ScalarIsComplex ? 4 : 2 ) ;
2011-12-05 14:52:21 +07:00
compute ( matrix ) ;
}
} ;
2011-12-09 16:52:37 +01:00
/** \ingroup PARDISOSupport_Module
* \ class PardisoLDLT
* \ brief A sparse direct Cholesky ( LLT ) factorization and solver based on the PARDISO library
*
* This class allows to solve for A . X = B sparse linear problems via a LDL ^ T Cholesky factorization
2012-02-04 14:20:56 +01:00
* using the Intel MKL PARDISO library . The sparse matrix A is assumed to be selfajoint and positive definite .
* For complex matrices , A can also be symmetric only , see the \ a Options template parameter .
2011-12-09 16:52:37 +01:00
* The vectors or matrices X and B can be either dense or sparse .
*
2012-02-04 14:20:56 +01:00
* \ tparam MatrixType the type of the sparse matrix A , it must be a SparseMatrix < >
* \ tparam Options can be any bitwise combination of Upper , Lower , and Symmetric . The default is Upper , meaning only the upper triangular part has to be used .
* Symmetric can be used for symmetric , non - selfadjoint complex matrices , the default being to assume a selfadjoint matrix .
* Upper | Lower can be used to tell both triangular parts can be used as input .
2011-12-09 16:52:37 +01:00
*
* \ sa \ ref TutorialSparseDirectSolvers
*/
2012-02-04 14:20:56 +01:00
template < typename MatrixType , int Options >
class PardisoLDLT : public PardisoImpl < PardisoLDLT < MatrixType , Options > >
2011-12-05 14:52:21 +07:00
{
protected :
typedef PardisoImpl < PardisoLDLT < MatrixType > > Base ;
typedef typename Base : : Scalar Scalar ;
2012-02-04 14:20:56 +01:00
typedef typename Base : : Index Index ;
2011-12-05 14:52:21 +07:00
typedef typename Base : : RealScalar RealScalar ;
2012-02-04 14:20:56 +01:00
using Base : : pardisoInit ;
2011-12-05 14:52:21 +07:00
public :
using Base : : compute ;
using Base : : solve ;
2012-02-04 14:20:56 +01:00
enum { UpLo = Options & ( Upper | Lower ) } ;
2011-12-05 14:52:21 +07:00
2012-02-04 14:20:56 +01:00
PardisoLDLT ( )
: Base ( )
2011-12-05 14:52:21 +07:00
{
2012-02-04 14:20:56 +01:00
pardisoInit ( Base : : ScalarIsComplex ? ( bool ( Options & Symmetric ) ? 6 : - 4 ) : - 2 ) ;
2011-12-05 14:52:21 +07:00
}
2012-02-04 14:20:56 +01:00
PardisoLDLT ( const MatrixType & matrix )
2011-12-05 14:52:21 +07:00
: Base ( flags )
{
2012-02-04 14:20:56 +01:00
pardisoInit ( Base : : ScalarIsComplex ? ( bool ( Options & Symmetric ) ? 6 : - 4 ) : - 2 ) ;
2011-12-05 14:52:21 +07:00
compute ( matrix , hermitian ) ;
}
2012-02-04 14:20:56 +01:00
void compute ( const MatrixType & matrix )
2011-12-05 14:52:21 +07:00
{
2012-02-04 14:20:56 +01:00
if ( Options & Upper = = 0 )
{
// PARDISO supports only upper, row-major matrices
PermutationMatrix < Dynamic , Dynamic , Index > P ( 0 ) ;
SparseMatrix < Scalar , RowMajor > tmp ( matrix . rows ( ) , matrix . cols ( ) ) ;
tmp . template selfadjointView < Upper > ( ) = matrix . template selfadjointView < Lower > ( ) . twistedBy ( P ) ;
Base : : compute ( tmp ) ;
}
else
Base : : compute ( matrix ) ;
2011-12-05 14:52:21 +07:00
}
} ;
namespace internal {
template < typename _Derived , typename Rhs >
struct solve_retval < PardisoImpl < _Derived > , Rhs >
: solve_retval_base < PardisoImpl < _Derived > , Rhs >
{
typedef PardisoImpl < _Derived > Dec ;
EIGEN_MAKE_SOLVE_HELPERS ( Dec , Rhs )
template < typename Dest > void evalTo ( Dest & dst ) const
{
2012-02-04 14:20:56 +01:00
dec ( ) . _solve ( rhs ( ) , dst ) ;
2011-12-05 14:52:21 +07:00
}
2012-02-04 14:20:56 +01:00
} ;
template < typename Derived , typename Rhs >
struct sparse_solve_retval < PardisoImpl < Derived > , Rhs >
: sparse_solve_retval_base < PardisoImpl < Derived > , Rhs >
{
typedef PardisoImpl < Derived > Dec ;
EIGEN_MAKE_SPARSE_SOLVE_HELPERS ( Dec , Rhs )
2011-12-05 14:52:21 +07:00
2012-02-04 14:20:56 +01:00
template < typename Dest > void evalTo ( Dest & dst ) const
{
dec ( ) . derived ( ) . _solve_sparse ( rhs ( ) , dst ) ;
}
2011-12-05 14:52:21 +07:00
} ;
}
# endif // EIGEN_PARDISOSUPPORT_H