// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.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/.

#ifndef EIGEN_DGMRES_H
#define EIGEN_DGMRES_H

#include "../../../../Eigen/Eigenvalues"

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

template <typename MatrixType_, typename Preconditioner_ = DiagonalPreconditioner<typename MatrixType_::Scalar> >
class DGMRES;

namespace internal {

template <typename MatrixType_, typename Preconditioner_>
struct traits<DGMRES<MatrixType_, Preconditioner_> > {
  typedef MatrixType_ MatrixType;
  typedef Preconditioner_ Preconditioner;
};

/** \brief Computes a permutation vector to have a sorted sequence
 * \param vec The vector to reorder.
 * \param perm gives the sorted sequence on output. Must be initialized with 0..n-1
 * \param ncut Put  the ncut smallest elements at the end of the vector
 * WARNING This is an expensive sort, so should be used only
 * for small size vectors
 * TODO: Use modified QuickSplit or std::nth_element to get the smallest values
 */
template <typename VectorType, typename IndexType>
void sortWithPermutation(VectorType& vec, IndexType& perm, typename IndexType::Scalar& ncut) {
  eigen_assert(vec.size() == perm.size());
  bool flag;
  for (Index k = 0; k < ncut; k++) {
    flag = false;
    for (Index j = 0; j < vec.size() - 1; j++) {
      if (vec(perm(j)) < vec(perm(j + 1))) {
        std::swap(perm(j), perm(j + 1));
        flag = true;
      }
      if (!flag) break;  // The vector is in sorted order
    }
  }
}

}  // namespace internal
/**
 * \ingroup IterativeLinearSolvers_Module
 * \brief A Restarted GMRES with deflation.
 * This class implements a modification of the GMRES solver for
 * sparse linear systems. The basis is built with modified
 * Gram-Schmidt. At each restart, a few approximated eigenvectors
 * corresponding to the smallest eigenvalues are used to build a
 * preconditioner for the next cycle. This preconditioner
 * for deflation can be combined with any other preconditioner,
 * the IncompleteLUT for instance. The preconditioner is applied
 * at right of the matrix and the combination is multiplicative.
 *
 * \tparam MatrixType_ the type of the sparse matrix A, can be a dense or a sparse matrix.
 * \tparam Preconditioner_ the type of the preconditioner. Default is DiagonalPreconditioner
 * Typical usage :
 * \code
 * SparseMatrix<double> A;
 * VectorXd x, b;
 * //Fill A and b ...
 * DGMRES<SparseMatrix<double> > solver;
 * solver.set_restart(30); // Set restarting value
 * solver.setEigenv(1); // Set the number of eigenvalues to deflate
 * solver.compute(A);
 * x = solver.solve(b);
 * \endcode
 *
 * DGMRES can also be used in a matrix-free context, see the following \link MatrixfreeSolverExample example \endlink.
 *
 * References :
 * [1] D. NUENTSA WAKAM and F. PACULL, Memory Efficient Hybrid
 *  Algebraic Solvers for Linear Systems Arising from Compressible
 *  Flows, Computers and Fluids, In Press,
 *  https://doi.org/10.1016/j.compfluid.2012.03.023
 * [2] K. Burrage and J. Erhel, On the performance of various
 * adaptive preconditioned GMRES strategies, 5(1998), 101-121.
 * [3] J. Erhel, K. Burrage and B. Pohl, Restarted GMRES
 *  preconditioned by deflation,J. Computational and Applied
 *  Mathematics, 69(1996), 303-318.

 *
 */
template <typename MatrixType_, typename Preconditioner_>
class DGMRES : public IterativeSolverBase<DGMRES<MatrixType_, Preconditioner_> > {
 protected:
  typedef IterativeSolverBase<DGMRES> Base;
  using Base::m_error;
  using Base::m_info;
  using Base::m_isInitialized;
  using Base::m_iterations;
  using Base::m_tolerance;
  using Base::matrix;

 public:
  using Base::_solve_impl;
  using Base::_solve_with_guess_impl;
  typedef MatrixType_ MatrixType;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::StorageIndex StorageIndex;
  typedef typename MatrixType::RealScalar RealScalar;
  typedef internal::make_complex_t<Scalar> ComplexScalar;
  typedef Preconditioner_ Preconditioner;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;
  typedef Matrix<RealScalar, Dynamic, Dynamic> DenseRealMatrix;
  typedef Matrix<Scalar, Dynamic, 1> DenseVector;
  typedef Matrix<RealScalar, Dynamic, 1> DenseRealVector;
  typedef Matrix<ComplexScalar, Dynamic, 1> ComplexVector;

  /** Default constructor. */
  DGMRES()
      : Base(), m_restart(30), m_neig(0), m_r(0), m_maxNeig(5), m_isDeflAllocated(false), m_isDeflInitialized(false) {}

  /** Initialize the solver with matrix \a A for further \c Ax=b solving.
   *
   * This constructor is a shortcut for the default constructor followed
   * by a call to compute().
   *
   * \warning this class stores a reference to the matrix A as well as some
   * precomputed values that depend on it. Therefore, if \a A is changed
   * this class becomes invalid. Call compute() to update it with the new
   * matrix A, or modify a copy of A.
   */
  template <typename MatrixDerived>
  explicit DGMRES(const EigenBase<MatrixDerived>& A)
      : Base(A.derived()),
        m_restart(30),
        m_neig(0),
        m_r(0),
        m_maxNeig(5),
        m_isDeflAllocated(false),
        m_isDeflInitialized(false) {}

  ~DGMRES() {}

  /** \internal */
  template <typename Rhs, typename Dest>
  void _solve_vector_with_guess_impl(const Rhs& b, Dest& x) const {
    EIGEN_STATIC_ASSERT(Rhs::ColsAtCompileTime == 1 || Dest::ColsAtCompileTime == 1,
                        YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX);

    m_iterations = Base::maxIterations();
    m_error = Base::m_tolerance;

    dgmres(matrix(), b, x, Base::m_preconditioner);
  }

  /**
   * Get the restart value
   */
  Index restart() const { return m_restart; }

  /**
   * Set the restart value (default is 30)
   */
  void set_restart(const Index restart) { m_restart = restart; }

  /**
   * Set the number of eigenvalues to deflate at each restart
   */
  void setEigenv(const Index neig) {
    m_neig = neig;
    if (neig + 1 > m_maxNeig) m_maxNeig = neig + 1;  // To allow for complex conjugates
  }

  /**
   * Get the size of the deflation subspace size
   */
  Index deflSize() const { return m_r; }

  /**
   * Set the maximum size of the deflation subspace
   */
  void setMaxEigenv(const Index maxNeig) { m_maxNeig = maxNeig; }

 protected:
  // DGMRES algorithm
  template <typename Rhs, typename Dest>
  void dgmres(const MatrixType& mat, const Rhs& rhs, Dest& x, const Preconditioner& precond) const;
  // Perform one cycle of GMRES
  template <typename Dest>
  Index dgmresCycle(const MatrixType& mat, const Preconditioner& precond, Dest& x, DenseVector& r0, RealScalar& beta,
                    const RealScalar& normRhs, Index& nbIts) const;
  // Compute data to use for deflation
  Index dgmresComputeDeflationData(const MatrixType& mat, const Preconditioner& precond, const Index& it,
                                   StorageIndex& neig) const;
  // Apply deflation to a vector
  template <typename RhsType, typename DestType>
  Index dgmresApplyDeflation(const RhsType& In, DestType& Out) const;
  ComplexVector schurValues(const ComplexSchur<DenseMatrix>& schurofH) const;
  ComplexVector schurValues(const RealSchur<DenseMatrix>& schurofH) const;
  // Init data for deflation
  void dgmresInitDeflation(Index& rows) const;
  mutable DenseMatrix m_V;                  // Krylov basis vectors
  mutable DenseMatrix m_H;                  // Hessenberg matrix
  mutable DenseMatrix m_Hes;                // Initial hessenberg matrix without Givens rotations applied
  mutable Index m_restart;                  // Maximum size of the Krylov subspace
  mutable DenseMatrix m_U;                  // Vectors that form the basis of the invariant subspace
  mutable DenseMatrix m_MU;                 // matrix operator applied to m_U (for next cycles)
  mutable DenseMatrix m_T;                  /* T=U^T*M^{-1}*A*U */
  mutable PartialPivLU<DenseMatrix> m_luT;  // LU factorization of m_T
  mutable StorageIndex m_neig;              // Number of eigenvalues to extract at each restart
  mutable Index m_r;                        // Current number of deflated eigenvalues, size of m_U
  mutable Index m_maxNeig;                  // Maximum number of eigenvalues to deflate
  mutable RealScalar m_lambdaN;             // Modulus of the largest eigenvalue of A
  mutable bool m_isDeflAllocated;
  mutable bool m_isDeflInitialized;

  // Adaptive strategy
  mutable RealScalar m_smv;  // Smaller multiple of the remaining number of steps allowed
  mutable bool m_force;      // Force the use of deflation at each restart
};
/**
 * \brief Perform several cycles of restarted GMRES with modified Gram Schmidt,
 *
 * A right preconditioner is used combined with deflation.
 *
 */
template <typename MatrixType_, typename Preconditioner_>
template <typename Rhs, typename Dest>
void DGMRES<MatrixType_, Preconditioner_>::dgmres(const MatrixType& mat, const Rhs& rhs, Dest& x,
                                                  const Preconditioner& precond) const {
  const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();

  RealScalar normRhs = rhs.norm();
  if (normRhs <= considerAsZero) {
    x.setZero();
    m_error = 0;
    return;
  }

  // Initialization
  m_isDeflInitialized = false;
  Index n = mat.rows();
  DenseVector r0(n);
  Index nbIts = 0;
  m_H.resize(m_restart + 1, m_restart);
  m_Hes.resize(m_restart, m_restart);
  m_V.resize(n, m_restart + 1);
  // Initial residual vector and initial norm
  if (x.squaredNorm() == 0) x = precond.solve(rhs);
  r0 = rhs - mat * x;
  RealScalar beta = r0.norm();

  m_error = beta / normRhs;
  if (m_error < m_tolerance)
    m_info = Success;
  else
    m_info = NoConvergence;

  // Iterative process
  while (nbIts < m_iterations && m_info == NoConvergence) {
    dgmresCycle(mat, precond, x, r0, beta, normRhs, nbIts);

    // Compute the new residual vector for the restart
    if (nbIts < m_iterations && m_info == NoConvergence) {
      r0 = rhs - mat * x;
      beta = r0.norm();
    }
  }
}

/**
 * \brief Perform one restart cycle of DGMRES
 * \param mat The coefficient matrix
 * \param precond The preconditioner
 * \param x the new approximated solution
 * \param r0 The initial residual vector
 * \param beta The norm of the residual computed so far
 * \param normRhs The norm of the right hand side vector
 * \param nbIts The number of iterations
 */
template <typename MatrixType_, typename Preconditioner_>
template <typename Dest>
Index DGMRES<MatrixType_, Preconditioner_>::dgmresCycle(const MatrixType& mat, const Preconditioner& precond, Dest& x,
                                                        DenseVector& r0, RealScalar& beta, const RealScalar& normRhs,
                                                        Index& nbIts) const {
  // Initialization
  DenseVector g(m_restart + 1);  // Right hand side of the least square problem
  g.setZero();
  g(0) = Scalar(beta);
  m_V.col(0) = r0 / beta;
  m_info = NoConvergence;
  std::vector<JacobiRotation<Scalar> > gr(m_restart);  // Givens rotations
  Index it = 0;                                        // Number of inner iterations
  Index n = mat.rows();
  DenseVector tv1(n), tv2(n);  // Temporary vectors
  while (m_info == NoConvergence && it < m_restart && nbIts < m_iterations) {
    // Apply preconditioner(s) at right
    if (m_isDeflInitialized) {
      dgmresApplyDeflation(m_V.col(it), tv1);  // Deflation
      tv2 = precond.solve(tv1);
    } else {
      tv2 = precond.solve(m_V.col(it));  // User's selected preconditioner
    }
    tv1 = mat * tv2;

    // Orthogonalize it with the previous basis in the basis using modified Gram-Schmidt
    Scalar coef;
    for (Index i = 0; i <= it; ++i) {
      coef = tv1.dot(m_V.col(i));
      tv1 = tv1 - coef * m_V.col(i);
      m_H(i, it) = coef;
      m_Hes(i, it) = coef;
    }
    // Normalize the vector. coef == 0 is an Arnoldi happy breakdown: the new
    // direction lies in span(V[0..it]), so skip the division (which would
    // poison m_V.col(it+1) with NaN) and fall through to the termination
    // check below.
    coef = tv1.norm();
    const bool happy_breakdown = numext::is_exactly_zero(coef);
    if (!happy_breakdown) {
      m_V.col(it + 1) = tv1 / coef;
    }
    m_H(it + 1, it) = coef;
    //     m_Hes(it+1,it) = coef;

    // Update Hessenberg matrix with Givens rotations
    for (Index i = 1; i <= it; ++i) {
      m_H.col(it).applyOnTheLeft(i - 1, i, gr[i - 1].adjoint());
    }

    // If the rotated diagonal is also zero, the reduced triangular system
    // becomes singular and the back-substitution below would produce Inf/NaN.
    // Stop with NumericalIssue instead of polluting x.
    if (happy_breakdown && numext::is_exactly_zero(m_H(it, it))) {
      m_info = NumericalIssue;
      break;
    }

    // Compute the new plane rotation
    gr[it].makeGivens(m_H(it, it), m_H(it + 1, it));
    // Apply the new rotation
    m_H.col(it).applyOnTheLeft(it, it + 1, gr[it].adjoint());
    g.applyOnTheLeft(it, it + 1, gr[it].adjoint());

    beta = std::abs(g(it + 1));
    m_error = beta / normRhs;
    it++;
    nbIts++;

    if (m_error < m_tolerance || happy_breakdown) {
      // Happy breakdown: residual on the current subspace is exactly zero, so
      // the it-dim triangular system yields the exact solution.
      m_info = Success;
      break;
    }
  }

  // Compute the new coefficients by solving the least square problem.
  DenseVector nrs(m_restart);
  nrs = m_H.topLeftCorner(it, it).template triangularView<Upper>().solve(g.head(it));

  // Form the new solution
  if (m_isDeflInitialized) {
    tv1 = m_V.leftCols(it) * nrs;
    dgmresApplyDeflation(tv1, tv2);
    x = x + precond.solve(tv2);
  } else
    x = x + precond.solve(m_V.leftCols(it) * nrs);

  // Go for a new cycle and compute data for deflation
  if (nbIts < m_iterations && m_info == NoConvergence && m_neig > 0 && (m_r + m_neig) < m_maxNeig)
    dgmresComputeDeflationData(mat, precond, it, m_neig);
  return 0;
}

template <typename MatrixType_, typename Preconditioner_>
void DGMRES<MatrixType_, Preconditioner_>::dgmresInitDeflation(Index& rows) const {
  m_U.resize(rows, m_maxNeig);
  m_MU.resize(rows, m_maxNeig);
  m_T.resize(m_maxNeig, m_maxNeig);
  m_lambdaN = 0.0;
  m_isDeflAllocated = true;
}

template <typename MatrixType_, typename Preconditioner_>
inline typename DGMRES<MatrixType_, Preconditioner_>::ComplexVector DGMRES<MatrixType_, Preconditioner_>::schurValues(
    const ComplexSchur<DenseMatrix>& schurofH) const {
  return schurofH.matrixT().diagonal();
}

template <typename MatrixType_, typename Preconditioner_>
inline typename DGMRES<MatrixType_, Preconditioner_>::ComplexVector DGMRES<MatrixType_, Preconditioner_>::schurValues(
    const RealSchur<DenseMatrix>& schurofH) const {
  const DenseMatrix& T = schurofH.matrixT();
  Index it = T.rows();
  ComplexVector eig(it);
  Index j = 0;
  while (j < it - 1) {
    if (T(j + 1, j) == Scalar(0)) {
      eig(j) = ComplexScalar(T(j, j), RealScalar(0));
      j++;
    } else {
      eig(j) = ComplexScalar(T(j, j), T(j + 1, j));
      eig(j + 1) = ComplexScalar(T(j, j + 1), T(j + 1, j + 1));
      j++;
    }
  }
  if (j < it - 1) eig(j) = ComplexScalar(T(j, j), RealScalar(0));
  return eig;
}

template <typename MatrixType_, typename Preconditioner_>
Index DGMRES<MatrixType_, Preconditioner_>::dgmresComputeDeflationData(const MatrixType& mat,
                                                                       const Preconditioner& precond, const Index& it,
                                                                       StorageIndex& neig) const {
  // First, find the Schur form of the Hessenberg matrix H
  std::conditional_t<NumTraits<Scalar>::IsComplex, ComplexSchur<DenseMatrix>, RealSchur<DenseMatrix> > schurofH;
  bool computeU = true;
  DenseMatrix matrixQ(it, it);
  matrixQ.setIdentity();
  schurofH.computeFromHessenberg(m_Hes.topLeftCorner(it, it), matrixQ, computeU);

  ComplexVector eig(it);
  Matrix<StorageIndex, Dynamic, 1> perm(it);
  eig = this->schurValues(schurofH);

  // Reorder the absolute values of Schur values
  DenseRealVector modulEig(it);
  for (Index j = 0; j < it; ++j) modulEig(j) = std::abs(eig(j));
  perm.setLinSpaced(it, 0, internal::convert_index<StorageIndex>(it - 1));
  internal::sortWithPermutation(modulEig, perm, neig);

  if (!m_lambdaN) {
    m_lambdaN = (std::max)(modulEig.maxCoeff(), m_lambdaN);
  }
  // Count the real number of extracted eigenvalues (with complex conjugates)
  Index nbrEig = 0;
  while (nbrEig < neig) {
    if (eig(perm(it - nbrEig - 1)).imag() == RealScalar(0))
      nbrEig++;
    else
      nbrEig += 2;
  }
  // Extract the  Schur vectors corresponding to the smallest Ritz values
  DenseMatrix Sr(it, nbrEig);
  Sr.setZero();
  for (Index j = 0; j < nbrEig; j++) {
    Sr.col(j) = schurofH.matrixU().col(perm(it - j - 1));
  }

  // Form the Schur vectors of the initial matrix using the Krylov basis
  DenseMatrix X;
  X = m_V.leftCols(it) * Sr;
  if (m_r) {
    // Orthogonalize X against m_U using modified Gram-Schmidt
    for (Index j = 0; j < nbrEig; j++)
      for (Index k = 0; k < m_r; k++) X.col(j) = X.col(j) - (m_U.col(k).dot(X.col(j))) * m_U.col(k);
  }

  // Compute m_MX = A * M^-1 * X
  Index m = m_V.rows();
  if (!m_isDeflAllocated) dgmresInitDeflation(m);
  DenseMatrix MX(m, nbrEig);
  DenseVector tv1(m);
  for (Index j = 0; j < nbrEig; j++) {
    tv1 = mat * X.col(j);
    MX.col(j) = precond.solve(tv1);
  }

  // Update m_T = [U'MU U'MX; X'MU X'MX]
  m_T.block(m_r, m_r, nbrEig, nbrEig) = X.transpose() * MX;
  if (m_r) {
    m_T.block(0, m_r, m_r, nbrEig) = m_U.leftCols(m_r).transpose() * MX;
    m_T.block(m_r, 0, nbrEig, m_r) = X.transpose() * m_MU.leftCols(m_r);
  }

  // Save X into m_U and m_MX in m_MU
  for (Index j = 0; j < nbrEig; j++) m_U.col(m_r + j) = X.col(j);
  for (Index j = 0; j < nbrEig; j++) m_MU.col(m_r + j) = MX.col(j);
  // Increase the size of the invariant subspace
  m_r += nbrEig;

  // Factorize m_T into m_luT
  m_luT.compute(m_T.topLeftCorner(m_r, m_r));

  // FIXME: Check if the factorization was correctly done (nonsingular matrix).
  m_isDeflInitialized = true;
  return 0;
}
template <typename MatrixType_, typename Preconditioner_>
template <typename RhsType, typename DestType>
Index DGMRES<MatrixType_, Preconditioner_>::dgmresApplyDeflation(const RhsType& x, DestType& y) const {
  DenseVector x1 = m_U.leftCols(m_r).transpose() * x;
  y = x + m_U.leftCols(m_r) * (m_lambdaN * m_luT.solve(x1) - x1);
  return 0;
}

}  // end namespace Eigen
#endif
