// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2012 Kolja Brix <brix@igpm.rwth-aaachen.de>
//
// 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

#include "sparse_solver.h"
#include <Eigen/IterativeLinearSolvers>

template <typename T>
void test_gmres_T() {
  GMRES<SparseMatrix<T>, DiagonalPreconditioner<T> > gmres_colmajor_diag;
  GMRES<SparseMatrix<T>, IdentityPreconditioner> gmres_colmajor_I;
  GMRES<SparseMatrix<T>, IncompleteLUT<T> > gmres_colmajor_ilut;
  // GMRES<SparseMatrix<T>, SSORPreconditioner<T> >     gmres_colmajor_ssor;

  CALL_SUBTEST(check_sparse_square_solving(gmres_colmajor_diag));
  //   CALL_SUBTEST( check_sparse_square_solving(gmres_colmajor_I)     );
  CALL_SUBTEST(check_sparse_square_solving(gmres_colmajor_ilut));
  // CALL_SUBTEST( check_sparse_square_solving(gmres_colmajor_ssor)     );
}

template <typename = void>
void test_gmres_solve_with_guess_tolerance() {
  const SparseMatrix<double>::StorageIndex size = 20;
  SparseMatrix<double> matrix(size, size);
  std::vector<Triplet<double> > triplets;
  for (SparseMatrix<double>::StorageIndex i = 0; i < size; ++i) {
    triplets.emplace_back(i, i, 2.0 + double(i) / double(size));
    if (i > 0) triplets.emplace_back(i, i - 1, -0.25);
    if (i + 1 < size) triplets.emplace_back(i, i + 1, 0.125);
  }
  matrix.setFromTriplets(triplets.begin(), triplets.end());

  VectorXd rhs = VectorXd::Ones(size);
  VectorXd guess(size);
  for (Index i = 0; i < size; ++i) {
    guess[i] = ((i % 2) ? 1.0 : -1.0) * 1e8;
  }

  GMRES<SparseMatrix<double>, DiagonalPreconditioner<double> > gmres;
  gmres.compute(matrix);
  gmres.setTolerance(1e-6);
  gmres.setMaxIterations(size);
  gmres.set_restart(size);

  VectorXd x = gmres.solveWithGuess(rhs, guess);
  DiagonalPreconditioner<double> preconditioner(matrix);
  const VectorXd residual = matrix * x - rhs;
  const double relativeResidual = preconditioner.solve(residual).norm() / preconditioner.solve(rhs).norm();
  VERIFY(gmres.info() == Success);
  VERIFY(gmres.iterations() > 1);
  VERIFY(relativeResidual < gmres.tolerance());
  VERIFY(gmres.error() < gmres.tolerance());
}

template <typename = void>
void test_gmres_large_restart() {
  const SparseMatrix<double>::StorageIndex size = 4;
  SparseMatrix<double> matrix(size, size);
  std::vector<Triplet<double> > triplets;
  for (SparseMatrix<double>::StorageIndex i = 0; i < size; ++i) {
    triplets.emplace_back(i, i, 2.0 + double(i));
  }
  matrix.setFromTriplets(triplets.begin(), triplets.end());

  const VectorXd rhs = VectorXd::LinSpaced(size, 1.0, 4.0);
  GMRES<SparseMatrix<double>, IdentityPreconditioner> gmres;
  gmres.compute(matrix);
  gmres.setTolerance(1e-12);
  gmres.setMaxIterations(size);
  gmres.set_restart(1000000);

  VectorXd x = gmres.solve(rhs);
  VERIFY(gmres.info() == Success);
  VERIFY_IS_APPROX(matrix * x, rhs);
}

// A zero right-hand side is solved by x = 0 without iterating; iterations() used to report the cap.
void test_zero_rhs() {
  SparseMatrix<double> A(4, 4);
  for (Index i = 0; i < 4; ++i) A.insert(i, i) = 2.0;
  GMRES<SparseMatrix<double> > solver(A);
  VectorXd x = solver.solve(VectorXd::Zero(4));
  VERIFY(x.isZero());
  VERIFY_IS_EQUAL(solver.iterations(), Index(0));
  VERIFY_IS_EQUAL(solver.error(), 0.0);
}

EIGEN_DECLARE_TEST(gmres) {
  CALL_SUBTEST_1(test_gmres_T<double>());
  CALL_SUBTEST_2(test_gmres_T<std::complex<double> >());
  CALL_SUBTEST_3(test_gmres_solve_with_guess_tolerance<>());
  CALL_SUBTEST_4(test_gmres_large_restart<>());
  CALL_SUBTEST_4(test_zero_rhs());
}
