// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2011 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/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_UMFPACKSUPPORT_H
#define EIGEN_UMFPACKSUPPORT_H

// for compatibility with super old version of umfpack,
// This may not be strictly needed, but it is harmless.
#ifndef SuiteSparse_long
#ifdef UF_long
#define SuiteSparse_long UF_long
#else
#error neither SuiteSparse_long nor UF_long are defined
#endif
#endif

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

namespace Eigen {

/* TODO extract L, extract U, compute det, etc... */

// generic double/complex<double> wrapper functions:

// Defaults
inline void umfpack_defaults(double control[UMFPACK_CONTROL], double, int) { umfpack_di_defaults(control); }

inline void umfpack_defaults(double control[UMFPACK_CONTROL], std::complex<double>, int) {
  umfpack_zi_defaults(control);
}

inline void umfpack_defaults(double control[UMFPACK_CONTROL], double, SuiteSparse_long) {
  umfpack_dl_defaults(control);
}

inline void umfpack_defaults(double control[UMFPACK_CONTROL], std::complex<double>, SuiteSparse_long) {
  umfpack_zl_defaults(control);
}

// Report info
inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], double, int) {
  umfpack_di_report_info(control, info);
}

inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], std::complex<double>, int) {
  umfpack_zi_report_info(control, info);
}

inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], double, SuiteSparse_long) {
  umfpack_dl_report_info(control, info);
}

inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], std::complex<double>,
                                SuiteSparse_long) {
  umfpack_zl_report_info(control, info);
}

// Report status
inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, double, int) {
  umfpack_di_report_status(control, status);
}

inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, std::complex<double>, int) {
  umfpack_zi_report_status(control, status);
}

inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, double, SuiteSparse_long) {
  umfpack_dl_report_status(control, status);
}

inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, std::complex<double>, SuiteSparse_long) {
  umfpack_zl_report_status(control, status);
}

// report control
inline void umfpack_report_control(double control[UMFPACK_CONTROL], double, int) { umfpack_di_report_control(control); }

inline void umfpack_report_control(double control[UMFPACK_CONTROL], std::complex<double>, int) {
  umfpack_zi_report_control(control);
}

inline void umfpack_report_control(double control[UMFPACK_CONTROL], double, SuiteSparse_long) {
  umfpack_dl_report_control(control);
}

inline void umfpack_report_control(double control[UMFPACK_CONTROL], std::complex<double>, SuiteSparse_long) {
  umfpack_zl_report_control(control);
}

// Free numeric
inline void umfpack_free_numeric(void **Numeric, double, int) {
  umfpack_di_free_numeric(Numeric);
  *Numeric = 0;
}

inline void umfpack_free_numeric(void **Numeric, std::complex<double>, int) {
  umfpack_zi_free_numeric(Numeric);
  *Numeric = 0;
}

inline void umfpack_free_numeric(void **Numeric, double, SuiteSparse_long) {
  umfpack_dl_free_numeric(Numeric);
  *Numeric = 0;
}

inline void umfpack_free_numeric(void **Numeric, std::complex<double>, SuiteSparse_long) {
  umfpack_zl_free_numeric(Numeric);
  *Numeric = 0;
}

// Free symbolic
inline void umfpack_free_symbolic(void **Symbolic, double, int) {
  umfpack_di_free_symbolic(Symbolic);
  *Symbolic = 0;
}

inline void umfpack_free_symbolic(void **Symbolic, std::complex<double>, int) {
  umfpack_zi_free_symbolic(Symbolic);
  *Symbolic = 0;
}

inline void umfpack_free_symbolic(void **Symbolic, double, SuiteSparse_long) {
  umfpack_dl_free_symbolic(Symbolic);
  *Symbolic = 0;
}

inline void umfpack_free_symbolic(void **Symbolic, std::complex<double>, SuiteSparse_long) {
  umfpack_zl_free_symbolic(Symbolic);
  *Symbolic = 0;
}

// Symbolic
inline int umfpack_symbolic(int n_row, int n_col, const int Ap[], const int Ai[], const double Ax[], void **Symbolic,
                            const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_di_symbolic(n_row, n_col, Ap, Ai, Ax, Symbolic, Control, Info);
}

inline int umfpack_symbolic(int n_row, int n_col, const int Ap[], const int Ai[], const std::complex<double> Ax[],
                            void **Symbolic, const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_zi_symbolic(n_row, n_col, Ap, Ai, &numext::real_ref(Ax[0]), 0, Symbolic, Control, Info);
}
inline SuiteSparse_long umfpack_symbolic(SuiteSparse_long n_row, SuiteSparse_long n_col, const SuiteSparse_long Ap[],
                                         const SuiteSparse_long Ai[], const double Ax[], void **Symbolic,
                                         const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_dl_symbolic(n_row, n_col, Ap, Ai, Ax, Symbolic, Control, Info);
}

inline SuiteSparse_long umfpack_symbolic(SuiteSparse_long n_row, SuiteSparse_long n_col, const SuiteSparse_long Ap[],
                                         const SuiteSparse_long Ai[], const std::complex<double> Ax[], void **Symbolic,
                                         const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_zl_symbolic(n_row, n_col, Ap, Ai, &numext::real_ref(Ax[0]), 0, Symbolic, Control, Info);
}

// Numeric
inline int umfpack_numeric(const int Ap[], const int Ai[], const double Ax[], void *Symbolic, void **Numeric,
                           const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_di_numeric(Ap, Ai, Ax, Symbolic, Numeric, Control, Info);
}

inline int umfpack_numeric(const int Ap[], const int Ai[], const std::complex<double> Ax[], void *Symbolic,
                           void **Numeric, const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_zi_numeric(Ap, Ai, &numext::real_ref(Ax[0]), 0, Symbolic, Numeric, Control, Info);
}
inline SuiteSparse_long umfpack_numeric(const SuiteSparse_long Ap[], const SuiteSparse_long Ai[], const double Ax[],
                                        void *Symbolic, void **Numeric, const double Control[UMFPACK_CONTROL],
                                        double Info[UMFPACK_INFO]) {
  return umfpack_dl_numeric(Ap, Ai, Ax, Symbolic, Numeric, Control, Info);
}

inline SuiteSparse_long umfpack_numeric(const SuiteSparse_long Ap[], const SuiteSparse_long Ai[],
                                        const std::complex<double> Ax[], void *Symbolic, void **Numeric,
                                        const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_zl_numeric(Ap, Ai, &numext::real_ref(Ax[0]), 0, Symbolic, Numeric, Control, Info);
}

// solve
inline int umfpack_solve(int sys, const int Ap[], const int Ai[], const double Ax[], double X[], const double B[],
                         void *Numeric, const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_di_solve(sys, Ap, Ai, Ax, X, B, Numeric, Control, Info);
}

inline int umfpack_solve(int sys, const int Ap[], const int Ai[], const std::complex<double> Ax[],
                         std::complex<double> X[], const std::complex<double> B[], void *Numeric,
                         const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_zi_solve(sys, Ap, Ai, &numext::real_ref(Ax[0]), 0, &numext::real_ref(X[0]), 0, &numext::real_ref(B[0]),
                          0, Numeric, Control, Info);
}

inline SuiteSparse_long umfpack_solve(int sys, const SuiteSparse_long Ap[], const SuiteSparse_long Ai[],
                                      const double Ax[], double X[], const double B[], void *Numeric,
                                      const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_dl_solve(sys, Ap, Ai, Ax, X, B, Numeric, Control, Info);
}

inline SuiteSparse_long umfpack_solve(int sys, const SuiteSparse_long Ap[], const SuiteSparse_long Ai[],
                                      const std::complex<double> Ax[], std::complex<double> X[],
                                      const std::complex<double> B[], void *Numeric,
                                      const double Control[UMFPACK_CONTROL], double Info[UMFPACK_INFO]) {
  return umfpack_zl_solve(sys, Ap, Ai, &numext::real_ref(Ax[0]), 0, &numext::real_ref(X[0]), 0, &numext::real_ref(B[0]),
                          0, Numeric, Control, Info);
}

// Get Lunz
inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric, double) {
  return umfpack_di_get_lunz(lnz, unz, n_row, n_col, nz_udiag, Numeric);
}

inline int umfpack_get_lunz(int *lnz, int *unz, int *n_row, int *n_col, int *nz_udiag, void *Numeric,
                            std::complex<double>) {
  return umfpack_zi_get_lunz(lnz, unz, n_row, n_col, nz_udiag, Numeric);
}

inline SuiteSparse_long umfpack_get_lunz(SuiteSparse_long *lnz, SuiteSparse_long *unz, SuiteSparse_long *n_row,
                                         SuiteSparse_long *n_col, SuiteSparse_long *nz_udiag, void *Numeric, double) {
  return umfpack_dl_get_lunz(lnz, unz, n_row, n_col, nz_udiag, Numeric);
}

inline SuiteSparse_long umfpack_get_lunz(SuiteSparse_long *lnz, SuiteSparse_long *unz, SuiteSparse_long *n_row,
                                         SuiteSparse_long *n_col, SuiteSparse_long *nz_udiag, void *Numeric,
                                         std::complex<double>) {
  return umfpack_zl_get_lunz(lnz, unz, n_row, n_col, nz_udiag, Numeric);
}

// Get Numeric
inline int umfpack_get_numeric(int Lp[], int Lj[], double Lx[], int Up[], int Ui[], double Ux[], int P[], int Q[],
                               double Dx[], int *do_recip, double Rs[], void *Numeric) {
  return umfpack_di_get_numeric(Lp, Lj, Lx, Up, Ui, Ux, P, Q, Dx, do_recip, Rs, Numeric);
}

inline int umfpack_get_numeric(int Lp[], int Lj[], std::complex<double> Lx[], int Up[], int Ui[],
                               std::complex<double> Ux[], int P[], int Q[], std::complex<double> Dx[], int *do_recip,
                               double Rs[], void *Numeric) {
  double &lx0_real = numext::real_ref(Lx[0]);
  double &ux0_real = numext::real_ref(Ux[0]);
  double &dx0_real = numext::real_ref(Dx[0]);
  return umfpack_zi_get_numeric(Lp, Lj, Lx ? &lx0_real : 0, 0, Up, Ui, Ux ? &ux0_real : 0, 0, P, Q, Dx ? &dx0_real : 0,
                                0, do_recip, Rs, Numeric);
}
inline SuiteSparse_long umfpack_get_numeric(SuiteSparse_long Lp[], SuiteSparse_long Lj[], double Lx[],
                                            SuiteSparse_long Up[], SuiteSparse_long Ui[], double Ux[],
                                            SuiteSparse_long P[], SuiteSparse_long Q[], double Dx[],
                                            SuiteSparse_long *do_recip, double Rs[], void *Numeric) {
  return umfpack_dl_get_numeric(Lp, Lj, Lx, Up, Ui, Ux, P, Q, Dx, do_recip, Rs, Numeric);
}

inline SuiteSparse_long umfpack_get_numeric(SuiteSparse_long Lp[], SuiteSparse_long Lj[], std::complex<double> Lx[],
                                            SuiteSparse_long Up[], SuiteSparse_long Ui[], std::complex<double> Ux[],
                                            SuiteSparse_long P[], SuiteSparse_long Q[], std::complex<double> Dx[],
                                            SuiteSparse_long *do_recip, double Rs[], void *Numeric) {
  double &lx0_real = numext::real_ref(Lx[0]);
  double &ux0_real = numext::real_ref(Ux[0]);
  double &dx0_real = numext::real_ref(Dx[0]);
  return umfpack_zl_get_numeric(Lp, Lj, Lx ? &lx0_real : 0, 0, Up, Ui, Ux ? &ux0_real : 0, 0, P, Q, Dx ? &dx0_real : 0,
                                0, do_recip, Rs, Numeric);
}

// Get Determinant
inline int umfpack_get_determinant(double *Mx, double *Ex, void *NumericHandle, double User_Info[UMFPACK_INFO], int) {
  return umfpack_di_get_determinant(Mx, Ex, NumericHandle, User_Info);
}

inline int umfpack_get_determinant(std::complex<double> *Mx, double *Ex, void *NumericHandle,
                                   double User_Info[UMFPACK_INFO], int) {
  double &mx_real = numext::real_ref(*Mx);
  return umfpack_zi_get_determinant(&mx_real, 0, Ex, NumericHandle, User_Info);
}

inline SuiteSparse_long umfpack_get_determinant(double *Mx, double *Ex, void *NumericHandle,
                                                double User_Info[UMFPACK_INFO], SuiteSparse_long) {
  return umfpack_dl_get_determinant(Mx, Ex, NumericHandle, User_Info);
}

inline SuiteSparse_long umfpack_get_determinant(std::complex<double> *Mx, double *Ex, void *NumericHandle,
                                                double User_Info[UMFPACK_INFO], SuiteSparse_long) {
  double &mx_real = numext::real_ref(*Mx);
  return umfpack_zl_get_determinant(&mx_real, 0, Ex, NumericHandle, User_Info);
}

/** \ingroup UmfPackSupport_Module
 * \brief A sparse LU factorization and solver based on UmfPack
 *
 * This class allows to solve for A.X = B sparse linear problems via a LU factorization
 * using the UmfPack library. The sparse matrix A must be square and full rank.
 * The vectors or matrices X and B can be either dense or sparse.
 *
 * \warning The input matrix A should be in a \b compressed and \b column-major form.
 * Otherwise an expensive copy will be made. You can call the inexpensive makeCompressed() to get a compressed matrix.
 * \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
 *
 * \implsparsesolverconcept
 *
 * \sa \ref TutorialSparseSolverConcept, class SparseLU
 */
template <typename MatrixType_>
class UmfPackLU : public SparseSolverBase<UmfPackLU<MatrixType_> > {
 protected:
  typedef SparseSolverBase<UmfPackLU<MatrixType_> > Base;
  using Base::m_isInitialized;

 public:
  using Base::_solve_impl;
  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 SparseMatrix<Scalar> LUMatrixType;
  typedef SparseMatrix<Scalar, ColMajor, StorageIndex> UmfpackMatrixType;
  typedef Ref<const UmfpackMatrixType, StandardCompressedFormat> UmfpackMatrixRef;
  enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };

 public:
  typedef Array<double, UMFPACK_CONTROL, 1> UmfpackControl;
  typedef Array<double, UMFPACK_INFO, 1> UmfpackInfo;

  UmfPackLU() : m_dummy(0, 0), mp_matrix(m_dummy) { init(); }

  template <typename InputMatrixType>
  explicit UmfPackLU(const InputMatrixType &matrix) : mp_matrix(matrix) {
    init();
    compute(matrix);
  }

  ~UmfPackLU() {
    if (m_symbolic) umfpack_free_symbolic(&m_symbolic, Scalar(), StorageIndex());
    if (m_numeric) umfpack_free_numeric(&m_numeric, Scalar(), StorageIndex());
  }

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

  /** \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;
  }

  inline const LUMatrixType &matrixL() const {
    if (m_extractedDataAreDirty) extractData();
    return m_l;
  }

  inline const LUMatrixType &matrixU() const {
    if (m_extractedDataAreDirty) extractData();
    return m_u;
  }

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

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

  /** Computes the sparse LU decomposition of \a matrix
   *  Note that the matrix should be column-major, and in compressed format for best performance.
   *  \sa SparseMatrix::makeCompressed().
   */
  template <typename InputMatrixType>
  void compute(const InputMatrixType &matrix) {
    if (m_symbolic) umfpack_free_symbolic(&m_symbolic, Scalar(), StorageIndex());
    if (m_numeric) umfpack_free_numeric(&m_numeric, Scalar(), StorageIndex());
    grab(matrix.derived());
    analyzePattern_impl();
    factorize_impl();
  }

  /** 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(), compute()
   */
  template <typename InputMatrixType>
  void analyzePattern(const InputMatrixType &matrix) {
    if (m_symbolic) umfpack_free_symbolic(&m_symbolic, Scalar(), StorageIndex());
    if (m_numeric) umfpack_free_numeric(&m_numeric, Scalar(), StorageIndex());

    grab(matrix.derived());

    analyzePattern_impl();
  }

  /** Provides the return status code returned by UmfPack during the numeric
   * factorization.
   *
   * \sa factorize(), compute()
   */
  inline int umfpackFactorizeReturncode() const {
    eigen_assert(m_numeric && "UmfPackLU: you must first call factorize()");
    return m_fact_errorCode;
  }

  /** Provides access to the control settings array used by UmfPack.
   *
   * If this array contains NaN's, the default values are used.
   *
   * See UMFPACK documentation for details.
   */
  inline const UmfpackControl &umfpackControl() const { return m_control; }

  /** Provides access to the control settings array used by UmfPack.
   *
   * If this array contains NaN's, the default values are used.
   *
   * See UMFPACK documentation for details.
   */
  inline UmfpackControl &umfpackControl() { return m_control; }

  /** Performs a numeric decomposition of \a matrix
   *
   * The given matrix must have the same sparsity as the matrix on which the pattern analysis has been performed.
   *
   * \sa analyzePattern(), compute()
   */
  template <typename InputMatrixType>
  void factorize(const InputMatrixType &matrix) {
    eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
    if (m_numeric) umfpack_free_numeric(&m_numeric, Scalar(), StorageIndex());

    grab(matrix.derived());

    factorize_impl();
  }

  /** Prints the current UmfPack control settings.
   *
   * \sa umfpackControl()
   */
  void printUmfpackControl() { umfpack_report_control(m_control.data(), Scalar(), StorageIndex()); }

  /** Prints statistics collected by UmfPack.
   *
   * \sa analyzePattern(), compute()
   */
  void printUmfpackInfo() {
    eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
    umfpack_report_info(m_control.data(), m_umfpackInfo.data(), Scalar(), StorageIndex());
  }

  /** Prints the status of the previous factorization operation performed by UmfPack (symbolic or numerical
   * factorization).
   *
   * \sa analyzePattern(), compute()
   */
  void printUmfpackStatus() {
    eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
    umfpack_report_status(m_control.data(), m_fact_errorCode, Scalar(), StorageIndex());
  }

  /** \internal */
  template <typename BDerived, typename XDerived>
  bool _solve_impl(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const;

  Scalar determinant() const;

  void extractData() const;

 protected:
  void init() {
    m_info = InvalidInput;
    m_isInitialized = false;
    m_numeric = 0;
    m_symbolic = 0;
    m_extractedDataAreDirty = true;

    umfpack_defaults(m_control.data(), Scalar(), StorageIndex());
  }

  void analyzePattern_impl() {
    m_fact_errorCode = umfpack_symbolic(internal::convert_index<StorageIndex>(mp_matrix.rows()),
                                        internal::convert_index<StorageIndex>(mp_matrix.cols()),
                                        mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
                                        &m_symbolic, m_control.data(), m_umfpackInfo.data());

    m_isInitialized = true;
    m_info = m_fact_errorCode ? InvalidInput : Success;
    m_analysisIsOk = true;
    m_factorizationIsOk = false;
    m_extractedDataAreDirty = true;
  }

  void factorize_impl() {
    m_fact_errorCode = umfpack_numeric(mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
                                       m_symbolic, &m_numeric, m_control.data(), m_umfpackInfo.data());

    m_info = m_fact_errorCode == UMFPACK_OK ? Success : NumericalIssue;
    m_factorizationIsOk = true;
    m_extractedDataAreDirty = true;
  }

  template <typename MatrixDerived>
  void grab(const EigenBase<MatrixDerived> &A) {
    internal::destroy_at(&mp_matrix);
    internal::construct_at(&mp_matrix, A.derived());
  }

  void grab(const UmfpackMatrixRef &A) {
    if (&(A.derived()) != &mp_matrix) {
      internal::destroy_at(&mp_matrix);
      internal::construct_at(&mp_matrix, A);
    }
  }

  // cached data to reduce reallocation, etc.
  mutable LUMatrixType m_l;
  StorageIndex m_fact_errorCode;
  UmfpackControl m_control;
  mutable UmfpackInfo m_umfpackInfo;

  mutable LUMatrixType m_u;
  mutable IntColVectorType m_p;
  mutable IntRowVectorType m_q;

  UmfpackMatrixType m_dummy;
  UmfpackMatrixRef mp_matrix;

  void *m_numeric;
  void *m_symbolic;

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

 private:
  UmfPackLU(const UmfPackLU &) {}
};

template <typename MatrixType>
void UmfPackLU<MatrixType>::extractData() const {
  if (m_extractedDataAreDirty) {
    // get size of the data
    StorageIndex lnz, unz, rows, cols, nz_udiag;
    umfpack_get_lunz(&lnz, &unz, &rows, &cols, &nz_udiag, m_numeric, Scalar());

    // allocate data
    m_l.resize(rows, (std::min)(rows, cols));
    m_l.resizeNonZeros(lnz);

    m_u.resize((std::min)(rows, cols), cols);
    m_u.resizeNonZeros(unz);

    m_p.resize(rows);
    m_q.resize(cols);

    // extract
    umfpack_get_numeric(m_l.outerIndexPtr(), m_l.innerIndexPtr(), m_l.valuePtr(), m_u.outerIndexPtr(),
                        m_u.innerIndexPtr(), m_u.valuePtr(), m_p.data(), m_q.data(), 0, 0, 0, m_numeric);

    m_extractedDataAreDirty = false;
  }
}

template <typename MatrixType>
typename UmfPackLU<MatrixType>::Scalar UmfPackLU<MatrixType>::determinant() const {
  Scalar det;
  umfpack_get_determinant(&det, 0, m_numeric, 0, StorageIndex());
  return det;
}

template <typename MatrixType>
template <typename BDerived, typename XDerived>
bool UmfPackLU<MatrixType>::_solve_impl(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const {
  Index rhsCols = b.cols();
  eigen_assert((BDerived::Flags & RowMajorBit) == 0 && "UmfPackLU backend does not support non col-major rhs yet");
  eigen_assert((XDerived::Flags & RowMajorBit) == 0 && "UmfPackLU backend does not support non col-major result yet");
  eigen_assert(b.derived().data() != x.derived().data() && " Umfpack does not support inplace solve");

  Scalar *x_ptr = 0;
  Matrix<Scalar, Dynamic, 1> x_tmp;
  if (x.innerStride() != 1) {
    x_tmp.resize(x.rows());
    x_ptr = x_tmp.data();
  }
  for (int j = 0; j < rhsCols; ++j) {
    if (x.innerStride() == 1) x_ptr = &x.col(j).coeffRef(0);
    StorageIndex errorCode =
        umfpack_solve(UMFPACK_A, mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(), x_ptr,
                      &b.const_cast_derived().col(j).coeffRef(0), m_numeric, m_control.data(), m_umfpackInfo.data());
    if (x.innerStride() != 1) x.col(j) = x_tmp;
    if (errorCode != 0) return false;
  }

  return true;
}

}  // end namespace Eigen

#endif  // EIGEN_UMFPACKSUPPORT_H
