// 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;
  typedef typename NumTraits<Scalar>::Real RealScalar;

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

  // d det(A) = det(A) tr(A^{-1} dA). With the LU backward error |dA| <= gamma_n |L||U| (Higham, ASNA, Thm. 9.3) and
  // |L||U| ~ |A|, each determinant is off by about n eps cond |det(A)|, cond = sum_ij |A^{-1}_ji| |A_ij| >= n, which
  // is unbounded for the matrices check_sparse_square_determinant draws. The factor 8 is empirical: partial pivoting
  // stays below 0.5. The test_precision floor admits the growth of threshold pivoting, which |L||U| ~ |A| ignores;
  // UMFPACK's symmetric strategy takes diagonal pivots down to 1e-3 of the column maximum.
  const RealScalar cond = dA.inverse().transpose().cwiseAbs().cwiseProduct(dA.cwiseAbs()).sum();
  const RealScalar tolerance =
      numext::maxi(test_precision<Scalar>(), RealScalar(8 * dA.rows()) * NumTraits<RealScalar>::epsilon() * cond);
  VERIFY((numext::isfinite)(tolerance));
  const Scalar refDet = dA.determinant();
  VERIFY(numext::abs(solver.determinant() - refDet) <= tolerance * numext::abs(refDet));
}
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>
void check_sparse_log_abs_determinant(Solver& solver, const typename Solver::MatrixType& A, const DenseMat& dA) {
  typedef typename Solver::MatrixType Mat;
  typedef typename Mat::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

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

  Scalar refDet = dA.determinant();
  RealScalar refAbsDet = numext::abs(refDet);
  VERIFY_IS_APPROX(refAbsDet, solver.absDeterminant());
  VERIFY_IS_APPROX(numext::sign(refDet), solver.signDeterminant());
  // log|det| crosses zero, so the meaningful bound here is absolute once |log|det|| drops below one.
  RealScalar refLogAbsDet = numext::log(refAbsDet);
  VERIFY_IS_MUCH_SMALLER_THAN(solver.logAbsDeterminant() - refLogAbsDet,
                              numext::maxi(RealScalar(1), numext::abs(refLogAbsDet)));
}

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);

  check_sparse_determinant(solver, A, dA);
  check_sparse_determinant(solver, halfA, dA);
}

template <typename Solver>
void check_sparse_spd_log_abs_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);

  check_sparse_log_abs_determinant(solver, A, dA);
  check_sparse_log_abs_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_nonhermitian_log_abs_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_log_abs_determinant(solver, A, dA);
    check_sparse_log_abs_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);
    }
  }
}
