// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.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_TEST_SPARSE_SOLVER_H
#define EIGEN_TEST_SPARSE_SOLVER_H

#include "sparse.h"
#include <Eigen/SparseCore>
#include <Eigen/SparseLU>
#include <sstream>

template <typename Solver, typename Rhs, typename Guess, typename Result>
void solve_with_guess(IterativeSolverBase<Solver>& solver, const MatrixBase<Rhs>& b, const Guess& g, Result& x) {
  if (internal::random<bool>()) {
    // With a temporary through evaluator<SolveWithGuess>
    x = solver.derived().solveWithGuess(b, g) + Result::Zero(x.rows(), x.cols());
  } else {
    // direct evaluation within x through Assignment<Result,SolveWithGuess>
    x = solver.derived().solveWithGuess(b.derived(), g);
  }
}

template <typename Solver, typename Rhs, typename Guess, typename Result>
void solve_with_guess(SparseSolverBase<Solver>& solver, const MatrixBase<Rhs>& b, const Guess&, Result& x) {
  if (internal::random<bool>())
    x = solver.derived().solve(b) + Result::Zero(x.rows(), x.cols());
  else
    x = solver.derived().solve(b);
}

template <typename Solver, typename Rhs, typename Guess, typename Result>
void solve_with_guess(SparseSolverBase<Solver>& solver, const SparseMatrixBase<Rhs>& b, const Guess&, Result& x) {
  x = solver.derived().solve(b);
}

template <typename Solver, typename Rhs, typename DenseMat, typename DenseRhs>
void check_sparse_solving(Solver& solver, const typename Solver::MatrixType& A, const Rhs& b, const DenseMat& dA,
                          const DenseRhs& db) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef typename Mat::StorageIndex StorageIndex;

  DenseRhs refX = dA.householderQr().solve(db);
  {
    Rhs x(A.cols(), b.cols());
    Rhs oldb = b;

    solver.compute(A);
    if (solver.info() != Success) {
      std::cerr << "ERROR | sparse solver testing, factorization failed (" << typeid(Solver).name() << ")\n";
      VERIFY(solver.info() == Success);
    }
    x = solver.solve(b);
    if (solver.info() != Success) {
      std::cerr << "WARNING: sparse solver testing: solving failed (" << typeid(Solver).name() << ")\n";
      // dump call stack:
      g_test_level++;
      VERIFY(solver.info() == Success);
      g_test_level--;
      return;
    }
    VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(x.isApprox(refX, test_precision<Scalar>()));

    x.setZero();
    solve_with_guess(solver, b, x, x);
    VERIFY(solver.info() == Success && "solving failed when using solve_with_guess API");
    VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(x.isApprox(refX, test_precision<Scalar>()));

    x.setZero();
    // test the analyze/factorize API
    solver.analyzePattern(A);
    solver.factorize(A);
    VERIFY(solver.info() == Success && "factorization failed when using analyzePattern/factorize API");
    x = solver.solve(b);
    VERIFY(solver.info() == Success && "solving failed when using analyzePattern/factorize API");
    VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(x.isApprox(refX, test_precision<Scalar>()));

    x.setZero();
    // test with Map
    Map<SparseMatrix<Scalar, Mat::Options, StorageIndex>> Am(
        A.rows(), A.cols(), A.nonZeros(), const_cast<StorageIndex*>(A.outerIndexPtr()),
        const_cast<StorageIndex*>(A.innerIndexPtr()), const_cast<Scalar*>(A.valuePtr()));
    solver.compute(Am);
    VERIFY(solver.info() == Success && "factorization failed when using Map");
    DenseRhs dx(refX);
    dx.setZero();
    Map<DenseRhs> xm(dx.data(), dx.rows(), dx.cols());
    Map<const DenseRhs> bm(db.data(), db.rows(), db.cols());
    xm = solver.solve(bm);
    VERIFY(solver.info() == Success && "solving failed when using Map");
    VERIFY(oldb.isApprox(bm) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(xm.isApprox(refX, test_precision<Scalar>()));

    // Test with a Map and non-unit stride.
    Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> out(2 * xm.rows(), 2 * xm.cols());
    out.setZero();
    Eigen::Map<DenseRhs, 0, Stride<Eigen::Dynamic, 2>> outm(out.data(), xm.rows(), xm.cols(),
                                                            Stride<Eigen::Dynamic, 2>(2 * xm.rows(), 2));
    outm = solver.solve(bm);
    VERIFY(outm.isApprox(refX, test_precision<Scalar>()));
  }

  // if not too large, do some extra check:
  if (A.rows() < 2000) {
    // test initialization ctor
    {
      Rhs x(b.rows(), b.cols());
      Solver solver2(A);
      VERIFY(solver2.info() == Success);
      x = solver2.solve(b);
      VERIFY(x.isApprox(refX, test_precision<Scalar>()));
    }

    // test dense Block as the result and rhs:
    {
      DenseRhs x(refX.rows(), refX.cols());
      DenseRhs oldb(db);
      x.setZero();
      x.block(0, 0, x.rows(), x.cols()) = solver.solve(db.block(0, 0, db.rows(), db.cols()));
      VERIFY(oldb.isApprox(db) && "sparse solver testing: the rhs should not be modified!");
      VERIFY(x.isApprox(refX, test_precision<Scalar>()));
    }

    // test uncompressed inputs
    {
      Mat A2 = A;
      A2.reserve((ArrayXf::Random(A.outerSize()) + 2).template cast<typename Mat::StorageIndex>().eval());
      solver.compute(A2);
      Rhs x = solver.solve(b);
      VERIFY(x.isApprox(refX, test_precision<Scalar>()));
    }

    // test expression as input
    {
      solver.compute(0.5 * (A + A));
      Rhs x = solver.solve(b);
      VERIFY(x.isApprox(refX, test_precision<Scalar>()));

      Solver solver2(0.5 * (A + A));
      Rhs x2 = solver2.solve(b);
      VERIFY(x2.isApprox(refX, test_precision<Scalar>()));
    }
  }
}

#endif  // EIGEN_TEST_SPARSE_SOLVER_H

// specialization of generic check_sparse_solving for SuperLU in order to also test adjoint and transpose solves
template <typename Scalar, typename Rhs, typename DenseMat, typename DenseRhs>
void check_sparse_solving(Eigen::SparseLU<Eigen::SparseMatrix<Scalar>>& solver,
                          const typename Eigen::SparseMatrix<Scalar>& A, const Rhs& b, const DenseMat& dA,
                          const DenseRhs& db) {
  typedef typename Eigen::SparseMatrix<Scalar> Mat;
  typedef typename Mat::StorageIndex StorageIndex;
  typedef typename Eigen::SparseLU<Eigen::SparseMatrix<Scalar>> Solver;

  // reference solutions computed by dense QR solver
  DenseRhs refX1 = dA.householderQr().solve(db);              // solution of A x = db
  DenseRhs refX2 = dA.transpose().householderQr().solve(db);  // solution of A^T * x = db (use transposed matrix A^T)
  DenseRhs refX3 = dA.adjoint().householderQr().solve(db);    // solution of A^* * x = db (use adjoint matrix A^*)

  {
    Rhs x1(A.cols(), b.cols());
    Rhs x2(A.cols(), b.cols());
    Rhs x3(A.cols(), b.cols());
    Rhs oldb = b;

    solver.compute(A);
    if (solver.info() != Success) {
      std::cerr << "ERROR | sparse solver testing, factorization failed (" << typeid(Solver).name() << ")\n";
      VERIFY(solver.info() == Success);
    }
    x1 = solver.solve(b);
    if (solver.info() != Success) {
      std::cerr << "WARNING | sparse solver testing: solving failed (" << typeid(Solver).name() << ")\n";
      return;
    }
    VERIFY(oldb.isApprox(b, 0.0) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(x1.isApprox(refX1, test_precision<Scalar>()));

    // test solve with transposed
    x2 = solver.transpose().solve(b);
    VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(x2.isApprox(refX2, test_precision<Scalar>()));

    // test solve with adjoint
    // solver.template _solve_impl_transposed<true>(b, x3);
    x3 = solver.adjoint().solve(b);
    VERIFY(oldb.isApprox(b, 0.0) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(x3.isApprox(refX3, test_precision<Scalar>()));

    x1.setZero();
    solve_with_guess(solver, b, x1, x1);
    VERIFY(solver.info() == Success && "solving failed when using analyzePattern/factorize API");
    VERIFY(oldb.isApprox(b, 0.0) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(x1.isApprox(refX1, test_precision<Scalar>()));

    x1.setZero();
    x2.setZero();
    x3.setZero();
    // test the analyze/factorize API
    solver.analyzePattern(A);
    solver.factorize(A);
    VERIFY(solver.info() == Success && "factorization failed when using analyzePattern/factorize API");
    x1 = solver.solve(b);
    x2 = solver.transpose().solve(b);
    x3 = solver.adjoint().solve(b);

    VERIFY(solver.info() == Success && "solving failed when using analyzePattern/factorize API");
    VERIFY(oldb.isApprox(b, 0.0) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(x1.isApprox(refX1, test_precision<Scalar>()));
    VERIFY(x2.isApprox(refX2, test_precision<Scalar>()));
    VERIFY(x3.isApprox(refX3, test_precision<Scalar>()));

    x1.setZero();
    // test with Map
    Map<SparseMatrix<Scalar, Mat::Options, StorageIndex>> Am(
        A.rows(), A.cols(), A.nonZeros(), const_cast<StorageIndex*>(A.outerIndexPtr()),
        const_cast<StorageIndex*>(A.innerIndexPtr()), const_cast<Scalar*>(A.valuePtr()));
    solver.compute(Am);
    VERIFY(solver.info() == Success && "factorization failed when using Map");
    DenseRhs dx(refX1);
    dx.setZero();
    Map<DenseRhs> xm(dx.data(), dx.rows(), dx.cols());
    Map<const DenseRhs> bm(db.data(), db.rows(), db.cols());
    xm = solver.solve(bm);
    VERIFY(solver.info() == Success && "solving failed when using Map");
    VERIFY(oldb.isApprox(bm, 0.0) && "sparse solver testing: the rhs should not be modified!");
    VERIFY(xm.isApprox(refX1, test_precision<Scalar>()));
  }

  // if not too large, do some extra check:
  if (A.rows() < 2000) {
    // test initialization ctor
    {
      Rhs x(b.rows(), b.cols());
      Solver solver2(A);
      VERIFY(solver2.info() == Success);
      x = solver2.solve(b);
      VERIFY(x.isApprox(refX1, test_precision<Scalar>()));
    }

    // test dense Block as the result and rhs:
    {
      DenseRhs x(refX1.rows(), refX1.cols());
      DenseRhs oldb(db);
      x.setZero();
      x.block(0, 0, x.rows(), x.cols()) = solver.solve(db.block(0, 0, db.rows(), db.cols()));
      VERIFY(oldb.isApprox(db, 0.0) && "sparse solver testing: the rhs should not be modified!");
      VERIFY(x.isApprox(refX1, test_precision<Scalar>()));
    }

    // test uncompressed inputs
    {
      Mat A2 = A;
      A2.reserve((ArrayXf::Random(A.outerSize()) + 2).template cast<typename Mat::StorageIndex>().eval());
      solver.compute(A2);
      Rhs x = solver.solve(b);
      VERIFY(x.isApprox(refX1, test_precision<Scalar>()));
    }

    // test expression as input
    {
      solver.compute(0.5 * (A + A));
      Rhs x = solver.solve(b);
      VERIFY(x.isApprox(refX1, test_precision<Scalar>()));

      Solver solver2(0.5 * (A + A));
      Rhs x2 = solver2.solve(b);
      VERIFY(x2.isApprox(refX1, test_precision<Scalar>()));
    }
  }
}

template <typename Solver, typename Rhs>
void check_sparse_solving_real_cases(Solver& solver, const typename Solver::MatrixType& A, const Rhs& b,
                                     const typename Solver::MatrixType& fullA, const Rhs& refX) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef typename Mat::RealScalar RealScalar;

  Rhs x(A.cols(), b.cols());

  solver.compute(A);
  if (solver.info() != Success) {
    std::cerr << "ERROR | sparse solver testing, factorization failed (" << typeid(Solver).name() << ")\n";
    VERIFY(solver.info() == Success);
  }
  x = solver.solve(b);

  if (solver.info() != Success) {
    std::cerr << "WARNING | sparse solver testing, solving failed (" << typeid(Solver).name() << ")\n";
    return;
  }

  RealScalar res_error = (fullA * x - b).norm() / b.norm();
  VERIFY((res_error <= test_precision<Scalar>()) && "sparse solver failed without noticing it");

  if (refX.size() != 0 && (refX - x).norm() / refX.norm() > test_precision<Scalar>()) {
    std::cerr << "WARNING | found solution is different from the provided reference one\n";
  }
}
template <typename Solver, typename DenseMat>
void check_sparse_determinant(Solver& solver, const typename Solver::MatrixType& A, const DenseMat& dA) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;

  solver.compute(A);
  if (solver.info() != Success) {
    std::cerr << "WARNING | sparse solver testing: factorization failed (check_sparse_determinant)\n";
    return;
  }

  Scalar refDet = dA.determinant();
  VERIFY_IS_APPROX(refDet, solver.determinant());
}
template <typename Solver, typename DenseMat>
void check_sparse_abs_determinant(Solver& solver, const typename Solver::MatrixType& A, const DenseMat& dA) {
  using std::abs;
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;

  solver.compute(A);
  if (solver.info() != Success) {
    std::cerr << "WARNING | sparse solver testing: factorization failed (check_sparse_abs_determinant)\n";
    return;
  }

  Scalar refDet = abs(dA.determinant());
  VERIFY_IS_APPROX(refDet, solver.absDeterminant());
}

template <typename Solver, typename DenseMat>
int generate_sparse_spd_problem(Solver&, typename Solver::MatrixType& A, typename Solver::MatrixType& halfA,
                                DenseMat& dA, int maxSize = 300) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;

  int size = internal::random<int>(1, maxSize);
  double density = (std::max)(8. / static_cast<double>(size * size), 0.01);

  Mat M(size, size);
  DenseMatrix dM(size, size);

  initSparse<Scalar>(density, dM, M, ForceNonZeroDiag);

  A = M * M.adjoint();
  dA = dM * dM.adjoint();

  halfA.resize(size, size);
  if (Solver::UpLo == (Lower | Upper))
    halfA = A;
  else
    halfA.template selfadjointView<Solver::UpLo>().rankUpdate(M);

  return size;
}

#ifdef TEST_REAL_CASES
template <typename Scalar>
inline std::string get_matrixfolder() {
  std::string mat_folder = TEST_REAL_CASES;
  if (std::is_same<Scalar, std::complex<float>>::value || std::is_same<Scalar, std::complex<double>>::value)
    mat_folder = mat_folder + static_cast<std::string>("/complex/");
  else
    mat_folder = mat_folder + static_cast<std::string>("/real/");
  return mat_folder;
}
std::string sym_to_string(int sym) {
  if (sym == Symmetric) return "Symmetric ";
  if (sym == SPD) return "SPD ";
  return "";
}
template <typename Derived>
std::string solver_stats(const IterativeSolverBase<Derived>& solver) {
  std::stringstream ss;
  ss << solver.iterations() << " iters, error: " << solver.error();
  return ss.str();
}
template <typename Derived>
std::string solver_stats(const SparseSolverBase<Derived>& /*solver*/) {
  return "";
}
#endif

template <typename Solver>
void check_sparse_spd_solving(Solver& solver, int maxSize = (std::min)(300, EIGEN_TEST_MAX_SIZE),
                              int maxRealWorldSize = 100000) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef typename Mat::StorageIndex StorageIndex;
  typedef SparseMatrix<Scalar, ColMajor, StorageIndex> SpMat;
  typedef SparseVector<Scalar, 0, StorageIndex> SpVec;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;
  typedef Matrix<Scalar, Dynamic, 1> DenseVector;

  // generate the problem
  Mat A, halfA;
  DenseMatrix dA;
  for (int i = 0; i < g_repeat; i++) {
    int size = generate_sparse_spd_problem(solver, A, halfA, dA, maxSize);

    // generate the right hand sides
    int rhsCols = internal::random<int>(1, 16);
    double density = (std::max)(8. / static_cast<double>(size * rhsCols), 0.1);
    SpMat B(size, rhsCols);
    DenseVector b = DenseVector::Random(size);
    DenseMatrix dB(size, rhsCols);
    initSparse<Scalar>(density, dB, B, ForceNonZeroDiag);
    SpVec c = B.col(0);
    DenseVector dc = dB.col(0);

    CALL_SUBTEST(check_sparse_solving(solver, A, b, dA, b));
    CALL_SUBTEST(check_sparse_solving(solver, halfA, b, dA, b));
    CALL_SUBTEST(check_sparse_solving(solver, A, dB, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, halfA, dB, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, A, B, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, halfA, B, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, A, c, dA, dc));
    CALL_SUBTEST(check_sparse_solving(solver, halfA, c, dA, dc));

    // check only once
    if (i == 0) {
      b = DenseVector::Zero(size);
      check_sparse_solving(solver, A, b, dA, b);
    }
  }

  // First, get the folder
#ifdef TEST_REAL_CASES
  // Test real problems with double precision only
  if (std::is_same<typename NumTraits<Scalar>::Real, double>::value) {
    std::string mat_folder = get_matrixfolder<Scalar>();
    MatrixMarketIterator<Scalar> it(mat_folder);
    for (; it; ++it) {
      if (it.sym() == SPD) {
        A = it.matrix();
        if (A.diagonal().size() <= maxRealWorldSize) {
          DenseVector b = it.rhs();
          DenseVector refX = it.refX();
          PermutationMatrix<Dynamic, Dynamic, StorageIndex> pnull;
          halfA.resize(A.rows(), A.cols());
          if (Solver::UpLo == (Lower | Upper))
            halfA = A;
          else
            halfA.template selfadjointView<Solver::UpLo>() = A.template triangularView<Eigen::Lower>().twistedBy(pnull);

          std::cout << "INFO | Testing " << sym_to_string(it.sym()) << "sparse problem " << it.matname() << " ("
                    << A.rows() << "x" << A.cols() << ") using " << typeid(Solver).name() << "..." << std::endl;
          CALL_SUBTEST(check_sparse_solving_real_cases(solver, A, b, A, refX));
          std::string stats = solver_stats(solver);
          if (stats.size() > 0) std::cout << "INFO |  " << stats << std::endl;
          CALL_SUBTEST(check_sparse_solving_real_cases(solver, halfA, b, A, refX));
        } else {
          std::cout << "INFO | Skip sparse problem \"" << it.matname() << "\" (too large)" << std::endl;
        }
      }
    }
  }
#else
  EIGEN_UNUSED_VARIABLE(maxRealWorldSize);
#endif
}

template <typename Solver>
void check_sparse_spd_determinant(Solver& solver) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;

  // generate the problem
  Mat A, halfA;
  DenseMatrix dA;
  generate_sparse_spd_problem(solver, A, halfA, dA, 30);

  for (int i = 0; i < g_repeat; i++) {
    check_sparse_determinant(solver, A, dA);
    check_sparse_determinant(solver, halfA, dA);
  }
}

template <typename Solver, typename DenseMat>
int generate_sparse_nonhermitian_problem(Solver&, typename Solver::MatrixType& A, typename Solver::MatrixType& halfA,
                                         DenseMat& dA, int maxSize = 300) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;

  int size = internal::random<int>(1, maxSize);
  double density = (std::max)(8. / static_cast<double>(size * size), 0.01);

  Mat M(size, size);
  DenseMatrix dM(size, size);

  initSparse<Scalar>(density, dM, M, ForceNonZeroDiag);

  A = M * M.transpose();
  dA = dM * dM.transpose();

  halfA.resize(size, size);
  if (Solver::UpLo == (Lower | Upper))
    halfA = A;
  else
    halfA = A.template triangularView<Solver::UpLo>();

  return size;
}

template <typename Solver>
void check_sparse_nonhermitian_solving(Solver& solver, int maxSize = (std::min)(300, EIGEN_TEST_MAX_SIZE),
                                       int maxRealWorldSize = 100000) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef typename Mat::StorageIndex StorageIndex;
  typedef SparseMatrix<Scalar, ColMajor, StorageIndex> SpMat;
  typedef SparseVector<Scalar, 0, StorageIndex> SpVec;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;
  typedef Matrix<Scalar, Dynamic, 1> DenseVector;

  // generate the problem
  Mat A, halfA;
  DenseMatrix dA;
  for (int i = 0; i < g_repeat; i++) {
    int size = generate_sparse_nonhermitian_problem(solver, A, halfA, dA, maxSize);

    // generate the right hand sides
    int rhsCols = internal::random<int>(1, 16);
    double density = (std::max)(8. / static_cast<double>(size * rhsCols), 0.1);
    SpMat B(size, rhsCols);
    DenseVector b = DenseVector::Random(size);
    DenseMatrix dB(size, rhsCols);
    initSparse<Scalar>(density, dB, B, ForceNonZeroDiag);
    SpVec c = B.col(0);
    DenseVector dc = dB.col(0);

    CALL_SUBTEST(check_sparse_solving(solver, A, b, dA, b));
    CALL_SUBTEST(check_sparse_solving(solver, halfA, b, dA, b));
    CALL_SUBTEST(check_sparse_solving(solver, A, dB, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, halfA, dB, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, A, B, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, halfA, B, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, A, c, dA, dc));
    CALL_SUBTEST(check_sparse_solving(solver, halfA, c, dA, dc));

    // check only once
    if (i == 0) {
      b = DenseVector::Zero(size);
      check_sparse_solving(solver, A, b, dA, b);
    }
  }

  EIGEN_UNUSED_VARIABLE(maxRealWorldSize);
}

template <typename Solver>
void check_sparse_nonhermitian_determinant(Solver& solver) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;

  // generate the problem
  Mat A, halfA;
  DenseMatrix dA;
  generate_sparse_nonhermitian_problem(solver, A, halfA, dA, 30);

  for (int i = 0; i < g_repeat; i++) {
    check_sparse_determinant(solver, A, dA);
    check_sparse_determinant(solver, halfA, dA);
  }
}

template <typename Solver>
void check_sparse_zero_matrix(Solver& solver) {
  typedef typename Solver::MatrixType Mat;

  Mat A(1, 1);
  solver.compute(A);
  VERIFY_IS_EQUAL(solver.info(), NumericalIssue);
}

template <typename Solver, typename DenseMat>
Index generate_sparse_square_problem(Solver&, typename Solver::MatrixType& A, DenseMat& dA, int maxSize = 300,
                                     int options = ForceNonZeroDiag) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;

  Index size = internal::random<int>(1, maxSize);
  double density = (std::max)(8. / static_cast<double>(size * size), 0.01);

  A.resize(size, size);
  dA.resize(size, size);

  initSparse<Scalar>(density, dA, A, options);

  return size;
}

struct prune_column {
  Index m_col;
  prune_column(Index col) : m_col(col) {}
  template <class Scalar>
  bool operator()(Index, Index col, const Scalar&) const {
    return col != m_col;
  }
};

template <typename Solver>
void check_sparse_square_solving(Solver& solver, int maxSize = 300, int maxRealWorldSize = 100000,
                                 bool checkDeficient = false) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef SparseMatrix<Scalar, ColMajor, typename Mat::StorageIndex> SpMat;
  typedef SparseVector<Scalar, 0, typename Mat::StorageIndex> SpVec;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;
  typedef Matrix<Scalar, Dynamic, 1> DenseVector;

  int rhsCols = internal::random<int>(1, 16);

  Mat A;
  DenseMatrix dA;
  for (int i = 0; i < g_repeat; i++) {
    Index size = generate_sparse_square_problem(solver, A, dA, maxSize);

    A.makeCompressed();
    DenseVector b = DenseVector::Random(size);
    DenseMatrix dB(size, rhsCols);
    SpMat B(size, rhsCols);
    double density = (std::max)(8. / double(size * rhsCols), 0.1);
    initSparse<Scalar>(density, dB, B, ForceNonZeroDiag);
    B.makeCompressed();
    SpVec c = B.col(0);
    DenseVector dc = dB.col(0);
    CALL_SUBTEST(check_sparse_solving(solver, A, b, dA, b));
    CALL_SUBTEST(check_sparse_solving(solver, A, dB, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, A, B, dA, dB));
    CALL_SUBTEST(check_sparse_solving(solver, A, c, dA, dc));

    // check only once
    if (i == 0) {
      CALL_SUBTEST(b = DenseVector::Zero(size); check_sparse_solving(solver, A, b, dA, b));
    }
    // regression test for Bug 792 (structurally rank deficient matrices):
    if (checkDeficient && size > 1) {
      Index col = internal::random<int>(0, int(size - 1));
      A.prune(prune_column(col));
      solver.compute(A);
      VERIFY_IS_EQUAL(solver.info(), NumericalIssue);
    }
  }

  // First, get the folder
#ifdef TEST_REAL_CASES
  // Test real problems with double precision only
  if (std::is_same<typename NumTraits<Scalar>::Real, double>::value) {
    std::string mat_folder = get_matrixfolder<Scalar>();
    MatrixMarketIterator<Scalar> it(mat_folder);
    for (; it; ++it) {
      A = it.matrix();
      if (A.diagonal().size() <= maxRealWorldSize) {
        DenseVector b = it.rhs();
        DenseVector refX = it.refX();
        std::cout << "INFO | Testing " << sym_to_string(it.sym()) << "sparse problem " << it.matname() << " ("
                  << A.rows() << "x" << A.cols() << ") using " << typeid(Solver).name() << "..." << std::endl;
        CALL_SUBTEST(check_sparse_solving_real_cases(solver, A, b, A, refX));
        std::string stats = solver_stats(solver);
        if (stats.size() > 0) std::cout << "INFO |  " << stats << std::endl;
      } else {
        std::cout << "INFO | SKIP sparse problem \"" << it.matname() << "\" (too large)" << std::endl;
      }
    }
  }
#else
  EIGEN_UNUSED_VARIABLE(maxRealWorldSize);
#endif
}

template <typename Solver>
void check_sparse_square_determinant(Solver& solver) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;

  for (int i = 0; i < g_repeat; i++) {
    // generate the problem
    Mat A;
    DenseMatrix dA;

    int size = internal::random<int>(1, 30);
    dA.setRandom(size, size);

    dA = (dA.array().abs() < 0.3).select(0, dA);
    dA.diagonal() = (dA.diagonal().array() == 0).select(1, dA.diagonal());
    A = dA.sparseView();
    A.makeCompressed();

    check_sparse_determinant(solver, A, dA);
  }
}

template <typename Solver>
void check_sparse_square_abs_determinant(Solver& solver) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;

  for (int i = 0; i < g_repeat; i++) {
    // generate the problem
    Mat A;
    DenseMatrix dA;
    generate_sparse_square_problem(solver, A, dA, 30);
    A.makeCompressed();
    check_sparse_abs_determinant(solver, A, dA);
  }
}

template <typename Solver, typename DenseMat>
void generate_sparse_leastsquare_problem(Solver&, typename Solver::MatrixType& A, DenseMat& dA, int maxSize = 300,
                                         int options = ForceNonZeroDiag) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;

  int rows = internal::random<int>(1, maxSize);
  int cols = internal::random<int>(1, rows);
  double density = (std::max)(8. / (rows * cols), 0.01);

  A.resize(rows, cols);
  dA.resize(rows, cols);

  initSparse<Scalar>(density, dA, A, options);
}

template <typename Solver>
void check_sparse_leastsquare_solving(Solver& solver) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef SparseMatrix<Scalar, ColMajor, typename Mat::StorageIndex> SpMat;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;
  typedef Matrix<Scalar, Dynamic, 1> DenseVector;

  int rhsCols = internal::random<int>(1, 16);

  Mat A;
  DenseMatrix dA;
  for (int i = 0; i < g_repeat; i++) {
    generate_sparse_leastsquare_problem(solver, A, dA);

    A.makeCompressed();
    DenseVector b = DenseVector::Random(A.rows());
    DenseMatrix dB(A.rows(), rhsCols);
    SpMat B(A.rows(), rhsCols);
    double density = (std::max)(8. / (A.rows() * rhsCols), 0.1);
    initSparse<Scalar>(density, dB, B, ForceNonZeroDiag);
    B.makeCompressed();
    check_sparse_solving(solver, A, b, dA, b);
    check_sparse_solving(solver, A, dB, dA, dB);
    check_sparse_solving(solver, A, B, dA, dB);

    // check only once
    if (i == 0) {
      b = DenseVector::Zero(A.rows());
      check_sparse_solving(solver, A, b, dA, b);
    }
  }
}
