11#ifndef EIGEN_SUPERLUSUPPORT_H
12#define EIGEN_SUPERLUSUPPORT_H
15#include "./InternalHeaderCheck.h"
19#if defined(SUPERLU_MAJOR_VERSION) && (SUPERLU_MAJOR_VERSION >= 5)
20#define DECL_GSSVX(PREFIX, FLOATTYPE, KEYTYPE) \
22 extern void PREFIX##gssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
23 SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, \
24 FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, \
27 inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree, \
28 char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work, \
29 int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth, \
30 FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, SuperLUStat_t *stats, int *info, \
32 mem_usage_t mem_usage; \
34 PREFIX##gssvx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond, \
35 ferr, berr, &gLU, &mem_usage, stats, info); \
36 return mem_usage.for_lu; \
39#define DECL_GSSVX(PREFIX, FLOATTYPE, KEYTYPE) \
41 extern void PREFIX##gssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
42 SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, \
43 FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, mem_usage_t *, SuperLUStat_t *, int *); \
45 inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree, \
46 char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work, \
47 int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth, \
48 FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, SuperLUStat_t *stats, int *info, \
50 mem_usage_t mem_usage; \
51 PREFIX##gssvx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond, \
52 ferr, berr, &mem_usage, stats, info); \
53 return mem_usage.for_lu; \
57DECL_GSSVX(s,
float,
float)
58DECL_GSSVX(c,
float, std::complex<float>)
59DECL_GSSVX(d,
double,
double)
60DECL_GSSVX(z,
double, std::complex<double>)
64#define EIGEN_SUPERLU_HAS_ILU
67#ifdef EIGEN_SUPERLU_HAS_ILU
70#if defined(SUPERLU_MAJOR_VERSION) && (SUPERLU_MAJOR_VERSION >= 5)
71#define DECL_GSISX(PREFIX, FLOATTYPE, KEYTYPE) \
73 extern void PREFIX##gsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
74 SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, \
75 FLOATTYPE *, GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *); \
77 inline float SuperLU_gsisx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree, \
78 char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work, \
79 int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth, \
80 FLOATTYPE *rcond, SuperLUStat_t *stats, int *info, KEYTYPE) { \
81 mem_usage_t mem_usage; \
83 PREFIX##gsisx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond, \
84 &gLU, &mem_usage, stats, info); \
85 return mem_usage.for_lu; \
88#define DECL_GSISX(PREFIX, FLOATTYPE, KEYTYPE) \
90 extern void PREFIX##gsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
91 SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, \
92 FLOATTYPE *, mem_usage_t *, SuperLUStat_t *, int *); \
94 inline float SuperLU_gsisx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree, \
95 char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work, \
96 int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth, \
97 FLOATTYPE *rcond, SuperLUStat_t *stats, int *info, KEYTYPE) { \
98 mem_usage_t mem_usage; \
99 PREFIX##gsisx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond, \
100 &mem_usage, stats, info); \
101 return mem_usage.for_lu; \
105DECL_GSISX(s,
float,
float)
106DECL_GSISX(c,
float, std::complex<float>)
107DECL_GSISX(d,
double,
double)
108DECL_GSISX(z,
double, std::complex<double>)
113template <
typename MatrixType>
114struct SluMatrixMapHelper;
123struct SluMatrix : SuperMatrix {
124 SluMatrix() { Store = &storage; }
126 SluMatrix(
const SluMatrix &other) : SuperMatrix(other) {
128 storage = other.storage;
131 SluMatrix &operator=(
const SluMatrix &other) {
132 SuperMatrix::operator=(
static_cast<const SuperMatrix &
>(other));
134 storage = other.storage;
148 void setStorageType(Stype_t t) {
150 if (t == SLU_NC || t == SLU_NR || t == SLU_DN)
153 eigen_assert(
false &&
"storage type not supported");
158 template <
typename Scalar>
159 void setScalarType() {
160 EIGEN_IF_CONSTEXPR ((std::is_same<Scalar, float>::value))
162 else EIGEN_IF_CONSTEXPR ((std::is_same<Scalar, double>::value))
164 else EIGEN_IF_CONSTEXPR ((std::is_same<Scalar, std::complex<float> >::value))
166 else EIGEN_IF_CONSTEXPR ((std::is_same<Scalar, std::complex<double> >::value))
169 eigen_assert(
false &&
"Scalar type not supported by SuperLU");
173 template <
typename MatrixType>
174 static SluMatrix Map(MatrixBase<MatrixType> &_mat) {
175 MatrixType &mat(_mat.derived());
177 "row-major dense matrices are not supported by SuperLU");
179 res.setStorageType(SLU_DN);
180 res.setScalarType<
typename MatrixType::Scalar>();
183 res.nrow = internal::convert_index<int>(mat.rows());
184 res.ncol = internal::convert_index<int>(mat.cols());
186 res.storage.lda = internal::convert_index<int>(MatrixType::IsVectorAtCompileTime ? mat.size() : mat.outerStride());
187 res.storage.values = (
void *)(mat.data());
191 template <
typename MatrixType>
192 static SluMatrix Map(SparseMatrixBase<MatrixType> &a_mat) {
193 MatrixType &mat(a_mat.derived());
196 res.setStorageType(SLU_NR);
197 res.nrow = internal::convert_index<int>(mat.cols());
198 res.ncol = internal::convert_index<int>(mat.rows());
200 res.setStorageType(SLU_NC);
201 res.nrow = internal::convert_index<int>(mat.rows());
202 res.ncol = internal::convert_index<int>(mat.cols());
207 res.storage.nnz = internal::convert_index<int>(mat.nonZeros());
208 res.storage.values = mat.valuePtr();
209 res.storage.innerInd = mat.innerIndexPtr();
210 res.storage.outerInd = mat.outerIndexPtr();
212 res.setScalarType<
typename MatrixType::Scalar>();
215 EIGEN_IF_CONSTEXPR (
int(MatrixType::Flags) &
int(
Upper)) res.Mtype = SLU_TRU;
216 EIGEN_IF_CONSTEXPR (
int(MatrixType::Flags) &
int(
Lower)) res.Mtype = SLU_TRL;
218 eigen_assert(((
int(MatrixType::Flags) &
int(
SelfAdjoint)) == 0) &&
219 "SelfAdjoint matrix shape not supported by SuperLU");
225template <
typename Scalar,
int Rows,
int Cols,
int Options,
int MRows,
int MCols>
226struct SluMatrixMapHelper<
Matrix<Scalar, Rows, Cols, Options, MRows, MCols> > {
227 typedef Matrix<Scalar, Rows, Cols, Options, MRows, MCols> MatrixType;
228 static void run(MatrixType &mat, SluMatrix &res) {
229 eigen_assert(((Options &
RowMajor) !=
RowMajor) &&
"row-major dense matrices is not supported by SuperLU");
230 res.setStorageType(SLU_DN);
231 res.setScalarType<Scalar>();
234 res.nrow = mat.rows();
235 res.ncol = mat.cols();
237 res.storage.lda = mat.outerStride();
238 res.storage.values = mat.data();
242template <
typename Derived>
244 typedef Derived MatrixType;
245 static void run(MatrixType &mat, SluMatrix &res) {
247 res.setStorageType(SLU_NR);
248 res.nrow = mat.cols();
249 res.ncol = mat.rows();
251 res.setStorageType(SLU_NC);
252 res.nrow = mat.rows();
253 res.ncol = mat.cols();
258 res.storage.nnz = mat.nonZeros();
259 res.storage.values = mat.valuePtr();
260 res.storage.innerInd = mat.innerIndexPtr();
261 res.storage.outerInd = mat.outerIndexPtr();
263 res.setScalarType<
typename MatrixType::Scalar>();
266 EIGEN_IF_CONSTEXPR (MatrixType::Flags &
Upper) res.Mtype = SLU_TRU;
267 EIGEN_IF_CONSTEXPR (MatrixType::Flags &
Lower) res.Mtype = SLU_TRL;
269 eigen_assert(((MatrixType::Flags &
SelfAdjoint) == 0) &&
"SelfAdjoint matrix shape not supported by SuperLU");
275template <
typename MatrixType>
276SluMatrix asSluMatrix(MatrixType &mat) {
277 return SluMatrix::Map(mat);
281template <
typename Scalar,
int Flags,
typename Index>
282Map<SparseMatrix<Scalar, Flags, Index> > map_superlu(SluMatrix &sluMat) {
286 Index outerSize = (Flags &
RowMajor) ==
RowMajor ? sluMat.ncol : sluMat.nrow;
288 return Map<SparseMatrix<Scalar, Flags, Index> >(sluMat.nrow, sluMat.ncol, sluMat.storage.outerInd[outerSize],
289 sluMat.storage.outerInd, sluMat.storage.innerInd,
290 reinterpret_cast<Scalar *
>(sluMat.storage.values));
299template <
typename MatrixType_,
typename Derived>
304 using Base::m_isInitialized;
307 typedef MatrixType_ MatrixType;
308 typedef typename MatrixType::Scalar Scalar;
309 typedef typename MatrixType::RealScalar RealScalar;
310 typedef typename MatrixType::StorageIndex StorageIndex;
316 enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };
321 ~SuperLUBase() { clearFactors(); }
323 inline Index rows()
const {
return m_matrix.rows(); }
324 inline Index cols()
const {
return m_matrix.cols(); }
327 inline superlu_options_t &
options() {
return m_sluOptions; }
335 eigen_assert(m_isInitialized &&
"Decomposition is not initialized.");
341 derived().analyzePattern(matrix);
342 derived().factorize(matrix);
352 m_isInitialized =
true;
354 m_analysisIsOk =
true;
355 m_factorizationIsOk =
false;
358 template <
typename Stream>
359 void dumpMemory(Stream & ) {}
362 void initFactorization(
const MatrixType &a) {
363 set_default_options(&this->m_sluOptions);
365 const Index size = a.rows();
368 m_sluA = internal::asSluMatrix(m_matrix);
375 m_sluEtree.resize(size);
378 m_sluB.setStorageType(SLU_DN);
379 m_sluB.setScalarType<Scalar>();
380 m_sluB.Mtype = SLU_GE;
381 m_sluB.storage.values = 0;
384 m_sluB.storage.lda = internal::convert_index<int>(size);
387 m_extractedDataAreDirty =
true;
392 m_isInitialized =
false;
397 void extractData()
const;
399 void clearFactors() {
400 if (m_sluL.Store) Destroy_SuperNode_Matrix(&m_sluL);
401 if (m_sluU.Store) Destroy_CompCol_Matrix(&m_sluU);
406 memset(&m_sluL, 0,
sizeof m_sluL);
407 memset(&m_sluU, 0,
sizeof m_sluU);
411 mutable LUMatrixType m_l;
412 mutable LUMatrixType m_u;
413 mutable IntColVectorType m_p;
414 mutable IntRowVectorType m_q;
416 mutable LUMatrixType m_matrix;
417 mutable SluMatrix m_sluA;
418 mutable SuperMatrix m_sluL, m_sluU;
419 mutable SluMatrix m_sluB, m_sluX;
420 mutable SuperLUStat_t m_sluStat;
421 mutable superlu_options_t m_sluOptions;
422 mutable std::vector<int> m_sluEtree;
423 mutable Matrix<RealScalar, Dynamic, 1> m_sluRscale, m_sluCscale;
424 mutable Matrix<RealScalar, Dynamic, 1> m_sluFerr, m_sluBerr;
425 mutable char m_sluEqued;
428 int m_factorizationIsOk;
430 mutable bool m_extractedDataAreDirty;
433 SuperLUBase(SuperLUBase &) {}
452template <
typename MatrixType_>
453class SuperLU :
public SuperLUBase<MatrixType_, SuperLU<MatrixType_> > {
455 typedef SuperLUBase<MatrixType_, SuperLU> Base;
456 typedef MatrixType_ MatrixType;
457 typedef typename Base::Scalar Scalar;
458 typedef typename Base::RealScalar RealScalar;
459 typedef typename Base::StorageIndex StorageIndex;
460 typedef typename Base::IntRowVectorType IntRowVectorType;
461 typedef typename Base::IntColVectorType IntColVectorType;
462 typedef typename Base::PermutationMap PermutationMap;
463 typedef typename Base::LUMatrixType LUMatrixType;
468 using Base::_solve_impl;
470 SuperLU() : Base() { init(); }
472 explicit SuperLU(
const MatrixType &matrix) : Base() {
485 m_isInitialized =
false;
496 void factorize(
const MatrixType &matrix);
499 template <
typename Rhs,
typename Dest>
502 inline const LMatrixType &matrixL()
const {
503 if (m_extractedDataAreDirty) this->extractData();
507 inline const UMatrixType &matrixU()
const {
508 if (m_extractedDataAreDirty) this->extractData();
512 inline const IntColVectorType &permutationP()
const {
513 if (m_extractedDataAreDirty) this->extractData();
517 inline const IntRowVectorType &permutationQ()
const {
518 if (m_extractedDataAreDirty) this->extractData();
522 Scalar determinant()
const;
526 using Base::m_matrix;
531 using Base::m_sluBerr;
532 using Base::m_sluCscale;
533 using Base::m_sluEqued;
534 using Base::m_sluEtree;
535 using Base::m_sluFerr;
537 using Base::m_sluOptions;
538 using Base::m_sluRscale;
539 using Base::m_sluStat;
544 using Base::m_analysisIsOk;
545 using Base::m_extractedDataAreDirty;
546 using Base::m_factorizationIsOk;
548 using Base::m_isInitialized;
553 set_default_options(&this->m_sluOptions);
554 m_sluOptions.PrintStat = NO;
555 m_sluOptions.ConditionNumber = NO;
556 m_sluOptions.Trans = NOTRANS;
557 m_sluOptions.ColPerm = COLAMD;
561 SuperLU(SuperLU &) {}
564template <
typename MatrixType>
566 eigen_assert(m_analysisIsOk &&
"You must first call analyzePattern()");
567 if (!m_analysisIsOk) {
572 this->initFactorization(a);
574 m_sluOptions.ColPerm = COLAMD;
576 RealScalar recip_pivot_growth, rcond;
577 RealScalar ferr, berr;
579 StatInit(&m_sluStat);
580 SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
581 &m_sluCscale[0], &m_sluL, &m_sluU,
nullptr, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond, &ferr,
582 &berr, &m_sluStat, &
info, Scalar());
583 StatFree(&m_sluStat);
585 m_extractedDataAreDirty =
true;
589 m_factorizationIsOk =
true;
592template <
typename MatrixType>
593template <
typename Rhs,
typename Dest>
595 eigen_assert(m_factorizationIsOk &&
596 "The decomposition is not in a valid state for solving, you must first call either compute() or "
597 "analyzePattern()/factorize()");
599 const Index rhsCols = b.cols();
600 eigen_assert(m_matrix.rows() == b.rows());
602 m_sluOptions.Trans = NOTRANS;
603 m_sluOptions.Fact = FACTORED;
604 m_sluOptions.IterRefine = NOREFINE;
606 m_sluFerr.resize(rhsCols);
607 m_sluBerr.resize(rhsCols);
612 m_sluB = SluMatrix::Map(b_ref.const_cast_derived());
613 m_sluX = SluMatrix::Map(x_ref.const_cast_derived());
615 typename Rhs::PlainObject b_cpy;
616 if (m_sluEqued !=
'N') {
618 m_sluB = SluMatrix::Map(b_cpy.const_cast_derived());
621 StatInit(&m_sluStat);
623 RealScalar recip_pivot_growth, rcond;
624 SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
625 &m_sluCscale[0], &m_sluL, &m_sluU,
nullptr, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond,
626 &m_sluFerr[0], &m_sluBerr[0], &m_sluStat, &info, Scalar());
627 StatFree(&m_sluStat);
629 if (x.derived().data() != x_ref.data()) x = x_ref;
641template <
typename MatrixType,
typename Derived>
642void SuperLUBase<MatrixType, Derived>::extractData()
const {
643 eigen_assert(m_factorizationIsOk &&
644 "The decomposition is not in a valid state for extracting factors, you must first call either compute() "
645 "or analyzePattern()/factorize()");
646 if (m_extractedDataAreDirty) {
648 int fsupc, istart, nsupr;
649 int lastl = 0, lastu = 0;
650 SCformat *Lstore =
static_cast<SCformat *
>(m_sluL.Store);
651 NCformat *Ustore =
static_cast<NCformat *
>(m_sluU.Store);
654 const Index size = m_matrix.rows();
655 m_l.resize(size, size);
656 m_l.resizeNonZeros(Lstore->nnz);
657 m_u.resize(size, size);
658 m_u.resizeNonZeros(Ustore->nnz);
660 int *Lcol = m_l.outerIndexPtr();
661 int *Lrow = m_l.innerIndexPtr();
662 Scalar *Lval = m_l.valuePtr();
664 int *Ucol = m_u.outerIndexPtr();
665 int *Urow = m_u.innerIndexPtr();
666 Scalar *Uval = m_u.valuePtr();
671 for (
int k = 0; k <= Lstore->nsuper; ++k) {
672 fsupc = L_FST_SUPC(k);
673 istart = L_SUB_START(fsupc);
674 nsupr = L_SUB_START(fsupc + 1) - istart;
678 for (
int j = fsupc; j < L_FST_SUPC(k + 1); ++j) {
679 SNptr = &((Scalar *)Lstore->nzval)[L_NZ_START(j)];
682 for (
int i = U_NZ_START(j); i < U_NZ_START(j + 1); ++i) {
683 Uval[lastu] = ((Scalar *)Ustore->nzval)[i];
685 if (Uval[lastu] != 0.0) Urow[lastu++] = U_SUB(i);
687 for (
int i = 0; i < upper; ++i) {
689 Uval[lastu] = SNptr[i];
691 if (Uval[lastu] != 0.0) Urow[lastu++] = L_SUB(istart + i);
697 Lrow[lastl++] = L_SUB(istart + upper - 1);
698 for (
int i = upper; i < nsupr; ++i) {
699 Lval[lastl] = SNptr[i];
701 if (Lval[lastl] != 0.0) Lrow[lastl++] = L_SUB(istart + i);
711 m_l.resizeNonZeros(lastl);
712 m_u.resizeNonZeros(lastu);
714 m_extractedDataAreDirty =
false;
718template <
typename MatrixType>
719typename SuperLU<MatrixType>::Scalar SuperLU<MatrixType>::determinant()
const {
720 eigen_assert(m_factorizationIsOk &&
721 "The decomposition is not in a valid state for computing the determinant, you must first call either "
722 "compute() or analyzePattern()/factorize()");
724 if (m_extractedDataAreDirty) this->extractData();
726 Scalar det = Scalar(1);
727 for (
int j = 0; j < m_u.cols(); ++j) {
728 if (m_u.outerIndexPtr()[j + 1] - m_u.outerIndexPtr()[j] > 0) {
729 int lastId = m_u.outerIndexPtr()[j + 1] - 1;
730 eigen_assert(m_u.innerIndexPtr()[lastId] <= j);
731 if (m_u.innerIndexPtr()[lastId] == j) det *= m_u.valuePtr()[lastId];
734 if (PermutationMap(m_p.data(), m_p.size()).determinant() * PermutationMap(m_q.data(), m_q.size()).determinant() < 0)
736 if (m_sluEqued !=
'N')
737 return det / m_sluRscale.prod() / m_sluCscale.prod();
742#ifdef EIGEN_PARSED_BY_DOXYGEN
743#define EIGEN_SUPERLU_HAS_ILU
746#ifdef EIGEN_SUPERLU_HAS_ILU
765template <
typename MatrixType_>
766class SuperILU :
public SuperLUBase<MatrixType_, SuperILU<MatrixType_> > {
768 typedef SuperLUBase<MatrixType_, SuperILU> Base;
769 typedef MatrixType_ MatrixType;
770 typedef typename Base::Scalar Scalar;
771 typedef typename Base::RealScalar RealScalar;
774 using Base::_solve_impl;
776 SuperILU() : Base() { init(); }
778 SuperILU(
const MatrixType &matrix) : Base() {
798 void factorize(
const MatrixType &matrix);
800#ifndef EIGEN_PARSED_BY_DOXYGEN
802 template <
typename Rhs,
typename Dest>
808 using Base::m_matrix;
813 using Base::m_sluBerr;
814 using Base::m_sluCscale;
815 using Base::m_sluEqued;
816 using Base::m_sluEtree;
817 using Base::m_sluFerr;
819 using Base::m_sluOptions;
820 using Base::m_sluRscale;
821 using Base::m_sluStat;
826 using Base::m_analysisIsOk;
827 using Base::m_extractedDataAreDirty;
828 using Base::m_factorizationIsOk;
830 using Base::m_isInitialized;
835 ilu_set_default_options(&m_sluOptions);
836 m_sluOptions.PrintStat = NO;
837 m_sluOptions.ConditionNumber = NO;
838 m_sluOptions.Trans = NOTRANS;
839 m_sluOptions.ColPerm = MMD_AT_PLUS_A;
842 m_sluOptions.ILU_MILU = SILU;
846 m_sluOptions.ILU_DropRule = DROP_BASIC;
847 m_sluOptions.ILU_DropTol = NumTraits<Scalar>::dummy_precision() * 10;
851 SuperILU(SuperILU &) {}
854template <
typename MatrixType>
856 eigen_assert(m_analysisIsOk &&
"You must first call analyzePattern()");
857 if (!m_analysisIsOk) {
862 this->initFactorization(a);
865 RealScalar recip_pivot_growth, rcond;
867 StatInit(&m_sluStat);
868 SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
869 &m_sluCscale[0], &m_sluL, &m_sluU,
nullptr, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond,
870 &m_sluStat, &
info, Scalar());
871 StatFree(&m_sluStat);
875 m_factorizationIsOk =
true;
878#ifndef EIGEN_PARSED_BY_DOXYGEN
879template <
typename MatrixType>
880template <
typename Rhs,
typename Dest>
882 eigen_assert(m_factorizationIsOk &&
883 "The decomposition is not in a valid state for solving, you must first call either compute() or "
884 "analyzePattern()/factorize()");
886 const int rhsCols = b.cols();
887 eigen_assert(m_matrix.rows() == b.rows());
889 m_sluOptions.Trans = NOTRANS;
890 m_sluOptions.Fact = FACTORED;
891 m_sluOptions.IterRefine = NOREFINE;
893 m_sluFerr.resize(rhsCols);
894 m_sluBerr.resize(rhsCols);
899 m_sluB = SluMatrix::Map(b_ref.const_cast_derived());
900 m_sluX = SluMatrix::Map(x_ref.const_cast_derived());
902 typename Rhs::PlainObject b_cpy;
903 if (m_sluEqued !=
'N') {
905 m_sluB = SluMatrix::Map(b_cpy.const_cast_derived());
909 RealScalar recip_pivot_growth, rcond;
911 StatInit(&m_sluStat);
912 SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
913 &m_sluCscale[0], &m_sluL, &m_sluU,
nullptr, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond,
914 &m_sluStat, &info, Scalar());
915 StatFree(&m_sluStat);
917 if (x.derived().data() != x_ref.data()) x = x_ref;
A matrix or vector expression mapping an existing array of data.
Definition Map.h:97
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
constexpr void resize(Index rows, Index cols)
Definition PlainObjectBase.h:282
A matrix or vector expression mapping an existing expression.
Definition Ref.h:262
Base class of any sparse matrices or sparse expressions.
Definition SparseMatrixBase.h:31
A versatile sparse matrix representation.
Definition SparseMatrix.h:122
SparseSolverBase()=default
A sparse direct incomplete LU factorization and solver based on the SuperLU library.
Definition SuperLUSupport.h:766
void analyzePattern(const MatrixType &matrix)
Definition SuperLUSupport.h:789
void factorize(const MatrixType &matrix)
Definition SuperLUSupport.h:855
void compute(const MatrixType &matrix)
Definition SuperLUSupport.h:340
ComputationInfo info() const
Reports whether previous computation was successful.
Definition SuperLUSupport.h:334
void analyzePattern(const MatrixType &)
Definition SuperLUSupport.h:351
superlu_options_t & options()
Definition SuperLUSupport.h:327
void factorize(const MatrixType &matrix)
Definition SuperLUSupport.h:565
void analyzePattern(const MatrixType &matrix)
Definition SuperLUSupport.h:483
Expression of a triangular part in a matrix.
Definition TriangularMatrix.h:426
ComputationInfo
Definition Constants.h:455
@ SelfAdjoint
Definition Constants.h:228
@ Lower
Definition Constants.h:212
@ Upper
Definition Constants.h:214
@ NumericalIssue
Definition Constants.h:459
@ InvalidInput
Definition Constants.h:464
@ Success
Definition Constants.h:457
@ ColMajor
Definition Constants.h:319
@ RowMajor
Definition Constants.h:321
constexpr unsigned int RowMajorBit
Definition Constants.h:71