32#ifndef EIGEN_PARDISOSUPPORT_H
33#define EIGEN_PARDISOSUPPORT_H
36#include "./InternalHeaderCheck.h"
40template <
typename MatrixType_>
42template <
typename MatrixType_,
int Options = Upper>
44template <
typename MatrixType_,
int Options = Upper>
48template <
typename IndexType>
49struct pardiso_run_selector {
50 static IndexType run(_MKL_DSS_HANDLE_t pt, IndexType maxfct, IndexType mnum, IndexType type, IndexType phase,
51 IndexType n,
void* a, IndexType* ia, IndexType* ja, IndexType* perm, IndexType nrhs,
52 IndexType* iparm, IndexType msglvl,
void* b,
void* x) {
54 ::pardiso(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error);
59struct pardiso_run_selector<long long int> {
60 typedef long long int IndexType;
61 static IndexType run(_MKL_DSS_HANDLE_t pt, IndexType maxfct, IndexType mnum, IndexType type, IndexType phase,
62 IndexType n,
void* a, IndexType* ia, IndexType* ja, IndexType* perm, IndexType nrhs,
63 IndexType* iparm, IndexType msglvl,
void* b,
void* x) {
65 ::pardiso_64(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error);
70template <
class Pardiso>
73template <
typename MatrixType_>
74struct pardiso_traits<PardisoLU<MatrixType_> > {
75 typedef MatrixType_ MatrixType;
76 typedef typename MatrixType_::Scalar Scalar;
77 typedef typename MatrixType_::RealScalar RealScalar;
78 typedef typename MatrixType_::StorageIndex StorageIndex;
81template <
typename MatrixType_,
int Options>
82struct pardiso_traits<PardisoLLT<MatrixType_, Options> > {
83 typedef MatrixType_ MatrixType;
84 typedef typename MatrixType_::Scalar Scalar;
85 typedef typename MatrixType_::RealScalar RealScalar;
86 typedef typename MatrixType_::StorageIndex StorageIndex;
89template <
typename MatrixType_,
int Options>
90struct pardiso_traits<PardisoLDLT<MatrixType_, Options> > {
91 typedef MatrixType_ MatrixType;
92 typedef typename MatrixType_::Scalar Scalar;
93 typedef typename MatrixType_::RealScalar RealScalar;
94 typedef typename MatrixType_::StorageIndex StorageIndex;
99template <
class Derived>
104 using Base::m_isInitialized;
106 typedef internal::pardiso_traits<Derived> Traits;
109 using Base::_solve_impl;
111 typedef typename Traits::MatrixType MatrixType;
112 typedef typename Traits::Scalar Scalar;
113 typedef typename Traits::RealScalar RealScalar;
114 typedef typename Traits::StorageIndex StorageIndex;
115 typedef SparseMatrix<Scalar, RowMajor, StorageIndex> SparseMatrixType;
116 typedef Matrix<Scalar, Dynamic, 1> VectorType;
117 typedef Matrix<StorageIndex, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
118 typedef Matrix<StorageIndex, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
119 typedef Array<StorageIndex, 64, 1, DontAlign> ParameterType;
120 enum { ScalarIsComplex = NumTraits<Scalar>::IsComplex, ColsAtCompileTime =
Dynamic, MaxColsAtCompileTime =
Dynamic };
122 PardisoImpl() : m_analysisIsOk(false), m_factorizationIsOk(false) {
123 eigen_assert((
sizeof(StorageIndex) >=
sizeof(_INTEGER_t) &&
sizeof(StorageIndex) <= 8) &&
124 "Non-supported index type");
127 m_isInitialized =
false;
130 ~PardisoImpl() { pardisoRelease(); }
132 inline Index cols()
const {
return m_size; }
133 inline Index rows()
const {
return m_size; }
141 eigen_assert(m_isInitialized &&
"Decomposition is not initialized.");
148 ParameterType& pardisoParameterArray() {
return m_iparm; }
156 Derived& analyzePattern(
const MatrixType& matrix);
165 Derived& factorize(
const MatrixType& matrix);
167 Derived& compute(
const MatrixType& matrix);
169 template <
typename Rhs,
typename Dest>
170 void _solve_impl(
const MatrixBase<Rhs>& b, MatrixBase<Dest>& dest)
const;
173 void pardisoRelease() {
176 internal::pardiso_run_selector<StorageIndex>::run(m_pt, 1, 1, m_type, -1,
177 internal::convert_index<StorageIndex>(m_size), 0, 0, 0,
178 m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL);
179 m_isInitialized =
false;
183 void pardisoInit(
int type) {
185 bool symmetric = std::abs(m_type) < 10;
196 m_iparm[10] = symmetric ? 0 : 1;
198 m_iparm[12] = symmetric ? 0 : 1;
210 m_iparm[27] = (
sizeof(RealScalar) == 4) ? 1 : 0;
215 memset(m_pt, 0,
sizeof(m_pt));
221 void manageErrorCode(
Index error)
const {
235 mutable SparseMatrixType m_matrix;
237 bool m_analysisIsOk, m_factorizationIsOk;
238 StorageIndex m_type, m_msglvl;
239 mutable void* m_pt[64];
240 mutable ParameterType m_iparm;
241 mutable IntColVectorType m_perm;
245template <
class Derived>
246Derived& PardisoImpl<Derived>::compute(
const MatrixType& a) {
248 eigen_assert(a.rows() == a.cols());
251 m_perm.setZero(m_size);
252 derived().getMatrix(a);
255 error = internal::pardiso_run_selector<StorageIndex>::run(
256 m_pt, 1, 1, m_type, 12, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
257 m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL);
258 manageErrorCode(error);
261 m_isInitialized =
true;
265template <
class Derived>
266Derived& PardisoImpl<Derived>::analyzePattern(
const MatrixType& a) {
268 eigen_assert(m_size == a.cols());
271 m_perm.setZero(m_size);
272 derived().getMatrix(a);
275 error = internal::pardiso_run_selector<StorageIndex>::run(
276 m_pt, 1, 1, m_type, 11, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
277 m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL);
279 manageErrorCode(error);
281 m_factorizationIsOk =
false;
282 m_isInitialized =
true;
286template <
class Derived>
287Derived& PardisoImpl<Derived>::factorize(
const MatrixType& a) {
288 eigen_assert(m_analysisIsOk &&
"You must first call analyzePattern()");
289 eigen_assert(m_size == a.rows() && m_size == a.cols());
291 derived().getMatrix(a);
294 error = internal::pardiso_run_selector<StorageIndex>::run(
295 m_pt, 1, 1, m_type, 22, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
296 m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL);
298 manageErrorCode(error);
303template <
class Derived>
304template <
typename BDerived,
typename XDerived>
314 eigen_assert(m_size == b.rows());
316 "Row-major right hand sides are not supported");
318 "Row-major matrices of unknowns are not supported");
319 eigen_assert(((nrhs == 1) || b.outerStride() == b.rows()));
330 Scalar* rhs_ptr =
const_cast<Scalar*
>(b.derived().data());
334 if (rhs_ptr == x.derived().data()) {
336 rhs_ptr = tmp.data();
340 error = internal::pardiso_run_selector<StorageIndex>::run(
341 m_pt, 1, 1, m_type, 33, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
342 m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), internal::convert_index<StorageIndex>(nrhs),
343 m_iparm.data(), m_msglvl, rhs_ptr, x.derived().data());
345 manageErrorCode(error);
365template <
typename MatrixType>
366class PardisoLU :
public PardisoImpl<PardisoLU<MatrixType> > {
368 typedef PardisoImpl<PardisoLU> Base;
369 using Base::m_matrix;
370 using Base::pardisoInit;
371 friend class PardisoImpl<PardisoLU<MatrixType> >;
374 typedef typename Base::Scalar Scalar;
375 typedef typename Base::RealScalar RealScalar;
380 PardisoLU() : Base() { pardisoInit(Base::ScalarIsComplex ? 13 : 11); }
382 explicit PardisoLU(
const MatrixType& matrix) : Base() {
383 pardisoInit(Base::ScalarIsComplex ? 13 : 11);
388 void getMatrix(
const MatrixType& matrix) {
390 m_matrix.makeCompressed();
413template <
typename MatrixType,
int UpLo_>
414class PardisoLLT :
public PardisoImpl<PardisoLLT<MatrixType, UpLo_> > {
416 typedef PardisoImpl<PardisoLLT<MatrixType, UpLo_> > Base;
417 using Base::m_matrix;
418 using Base::pardisoInit;
419 friend class PardisoImpl<PardisoLLT<MatrixType, UpLo_> >;
422 typedef typename Base::Scalar Scalar;
423 typedef typename Base::RealScalar RealScalar;
424 typedef typename Base::StorageIndex StorageIndex;
425 enum { UpLo = UpLo_ };
428 PardisoLLT() : Base() { pardisoInit(Base::ScalarIsComplex ? 4 : 2); }
430 explicit PardisoLLT(
const MatrixType& matrix) : Base() {
431 pardisoInit(Base::ScalarIsComplex ? 4 : 2);
436 void getMatrix(
const MatrixType& matrix) {
439 m_matrix.
resize(matrix.rows(), matrix.cols());
440 m_matrix.template selfadjointView<Upper>() = matrix.template selfadjointView<UpLo>().twistedBy(p_null);
441 m_matrix.makeCompressed();
467template <
typename MatrixType,
int Options>
468class PardisoLDLT :
public PardisoImpl<PardisoLDLT<MatrixType, Options> > {
470 typedef PardisoImpl<PardisoLDLT<MatrixType, Options> > Base;
471 using Base::m_matrix;
472 using Base::pardisoInit;
473 friend class PardisoImpl<PardisoLDLT<MatrixType, Options> >;
476 typedef typename Base::Scalar Scalar;
477 typedef typename Base::RealScalar RealScalar;
478 typedef typename Base::StorageIndex StorageIndex;
482 PardisoLDLT() : Base() { pardisoInit(Base::ScalarIsComplex ? (
bool(Options &
Symmetric) ? 6 : -4) : -2); }
484 explicit PardisoLDLT(
const MatrixType& matrix) : Base() {
485 pardisoInit(Base::ScalarIsComplex ? (
bool(Options &
Symmetric) ? 6 : -4) : -2);
489 void getMatrix(
const MatrixType& matrix) {
492 m_matrix.
resize(matrix.rows(), matrix.cols());
493 m_matrix.template selfadjointView<Upper>() = matrix.template selfadjointView<UpLo>().twistedBy(p_null);
494 m_matrix.makeCompressed();
@ Flags
Definition DenseBase.h:161
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:52
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:186
A sparse direct Cholesky (LDLT) factorization and solver based on the PARDISO library.
Definition PardisoSupport.h:468
A sparse direct Cholesky (LLT) factorization and solver based on the PARDISO library.
Definition PardisoSupport.h:414
A sparse direct LU factorization and solver based on the PARDISO library.
Definition PardisoSupport.h:366
void resize(Index newSize)
Definition PermutationMatrix.h:122
Permutation matrix.
Definition PermutationMatrix.h:283
A base class for sparse solvers.
Definition SparseSolverBase.h:67
const Solve< Derived, Rhs > solve(const MatrixBase< Rhs > &b) const
Definition SparseSolverBase.h:84
SparseSolverBase()
Definition SparseSolverBase.h:70
ComputationInfo
Definition Constants.h:438
@ Symmetric
Definition Constants.h:229
@ Lower
Definition Constants.h:211
@ Upper
Definition Constants.h:213
@ NumericalIssue
Definition Constants.h:442
@ InvalidInput
Definition Constants.h:447
@ Success
Definition Constants.h:440
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
const int Dynamic
Definition Constants.h:25