// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.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/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H
#define EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H

#include "./Tridiagonalization.h"

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

namespace Eigen {

/** \eigenvalues_module \ingroup Eigenvalues_Module
 *
 *
 * \class GeneralizedSelfAdjointEigenSolver
 *
 * \brief Computes eigenvalues and eigenvectors of the generalized selfadjoint eigen problem
 *
 * \tparam MatrixType_ the type of the matrix of which we are computing the
 * eigendecomposition; this is expected to be an instantiation of the Matrix
 * class template.
 *
 * This class solves the generalized eigenvalue problem
 * \f$ Av = \lambda Bv \f$. In this case, the matrix \f$ A \f$ should be
 * selfadjoint and the matrix \f$ B \f$ should be positive definite.
 *
 * Only the \b lower \b triangular \b part of the input matrix is referenced.
 *
 * Call the function compute() to compute the eigenvalues and eigenvectors of
 * a given matrix. Alternatively, you can use the
 * GeneralizedSelfAdjointEigenSolver(const MatrixType&, const MatrixType&, int)
 * 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.
 *
 * The documentation for GeneralizedSelfAdjointEigenSolver(const MatrixType&, const MatrixType&, int)
 * contains an example of the typical use of this class.
 *
 * \sa class SelfAdjointEigenSolver, class EigenSolver, class ComplexEigenSolver
 */
template <typename MatrixType_>
class GeneralizedSelfAdjointEigenSolver : public SelfAdjointEigenSolver<MatrixType_> {
  using Base = SelfAdjointEigenSolver<MatrixType_>;

 public:
  using MatrixType = MatrixType_;

  /** \brief Default constructor for fixed-size matrices.
   *
   * The default constructor is useful in cases in which the user intends to
   * perform decompositions via compute(). This constructor
   * can only be used if \p MatrixType_ is a fixed-size matrix; use
   * GeneralizedSelfAdjointEigenSolver(Index) for dynamic-size matrices.
   */
  GeneralizedSelfAdjointEigenSolver() : Base(), m_cholB(), m_matC() {}

  /** \brief Constructor, pre-allocates memory for dynamic-size matrices.
   *
   * \param [in]  size  Positive integer, size of the matrix whose
   * eigenvalues and eigenvectors will be computed.
   *
   * This constructor is useful for dynamic-size matrices, when the user
   * intends to perform decompositions via compute(). The \p size
   * parameter is only used as a hint. It is not an error to give a wrong
   * \p size, but it may impair performance.
   *
   * \sa compute() for an example
   */
  explicit GeneralizedSelfAdjointEigenSolver(Index size) : Base(size), m_cholB(size), m_matC(size, size) {}

  /** \brief Constructor; computes generalized eigendecomposition of given matrix pencil.
   *
   * \param[in]  matA  Selfadjoint matrix in matrix pencil.
   *                   Only the lower triangular part of the matrix is referenced.
   * \param[in]  matB  Positive-definite matrix in matrix pencil.
   *                   Only the lower triangular part of the matrix is referenced.
   * \param[in]  options A or-ed set of flags {#ComputeEigenvectors,#EigenvaluesOnly} | {#Ax_lBx,#ABx_lx,#BAx_lx}.
   *                     Default is #ComputeEigenvectors|#Ax_lBx.
   *
   * This constructor calls compute(const MatrixType&, const MatrixType&, int)
   * to compute the eigenvalues and (if requested) the eigenvectors of the
   * generalized eigenproblem \f$ Ax = \lambda B x \f$ with \a matA the
   * selfadjoint matrix \f$ A \f$ and \a matB the positive definite matrix
   * \f$ B \f$. Each eigenvector \f$ x \f$ satisfies the property
   * \f$ x^* B x = 1 \f$ for \c Ax_lBx and \c ABx_lx, and the property
   * \f$ x^* B^{-1} x = 1 \f$ for \c BAx_lx. The eigenvectors are computed if
   * \a options contains ComputeEigenvectors.
   *
   * In addition, the two following variants can be solved via \p options:
   * - \c ABx_lx: \f$ ABx = \lambda x \f$
   * - \c BAx_lx: \f$ BAx = \lambda x \f$
   *
   * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp
   * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.out
   *
   * \sa compute(const MatrixType&, const MatrixType&, int)
   */
  template <typename InputTypeA, typename InputTypeB>
  GeneralizedSelfAdjointEigenSolver(const EigenBase<InputTypeA>& matA, const EigenBase<InputTypeB>& matB,
                                    int options = ComputeEigenvectors | Ax_lBx)
      : Base(matA.cols()) {
    compute(matA.derived(), matB.derived(), options);
  }

  /** \brief Constructor for \link InplaceDecomposition inplace decomposition \endlink
   *
   * \param[in,out]  matA  Selfadjoint matrix in matrix pencil.
   *                       Only the lower triangular part of the matrix is referenced.
   * \param[in,out]  matB  Positive-definite matrix in matrix pencil.
   *                       Only the lower triangular part of the matrix is referenced.
   * \param[in]  options A or-ed set of flags {#ComputeEigenvectors,#EigenvaluesOnly} | {#Ax_lBx,#ABx_lx,#BAx_lx}.
   *                     Default is #ComputeEigenvectors|#Ax_lBx.
   *
   * This constructor is only available when \p MatrixType is a Ref<>. The decomposition is then computed within
   * the memory of \p matA and \p matB: \p matB receives the Cholesky factor of B and \p matA the transformed
   * matrix C, then, with #ComputeEigenvectors, the eigenvectors, which eigenvectors() refers to. The forms
   * #ABx_lx and #BAx_lx allocate one temporary of the size of \p matA for the products that cannot run in place.
   */
  template <typename InputTypeA, typename InputTypeB, bool IsRef = internal::is_ref<MatrixType>::value,
            std::enable_if_t<IsRef, int> = 0>
  GeneralizedSelfAdjointEigenSolver(EigenBase<InputTypeA>& matA, EigenBase<InputTypeB>& matB,
                                    int options = ComputeEigenvectors | Ax_lBx)
      : Base(matA, typename Base::BindStorageTag()), m_cholB(matB.derived()), m_matC(matA.derived()) {
    // Complete the upper triangle from the referenced lower one.
    m_matC = m_matC.template selfadjointView<Lower>();
    computeInPlace(options);
  }

  /** \brief Computes generalized eigendecomposition of given matrix pencil.
   *
   * \param[in]  matA  Selfadjoint matrix in matrix pencil.
   *                   Only the lower triangular part of the matrix is referenced.
   * \param[in]  matB  Positive-definite matrix in matrix pencil.
   *                   Only the lower triangular part of the matrix is referenced.
   * \param[in]  options A or-ed set of flags {#ComputeEigenvectors,#EigenvaluesOnly} | {#Ax_lBx,#ABx_lx,#BAx_lx}.
   *                     Default is #ComputeEigenvectors|#Ax_lBx.
   *
   * \returns    Reference to \c *this
   *
   * According to \p options, this function computes eigenvalues and (if requested)
   * the eigenvectors of one of the following three generalized eigenproblems:
   * - \c Ax_lBx: \f$ Ax = \lambda B x \f$
   * - \c ABx_lx: \f$ ABx = \lambda x \f$
   * - \c BAx_lx: \f$ BAx = \lambda x \f$
   * with \a matA the selfadjoint matrix \f$ A \f$ and \a matB the positive definite
   * matrix \f$ B \f$.
   * In addition, each eigenvector \f$ x \f$ satisfies the property \f$ x^* B x = 1 \f$ for \c Ax_lBx and \c ABx_lx.
   * For \c BAx_lx, the eigenvectors are instead normalized such that \f$ x^* B^{-1} x = 1 \f$, following the same
   * convention as LAPACK's \c ?sygv with \c itype=3.
   *
   * The eigenvalues() function can be used to retrieve
   * the eigenvalues. If \p options contains ComputeEigenvectors, then the
   * eigenvectors are also computed and can be retrieved by calling
   * eigenvectors().
   *
   * The implementation uses LLT to compute the Cholesky decomposition
   * \f$ B = LL^* \f$ and computes the classical eigendecomposition
   * of the selfadjoint matrix \f$ L^{-1} A (L^*)^{-1} \f$ if \p options contains Ax_lBx
   * and of \f$ L^{*} A L \f$ otherwise. This solves the
   * generalized eigenproblem, because any solution of the generalized
   * eigenproblem \f$ Ax = \lambda B x \f$ corresponds to a solution
   * \f$ L^{-1} A (L^*)^{-1} (L^* x) = \lambda (L^* x) \f$ of the
   * eigenproblem for \f$ L^{-1} A (L^*)^{-1} \f$. Similar statements
   * can be made for the two other variants.
   *
   * Example: \include SelfAdjointEigenSolver_compute_MatrixType2.cpp
   * Output: \verbinclude SelfAdjointEigenSolver_compute_MatrixType2.out
   *
   * \sa GeneralizedSelfAdjointEigenSolver(const MatrixType&, const MatrixType&, int)
   */
  template <typename InputTypeA, typename InputTypeB>
  GeneralizedSelfAdjointEigenSolver& compute(const EigenBase<InputTypeA>& matA, const EigenBase<InputTypeB>& matB,
                                             int options = ComputeEigenvectors | Ax_lBx);

 protected:
  // Reused across compute() calls so that a solver constructed with its size,
  // or computed with once, does not allocate again.
  LLT<MatrixType> m_cholB;
  MatrixType m_matC;

 private:
  GeneralizedSelfAdjointEigenSolver& computeInPlace(int options);
};

template <typename MatrixType>
template <typename InputTypeA, typename InputTypeB>
GeneralizedSelfAdjointEigenSolver<MatrixType>& GeneralizedSelfAdjointEigenSolver<MatrixType>::compute(
    const EigenBase<InputTypeA>& matA, const EigenBase<InputTypeB>& matB, int options) {
  EIGEN_INTERNAL_ASSERT_SQUARE(matA);
  EIGEN_INTERNAL_ASSERT_SAME_SHAPE(matA, matB);

  // Compute the cholesky decomposition of matB = L L' = U'U
  m_cholB.compute(matB.derived());
  m_matC = matA.derived().template selfadjointView<Lower>();
  return computeInPlace(options);
}

/** \internal Computes the generalized eigendecomposition from the Cholesky factor of B held by m_cholB and the
 * selfadjoint matrix A held in full by m_matC, which is overwritten by the transformed matrix C. */
template <typename MatrixType>
GeneralizedSelfAdjointEigenSolver<MatrixType>& GeneralizedSelfAdjointEigenSolver<MatrixType>::computeInPlace(
    int options) {
  EIGEN_INTERNAL_ASSERT_SQUARE(m_matC);
  EIGEN_INTERNAL_ASSERT_SAME_ROWS(m_cholB, m_matC);
  eigen_assert((options & ~(EigVecMask | GenEigMask)) == 0 && (options & EigVecMask) != EigVecMask &&
               ((options & GenEigMask) == 0 || (options & GenEigMask) == Ax_lBx || (options & GenEigMask) == ABx_lx ||
                (options & GenEigMask) == BAx_lx) &&
               "invalid option parameter");

  bool computeEigVecs = ((options & EigVecMask) == 0) || ((options & EigVecMask) == ComputeEigenvectors);

  int type = (options & GenEigMask);
  if (type == 0) type = Ax_lBx;

  // In the inplace decomposition the eigenvector storage is the matrix A itself, i.e. m_matC: the products of the
  // ABx_lx and BAx_lx forms, which cannot run in place, then go through a temporary instead.
  const bool eivecIsMatC = internal::is_same_dense(Base::m_eivec, m_matC);

  if (type == Ax_lBx) {
    // compute C = inv(L) A inv(L')
    m_cholB.matrixL().template solveInPlace<OnTheLeft>(m_matC);
    m_cholB.matrixU().template solveInPlace<OnTheRight>(m_matC);

    Base::compute(m_matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly);

    // transform back the eigen vectors: evecs = inv(U) * evecs
    if (computeEigVecs) m_cholB.matrixU().solveInPlace(Base::m_eivec);
  } else if (type == ABx_lx) {
    // compute C = L' A L, using Base::m_eivec for the intermediate product: Base::compute()
    // overwrites it before reading it.
    if (eivecIsMatC) {
      typename Base::PlainMatrixType tmp = m_matC * m_cholB.matrixL();
      m_matC.noalias() = m_cholB.matrixU() * tmp;
    } else {
      Base::m_eivec.noalias() = m_matC * m_cholB.matrixL();
      m_matC.noalias() = m_cholB.matrixU() * Base::m_eivec;
    }

    Base::compute(m_matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly);

    // transform back the eigen vectors: evecs = inv(U) * evecs
    if (computeEigVecs) m_cholB.matrixU().solveInPlace(Base::m_eivec);
  } else if (type == BAx_lx) {
    // compute C = L' A L
    if (eivecIsMatC) {
      typename Base::PlainMatrixType tmp = m_matC * m_cholB.matrixL();
      m_matC.noalias() = m_cholB.matrixU() * tmp;
    } else {
      Base::m_eivec.noalias() = m_matC * m_cholB.matrixL();
      m_matC.noalias() = m_cholB.matrixU() * Base::m_eivec;
    }

    Base::compute(m_matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly);

    // transform back the eigen vectors: evecs = L * evecs, using m_matC as the
    // intermediate: Base::compute() has consumed it.
    if (computeEigVecs) {
      if (eivecIsMatC) {
        Base::m_eivec = m_cholB.matrixL() * Base::m_eivec;
      } else {
        m_matC.noalias() = m_cholB.matrixL() * Base::m_eivec;
        Base::m_eivec = m_matC;
      }
    }
  }

  // The reduction above is only valid for a positive definite B.
  if (m_cholB.info() != Success) Base::m_info = NumericalIssue;

  return *this;
}

}  // end namespace Eigen

#endif  // EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H
