// 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();
    // The outer stride spans DenseRhs's outer dimension, so it must be taken from outerStride()
    // rather than from rows(): the two differ when DenseRhs is row major.
    Eigen::Map<DenseRhs, 0, Stride<Eigen::Dynamic, 2>> outm(out.data(), xm.rows(), xm.cols(),
                                                            Stride<Eigen::Dynamic, 2>(2 * xm.outerStride(), 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);
    }
  }
}
