// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
// Copyright (C) 2016 Tobias Wood <tobias@spinicist.org.uk>
//
// 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_GENERALIZEDEIGENSOLVER_H
#define EIGEN_GENERALIZEDEIGENSOLVER_H

#include "./RealQZ.h"

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

namespace Eigen {

/** \eigenvalues_module \ingroup Eigenvalues_Module
 *
 *
 * \class GeneralizedEigenSolver
 *
 * \brief Computes the generalized eigenvalues and eigenvectors of a pair of general matrices
 *
 * \tparam MatrixType_ the type of the matrices of which we are computing the
 * eigen-decomposition; this is expected to be an instantiation of the Matrix
 * class template. Currently, only real matrices are supported.
 *
 * The generalized eigenvalues and eigenvectors of a matrix pair \f$ A \f$ and \f$ B \f$ are scalars
 * \f$ \lambda \f$ and vectors \f$ v \f$ such that \f$ Av = \lambda Bv \f$.  If
 * \f$ D \f$ is a diagonal matrix with the eigenvalues on the diagonal, and
 * \f$ V \f$ is a matrix with the eigenvectors as its columns, then \f$ A V =
 * B V D \f$. The matrix \f$ V \f$ is almost always invertible, in which case we
 * have \f$ A = B V D V^{-1} \f$. This is called the generalized eigen-decomposition.
 *
 * The generalized eigenvalues and eigenvectors of a matrix pair may be complex, even when the
 * matrices are real. Moreover, the generalized eigenvalue might be infinite if the matrix B is
 * singular. To workaround this difficulty, the eigenvalues are provided as a pair of complex \f$ \alpha \f$
 * and real \f$ \beta \f$ such that: \f$ \lambda_i = \alpha_i / \beta_i \f$. If \f$ \beta_i \f$ is (nearly) zero,
 * then one can consider the well defined left eigenvalue \f$ \mu = \beta_i / \alpha_i\f$ such that:
 * \f$ \mu_i A v_i = B v_i \f$, or even \f$ \mu_i u_i^T A  = u_i^T B \f$ where \f$ u_i \f$ is
 * called the left eigenvector.
 *
 * Call the function compute() to compute the generalized eigenvalues and eigenvectors of
 * a given matrix pair. Alternatively, you can use the
 * GeneralizedEigenSolver(const MatrixType&, const MatrixType&, bool) constructor which computes the
 * eigenvalues and eigenvectors at construction time. Once the eigenvalue and
 * eigenvectors are computed, they can be retrieved with the eigenvalues() and
 * eigenvectors() functions.
 *
 * Here is an usage example of this class:
 * Example: \include GeneralizedEigenSolver.cpp
 * Output: \verbinclude GeneralizedEigenSolver.out
 *
 * \sa MatrixBase::eigenvalues(), class ComplexEigenSolver, class SelfAdjointEigenSolver
 */
template <typename MatrixType_>
class GeneralizedEigenSolver {
 public:
  /** \brief Synonym for the template parameter \p MatrixType_. */
  typedef MatrixType_ MatrixType;

  enum {
    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
    Options = internal::traits<MatrixType>::Options,
    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
  };

  /** \brief Scalar type for matrices of type #MatrixType. */
  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Eigen::Index Index;  ///< \deprecated since Eigen 3.3

  /** \brief Complex scalar type for #MatrixType.
   *
   * This is \c std::complex<Scalar> if #Scalar is real (e.g.,
   * \c float or \c double) and just \c Scalar if #Scalar is
   * complex.
   */
  typedef internal::make_complex_t<Scalar> ComplexScalar;

  /** \brief Type for vector of real scalar values eigenvalues as returned by betas().
   *
   * This is a column vector with entries of type #Scalar.
   * The length of the vector is the size of #MatrixType.
   */
  typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> VectorType;

  /** \brief Type for vector of complex scalar values eigenvalues as returned by alphas().
   *
   * This is a column vector with entries of type #ComplexScalar.
   * The length of the vector is the size of #MatrixType.
   */
  typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ComplexVectorType;

  /** \brief Expression type for the eigenvalues as returned by eigenvalues().
   */
  typedef CwiseBinaryOp<internal::scalar_quotient_op<ComplexScalar, Scalar>, ComplexVectorType, VectorType>
      EigenvalueType;

  /** \brief Type for matrix of eigenvectors as returned by eigenvectors().
   *
   * This is a square matrix with entries of type #ComplexScalar.
   * The size is the same as the size of #MatrixType.
   */
  typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime,
                 MaxColsAtCompileTime>
      EigenvectorsType;

  /** \brief Default constructor.
   *
   * The default constructor is useful in cases in which the user intends to
   * perform decompositions via EigenSolver::compute(const MatrixType&, bool).
   *
   * \sa compute() for an example.
   */
  GeneralizedEigenSolver()
      : m_eivec(), m_alphas(), m_betas(), m_computeEigenvectors(false), m_isInitialized(false), m_realQZ() {}

  /** \brief Default constructor with memory preallocation
   *
   * Like the default constructor but with preallocation of the internal data
   * according to the specified problem \a size.
   * \sa GeneralizedEigenSolver()
   */
  explicit GeneralizedEigenSolver(Index size)
      : m_eivec(size, size),
        m_alphas(size),
        m_betas(size),
        m_computeEigenvectors(false),
        m_isInitialized(false),
        m_realQZ(size),
        m_tmp(size) {}

  /** \brief Constructor; computes the generalized eigendecomposition of given matrix pair.
   *
   * \param[in]  A  Square matrix whose eigendecomposition is to be computed.
   * \param[in]  B  Square matrix whose eigendecomposition is to be computed.
   * \param[in]  computeEigenvectors  If true, both the eigenvectors and the
   *    eigenvalues are computed; if false, only the eigenvalues are computed.
   *
   * This constructor calls compute() to compute the generalized eigenvalues
   * and eigenvectors.
   *
   * \sa compute()
   */
  GeneralizedEigenSolver(const MatrixType& A, const MatrixType& B, bool computeEigenvectors = true)
      : m_eivec(A.rows(), A.cols()),
        m_alphas(A.cols()),
        m_betas(A.cols()),
        m_computeEigenvectors(false),
        m_isInitialized(false),
        m_realQZ(A.cols()),
        m_tmp(A.cols()) {
    compute(A, B, computeEigenvectors);
  }

  /** \brief Returns the computed generalized eigenvectors.
   *
   * \returns  %Matrix whose columns are the (possibly complex) right eigenvectors.
   * i.e. the eigenvectors that solve (A - l*B)x = 0. The ordering matches the eigenvalues.
   *
   * \pre Either the constructor
   * GeneralizedEigenSolver(const MatrixType&,const MatrixType&, bool) or the member function
   * compute(const MatrixType&, const MatrixType& bool) has been called before, and
   * \p computeEigenvectors was set to true (the default).
   *
   * \sa eigenvalues()
   */
  EigenvectorsType eigenvectors() const {
    eigen_assert(info() == Success && "GeneralizedEigenSolver failed to compute eigenvectors");
    eigen_assert(m_computeEigenvectors && "Eigenvectors for GeneralizedEigenSolver were not calculated");
    return m_eivec;
  }

  /** \brief Returns an expression of the computed generalized eigenvalues.
   *
   * \returns An expression of the column vector containing the eigenvalues.
   *
   * It is a shortcut for \code this->alphas().cwiseQuotient(this->betas()); \endcode
   * Not that betas might contain zeros. It is therefore not recommended to use this function,
   * but rather directly deal with the alphas and betas vectors.
   *
   * \pre Either the constructor
   * GeneralizedEigenSolver(const MatrixType&,const MatrixType&,bool) or the member function
   * compute(const MatrixType&,const MatrixType&,bool) has been called before.
   *
   * The eigenvalues are repeated according to their algebraic multiplicity,
   * so there are as many eigenvalues as rows in the matrix. The eigenvalues
   * are not sorted in any particular order.
   *
   * \sa alphas(), betas(), eigenvectors()
   */
  EigenvalueType eigenvalues() const {
    eigen_assert(info() == Success && "GeneralizedEigenSolver failed to compute eigenvalues.");
    return EigenvalueType(m_alphas, m_betas);
  }

  /** \returns A const reference to the vectors containing the alpha values
   *
   * This vector permits to reconstruct the j-th eigenvalues as alphas(i)/betas(j).
   *
   * \sa betas(), eigenvalues() */
  const ComplexVectorType& alphas() const {
    eigen_assert(info() == Success && "GeneralizedEigenSolver failed to compute alphas.");
    return m_alphas;
  }

  /** \returns A const reference to the vectors containing the beta values
   *
   * This vector permits to reconstruct the j-th eigenvalues as alphas(i)/betas(j).
   *
   * \sa alphas(), eigenvalues() */
  const VectorType& betas() const {
    eigen_assert(info() == Success && "GeneralizedEigenSolver failed to compute betas.");
    return m_betas;
  }

  /** \brief Computes generalized eigendecomposition of given matrix.
   *
   * \param[in]  A  Square matrix whose eigendecomposition is to be computed.
   * \param[in]  B  Square matrix whose eigendecomposition is to be computed.
   * \param[in]  computeEigenvectors  If true, both the eigenvectors and the
   *    eigenvalues are computed; if false, only the eigenvalues are
   *    computed.
   * \returns    Reference to \c *this
   *
   * This function computes the eigenvalues of the real matrix \p matrix.
   * The eigenvalues() function can be used to retrieve them.  If
   * \p computeEigenvectors is true, then the eigenvectors are also computed
   * and can be retrieved by calling eigenvectors().
   *
   * The matrix is first reduced to real generalized Schur form using the RealQZ
   * class. The generalized Schur decomposition is then used to compute the eigenvalues
   * and eigenvectors.
   *
   * The cost of the computation is dominated by the cost of the
   * generalized Schur decomposition.
   *
   * This method reuses of the allocated data in the GeneralizedEigenSolver object.
   */
  GeneralizedEigenSolver& compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors = true);

  ComputationInfo info() const {
    eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
    return m_realQZ.info();
  }

  /** Sets the maximal number of iterations allowed.
   */
  GeneralizedEigenSolver& setMaxIterations(Index maxIters) {
    m_realQZ.setMaxIterations(maxIters);
    return *this;
  }

 protected:
  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
  EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL)

  EigenvectorsType m_eivec;
  ComplexVectorType m_alphas;
  VectorType m_betas;
  bool m_computeEigenvectors;
  bool m_isInitialized;
  RealQZ<MatrixType> m_realQZ;
  ComplexVectorType m_tmp;
};

template <typename MatrixType>
GeneralizedEigenSolver<MatrixType>& GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A,
                                                                                const MatrixType& B,
                                                                                bool computeEigenvectors) {
  using std::abs;
  using std::sqrt;
  eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
  Index size = A.cols();
  // Reduce to generalized real Schur form:
  // A = Q S Z and B = Q T Z
  m_realQZ.compute(A, B, computeEigenvectors);
  if (m_realQZ.info() == Success) {
    // Resize storage
    m_alphas.resize(size);
    m_betas.resize(size);
    if (computeEigenvectors) {
      m_eivec.resize(size, size);
      m_tmp.resize(size);
    }

    // Aliases:
    Map<VectorType> v(reinterpret_cast<Scalar*>(m_tmp.data()), size);
    ComplexVectorType& cv = m_tmp;
    const MatrixType& mS = m_realQZ.matrixS();
    const MatrixType& mT = m_realQZ.matrixT();

    Index i = 0;
    while (i < size) {
      if (i == size - 1 || mS.coeff(i + 1, i) == Scalar(0)) {
        // Real eigenvalue
        m_alphas.coeffRef(i) = mS.diagonal().coeff(i);
        m_betas.coeffRef(i) = mT.diagonal().coeff(i);
        if (computeEigenvectors) {
          v.setConstant(Scalar(0.0));
          v.coeffRef(i) = Scalar(1.0);
          // For singular eigenvalues do nothing more
          if (abs(m_betas.coeffRef(i)) >= (std::numeric_limits<RealScalar>::min)()) {
            // Non-singular eigenvalue
            const Scalar alpha = real(m_alphas.coeffRef(i));
            const Scalar beta = m_betas.coeffRef(i);
            for (Index j = i - 1; j >= 0; j--) {
              const Index st = j + 1;
              const Index sz = i - j;
              if (j > 0 && mS.coeff(j, j - 1) != Scalar(0)) {
                // 2x2 block
                Matrix<Scalar, 2, 1> rhs = (alpha * mT.template block<2, Dynamic>(j - 1, st, 2, sz) -
                                            beta * mS.template block<2, Dynamic>(j - 1, st, 2, sz))
                                               .lazyProduct(v.segment(st, sz));
                Matrix<Scalar, 2, 2> lhs =
                    beta * mS.template block<2, 2>(j - 1, j - 1) - alpha * mT.template block<2, 2>(j - 1, j - 1);
                v.template segment<2>(j - 1) = lhs.partialPivLu().solve(rhs);
                j--;
              } else {
                v.coeffRef(j) = -v.segment(st, sz)
                                     .transpose()
                                     .cwiseProduct(beta * mS.block(j, st, 1, sz) - alpha * mT.block(j, st, 1, sz))
                                     .sum() /
                                (beta * mS.coeffRef(j, j) - alpha * mT.coeffRef(j, j));
              }
            }
          }
          m_eivec.col(i).real().noalias() = m_realQZ.matrixZ().transpose() * v;
          m_eivec.col(i).real().normalize();
          m_eivec.col(i).imag().setConstant(0);
        }
        ++i;
      } else {
        // We need to extract the generalized eigenvalues of the pair of a general 2x2 block S and a positive diagonal
        // 2x2 block T Then taking beta=T_00*T_11, we can avoid any division, and alpha is the eigenvalues of A = (U^-1
        // * S * U) * diag(T_11,T_00):

        // T =  [a 0]
        //      [0 b]
        RealScalar a = mT.diagonal().coeff(i), b = mT.diagonal().coeff(i + 1);
        const RealScalar beta = m_betas.coeffRef(i) = m_betas.coeffRef(i + 1) = a * b;

        // ^^ NOTE: using diagonal()(i) instead of coeff(i,i) workarounds a MSVC bug.
        Matrix<RealScalar, 2, 2> S2 = mS.template block<2, 2>(i, i) * Matrix<Scalar, 2, 1>(b, a).asDiagonal();

        Scalar p = Scalar(0.5) * (S2.coeff(0, 0) - S2.coeff(1, 1));
        Scalar z = sqrt(abs(p * p + S2.coeff(1, 0) * S2.coeff(0, 1)));
        const ComplexScalar alpha = ComplexScalar(S2.coeff(1, 1) + p, (beta > 0) ? z : -z);
        m_alphas.coeffRef(i) = conj(alpha);
        m_alphas.coeffRef(i + 1) = alpha;

        if (computeEigenvectors) {
          // Compute eigenvector in position (i+1) and then position (i) is just the conjugate
          cv.setZero();
          cv.coeffRef(i + 1) = Scalar(1.0);
          // here, the "static_cast" workaround expression template issues.
          cv.coeffRef(i) = -(static_cast<Scalar>(beta * mS.coeffRef(i, i + 1)) - alpha * mT.coeffRef(i, i + 1)) /
                           (static_cast<Scalar>(beta * mS.coeffRef(i, i)) - alpha * mT.coeffRef(i, i));
          for (Index j = i - 1; j >= 0; j--) {
            const Index st = j + 1;
            const Index sz = i + 1 - j;
            if (j > 0 && mS.coeff(j, j - 1) != Scalar(0)) {
              // 2x2 block
              Matrix<ComplexScalar, 2, 1> rhs = (alpha * mT.template block<2, Dynamic>(j - 1, st, 2, sz) -
                                                 beta * mS.template block<2, Dynamic>(j - 1, st, 2, sz))
                                                    .lazyProduct(cv.segment(st, sz));
              Matrix<ComplexScalar, 2, 2> lhs =
                  beta * mS.template block<2, 2>(j - 1, j - 1) - alpha * mT.template block<2, 2>(j - 1, j - 1);
              cv.template segment<2>(j - 1) = lhs.partialPivLu().solve(rhs);
              j--;
            } else {
              cv.coeffRef(j) = cv.segment(st, sz)
                                   .transpose()
                                   .cwiseProduct(beta * mS.block(j, st, 1, sz) - alpha * mT.block(j, st, 1, sz))
                                   .sum() /
                               (alpha * mT.coeffRef(j, j) - static_cast<Scalar>(beta * mS.coeffRef(j, j)));
            }
          }
          m_eivec.col(i + 1).noalias() = (m_realQZ.matrixZ().transpose() * cv);
          m_eivec.col(i + 1).normalize();
          m_eivec.col(i) = m_eivec.col(i + 1).conjugate();
        }
        i += 2;
      }
    }
  }
  m_computeEigenvectors = computeEigenvectors;
  m_isInitialized = true;
  return *this;
}

}  // end namespace Eigen

#endif  // EIGEN_GENERALIZEDEIGENSOLVER_H
