// 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/.

#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>()));
    }
  }
}

// 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 (internal::is_same<Scalar, std::complex<float>>::value || internal::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 (internal::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 (internal::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);
    }
  }
}
