// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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/.

#ifndef EIGEN_SUPERLUSUPPORT_H
#define EIGEN_SUPERLUSUPPORT_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

#if defined(SUPERLU_MAJOR_VERSION) && (SUPERLU_MAJOR_VERSION >= 5)
#define DECL_GSSVX(PREFIX, FLOATTYPE, KEYTYPE)                                                                         \
  extern "C" {                                                                                                         \
  extern void PREFIX##gssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
                            SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *,      \
                            FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, GlobalLU_t *, mem_usage_t *, SuperLUStat_t *,       \
                            int *);                                                                                    \
  }                                                                                                                    \
  inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree,         \
                             char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work,      \
                             int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth,                 \
                             FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, SuperLUStat_t *stats, int *info,      \
                             KEYTYPE) {                                                                                \
    mem_usage_t mem_usage;                                                                                             \
    GlobalLU_t gLU;                                                                                                    \
    PREFIX##gssvx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond,  \
                  ferr, berr, &gLU, &mem_usage, stats, info);                                                          \
    return mem_usage.for_lu; /* bytes used by the factor storage */                                                    \
  }
#else  // version < 5.0
#define DECL_GSSVX(PREFIX, FLOATTYPE, KEYTYPE)                                                                         \
  extern "C" {                                                                                                         \
  extern void PREFIX##gssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
                            SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *,      \
                            FLOATTYPE *, FLOATTYPE *, FLOATTYPE *, mem_usage_t *, SuperLUStat_t *, int *);             \
  }                                                                                                                    \
  inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree,         \
                             char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work,      \
                             int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth,                 \
                             FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, SuperLUStat_t *stats, int *info,      \
                             KEYTYPE) {                                                                                \
    mem_usage_t mem_usage;                                                                                             \
    PREFIX##gssvx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond,  \
                  ferr, berr, &mem_usage, stats, info);                                                                \
    return mem_usage.for_lu; /* bytes used by the factor storage */                                                    \
  }
#endif

DECL_GSSVX(s, float, float)
DECL_GSSVX(c, float, std::complex<float>)
DECL_GSSVX(d, double, double)
DECL_GSSVX(z, double, std::complex<double>)

#ifdef MILU_ALPHA
#define EIGEN_SUPERLU_HAS_ILU
#endif

#ifdef EIGEN_SUPERLU_HAS_ILU

// similarly for the incomplete factorization using gsisx
#if defined(SUPERLU_MAJOR_VERSION) && (SUPERLU_MAJOR_VERSION >= 5)
#define DECL_GSISX(PREFIX, FLOATTYPE, KEYTYPE)                                                                         \
  extern "C" {                                                                                                         \
  extern void PREFIX##gsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
                            SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *,      \
                            FLOATTYPE *, GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *);                         \
  }                                                                                                                    \
  inline float SuperLU_gsisx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree,         \
                             char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work,      \
                             int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth,                 \
                             FLOATTYPE *rcond, SuperLUStat_t *stats, int *info, KEYTYPE) {                             \
    mem_usage_t mem_usage;                                                                                             \
    GlobalLU_t gLU;                                                                                                    \
    PREFIX##gsisx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond,  \
                  &gLU, &mem_usage, stats, info);                                                                      \
    return mem_usage.for_lu; /* bytes used by the factor storage */                                                    \
  }
#else  // version < 5.0
#define DECL_GSISX(PREFIX, FLOATTYPE, KEYTYPE)                                                                         \
  extern "C" {                                                                                                         \
  extern void PREFIX##gsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, char *, FLOATTYPE *, FLOATTYPE *, \
                            SuperMatrix *, SuperMatrix *, void *, int, SuperMatrix *, SuperMatrix *, FLOATTYPE *,      \
                            FLOATTYPE *, mem_usage_t *, SuperLUStat_t *, int *);                                       \
  }                                                                                                                    \
  inline float SuperLU_gsisx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, int *etree,         \
                             char *equed, FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, SuperMatrix *U, void *work,      \
                             int lwork, SuperMatrix *B, SuperMatrix *X, FLOATTYPE *recip_pivot_growth,                 \
                             FLOATTYPE *rcond, SuperLUStat_t *stats, int *info, KEYTYPE) {                             \
    mem_usage_t mem_usage;                                                                                             \
    PREFIX##gsisx(options, A, perm_c, perm_r, etree, equed, R, C, L, U, work, lwork, B, X, recip_pivot_growth, rcond,  \
                  &mem_usage, stats, info);                                                                            \
    return mem_usage.for_lu; /* bytes used by the factor storage */                                                    \
  }
#endif

DECL_GSISX(s, float, float)
DECL_GSISX(c, float, std::complex<float>)
DECL_GSISX(d, double, double)
DECL_GSISX(z, double, std::complex<double>)

#endif

template <typename MatrixType>
struct SluMatrixMapHelper;

/** \internal
 *
 * A wrapper class for SuperLU matrices. It supports only compressed sparse matrices
 * and dense matrices. Supernodal and other fancy format are not supported by this wrapper.
 *
 * This wrapper class mainly aims to avoids the need of dynamic allocation of the storage structure.
 */
struct SluMatrix : SuperMatrix {
  SluMatrix() { Store = &storage; }

  SluMatrix(const SluMatrix &other) : SuperMatrix(other) {
    Store = &storage;
    storage = other.storage;
  }

  SluMatrix &operator=(const SluMatrix &other) {
    SuperMatrix::operator=(static_cast<const SuperMatrix &>(other));
    Store = &storage;
    storage = other.storage;
    return *this;
  }

  struct {
    union {
      int nnz;
      int lda;
    };
    void *values;
    int *innerInd;
    int *outerInd;
  } storage;

  void setStorageType(Stype_t t) {
    Stype = t;
    if (t == SLU_NC || t == SLU_NR || t == SLU_DN)
      Store = &storage;
    else {
      eigen_assert(false && "storage type not supported");
      Store = 0;
    }
  }

  template <typename Scalar>
  void setScalarType() {
    if (internal::is_same<Scalar, float>::value)
      Dtype = SLU_S;
    else if (internal::is_same<Scalar, double>::value)
      Dtype = SLU_D;
    else if (internal::is_same<Scalar, std::complex<float> >::value)
      Dtype = SLU_C;
    else if (internal::is_same<Scalar, std::complex<double> >::value)
      Dtype = SLU_Z;
    else {
      eigen_assert(false && "Scalar type not supported by SuperLU");
    }
  }

  template <typename MatrixType>
  static SluMatrix Map(MatrixBase<MatrixType> &_mat) {
    MatrixType &mat(_mat.derived());
    eigen_assert(((MatrixType::Flags & RowMajorBit) != RowMajorBit) &&
                 "row-major dense matrices are not supported by SuperLU");
    SluMatrix res;
    res.setStorageType(SLU_DN);
    res.setScalarType<typename MatrixType::Scalar>();
    res.Mtype = SLU_GE;

    res.nrow = internal::convert_index<int>(mat.rows());
    res.ncol = internal::convert_index<int>(mat.cols());

    res.storage.lda = internal::convert_index<int>(MatrixType::IsVectorAtCompileTime ? mat.size() : mat.outerStride());
    res.storage.values = (void *)(mat.data());
    return res;
  }

  template <typename MatrixType>
  static SluMatrix Map(SparseMatrixBase<MatrixType> &a_mat) {
    MatrixType &mat(a_mat.derived());
    SluMatrix res;
    if ((MatrixType::Flags & RowMajorBit) == RowMajorBit) {
      res.setStorageType(SLU_NR);
      res.nrow = internal::convert_index<int>(mat.cols());
      res.ncol = internal::convert_index<int>(mat.rows());
    } else {
      res.setStorageType(SLU_NC);
      res.nrow = internal::convert_index<int>(mat.rows());
      res.ncol = internal::convert_index<int>(mat.cols());
    }

    res.Mtype = SLU_GE;

    res.storage.nnz = internal::convert_index<int>(mat.nonZeros());
    res.storage.values = mat.valuePtr();
    res.storage.innerInd = mat.innerIndexPtr();
    res.storage.outerInd = mat.outerIndexPtr();

    res.setScalarType<typename MatrixType::Scalar>();

    // FIXME: the following type mapping is approximate.
    if (int(MatrixType::Flags) & int(Upper)) res.Mtype = SLU_TRU;
    if (int(MatrixType::Flags) & int(Lower)) res.Mtype = SLU_TRL;

    eigen_assert(((int(MatrixType::Flags) & int(SelfAdjoint)) == 0) &&
                 "SelfAdjoint matrix shape not supported by SuperLU");

    return res;
  }
};

template <typename Scalar, int Rows, int Cols, int Options, int MRows, int MCols>
struct SluMatrixMapHelper<Matrix<Scalar, Rows, Cols, Options, MRows, MCols> > {
  typedef Matrix<Scalar, Rows, Cols, Options, MRows, MCols> MatrixType;
  static void run(MatrixType &mat, SluMatrix &res) {
    eigen_assert(((Options & RowMajor) != RowMajor) && "row-major dense matrices is not supported by SuperLU");
    res.setStorageType(SLU_DN);
    res.setScalarType<Scalar>();
    res.Mtype = SLU_GE;

    res.nrow = mat.rows();
    res.ncol = mat.cols();

    res.storage.lda = mat.outerStride();
    res.storage.values = mat.data();
  }
};

template <typename Derived>
struct SluMatrixMapHelper<SparseMatrixBase<Derived> > {
  typedef Derived MatrixType;
  static void run(MatrixType &mat, SluMatrix &res) {
    if ((MatrixType::Flags & RowMajorBit) == RowMajorBit) {
      res.setStorageType(SLU_NR);
      res.nrow = mat.cols();
      res.ncol = mat.rows();
    } else {
      res.setStorageType(SLU_NC);
      res.nrow = mat.rows();
      res.ncol = mat.cols();
    }

    res.Mtype = SLU_GE;

    res.storage.nnz = mat.nonZeros();
    res.storage.values = mat.valuePtr();
    res.storage.innerInd = mat.innerIndexPtr();
    res.storage.outerInd = mat.outerIndexPtr();

    res.setScalarType<typename MatrixType::Scalar>();

    // FIXME: the following type mapping is approximate.
    if (MatrixType::Flags & Upper) res.Mtype = SLU_TRU;
    if (MatrixType::Flags & Lower) res.Mtype = SLU_TRL;

    eigen_assert(((MatrixType::Flags & SelfAdjoint) == 0) && "SelfAdjoint matrix shape not supported by SuperLU");
  }
};

namespace internal {

template <typename MatrixType>
SluMatrix asSluMatrix(MatrixType &mat) {
  return SluMatrix::Map(mat);
}

/** View a Super LU matrix as an Eigen expression */
template <typename Scalar, int Flags, typename Index>
Map<SparseMatrix<Scalar, Flags, Index> > map_superlu(SluMatrix &sluMat) {
  eigen_assert(((Flags & RowMajor) == RowMajor && sluMat.Stype == SLU_NR) ||
               ((Flags & ColMajor) == ColMajor && sluMat.Stype == SLU_NC));

  Index outerSize = (Flags & RowMajor) == RowMajor ? sluMat.ncol : sluMat.nrow;

  return Map<SparseMatrix<Scalar, Flags, Index> >(sluMat.nrow, sluMat.ncol, sluMat.storage.outerInd[outerSize],
                                                  sluMat.storage.outerInd, sluMat.storage.innerInd,
                                                  reinterpret_cast<Scalar *>(sluMat.storage.values));
}

}  // end namespace internal

/** \ingroup SuperLUSupport_Module
 * \class SuperLUBase
 * \brief The base class for the direct and incomplete LU factorization of SuperLU
 */
template <typename MatrixType_, typename Derived>
class SuperLUBase : public SparseSolverBase<Derived> {
 protected:
  typedef SparseSolverBase<Derived> Base;
  using Base::derived;
  using Base::m_isInitialized;

 public:
  typedef MatrixType_ MatrixType;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;
  typedef typename MatrixType::StorageIndex StorageIndex;
  typedef Matrix<Scalar, Dynamic, 1> Vector;
  typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
  typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
  typedef Map<PermutationMatrix<Dynamic, Dynamic, int> > PermutationMap;
  typedef SparseMatrix<Scalar> LUMatrixType;
  enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };

 public:
  SuperLUBase() {}

  ~SuperLUBase() { clearFactors(); }

  inline Index rows() const { return m_matrix.rows(); }
  inline Index cols() const { return m_matrix.cols(); }

  /** \returns a reference to the Super LU option object to configure the  Super LU algorithms. */
  inline superlu_options_t &options() { return m_sluOptions; }

  /** \brief Reports whether previous computation was successful.
   *
   * \returns \c Success if computation was successful,
   *          \c NumericalIssue if the matrix.appears to be negative.
   */
  ComputationInfo info() const {
    eigen_assert(m_isInitialized && "Decomposition is not initialized.");
    return m_info;
  }

  /** Computes the sparse Cholesky decomposition of \a matrix */
  void compute(const MatrixType &matrix) {
    derived().analyzePattern(matrix);
    derived().factorize(matrix);
  }

  /** Performs a symbolic decomposition on the sparsity of \a matrix.
   *
   * This function is particularly useful when solving for several problems having the same structure.
   *
   * \sa factorize()
   */
  void analyzePattern(const MatrixType & /*matrix*/) {
    m_isInitialized = true;
    m_info = Success;
    m_analysisIsOk = true;
    m_factorizationIsOk = false;
  }

  template <typename Stream>
  void dumpMemory(Stream & /*s*/) {}

 protected:
  void initFactorization(const MatrixType &a) {
    set_default_options(&this->m_sluOptions);

    const Index size = a.rows();
    m_matrix = a;

    m_sluA = internal::asSluMatrix(m_matrix);
    clearFactors();

    m_p.resize(size);
    m_q.resize(size);
    m_sluRscale.resize(size);
    m_sluCscale.resize(size);
    m_sluEtree.resize(size);

    // set empty B and X
    m_sluB.setStorageType(SLU_DN);
    m_sluB.setScalarType<Scalar>();
    m_sluB.Mtype = SLU_GE;
    m_sluB.storage.values = 0;
    m_sluB.nrow = 0;
    m_sluB.ncol = 0;
    m_sluB.storage.lda = internal::convert_index<int>(size);
    m_sluX = m_sluB;

    m_extractedDataAreDirty = true;
  }

  void init() {
    m_info = InvalidInput;
    m_isInitialized = false;
    m_sluL.Store = 0;
    m_sluU.Store = 0;
  }

  void extractData() const;

  void clearFactors() {
    if (m_sluL.Store) Destroy_SuperNode_Matrix(&m_sluL);
    if (m_sluU.Store) Destroy_CompCol_Matrix(&m_sluU);

    m_sluL.Store = 0;
    m_sluU.Store = 0;

    memset(&m_sluL, 0, sizeof m_sluL);
    memset(&m_sluU, 0, sizeof m_sluU);
  }

  // cached data to reduce reallocation, etc.
  mutable LUMatrixType m_l;
  mutable LUMatrixType m_u;
  mutable IntColVectorType m_p;
  mutable IntRowVectorType m_q;

  mutable LUMatrixType m_matrix;  // copy of the factorized matrix
  mutable SluMatrix m_sluA;
  mutable SuperMatrix m_sluL, m_sluU;
  mutable SluMatrix m_sluB, m_sluX;
  mutable SuperLUStat_t m_sluStat;
  mutable superlu_options_t m_sluOptions;
  mutable std::vector<int> m_sluEtree;
  mutable Matrix<RealScalar, Dynamic, 1> m_sluRscale, m_sluCscale;
  mutable Matrix<RealScalar, Dynamic, 1> m_sluFerr, m_sluBerr;
  mutable char m_sluEqued;

  mutable ComputationInfo m_info;
  int m_factorizationIsOk;
  int m_analysisIsOk;
  mutable bool m_extractedDataAreDirty;

 private:
  SuperLUBase(SuperLUBase &) {}
};

/** \ingroup SuperLUSupport_Module
 * \class SuperLU
 * \brief A sparse direct LU factorization and solver based on the SuperLU library
 *
 * This class allows to solve for A.X = B sparse linear problems via a direct LU factorization
 * using the SuperLU 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<>
 *
 * \warning This class is only for the 4.x versions of SuperLU. The 3.x and 5.x versions are not supported.
 *
 * \implsparsesolverconcept
 *
 * \sa \ref TutorialSparseSolverConcept, class SparseLU
 */
template <typename MatrixType_>
class SuperLU : public SuperLUBase<MatrixType_, SuperLU<MatrixType_> > {
 public:
  typedef SuperLUBase<MatrixType_, SuperLU> Base;
  typedef MatrixType_ MatrixType;
  typedef typename Base::Scalar Scalar;
  typedef typename Base::RealScalar RealScalar;
  typedef typename Base::StorageIndex StorageIndex;
  typedef typename Base::IntRowVectorType IntRowVectorType;
  typedef typename Base::IntColVectorType IntColVectorType;
  typedef typename Base::PermutationMap PermutationMap;
  typedef typename Base::LUMatrixType LUMatrixType;
  typedef TriangularView<LUMatrixType, Lower | UnitDiag> LMatrixType;
  typedef TriangularView<LUMatrixType, Upper> UMatrixType;

 public:
  using Base::_solve_impl;

  SuperLU() : Base() { init(); }

  explicit SuperLU(const MatrixType &matrix) : Base() {
    init();
    Base::compute(matrix);
  }

  ~SuperLU() {}

  /** Performs a symbolic decomposition on the sparsity of \a matrix.
   *
   * This function is particularly useful when solving for several problems having the same structure.
   *
   * \sa factorize()
   */
  void analyzePattern(const MatrixType &matrix) {
    m_info = InvalidInput;
    m_isInitialized = false;
    Base::analyzePattern(matrix);
  }

  /** Performs a numeric decomposition of \a matrix
   *
   * The given matrix must have the same sparsity as the matrix on which the symbolic decomposition has been
   * performed.
   *
   * \sa analyzePattern()
   */
  void factorize(const MatrixType &matrix);

  /** \internal */
  template <typename Rhs, typename Dest>
  void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const;

  inline const LMatrixType &matrixL() const {
    if (m_extractedDataAreDirty) this->extractData();
    return m_l;
  }

  inline const UMatrixType &matrixU() const {
    if (m_extractedDataAreDirty) this->extractData();
    return m_u;
  }

  inline const IntColVectorType &permutationP() const {
    if (m_extractedDataAreDirty) this->extractData();
    return m_p;
  }

  inline const IntRowVectorType &permutationQ() const {
    if (m_extractedDataAreDirty) this->extractData();
    return m_q;
  }

  Scalar determinant() const;

 protected:
  using Base::m_l;
  using Base::m_matrix;
  using Base::m_p;
  using Base::m_q;
  using Base::m_sluA;
  using Base::m_sluB;
  using Base::m_sluBerr;
  using Base::m_sluCscale;
  using Base::m_sluEqued;
  using Base::m_sluEtree;
  using Base::m_sluFerr;
  using Base::m_sluL;
  using Base::m_sluOptions;
  using Base::m_sluRscale;
  using Base::m_sluStat;
  using Base::m_sluU;
  using Base::m_sluX;
  using Base::m_u;

  using Base::m_analysisIsOk;
  using Base::m_extractedDataAreDirty;
  using Base::m_factorizationIsOk;
  using Base::m_info;
  using Base::m_isInitialized;

  void init() {
    Base::init();

    set_default_options(&this->m_sluOptions);
    m_sluOptions.PrintStat = NO;
    m_sluOptions.ConditionNumber = NO;
    m_sluOptions.Trans = NOTRANS;
    m_sluOptions.ColPerm = COLAMD;
  }

 private:
  SuperLU(SuperLU &) {}
};

template <typename MatrixType>
void SuperLU<MatrixType>::factorize(const MatrixType &a) {
  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
  if (!m_analysisIsOk) {
    m_info = InvalidInput;
    return;
  }

  this->initFactorization(a);

  m_sluOptions.ColPerm = COLAMD;
  int info = 0;
  RealScalar recip_pivot_growth, rcond;
  RealScalar ferr, berr;

  StatInit(&m_sluStat);
  SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
                &m_sluCscale[0], &m_sluL, &m_sluU, NULL, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond, &ferr, &berr,
                &m_sluStat, &info, Scalar());
  StatFree(&m_sluStat);

  m_extractedDataAreDirty = true;

  // FIXME: implement more detailed error checking based on SuperLU info codes.
  m_info = info == 0 ? Success : NumericalIssue;
  m_factorizationIsOk = true;
}

template <typename MatrixType>
template <typename Rhs, typename Dest>
void SuperLU<MatrixType>::_solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &x) const {
  eigen_assert(m_factorizationIsOk &&
               "The decomposition is not in a valid state for solving, you must first call either compute() or "
               "analyzePattern()/factorize()");

  const Index rhsCols = b.cols();
  eigen_assert(m_matrix.rows() == b.rows());

  m_sluOptions.Trans = NOTRANS;
  m_sluOptions.Fact = FACTORED;
  m_sluOptions.IterRefine = NOREFINE;

  m_sluFerr.resize(rhsCols);
  m_sluBerr.resize(rhsCols);

  Ref<const Matrix<typename Rhs::Scalar, Dynamic, Dynamic, ColMajor> > b_ref(b);
  Ref<const Matrix<typename Dest::Scalar, Dynamic, Dynamic, ColMajor> > x_ref(x);

  m_sluB = SluMatrix::Map(b_ref.const_cast_derived());
  m_sluX = SluMatrix::Map(x_ref.const_cast_derived());

  typename Rhs::PlainObject b_cpy;
  if (m_sluEqued != 'N') {
    b_cpy = b;
    m_sluB = SluMatrix::Map(b_cpy.const_cast_derived());
  }

  StatInit(&m_sluStat);
  int info = 0;
  RealScalar recip_pivot_growth, rcond;
  SuperLU_gssvx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
                &m_sluCscale[0], &m_sluL, &m_sluU, NULL, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond,
                &m_sluFerr[0], &m_sluBerr[0], &m_sluStat, &info, Scalar());
  StatFree(&m_sluStat);

  if (x.derived().data() != x_ref.data()) x = x_ref;

  m_info = info == 0 ? Success : NumericalIssue;
}

// the code of this extractData() function has been adapted from the SuperLU's Matlab support code,
//
//  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
//
//  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
//  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
//
template <typename MatrixType, typename Derived>
void SuperLUBase<MatrixType, Derived>::extractData() const {
  eigen_assert(m_factorizationIsOk &&
               "The decomposition is not in a valid state for extracting factors, you must first call either compute() "
               "or analyzePattern()/factorize()");
  if (m_extractedDataAreDirty) {
    int upper;
    int fsupc, istart, nsupr;
    int lastl = 0, lastu = 0;
    SCformat *Lstore = static_cast<SCformat *>(m_sluL.Store);
    NCformat *Ustore = static_cast<NCformat *>(m_sluU.Store);
    Scalar *SNptr;

    const Index size = m_matrix.rows();
    m_l.resize(size, size);
    m_l.resizeNonZeros(Lstore->nnz);
    m_u.resize(size, size);
    m_u.resizeNonZeros(Ustore->nnz);

    int *Lcol = m_l.outerIndexPtr();
    int *Lrow = m_l.innerIndexPtr();
    Scalar *Lval = m_l.valuePtr();

    int *Ucol = m_u.outerIndexPtr();
    int *Urow = m_u.innerIndexPtr();
    Scalar *Uval = m_u.valuePtr();

    Ucol[0] = 0;
    Ucol[0] = 0;

    /* for each supernode */
    for (int k = 0; k <= Lstore->nsuper; ++k) {
      fsupc = L_FST_SUPC(k);
      istart = L_SUB_START(fsupc);
      nsupr = L_SUB_START(fsupc + 1) - istart;
      upper = 1;

      /* for each column in the supernode */
      for (int j = fsupc; j < L_FST_SUPC(k + 1); ++j) {
        SNptr = &((Scalar *)Lstore->nzval)[L_NZ_START(j)];

        /* Extract U */
        for (int i = U_NZ_START(j); i < U_NZ_START(j + 1); ++i) {
          Uval[lastu] = ((Scalar *)Ustore->nzval)[i];
          /* Matlab doesn't like explicit zero. */
          if (Uval[lastu] != 0.0) Urow[lastu++] = U_SUB(i);
        }
        for (int i = 0; i < upper; ++i) {
          /* upper triangle in the supernode */
          Uval[lastu] = SNptr[i];
          /* Matlab doesn't like explicit zero. */
          if (Uval[lastu] != 0.0) Urow[lastu++] = L_SUB(istart + i);
        }
        Ucol[j + 1] = lastu;

        /* Extract L */
        Lval[lastl] = 1.0; /* unit diagonal */
        Lrow[lastl++] = L_SUB(istart + upper - 1);
        for (int i = upper; i < nsupr; ++i) {
          Lval[lastl] = SNptr[i];
          /* Matlab doesn't like explicit zero. */
          if (Lval[lastl] != 0.0) Lrow[lastl++] = L_SUB(istart + i);
        }
        Lcol[j + 1] = lastl;

        ++upper;
      } /* for j ... */

    } /* for k ... */

    // squeeze the matrices :
    m_l.resizeNonZeros(lastl);
    m_u.resizeNonZeros(lastu);

    m_extractedDataAreDirty = false;
  }
}

template <typename MatrixType>
typename SuperLU<MatrixType>::Scalar SuperLU<MatrixType>::determinant() const {
  eigen_assert(m_factorizationIsOk &&
               "The decomposition is not in a valid state for computing the determinant, you must first call either "
               "compute() or analyzePattern()/factorize()");

  if (m_extractedDataAreDirty) this->extractData();

  Scalar det = Scalar(1);
  for (int j = 0; j < m_u.cols(); ++j) {
    if (m_u.outerIndexPtr()[j + 1] - m_u.outerIndexPtr()[j] > 0) {
      int lastId = m_u.outerIndexPtr()[j + 1] - 1;
      eigen_assert(m_u.innerIndexPtr()[lastId] <= j);
      if (m_u.innerIndexPtr()[lastId] == j) det *= m_u.valuePtr()[lastId];
    }
  }
  if (PermutationMap(m_p.data(), m_p.size()).determinant() * PermutationMap(m_q.data(), m_q.size()).determinant() < 0)
    det = -det;
  if (m_sluEqued != 'N')
    return det / m_sluRscale.prod() / m_sluCscale.prod();
  else
    return det;
}

#ifdef EIGEN_PARSED_BY_DOXYGEN
#define EIGEN_SUPERLU_HAS_ILU
#endif

#ifdef EIGEN_SUPERLU_HAS_ILU

/** \ingroup SuperLUSupport_Module
 * \class SuperILU
 * \brief A sparse direct \b incomplete LU factorization and solver based on the SuperLU library
 *
 * This class allows to solve for an approximate solution of A.X = B sparse linear problems via an incomplete LU
 * factorization using the SuperLU library. This class is aimed to be used as a preconditioner of the iterative linear
 * solvers.
 *
 * \warning This class is only for the 4.x versions of SuperLU. The 3.x and 5.x versions are not supported.
 *
 * \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
 *
 * \implsparsesolverconcept
 *
 * \sa \ref TutorialSparseSolverConcept, class IncompleteLUT, class ConjugateGradient, class BiCGSTAB
 */

template <typename MatrixType_>
class SuperILU : public SuperLUBase<MatrixType_, SuperILU<MatrixType_> > {
 public:
  typedef SuperLUBase<MatrixType_, SuperILU> Base;
  typedef MatrixType_ MatrixType;
  typedef typename Base::Scalar Scalar;
  typedef typename Base::RealScalar RealScalar;

 public:
  using Base::_solve_impl;

  SuperILU() : Base() { init(); }

  SuperILU(const MatrixType &matrix) : Base() {
    init();
    Base::compute(matrix);
  }

  ~SuperILU() {}

  /** Performs a symbolic decomposition on the sparsity of \a matrix.
   *
   * This function is particularly useful when solving for several problems having the same structure.
   *
   * \sa factorize()
   */
  void analyzePattern(const MatrixType &matrix) { Base::analyzePattern(matrix); }

  /** Performs a numeric decomposition of \a matrix
   *
   * The given matrix must have the same sparsity as the matrix on which the symbolic decomposition has been
   * performed.
   *
   * \sa analyzePattern()
   */
  void factorize(const MatrixType &matrix);

#ifndef EIGEN_PARSED_BY_DOXYGEN
  /** \internal */
  template <typename Rhs, typename Dest>
  void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const;
#endif  // EIGEN_PARSED_BY_DOXYGEN

 protected:
  using Base::m_l;
  using Base::m_matrix;
  using Base::m_p;
  using Base::m_q;
  using Base::m_sluA;
  using Base::m_sluB;
  using Base::m_sluBerr;
  using Base::m_sluCscale;
  using Base::m_sluEqued;
  using Base::m_sluEtree;
  using Base::m_sluFerr;
  using Base::m_sluL;
  using Base::m_sluOptions;
  using Base::m_sluRscale;
  using Base::m_sluStat;
  using Base::m_sluU;
  using Base::m_sluX;
  using Base::m_u;

  using Base::m_analysisIsOk;
  using Base::m_extractedDataAreDirty;
  using Base::m_factorizationIsOk;
  using Base::m_info;
  using Base::m_isInitialized;

  void init() {
    Base::init();

    ilu_set_default_options(&m_sluOptions);
    m_sluOptions.PrintStat = NO;
    m_sluOptions.ConditionNumber = NO;
    m_sluOptions.Trans = NOTRANS;
    m_sluOptions.ColPerm = MMD_AT_PLUS_A;

    // no attempt to preserve column sum
    m_sluOptions.ILU_MILU = SILU;
    // only basic ILU(k) support -- no direct control over memory consumption
    // better to use ILU_DropRule = DROP_BASIC | DROP_AREA
    // and set ILU_FillFactor to max memory growth
    m_sluOptions.ILU_DropRule = DROP_BASIC;
    m_sluOptions.ILU_DropTol = NumTraits<Scalar>::dummy_precision() * 10;
  }

 private:
  SuperILU(SuperILU &) {}
};

template <typename MatrixType>
void SuperILU<MatrixType>::factorize(const MatrixType &a) {
  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
  if (!m_analysisIsOk) {
    m_info = InvalidInput;
    return;
  }

  this->initFactorization(a);

  int info = 0;
  RealScalar recip_pivot_growth, rcond;

  StatInit(&m_sluStat);
  SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
                &m_sluCscale[0], &m_sluL, &m_sluU, NULL, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond, &m_sluStat,
                &info, Scalar());
  StatFree(&m_sluStat);

  // FIXME: implement more detailed error checking based on SuperLU info codes.
  m_info = info == 0 ? Success : NumericalIssue;
  m_factorizationIsOk = true;
}

#ifndef EIGEN_PARSED_BY_DOXYGEN
template <typename MatrixType>
template <typename Rhs, typename Dest>
void SuperILU<MatrixType>::_solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &x) const {
  eigen_assert(m_factorizationIsOk &&
               "The decomposition is not in a valid state for solving, you must first call either compute() or "
               "analyzePattern()/factorize()");

  const int rhsCols = b.cols();
  eigen_assert(m_matrix.rows() == b.rows());

  m_sluOptions.Trans = NOTRANS;
  m_sluOptions.Fact = FACTORED;
  m_sluOptions.IterRefine = NOREFINE;

  m_sluFerr.resize(rhsCols);
  m_sluBerr.resize(rhsCols);

  Ref<const Matrix<typename Rhs::Scalar, Dynamic, Dynamic, ColMajor> > b_ref(b);
  Ref<const Matrix<typename Dest::Scalar, Dynamic, Dynamic, ColMajor> > x_ref(x);

  m_sluB = SluMatrix::Map(b_ref.const_cast_derived());
  m_sluX = SluMatrix::Map(x_ref.const_cast_derived());

  typename Rhs::PlainObject b_cpy;
  if (m_sluEqued != 'N') {
    b_cpy = b;
    m_sluB = SluMatrix::Map(b_cpy.const_cast_derived());
  }

  int info = 0;
  RealScalar recip_pivot_growth, rcond;

  StatInit(&m_sluStat);
  SuperLU_gsisx(&m_sluOptions, &m_sluA, m_q.data(), m_p.data(), &m_sluEtree[0], &m_sluEqued, &m_sluRscale[0],
                &m_sluCscale[0], &m_sluL, &m_sluU, NULL, 0, &m_sluB, &m_sluX, &recip_pivot_growth, &rcond, &m_sluStat,
                &info, Scalar());
  StatFree(&m_sluStat);

  if (x.derived().data() != x_ref.data()) x = x_ref;

  m_info = info == 0 ? Success : NumericalIssue;
}
#endif

#endif

}  // end namespace Eigen

#endif  // EIGEN_SUPERLUSUPPORT_H
