SuperLUSupport.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-2015 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_SUPERLUSUPPORT_H
11 #define EIGEN_SUPERLUSUPPORT_H
12 
13 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 #if defined(SUPERLU_MAJOR_VERSION) && (SUPERLU_MAJOR_VERSION >= 5)
19 #define DECL_GSSVX(PREFIX, FLOATTYPE, KEYTYPE) \
20  extern "C" { \
21  extern void PREFIX##gssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
22  SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, \
23  FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, \
24  int *); \
25  } \
26  inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree, \
27  char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work, \
28  int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth, \
29  FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, SuperLUStat_t *stats, int *info, \
30  KEYTYPE) { \
31  mem_usage_t mem_usage; \
32  GlobalLU_t gLU; \
33  PREFIX##gssvx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond, \
34  ferr, berr, &gLU, &mem_usage, stats, info); \
35  return mem_usage.for_lu; /* bytes used by the factor storage */ \
36  }
37 #else // version < 5.0
38 #define DECL_GSSVX(PREFIX, FLOATTYPE, KEYTYPE) \
39  extern "C" { \
40  extern void PREFIX##gssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
41  SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, \
42  FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, mem_usage_t *, SuperLUStat_t *, int *); \
43  } \
44  inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree, \
45  char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work, \
46  int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth, \
47  FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, SuperLUStat_t *stats, int *info, \
48  KEYTYPE) { \
49  mem_usage_t mem_usage; \
50  PREFIX##gssvx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond, \
51  ferr, berr, &mem_usage, stats, info); \
52  return mem_usage.for_lu; /* bytes used by the factor storage */ \
53  }
54 #endif
55 
56 DECL_GSSVX(s, float, float)
57 DECL_GSSVX(c, float, std::complex<float>)
58 DECL_GSSVX(d, double, double)
59 DECL_GSSVX(z, double, std::complex<double>)
60 
61 #ifdef MILU_ALPHA
62 #define EIGEN_SUPERLU_HAS_ILU
63 #endif
64 
65 #ifdef EIGEN_SUPERLU_HAS_ILU
66 
67 // similarly for the incomplete factorization using gsisx
68 #define DECL_GSISX(PREFIX, FLOATTYPE, KEYTYPE) \
69  extern "C" { \
70  extern void PREFIX##gsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
71  SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *, \
72  FLOATTYPE *, mem_usage_t *, SuperLUStat_t *, int *); \
73  } \
74  inline float SuperLU_gsisx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree, \
75  char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work, \
76  int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth, \
77  FLOATTYPE *rcond, SuperLUStat_t *stats, int *info, KEYTYPE) { \
78  mem_usage_t mem_usage; \
79  PREFIX##gsisx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond, \
80  &mem_usage, stats, info); \
81  return mem_usage.for_lu; /* bytes used by the factor storage */ \
82  }
83 
84 DECL_GSISX(s, float, float)
85 DECL_GSISX(c, float, std::complex<float>)
86 DECL_GSISX(d, double, double)
87 DECL_GSISX(z, double, std::complex<double>)
88 
89 #endif
90 
91 template <typename MatrixType>
93 
103 
104  SluMatrix(const SluMatrix &other) : SuperMatrix(other) {
105  Store = &storage;
106  storage = other.storage;
107  }
108 
109  SluMatrix &operator=(const SluMatrix &other) {
110  SuperMatrix::operator=(static_cast<const SuperMatrix &>(other));
111  Store = &storage;
112  storage = other.storage;
113  return *this;
114  }
115 
116  struct {
117  union {
118  int nnz;
119  int lda;
120  };
121  void *values;
122  int *innerInd;
123  int *outerInd;
125 
127  Stype = t;
128  if (t == SLU_NC || t == SLU_NR || t == SLU_DN)
129  Store = &storage;
130  else {
131  eigen_assert(false && "storage type not supported");
132  Store = 0;
133  }
134  }
135 
136  template <typename Scalar>
137  void setScalarType() {
139  Dtype = SLU_S;
141  Dtype = SLU_D;
142  else if (internal::is_same<Scalar, std::complex<float> >::value)
143  Dtype = SLU_C;
144  else if (internal::is_same<Scalar, std::complex<double> >::value)
145  Dtype = SLU_Z;
146  else {
147  eigen_assert(false && "Scalar type not supported by SuperLU");
148  }
149  }
150 
151  template <typename MatrixType>
153  MatrixType &mat(_mat.derived());
154  eigen_assert(((MatrixType::Flags & RowMajorBit) != RowMajorBit) &&
155  "row-major dense matrices are not supported by SuperLU");
156  SluMatrix res;
157  res.setStorageType(SLU_DN);
158  res.setScalarType<typename MatrixType::Scalar>();
159  res.Mtype = SLU_GE;
160 
161  res.nrow = internal::convert_index<int>(mat.rows());
162  res.ncol = internal::convert_index<int>(mat.cols());
163 
164  res.storage.lda = internal::convert_index<int>(MatrixType::IsVectorAtCompileTime ? mat.size() : mat.outerStride());
165  res.storage.values = (void *)(mat.data());
166  return res;
167  }
168 
169  template <typename MatrixType>
171  MatrixType &mat(a_mat.derived());
172  SluMatrix res;
173  if ((MatrixType::Flags & RowMajorBit) == RowMajorBit) {
174  res.setStorageType(SLU_NR);
175  res.nrow = internal::convert_index<int>(mat.cols());
176  res.ncol = internal::convert_index<int>(mat.rows());
177  } else {
178  res.setStorageType(SLU_NC);
179  res.nrow = internal::convert_index<int>(mat.rows());
180  res.ncol = internal::convert_index<int>(mat.cols());
181  }
182 
183  res.Mtype = SLU_GE;
184 
185  res.storage.nnz = internal::convert_index<int>(mat.nonZeros());
186  res.storage.values = mat.valuePtr();
187  res.storage.innerInd = mat.innerIndexPtr();
188  res.storage.outerInd = mat.outerIndexPtr();
189 
190  res.setScalarType<typename MatrixType::Scalar>();
191 
192  // FIXME the following is not very accurate
193  if (int(MatrixType::Flags) & int(Upper)) res.Mtype = SLU_TRU;
194  if (int(MatrixType::Flags) & int(Lower)) res.Mtype = SLU_TRL;
195 
196  eigen_assert(((int(MatrixType::Flags) & int(SelfAdjoint)) == 0) &&
197  "SelfAdjoint matrix shape not supported by SuperLU");
198 
199  return res;
200  }
201 };
202 
203 template <typename Scalar, int Rows, int Cols, int Options, int MRows, int MCols>
204 struct SluMatrixMapHelper<Matrix<Scalar, Rows, Cols, Options, MRows, MCols> > {
206  static void run(MatrixType &mat, SluMatrix &res) {
207  eigen_assert(((Options & RowMajor) != RowMajor) && "row-major dense matrices is not supported by SuperLU");
208  res.setStorageType(SLU_DN);
209  res.setScalarType<Scalar>();
210  res.Mtype = SLU_GE;
211 
212  res.nrow = mat.rows();
213  res.ncol = mat.cols();
214 
215  res.storage.lda = mat.outerStride();
216  res.storage.values = mat.data();
217  }
218 };
219 
220 template <typename Derived>
222  typedef Derived MatrixType;
223  static void run(MatrixType &mat, SluMatrix &res) {
224  if ((MatrixType::Flags & RowMajorBit) == RowMajorBit) {
225  res.setStorageType(SLU_NR);
226  res.nrow = mat.cols();
227  res.ncol = mat.rows();
228  } else {
229  res.setStorageType(SLU_NC);
230  res.nrow = mat.rows();
231  res.ncol = mat.cols();
232  }
233 
234  res.Mtype = SLU_GE;
235 
236  res.storage.nnz = mat.nonZeros();
237  res.storage.values = mat.valuePtr();
238  res.storage.innerInd = mat.innerIndexPtr();
239  res.storage.outerInd = mat.outerIndexPtr();
240 
241  res.setScalarType<typename MatrixType::Scalar>();
242 
243  // FIXME the following is not very accurate
244  if (MatrixType::Flags & Upper) res.Mtype = SLU_TRU;
245  if (MatrixType::Flags & Lower) res.Mtype = SLU_TRL;
246 
247  eigen_assert(((MatrixType::Flags & SelfAdjoint) == 0) && "SelfAdjoint matrix shape not supported by SuperLU");
248  }
249 };
250 
251 namespace internal {
252 
253 template <typename MatrixType>
255  return SluMatrix::Map(mat);
256 }
257 
259 template <typename Scalar, int Flags, typename Index>
261  eigen_assert(((Flags & RowMajor) == RowMajor && sluMat.Stype == SLU_NR) ||
262  ((Flags & ColMajor) == ColMajor && sluMat.Stype == SLU_NC));
263 
264  Index outerSize = (Flags & RowMajor) == RowMajor ? sluMat.ncol : sluMat.nrow;
265 
266  return Map<SparseMatrix<Scalar, Flags, Index> >(sluMat.nrow, sluMat.ncol, sluMat.storage.outerInd[outerSize],
267  sluMat.storage.outerInd, sluMat.storage.innerInd,
268  reinterpret_cast<Scalar *>(sluMat.storage.values));
269 }
270 
271 } // end namespace internal
272 
277 template <typename MatrixType_, typename Derived>
278 class SuperLUBase : public SparseSolverBase<Derived> {
279  protected:
281  using Base::derived;
282  using Base::m_isInitialized;
283 
284  public:
285  typedef MatrixType_ MatrixType;
286  typedef typename MatrixType::Scalar Scalar;
288  typedef typename MatrixType::StorageIndex StorageIndex;
294  enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };
295 
296  public:
298 
300 
301  inline Index rows() const { return m_matrix.rows(); }
302  inline Index cols() const { return m_matrix.cols(); }
303 
305  inline superlu_options_t &options() { return m_sluOptions; }
306 
313  eigen_assert(m_isInitialized && "Decomposition is not initialized.");
314  return m_info;
315  }
316 
318  void compute(const MatrixType &matrix) {
319  derived().analyzePattern(matrix);
320  derived().factorize(matrix);
321  }
322 
329  void analyzePattern(const MatrixType & /*matrix*/) {
330  m_isInitialized = true;
331  m_info = Success;
332  m_analysisIsOk = true;
333  m_factorizationIsOk = false;
334  }
335 
336  template <typename Stream>
337  void dumpMemory(Stream & /*s*/) {}
338 
339  protected:
342 
343  const Index size = a.rows();
344  m_matrix = a;
345 
347  clearFactors();
348 
349  m_p.resize(size);
350  m_q.resize(size);
353  m_sluEtree.resize(size);
354 
355  // set empty B and X
358  m_sluB.Mtype = SLU_GE;
359  m_sluB.storage.values = 0;
360  m_sluB.nrow = 0;
361  m_sluB.ncol = 0;
362  m_sluB.storage.lda = internal::convert_index<int>(size);
363  m_sluX = m_sluB;
364 
366  }
367 
368  void init() {
370  m_isInitialized = false;
371  m_sluL.Store = 0;
372  m_sluU.Store = 0;
373  }
374 
375  void extractData() const;
376 
377  void clearFactors() {
380 
381  m_sluL.Store = 0;
382  m_sluU.Store = 0;
383 
384  memset(&m_sluL, 0, sizeof m_sluL);
385  memset(&m_sluU, 0, sizeof m_sluU);
386  }
387 
388  // cached data to reduce reallocation, etc.
389  mutable LUMatrixType m_l;
390  mutable LUMatrixType m_u;
393 
394  mutable LUMatrixType m_matrix; // copy of the factorized matrix
395  mutable SluMatrix m_sluA;
400  mutable std::vector<int> m_sluEtree;
403  mutable char m_sluEqued;
404 
409 
410  private:
412 };
413 
430 template <typename MatrixType_>
431 class SuperLU : public SuperLUBase<MatrixType_, SuperLU<MatrixType_> > {
432  public:
434  typedef MatrixType_ MatrixType;
435  typedef typename Base::Scalar Scalar;
436  typedef typename Base::RealScalar RealScalar;
444 
445  public:
446  using Base::_solve_impl;
447 
448  SuperLU() : Base() { init(); }
449 
450  explicit SuperLU(const MatrixType &matrix) : Base() {
451  init();
453  }
454 
455  ~SuperLU() {}
456 
465  m_isInitialized = false;
467  }
468 
475  void factorize(const MatrixType &matrix);
476 
478  template <typename Rhs, typename Dest>
479  void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const;
480 
481  inline const LMatrixType &matrixL() const {
483  return m_l;
484  }
485 
486  inline const UMatrixType &matrixU() const {
488  return m_u;
489  }
490 
491  inline const IntColVectorType &permutationP() const {
493  return m_p;
494  }
495 
496  inline const IntRowVectorType &permutationQ() const {
498  return m_q;
499  }
500 
501  Scalar determinant() const;
502 
503  protected:
504  using Base::m_l;
505  using Base::m_matrix;
506  using Base::m_p;
507  using Base::m_q;
508  using Base::m_sluA;
509  using Base::m_sluB;
510  using Base::m_sluBerr;
511  using Base::m_sluCscale;
512  using Base::m_sluEqued;
513  using Base::m_sluEtree;
514  using Base::m_sluFerr;
515  using Base::m_sluL;
516  using Base::m_sluOptions;
517  using Base::m_sluRscale;
518  using Base::m_sluStat;
519  using Base::m_sluU;
520  using Base::m_sluX;
521  using Base::m_u;
522 
523  using Base::m_analysisIsOk;
526  using Base::m_info;
527  using Base::m_isInitialized;
528 
529  void init() {
530  Base::init();
531 
537  }
538 
539  private:
541 };
542 
543 template <typename MatrixType>
545  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
546  if (!m_analysisIsOk) {
547  m_info = InvalidInput;
548  return;
549  }
550 
551  this->initFactorization(a);
552 
553  m_sluOptions.ColPerm = COLAMD;
554  int info = 0;
555  RealScalar recip_pivot_growth, rcond;
556  RealScalar ferr, berr;
557 
558  StatInit(&m_sluStat);
559  SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
560  &m_sluCscale[0], &m_sluL, &m_sluU, NULL, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond, &ferr, &berr,
561  &m_sluStat, &info, Scalar());
562  StatFree(&m_sluStat);
563 
564  m_extractedDataAreDirty = true;
565 
566  // FIXME how to better check for errors ???
567  m_info = info == 0 ? Success : NumericalIssue;
568  m_factorizationIsOk = true;
569 }
570 
571 template <typename MatrixType>
572 template <typename Rhs, typename Dest>
574  eigen_assert(m_factorizationIsOk &&
575  "The decomposition is not in a valid state for solving, you must first call either compute() or "
576  "analyzePattern()/factorize()");
577 
578  const Index rhsCols = b.cols();
579  eigen_assert(m_matrix.rows() == b.rows());
580 
581  m_sluOptions.Trans = NOTRANS;
582  m_sluOptions.Fact = FACTORED;
583  m_sluOptions.IterRefine = NOREFINE;
584 
585  m_sluFerr.resize(rhsCols);
586  m_sluBerr.resize(rhsCols);
587 
590 
591  m_sluB = SluMatrix::Map(b_ref.const_cast_derived());
592  m_sluX = SluMatrix::Map(x_ref.const_cast_derived());
593 
594  typename Rhs::PlainObject b_cpy;
595  if (m_sluEqued != 'N') {
596  b_cpy = b;
597  m_sluB = SluMatrix::Map(b_cpy.const_cast_derived());
598  }
599 
600  StatInit(&m_sluStat);
601  int info = 0;
602  RealScalar recip_pivot_growth, rcond;
603  SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
604  &m_sluCscale[0], &m_sluL, &m_sluU, NULL, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond,
605  &m_sluFerr[0], &m_sluBerr[0], &m_sluStat, &info, Scalar());
606  StatFree(&m_sluStat);
607 
608  if (x.derived().data() != x_ref.data()) x = x_ref;
609 
610  m_info = info == 0 ? Success : NumericalIssue;
611 }
612 
613 // the code of this extractData() function has been adapted from the SuperLU's Matlab support code,
614 //
615 // Copyright (c) 1994 by Xerox Corporation. All rights reserved.
616 //
617 // THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
618 // EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
619 //
620 template <typename MatrixType, typename Derived>
622  eigen_assert(m_factorizationIsOk &&
623  "The decomposition is not in a valid state for extracting factors, you must first call either compute() "
624  "or analyzePattern()/factorize()");
625  if (m_extractedDataAreDirty) {
626  int upper;
627  int fsupc, istart, nsupr;
628  int lastl = 0, lastu = 0;
629  SCformat *Lstore = static_cast<SCformat *>(m_sluL.Store);
630  NCformat *Ustore = static_cast<NCformat *>(m_sluU.Store);
631  Scalar *SNptr;
632 
633  const Index size = m_matrix.rows();
634  m_l.resize(size, size);
635  m_l.resizeNonZeros(Lstore->nnz);
636  m_u.resize(size, size);
637  m_u.resizeNonZeros(Ustore->nnz);
638 
639  int *Lcol = m_l.outerIndexPtr();
640  int *Lrow = m_l.innerIndexPtr();
641  Scalar *Lval = m_l.valuePtr();
642 
643  int *Ucol = m_u.outerIndexPtr();
644  int *Urow = m_u.innerIndexPtr();
645  Scalar *Uval = m_u.valuePtr();
646 
647  Ucol[0] = 0;
648  Ucol[0] = 0;
649 
650  /* for each supernode */
651  for (int k = 0; k <= Lstore->nsuper; ++k) {
652  fsupc = L_FST_SUPC(k);
653  istart = L_SUB_START(fsupc);
654  nsupr = L_SUB_START(fsupc + 1) - istart;
655  upper = 1;
656 
657  /* for each column in the supernode */
658  for (int j = fsupc; j < L_FST_SUPC(k + 1); ++j) {
659  SNptr = &((Scalar *)Lstore->nzval)[L_NZ_START(j)];
660 
661  /* Extract U */
662  for (int i = U_NZ_START(j); i < U_NZ_START(j + 1); ++i) {
663  Uval[lastu] = ((Scalar *)Ustore->nzval)[i];
664  /* Matlab doesn't like explicit zero. */
665  if (Uval[lastu] != 0.0) Urow[lastu++] = U_SUB(i);
666  }
667  for (int i = 0; i < upper; ++i) {
668  /* upper triangle in the supernode */
669  Uval[lastu] = SNptr[i];
670  /* Matlab doesn't like explicit zero. */
671  if (Uval[lastu] != 0.0) Urow[lastu++] = L_SUB(istart + i);
672  }
673  Ucol[j + 1] = lastu;
674 
675  /* Extract L */
676  Lval[lastl] = 1.0; /* unit diagonal */
677  Lrow[lastl++] = L_SUB(istart + upper - 1);
678  for (int i = upper; i < nsupr; ++i) {
679  Lval[lastl] = SNptr[i];
680  /* Matlab doesn't like explicit zero. */
681  if (Lval[lastl] != 0.0) Lrow[lastl++] = L_SUB(istart + i);
682  }
683  Lcol[j + 1] = lastl;
684 
685  ++upper;
686  } /* for j ... */
687 
688  } /* for k ... */
689 
690  // squeeze the matrices :
691  m_l.resizeNonZeros(lastl);
692  m_u.resizeNonZeros(lastu);
693 
694  m_extractedDataAreDirty = false;
695  }
696 }
697 
698 template <typename MatrixType>
700  eigen_assert(m_factorizationIsOk &&
701  "The decomposition is not in a valid state for computing the determinant, you must first call either "
702  "compute() or analyzePattern()/factorize()");
703 
704  if (m_extractedDataAreDirty) this->extractData();
705 
706  Scalar det = Scalar(1);
707  for (int j = 0; j < m_u.cols(); ++j) {
708  if (m_u.outerIndexPtr()[j + 1] - m_u.outerIndexPtr()[j] > 0) {
709  int lastId = m_u.outerIndexPtr()[j + 1] - 1;
710  eigen_assert(m_u.innerIndexPtr()[lastId] <= j);
711  if (m_u.innerIndexPtr()[lastId] == j) det *= m_u.valuePtr()[lastId];
712  }
713  }
714  if (PermutationMap(m_p.data(), m_p.size()).determinant() * PermutationMap(m_q.data(), m_q.size()).determinant() < 0)
715  det = -det;
716  if (m_sluEqued != 'N')
717  return det / m_sluRscale.prod() / m_sluCscale.prod();
718  else
719  return det;
720 }
721 
722 #ifdef EIGEN_PARSED_BY_DOXYGEN
723 #define EIGEN_SUPERLU_HAS_ILU
724 #endif
725 
726 #ifdef EIGEN_SUPERLU_HAS_ILU
727 
745 template <typename MatrixType_>
746 class SuperILU : public SuperLUBase<MatrixType_, SuperILU<MatrixType_> > {
747  public:
749  typedef MatrixType_ MatrixType;
750  typedef typename Base::Scalar Scalar;
751  typedef typename Base::RealScalar RealScalar;
752 
753  public:
754  using Base::_solve_impl;
755 
756  SuperILU() : Base() { init(); }
757 
758  SuperILU(const MatrixType &matrix) : Base() {
759  init();
761  }
762 
763  ~SuperILU() {}
764 
771  void analyzePattern(const MatrixType &matrix) { Base::analyzePattern(matrix); }
772 
779  void factorize(const MatrixType &matrix);
780 
781 #ifndef EIGEN_PARSED_BY_DOXYGEN
783  template <typename Rhs, typename Dest>
784  void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const;
785 #endif // EIGEN_PARSED_BY_DOXYGEN
786 
787  protected:
788  using Base::m_l;
789  using Base::m_matrix;
790  using Base::m_p;
791  using Base::m_q;
792  using Base::m_sluA;
793  using Base::m_sluB;
794  using Base::m_sluBerr;
795  using Base::m_sluCscale;
796  using Base::m_sluEqued;
797  using Base::m_sluEtree;
798  using Base::m_sluFerr;
799  using Base::m_sluL;
800  using Base::m_sluOptions;
801  using Base::m_sluRscale;
802  using Base::m_sluStat;
803  using Base::m_sluU;
804  using Base::m_sluX;
805  using Base::m_u;
806 
807  using Base::m_analysisIsOk;
808  using Base::m_extractedDataAreDirty;
809  using Base::m_factorizationIsOk;
810  using Base::m_info;
811  using Base::m_isInitialized;
812 
813  void init() {
814  Base::init();
815 
816  ilu_set_default_options(&m_sluOptions);
817  m_sluOptions.PrintStat = NO;
818  m_sluOptions.ConditionNumber = NO;
819  m_sluOptions.Trans = NOTRANS;
820  m_sluOptions.ColPerm = MMD_AT_PLUS_A;
821 
822  // no attempt to preserve column sum
823  m_sluOptions.ILU_MILU = SILU;
824  // only basic ILU(k) support -- no direct control over memory consumption
825  // better to use ILU_DropRule = DROP_BASIC | DROP_AREA
826  // and set ILU_FillFactor to max memory growth
827  m_sluOptions.ILU_DropRule = DROP_BASIC;
828  m_sluOptions.ILU_DropTol = NumTraits<Scalar>::dummy_precision() * 10;
829  }
830 
831  private:
832  SuperILU(SuperILU &) {}
833 };
834 
835 template <typename MatrixType>
836 void SuperILU<MatrixType>::factorize(const MatrixType &a) {
837  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
838  if (!m_analysisIsOk) {
839  m_info = InvalidInput;
840  return;
841  }
842 
843  this->initFactorization(a);
844 
845  int info = 0;
846  RealScalar recip_pivot_growth, rcond;
847 
848  StatInit(&m_sluStat);
849  SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
850  &m_sluCscale[0], &m_sluL, &m_sluU, NULL, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond, &m_sluStat,
851  &info, Scalar());
852  StatFree(&m_sluStat);
853 
854  // FIXME how to better check for errors ???
855  m_info = info == 0 ? Success : NumericalIssue;
856  m_factorizationIsOk = true;
857 }
858 
859 #ifndef EIGEN_PARSED_BY_DOXYGEN
860 template <typename MatrixType>
861 template <typename Rhs, typename Dest>
862 void SuperILU<MatrixType>::_solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &x) const {
863  eigen_assert(m_factorizationIsOk &&
864  "The decomposition is not in a valid state for solving, you must first call either compute() or "
865  "analyzePattern()/factorize()");
866 
867  const int rhsCols = b.cols();
868  eigen_assert(m_matrix.rows() == b.rows());
869 
870  m_sluOptions.Trans = NOTRANS;
871  m_sluOptions.Fact = FACTORED;
872  m_sluOptions.IterRefine = NOREFINE;
873 
874  m_sluFerr.resize(rhsCols);
875  m_sluBerr.resize(rhsCols);
876 
877  Ref<const Matrix<typename Rhs::Scalar, Dynamic, Dynamic, ColMajor> > b_ref(b);
878  Ref<const Matrix<typename Dest::Scalar, Dynamic, Dynamic, ColMajor> > x_ref(x);
879 
880  m_sluB = SluMatrix::Map(b_ref.const_cast_derived());
881  m_sluX = SluMatrix::Map(x_ref.const_cast_derived());
882 
883  typename Rhs::PlainObject b_cpy;
884  if (m_sluEqued != 'N') {
885  b_cpy = b;
886  m_sluB = SluMatrix::Map(b_cpy.const_cast_derived());
887  }
888 
889  int info = 0;
890  RealScalar recip_pivot_growth, rcond;
891 
892  StatInit(&m_sluStat);
893  SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
894  &m_sluCscale[0], &m_sluL, &m_sluU, NULL, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond, &m_sluStat,
895  &info, Scalar());
896  StatFree(&m_sluStat);
897 
898  if (x.derived().data() != x_ref.data()) x = x_ref;
899 
900  m_info = info == 0 ? Success : NumericalIssue;
901 }
902 #endif
903 
904 #endif
905 
906 } // end namespace Eigen
907 
908 #endif // EIGEN_SUPERLUSUPPORT_H
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Eigen::SparseMatrix< double > mat
Definition: EigenUnitTest.cpp:10
#define eigen_assert(x)
Definition: Macros.h:910
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
#define DECL_GSSVX(PREFIX, FLOATTYPE, KEYTYPE)
Definition: SuperLUSupport.h:38
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Scalar * b
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:96
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:52
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:294
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:264
Base class of any sparse matrices or sparse expressions.
Definition: SparseMatrixBase.h:30
Index size() const
Definition: SparseMatrixBase.h:187
const Derived & derived() const
Definition: SparseMatrixBase.h:144
Index nonZeros() const
Definition: SparseCompressedBase.h:64
Index cols() const
Definition: SparseMatrix.h:161
const Scalar * valuePtr() const
Definition: SparseMatrix.h:171
Index rows() const
Definition: SparseMatrix.h:159
const StorageIndex * outerIndexPtr() const
Definition: SparseMatrix.h:189
const StorageIndex * innerIndexPtr() const
Definition: SparseMatrix.h:180
constexpr Storage & data()
Definition: SparseMatrix.h:205
A base class for sparse solvers.
Definition: SparseSolverBase.h:67
void _solve_impl(const SparseMatrixBase< Rhs > &b, SparseMatrixBase< Dest > &dest) const
Definition: SparseSolverBase.h:104
bool m_isInitialized
Definition: SparseSolverBase.h:110
Derived & derived()
Definition: SparseSolverBase.h:76
The base class for the direct and incomplete LU factorization of SuperLU.
Definition: SuperLUSupport.h:278
Matrix< RealScalar, Dynamic, 1 > m_sluRscale
Definition: SuperLUSupport.h:401
std::vector< int > m_sluEtree
Definition: SuperLUSupport.h:400
void extractData() const
Definition: SuperLUSupport.h:621
SuperMatrix m_sluL
Definition: SuperLUSupport.h:396
Matrix< Scalar, Dynamic, 1 > Vector
Definition: SuperLUSupport.h:289
void compute(const MatrixType &matrix)
Definition: SuperLUSupport.h:318
bool m_extractedDataAreDirty
Definition: SuperLUSupport.h:408
LUMatrixType m_l
Definition: SuperLUSupport.h:389
~SuperLUBase()
Definition: SuperLUSupport.h:299
SuperLUStat_t m_sluStat
Definition: SuperLUSupport.h:398
Matrix< RealScalar, Dynamic, 1 > m_sluBerr
Definition: SuperLUSupport.h:402
Index rows() const
Definition: SuperLUSupport.h:301
ComputationInfo info() const
Reports whether previous computation was successful.
Definition: SuperLUSupport.h:312
MatrixType::StorageIndex StorageIndex
Definition: SuperLUSupport.h:288
MatrixType::RealScalar RealScalar
Definition: SuperLUSupport.h:287
SluMatrix m_sluB
Definition: SuperLUSupport.h:397
SparseSolverBase< Derived > Base
Definition: SuperLUSupport.h:280
SuperLUBase()
Definition: SuperLUSupport.h:297
SuperMatrix m_sluU
Definition: SuperLUSupport.h:396
IntRowVectorType m_q
Definition: SuperLUSupport.h:392
void clearFactors()
Definition: SuperLUSupport.h:377
MatrixType::Scalar Scalar
Definition: SuperLUSupport.h:286
SluMatrix m_sluX
Definition: SuperLUSupport.h:397
Matrix< RealScalar, Dynamic, 1 > m_sluFerr
Definition: SuperLUSupport.h:402
LUMatrixType m_u
Definition: SuperLUSupport.h:390
Matrix< RealScalar, Dynamic, 1 > m_sluCscale
Definition: SuperLUSupport.h:401
int m_analysisIsOk
Definition: SuperLUSupport.h:407
@ ColsAtCompileTime
Definition: SuperLUSupport.h:294
@ MaxColsAtCompileTime
Definition: SuperLUSupport.h:294
superlu_options_t & options()
Definition: SuperLUSupport.h:305
Map< PermutationMatrix< Dynamic, Dynamic, int > > PermutationMap
Definition: SuperLUSupport.h:292
int m_factorizationIsOk
Definition: SuperLUSupport.h:406
IntColVectorType m_p
Definition: SuperLUSupport.h:391
void dumpMemory(Stream &)
Definition: SuperLUSupport.h:337
void analyzePattern(const MatrixType &)
Definition: SuperLUSupport.h:329
void init()
Definition: SuperLUSupport.h:368
Matrix< int, MatrixType::RowsAtCompileTime, 1 > IntColVectorType
Definition: SuperLUSupport.h:291
SuperLUBase(SuperLUBase &)
Definition: SuperLUSupport.h:411
bool m_isInitialized
Definition: SparseSolverBase.h:110
superlu_options_t m_sluOptions
Definition: SuperLUSupport.h:399
Derived & derived()
Definition: SparseSolverBase.h:76
char m_sluEqued
Definition: SuperLUSupport.h:403
void initFactorization(const MatrixType &a)
Definition: SuperLUSupport.h:340
ComputationInfo m_info
Definition: SuperLUSupport.h:405
SparseMatrix< Scalar > LUMatrixType
Definition: SuperLUSupport.h:293
Matrix< int, 1, MatrixType::ColsAtCompileTime > IntRowVectorType
Definition: SuperLUSupport.h:290
SluMatrix m_sluA
Definition: SuperLUSupport.h:395
MatrixType_ MatrixType
Definition: SuperLUSupport.h:285
Index cols() const
Definition: SuperLUSupport.h:302
LUMatrixType m_matrix
Definition: SuperLUSupport.h:394
A sparse direct LU factorization and solver based on the SuperLU library.
Definition: SuperLUSupport.h:431
SuperLU()
Definition: SuperLUSupport.h:448
Base::IntRowVectorType IntRowVectorType
Definition: SuperLUSupport.h:438
void factorize(const MatrixType &matrix)
Definition: SuperLUSupport.h:544
void analyzePattern(const MatrixType &matrix)
Definition: SuperLUSupport.h:463
bool m_extractedDataAreDirty
Definition: SuperLUSupport.h:408
LUMatrixType m_l
Definition: SuperLUSupport.h:389
Base::IntColVectorType IntColVectorType
Definition: SuperLUSupport.h:439
const IntColVectorType & permutationP() const
Definition: SuperLUSupport.h:491
Base::Scalar Scalar
Definition: SuperLUSupport.h:435
Base::RealScalar RealScalar
Definition: SuperLUSupport.h:436
TriangularView< LUMatrixType, Upper > UMatrixType
Definition: SuperLUSupport.h:443
const UMatrixType & matrixU() const
Definition: SuperLUSupport.h:486
IntRowVectorType m_q
Definition: SuperLUSupport.h:392
const LMatrixType & matrixL() const
Definition: SuperLUSupport.h:481
Base::LUMatrixType LUMatrixType
Definition: SuperLUSupport.h:441
void init()
Definition: SuperLUSupport.h:529
LUMatrixType m_u
Definition: SuperLUSupport.h:390
TriangularView< LUMatrixType, Lower|UnitDiag > LMatrixType
Definition: SuperLUSupport.h:442
IntColVectorType m_p
Definition: SuperLUSupport.h:391
~SuperLU()
Definition: SuperLUSupport.h:455
SuperLU(SuperLU &)
Definition: SuperLUSupport.h:540
MatrixType_ MatrixType
Definition: SuperLUSupport.h:434
bool m_isInitialized
Definition: SparseSolverBase.h:110
SuperLUBase< MatrixType_, SuperLU > Base
Definition: SuperLUSupport.h:433
superlu_options_t m_sluOptions
Definition: SuperLUSupport.h:399
Scalar determinant() const
Definition: SuperLUSupport.h:699
const IntRowVectorType & permutationQ() const
Definition: SuperLUSupport.h:496
ComputationInfo m_info
Definition: SuperLUSupport.h:405
SuperLU(const MatrixType &matrix)
Definition: SuperLUSupport.h:450
Base::StorageIndex StorageIndex
Definition: SuperLUSupport.h:437
Base::PermutationMap PermutationMap
Definition: SuperLUSupport.h:440
void _solve_impl(const MatrixBase< Rhs > &b, MatrixBase< Dest > &dest) const
Definition: SuperLUSupport.h:573
Expression of a triangular part in a matrix.
Definition: TriangularMatrix.h:167
Concept for reading and writing characters.
Eigen::Map< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor >, 0, Eigen::OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:85
EIGEN_DONT_INLINE void compute(Solver &solver, const MatrixType &A)
Definition: dense_solvers.cpp:23
ComputationInfo
Definition: Constants.h:438
@ SelfAdjoint
Definition: Constants.h:227
@ 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
@ ColMajor
Definition: Constants.h:318
@ RowMajor
Definition: Constants.h:320
const unsigned int RowMajorBit
Definition: Constants.h:70
RealScalar s
Definition: level1_cplx_impl.h:130
return int(ret)+1
const Scalar * a
Definition: level2_cplx_impl.h:32
int info
Definition: level2_cplx_impl.h:39
if(UPLO(*uplo)==INVALID) info
Definition: level3_impl.h:428
char char char int int * k
Definition: level2_impl.h:374
SluMatrix asSluMatrix(MatrixType &mat)
Definition: SuperLUSupport.h:254
Map< SparseMatrix< Scalar, Flags, Index > > map_superlu(SluMatrix &sluMat)
Definition: SuperLUSupport.h:260
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
squared absolute value
Definition: GlobalFunctions.h:87
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
Extend namespace for flags.
Definition: fsi_chan_precond_driver.cc:56
int c
Definition: calibrate.py:100
Definition: Eigen_Colamd.h:49
list x
Definition: plotDoE.py:28
t
Definition: plotPSD.py:36
@ NOTRANS
Definition: oomph_superlu_4.3/superlu_enum_consts.h:21
@ SILU
Definition: oomph_superlu_4.3/superlu_enum_consts.h:28
@ NOREFINE
Definition: oomph_superlu_4.3/superlu_enum_consts.h:23
@ MMD_AT_PLUS_A
Definition: oomph_superlu_4.3/superlu_enum_consts.h:19
@ COLAMD
Definition: oomph_superlu_4.3/superlu_enum_consts.h:19
@ FACTORED
Definition: oomph_superlu_4.3/superlu_enum_consts.h:17
@ NO
Definition: oomph_superlu_4.3/superlu_enum_consts.h:16
@ SLU_TRL
Definition: oomph_superlu_4.3/supermatrix.h:35
@ SLU_TRU
Definition: oomph_superlu_4.3/supermatrix.h:36
@ SLU_GE
Definition: oomph_superlu_4.3/supermatrix.h:32
@ SLU_S
Definition: oomph_superlu_4.3/supermatrix.h:25
@ SLU_Z
Definition: oomph_superlu_4.3/supermatrix.h:28
@ SLU_C
Definition: oomph_superlu_4.3/supermatrix.h:27
@ SLU_D
Definition: oomph_superlu_4.3/supermatrix.h:26
Stype_t
Definition: oomph_superlu_4.3/supermatrix.h:11
@ SLU_NC
Definition: oomph_superlu_4.3/supermatrix.h:12
@ SLU_DN
Definition: oomph_superlu_4.3/supermatrix.h:20
@ SLU_NR
Definition: oomph_superlu_4.3/supermatrix.h:16
#define L_FST_SUPC(superno)
Definition: slu_util.h:76
void StatInit(SuperLUStat_t *)
void Destroy_CompCol_Matrix(SuperMatrix *)
#define L_SUB_START(col)
Definition: slu_util.h:73
void set_default_options(superlu_options_t *options)
#define L_NZ_START(col)
Definition: slu_util.h:75
#define L_SUB(ptr)
Definition: slu_util.h:74
void StatFree(SuperLUStat_t *)
#define U_NZ_START(col)
Definition: slu_util.h:77
#define U_SUB(ptr)
Definition: slu_util.h:78
void Destroy_SuperNode_Matrix(SuperMatrix *)
#define DROP_BASIC
Definition: slu_util.h:95
void ilu_set_default_options(superlu_options_t *options)
static void run(MatrixType &mat, SluMatrix &res)
Definition: SuperLUSupport.h:206
Matrix< Scalar, Rows, Cols, Options, MRows, MCols > MatrixType
Definition: SuperLUSupport.h:205
Derived MatrixType
Definition: SuperLUSupport.h:222
static void run(MatrixType &mat, SluMatrix &res)
Definition: SuperLUSupport.h:223
Definition: SuperLUSupport.h:92
Definition: SuperLUSupport.h:101
void * values
Definition: SuperLUSupport.h:121
SluMatrix & operator=(const SluMatrix &other)
Definition: SuperLUSupport.h:109
SluMatrix()
Definition: SuperLUSupport.h:102
SluMatrix(const SluMatrix &other)
Definition: SuperLUSupport.h:104
static SluMatrix Map(SparseMatrixBase< MatrixType > &a_mat)
Definition: SuperLUSupport.h:170
void setScalarType()
Definition: SuperLUSupport.h:137
struct Eigen::SluMatrix::@890 storage
int lda
Definition: SuperLUSupport.h:119
int nnz
Definition: SuperLUSupport.h:118
int * outerInd
Definition: SuperLUSupport.h:123
int * innerInd
Definition: SuperLUSupport.h:122
void setStorageType(Stype_t t)
Definition: SuperLUSupport.h:126
static SluMatrix Map(MatrixBase< MatrixType > &_mat)
Definition: SuperLUSupport.h:152
Definition: Meta.h:205
Definition: oomph_superlu_4.3/supermatrix.h:59
void * nzval
Definition: oomph_superlu_4.3/supermatrix.h:61
int_t nnz
Definition: oomph_superlu_4.3/supermatrix.h:60
Definition: oomph_superlu_4.3/supermatrix.h:85
int_t nnz
Definition: oomph_superlu_4.3/supermatrix.h:86
void * nzval
Definition: oomph_superlu_4.3/supermatrix.h:88
int_t nsuper
Definition: oomph_superlu_4.3/supermatrix.h:87
Definition: slu_util.h:290
Definition: oomph_superlu_4.3/supermatrix.h:43
Mtype_t Mtype
Definition: oomph_superlu_4.3/supermatrix.h:47
void * Store
Definition: oomph_superlu_4.3/supermatrix.h:51
int_t nrow
Definition: oomph_superlu_4.3/supermatrix.h:49
Stype_t Stype
Definition: oomph_superlu_4.3/supermatrix.h:44
int_t ncol
Definition: oomph_superlu_4.3/supermatrix.h:50
Dtype_t Dtype
Definition: oomph_superlu_4.3/supermatrix.h:46
Definition: TutorialInplaceLU.cpp:2
Definition: slu_util.h:246
trans_t Trans
Definition: slu_util.h:250
yes_no_t ConditionNumber
Definition: slu_util.h:255
yes_no_t PrintStat
Definition: slu_util.h:268
colperm_t ColPerm
Definition: slu_util.h:249
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2