// 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_SELFADJOINTEIGENSOLVER_H
#define EIGEN_SELFADJOINTEIGENSOLVER_H

#include "./Tridiagonalization.h"

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

namespace Eigen {

template <typename MatrixType_>
class GeneralizedSelfAdjointEigenSolver;

namespace internal {
template <typename SolverType, int Size, bool IsComplex>
struct direct_selfadjoint_eigenvalues;

template <typename MatrixType, bool WidenFloat = is_same<typename MatrixType::Scalar, float>::value>
struct direct_selfadjoint_eigensolver_matrix_scaling {
  using Scalar = typename MatrixType::Scalar;

  EIGEN_DEVICE_FUNC static void run(MatrixType& matrix, const Scalar& scale) { matrix /= scale; }
};

template <typename MatrixType>
struct direct_selfadjoint_eigensolver_matrix_scaling<MatrixType, true> {
  EIGEN_DEVICE_FUNC static void run(MatrixType& matrix, float scale) {
    // Below this threshold, a subnormal coefficient can be significant relative to the matrix norm.  Widening keeps
    // ARM NEON from flushing that coefficient before the division brings it into the normal range.
    if (scale >= (std::numeric_limits<float>::min)() / NumTraits<float>::epsilon()) {
      matrix /= scale;
      return;
    }
    const double wideScale = double(scale);
    for (Index col = 0; col < matrix.cols(); ++col) {
      for (Index row = 0; row < matrix.rows(); ++row) {
        matrix.coeffRef(row, col) = float(double(matrix.coeff(row, col)) / wideScale);
      }
    }
  }
};

template <bool PerBlockScaling, typename MatrixType, typename DiagType, typename SubDiagType>
EIGEN_DEVICE_FUNC ComputationInfo computeFromTridiagonal_impl(DiagType& diag, SubDiagType& subdiag,
                                                              const Index maxIterations, bool computeEigenvectors,
                                                              MatrixType& eivec);
}  // namespace internal

/** \eigenvalues_module \ingroup Eigenvalues_Module
 *
 *
 * \class SelfAdjointEigenSolver
 *
 * \brief Computes eigenvalues and eigenvectors of selfadjoint matrices
 *
 * \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.
 *
 * A matrix \f$ A \f$ is selfadjoint if it equals its adjoint. For real
 * matrices, this means that the matrix is symmetric: it equals its
 * transpose. This class computes the eigenvalues and eigenvectors of a
 * selfadjoint matrix. These are the scalars \f$ \lambda \f$ and vectors
 * \f$ v \f$ such that \f$ Av = \lambda v \f$.  The eigenvalues of a
 * selfadjoint matrix are always real. 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 D V^{-1} \f$. This is called the
 * eigendecomposition.
 *
 * For a selfadjoint matrix, \f$ V \f$ is unitary, meaning its inverse is equal
 * to its adjoint, \f$ V^{-1} = V^{\dagger} \f$. If \f$ A \f$ is real, then
 * \f$ V \f$ is also real and therefore orthogonal, meaning its inverse is
 * equal to its transpose, \f$ V^{-1} = V^T \f$.
 *
 * The algorithm exploits the fact that the matrix is selfadjoint, making it
 * faster and more accurate than the general purpose eigenvalue algorithms
 * implemented in EigenSolver and ComplexEigenSolver.
 *
 * 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
 * SelfAdjointEigenSolver(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 SelfAdjointEigenSolver(const MatrixType&, int)
 * contains an example of the typical use of this class.
 *
 * To solve the \em generalized eigenvalue problem \f$ Av = \lambda Bv \f$ and
 * the likes, see the class GeneralizedSelfAdjointEigenSolver.
 *
 * \sa MatrixBase::eigenvalues(), class EigenSolver, class ComplexEigenSolver
 */
template <typename MatrixType_>
class SelfAdjointEigenSolver {
 public:
  using MatrixType = MatrixType_;
  enum {
    Size = MatrixType::RowsAtCompileTime,
    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
    Options = internal::traits<MatrixType>::Options,
    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
  };

  /** \brief Scalar type for matrices of type \p MatrixType_. */
  using Scalar = typename MatrixType::Scalar;
  using Index = Eigen::Index;  ///< \deprecated since Eigen 3.3

  using EigenvectorsType = Matrix<Scalar, Size, Size, ColMajor, MaxColsAtCompileTime, MaxColsAtCompileTime>;

  /** \brief Real scalar type for \p MatrixType_.
   *
   * This is just \c Scalar if #Scalar is real (e.g., \c float or
   * \c double), and the type of the real part of \c Scalar if #Scalar is
   * complex.
   */
  using RealScalar = typename NumTraits<Scalar>::Real;

  friend struct internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver, Size, NumTraits<Scalar>::IsComplex>;

  /** \brief Type for vector of eigenvalues as returned by eigenvalues().
   *
   * This is a column vector with entries of type #RealScalar.
   * The length of the vector is the size of \p MatrixType_.
   */
  using VectorType = typename internal::plain_col_type<MatrixType, Scalar>::type;
  using RealVectorType = typename internal::plain_col_type<MatrixType, RealScalar>::type;
  using TridiagonalizationType = Tridiagonalization<MatrixType>;
  using SubDiagonalType = typename TridiagonalizationType::SubDiagonalType;

  /** \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
   * SelfAdjointEigenSolver(Index) for dynamic-size matrices.
   *
   * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp
   * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver.out
   */
  EIGEN_DEVICE_FUNC SelfAdjointEigenSolver()
      : m_eivec(),
        m_workspace(),
        m_eivalues(),
        m_subdiag(),
        m_hcoeffs(),
        m_info(InvalidInput),
        m_isInitialized(false),
        m_eigenvectorsOk(false) {}

  /** \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
   */
  EIGEN_DEVICE_FUNC explicit SelfAdjointEigenSolver(Index size)
      : m_eivec(size, size),
        m_workspace(size),
        m_eivalues(size),
        m_subdiag(size > 1 ? size - 1 : 1),
        m_hcoeffs(size > 1 ? size - 1 : 1),
        m_isInitialized(false),
        m_eigenvectorsOk(false) {}

  /** \brief Constructor; computes eigendecomposition of given matrix.
   *
   * \param[in]  matrix  Selfadjoint matrix whose eigendecomposition is to
   *    be computed. Only the lower triangular part of the matrix is referenced.
   * \param[in]  options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
   *
   * This constructor calls compute(const MatrixType&, int) to compute the
   * eigenvalues of the matrix \p matrix. The eigenvectors are computed if
   * \p options equals #ComputeEigenvectors.
   *
   * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp
   * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.out
   *
   * \sa compute(const MatrixType&, int)
   */
  template <typename InputType>
  EIGEN_DEVICE_FUNC explicit SelfAdjointEigenSolver(const EigenBase<InputType>& matrix,
                                                    int options = ComputeEigenvectors)
      : m_eivec(matrix.rows(), matrix.cols()),
        m_workspace(matrix.cols()),
        m_eivalues(matrix.cols()),
        m_subdiag(matrix.rows() > 1 ? matrix.rows() - 1 : 1),
        m_hcoeffs(matrix.cols() > 1 ? matrix.cols() - 1 : 1),
        m_isInitialized(false),
        m_eigenvectorsOk(false) {
    compute(matrix.derived(), options);
  }

  /** \brief Computes eigendecomposition of given matrix.
   *
   * \param[in]  matrix  Selfadjoint matrix whose eigendecomposition is to
   *    be computed. Only the lower triangular part of the matrix is referenced.
   * \param[in]  options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
   * \returns    Reference to \c *this
   *
   * This function computes the eigenvalues of \p matrix.  The eigenvalues()
   * function can be used to retrieve them.  If \p options equals #ComputeEigenvectors,
   * then the eigenvectors are also computed and can be retrieved by
   * calling eigenvectors().
   *
   * This implementation uses a symmetric QR algorithm. The matrix is first
   * reduced to tridiagonal form using the Tridiagonalization class. The
   * tridiagonal matrix is then brought to diagonal form with implicit
   * symmetric QR steps with Wilkinson shift. Details can be found in
   * Section 8.3 of Golub \& Van Loan, <i>%Matrix Computations</i>.
   *
   * The cost of the computation is about \f$ 9n^3 \f$ if the eigenvectors
   * are required and \f$ 4n^3/3 \f$ if they are not required.
   *
   * This method reuses the memory in the SelfAdjointEigenSolver object that
   * was allocated when the object was constructed, if the size of the
   * matrix does not change.
   *
   * Example: \include SelfAdjointEigenSolver_compute_MatrixType.cpp
   * Output: \verbinclude SelfAdjointEigenSolver_compute_MatrixType.out
   *
   * \sa SelfAdjointEigenSolver(const MatrixType&, int)
   */
  template <typename InputType>
  EIGEN_DEVICE_FUNC SelfAdjointEigenSolver& compute(const EigenBase<InputType>& matrix,
                                                    int options = ComputeEigenvectors);

  /** \brief Computes eigendecomposition of given matrix using a closed-form algorithm
   *
   * This is a variant of compute(const MatrixType&, int options) which
   * directly solves the underlying polynomial equation.
   *
   * Currently only 2x2 and 3x3 matrices for which the sizes are known at compile time are supported (e.g., Matrix3d).
   *
   * This method is usually significantly faster than the QR iterative algorithm
   * but it might also be less accurate. It is also worth noting that
   * for 3x3 matrices it involves trigonometric operations which are
   * not necessarily available for all scalar types.
   *
   * For the 3x3 case, we observed the following worst case relative error regarding the eigenvalues:
   *   - double: 1e-8
   *   - float:  1e-3
   *
   * \sa compute(const MatrixType&, int options)
   */
  EIGEN_DEVICE_FUNC SelfAdjointEigenSolver& computeDirect(const MatrixType& matrix, int options = ComputeEigenvectors);

  /**
   *\brief Computes the eigen decomposition from a tridiagonal symmetric matrix
   *
   * \param[in] diag The vector containing the diagonal of the matrix.
   * \param[in] subdiag The subdiagonal of the matrix.
   * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
   * \returns Reference to \c *this
   *
   * This function assumes that the matrix has been reduced to tridiagonal form.
   *
   * \sa compute(const MatrixType&, int) for more information
   */
  SelfAdjointEigenSolver& computeFromTridiagonal(const RealVectorType& diag, const SubDiagonalType& subdiag,
                                                 int options = ComputeEigenvectors);

  /** \brief Returns the eigenvectors of given matrix.
   *
   * \returns  A const reference to the matrix whose columns are the eigenvectors.
   *
   * \pre The eigenvectors have been computed before.
   *
   * Column \f$ k \f$ of the returned matrix is an eigenvector corresponding
   * to eigenvalue number \f$ k \f$ as returned by eigenvalues().  The
   * eigenvectors are normalized to have (Euclidean) norm equal to one. If
   * this object was used to solve the eigenproblem for the selfadjoint
   * matrix \f$ A \f$, then the matrix returned by this function is the
   * matrix \f$ V \f$ in the eigendecomposition \f$ A = V D V^{-1} \f$.
   *
   * For a selfadjoint matrix, \f$ V \f$ is unitary, meaning its inverse is equal
   * to its adjoint, \f$ V^{-1} = V^{\dagger} \f$. If \f$ A \f$ is real, then
   * \f$ V \f$ is also real and therefore orthogonal, meaning its inverse is
   * equal to its transpose, \f$ V^{-1} = V^T \f$.
   *
   * Example: \include SelfAdjointEigenSolver_eigenvectors.cpp
   * Output: \verbinclude SelfAdjointEigenSolver_eigenvectors.out
   *
   * \sa eigenvalues()
   */
  EIGEN_DEVICE_FUNC const EigenvectorsType& eigenvectors() const {
    eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
    eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
    return m_eivec;
  }

  /** \brief Returns the eigenvalues of given matrix.
   *
   * \returns A const reference to the column vector containing the eigenvalues.
   *
   * \pre The eigenvalues have been computed before.
   *
   * The eigenvalues are repeated according to their algebraic multiplicity,
   * so there are as many eigenvalues as rows in the matrix. The eigenvalues
   * are sorted in increasing order.
   *
   * Example: \include SelfAdjointEigenSolver_eigenvalues.cpp
   * Output: \verbinclude SelfAdjointEigenSolver_eigenvalues.out
   *
   * \sa eigenvectors(), MatrixBase::eigenvalues()
   */
  EIGEN_DEVICE_FUNC const RealVectorType& eigenvalues() const {
    eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
    return m_eivalues;
  }

  /** \brief Computes the positive-definite square root of the matrix.
   *
   * \returns the positive-definite square root of the matrix
   *
   * \pre The eigenvalues and eigenvectors of a positive-definite matrix
   * have been computed before.
   *
   * The square root of a positive-definite matrix \f$ A \f$ is the
   * positive-definite matrix whose square equals \f$ A \f$. This function
   * uses the eigendecomposition \f$ A = V D V^{-1} \f$ to compute the
   * square root as \f$ A^{1/2} = V D^{1/2} V^{-1} \f$.
   *
   * Example: \include SelfAdjointEigenSolver_operatorSqrt.cpp
   * Output: \verbinclude SelfAdjointEigenSolver_operatorSqrt.out
   *
   * \sa operatorInverseSqrt(), <a href="unsupported/group__MatrixFunctions__Module.html">MatrixFunctions Module</a>
   */
  EIGEN_DEVICE_FUNC MatrixType operatorSqrt() const {
    eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
    eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
    return m_eivec * m_eivalues.cwiseSqrt().asDiagonal() * m_eivec.adjoint();
  }

  /** \brief Computes the matrix exponential of the matrix.
   *
   * \returns the matrix exponential of the matrix.
   *
   * \pre The eigenvalues and eigenvectors of a positive-definite matrix
   * have been computed before.
   *
   * \sa operatorInverseSqrt(), operatorSqrt(),
   * <a href="unsupported/group__MatrixFunctions__Module.html">MatrixFunctions Module</a>
   */
  EIGEN_DEVICE_FUNC MatrixType operatorExp() const {
    eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
    eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
    return m_eivec * m_eivalues.array().exp().matrix().asDiagonal() * m_eivec.adjoint();
  }

  /** \brief Computes the inverse square root of the matrix.
   *
   * \returns the inverse positive-definite square root of the matrix
   *
   * \pre The eigenvalues and eigenvectors of a positive-definite matrix
   * have been computed before.
   *
   * This function uses the eigendecomposition \f$ A = V D V^{-1} \f$ to
   * compute the inverse square root as \f$ V D^{-1/2} V^{-1} \f$. This is
   * cheaper than first computing the square root with operatorSqrt() and
   * then its inverse with MatrixBase::inverse().
   *
   * Example: \include SelfAdjointEigenSolver_operatorInverseSqrt.cpp
   * Output: \verbinclude SelfAdjointEigenSolver_operatorInverseSqrt.out
   *
   * \sa operatorSqrt(), MatrixBase::inverse(), <a
   * href="unsupported/group__MatrixFunctions__Module.html">MatrixFunctions Module</a>
   */
  EIGEN_DEVICE_FUNC MatrixType operatorInverseSqrt() const {
    eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
    eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
    return m_eivec * m_eivalues.cwiseInverse().cwiseSqrt().asDiagonal() * m_eivec.adjoint();
  }

  /** \brief Reports whether previous computation was successful.
   *
   * \returns \c Success if computation was successful, \c NoConvergence otherwise.
   */
  EIGEN_DEVICE_FUNC ComputationInfo info() const {
    eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
    return m_info;
  }

  /** \brief Maximum number of iterations.
   *
   * The algorithm terminates if it does not converge within m_maxIterations * n iterations, where n
   * denotes the size of the matrix. This value is currently set to 30 (copied from LAPACK).
   */
  static const int m_maxIterations = 30;

 protected:
  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)

  EigenvectorsType m_eivec;
  VectorType m_workspace;
  RealVectorType m_eivalues;
  typename TridiagonalizationType::SubDiagonalType m_subdiag;
  typename TridiagonalizationType::CoeffVectorType m_hcoeffs;
  ComputationInfo m_info;
  bool m_isInitialized;
  bool m_eigenvectorsOk;
};

namespace internal {
/** \internal
 *
 * \eigenvalues_module \ingroup Eigenvalues_Module
 *
 * Performs a QR step on a tridiagonal symmetric matrix represented as a
 * pair of two vectors \a diag and \a subdiag.
 *
 * \param diag the diagonal part of the input selfadjoint tridiagonal matrix
 * \param subdiag the sub-diagonal part of the input selfadjoint tridiagonal matrix
 * \param start starting index of the submatrix to work on
 * \param end last+1 index of the submatrix to work on
 * \param matrixQ pointer to the column-major matrix holding the eigenvectors, can be 0
 * \param n size of the input matrix
 *
 * For compilation efficiency reasons, this procedure does not use eigen expression
 * for its arguments.
 *
 * Implemented from Golub's "Matrix Computations", algorithm 8.3.2:
 * "implicit symmetric QR step with Wilkinson shift"
 */
template <typename RealScalar, typename Scalar, typename Index>
EIGEN_DEVICE_FUNC static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end,
                                                  Scalar* matrixQ, Index n);
}  // namespace internal

template <typename MatrixType>
template <typename InputType>
EIGEN_DEVICE_FUNC SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>::compute(
    const EigenBase<InputType>& a_matrix, int options) {
  const InputType& matrix(a_matrix.derived());

  EIGEN_USING_STD(abs);
  eigen_assert(matrix.cols() == matrix.rows());
  eigen_assert((options & ~(EigVecMask | GenEigMask)) == 0 && (options & EigVecMask) != EigVecMask &&
               "invalid option parameter");
  bool computeEigenvectors = (options & ComputeEigenvectors) == ComputeEigenvectors;
  Index n = matrix.cols();
  m_eivalues.resize(n, 1);

  if (n == 1) {
    m_eivec = matrix;
    m_eivalues.coeffRef(0, 0) = numext::real(m_eivec.coeff(0, 0));
    if (computeEigenvectors) m_eivec.setOnes(n, n);
    m_info = (numext::isfinite)(m_eivalues.coeffRef(0, 0)) ? Success : NoConvergence;
    m_isInitialized = true;
    m_eigenvectorsOk = computeEigenvectors;
    return *this;
  }

  // declare some aliases
  RealVectorType& diag = m_eivalues;
  EigenvectorsType& mat = m_eivec;

  // Scale the matrix to [-1:1] to avoid overflow/underflow during tridiagonalization
  // and subsequent QR iteration. This uniform scaling ensures the tridiagonal output is
  // well-conditioned. Note: for block-diagonal matrices with widely separated scales, this
  // can underflow small blocks. Users with such matrices should tridiagonalize separately
  // and call computeFromTridiagonal(), which uses per-block scaling.
  mat = matrix.template triangularView<Lower>();
  RealScalar scale = mat.cwiseAbs().maxCoeff();
  if (!(numext::isfinite)(scale)) {
    // Input contains Inf or NaN.
    m_info = NoConvergence;
    m_isInitialized = true;
    m_eigenvectorsOk = false;
    return *this;
  }
  if (numext::is_exactly_zero(scale)) scale = RealScalar(1);
  mat.template triangularView<Lower>() /= scale;
  m_subdiag.resize(n - 1);
  m_hcoeffs.resize(n - 1);
  internal::tridiagonalization_inplace(mat, diag, m_subdiag, m_hcoeffs, m_workspace, computeEigenvectors);

  m_info = internal::computeFromTridiagonal_impl<false>(diag, m_subdiag, m_maxIterations, computeEigenvectors, m_eivec);

  // Scale back the eigenvalues.
  m_eivalues *= scale;

  m_isInitialized = true;
  m_eigenvectorsOk = computeEigenvectors;
  return *this;
}

template <typename MatrixType>
SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>::computeFromTridiagonal(
    const RealVectorType& diag, const SubDiagonalType& subdiag, int options) {
  bool computeEigenvectors = (options & ComputeEigenvectors) == ComputeEigenvectors;

  m_eivalues = diag;
  m_subdiag = subdiag;

  // Check for Inf/NaN in the input.
  {
    RealScalar scale = RealScalar(0);
    if (m_eivalues.size() > 0) scale = m_eivalues.cwiseAbs().maxCoeff();
    if (m_subdiag.size() > 0) scale = numext::maxi(scale, m_subdiag.cwiseAbs().maxCoeff());
    if (!(numext::isfinite)(scale)) {
      m_info = NoConvergence;
      m_isInitialized = true;
      m_eigenvectorsOk = false;
      return *this;
    }
  }

  if (computeEigenvectors) {
    m_eivec.setIdentity(diag.size(), diag.size());
  }
  // Use per-deflation-block scaling (like LAPACK's DSTERF) to avoid losing
  // precision when the tridiagonal entries span a wide range of magnitudes.
  m_info =
      internal::computeFromTridiagonal_impl<true>(m_eivalues, m_subdiag, m_maxIterations, computeEigenvectors, m_eivec);

  m_isInitialized = true;
  m_eigenvectorsOk = computeEigenvectors;
  return *this;
}

namespace internal {
/**
 * \internal
 * \brief Compute the eigendecomposition from a tridiagonal matrix
 *
 * \tparam PerBlockScaling If true, each deflation block is independently scaled to [-1,1] before
 *         QR iteration, following LAPACK's DSTERF approach. This prevents precision loss when entries
 *         span a wide range of magnitudes. When false, the caller is responsible for ensuring the
 *         entries are in a safe range (e.g. by pre-scaling the dense matrix before tridiagonalization).
 * \param[in,out] diag : On input, the diagonal of the matrix, on output the eigenvalues
 * \param[in,out] subdiag : The subdiagonal part of the matrix (entries are modified during the decomposition)
 * \param[in] maxIterations : the maximum number of iterations
 * \param[in] computeEigenvectors : whether the eigenvectors have to be computed or not
 * \param[out] eivec : The matrix to store the eigenvectors if computeEigenvectors==true. Must be allocated on input.
 * \returns \c Success or \c NoConvergence
 */
template <bool PerBlockScaling, typename MatrixType, typename DiagType, typename SubDiagType>
EIGEN_DEVICE_FUNC ComputationInfo computeFromTridiagonal_impl(DiagType& diag, SubDiagType& subdiag,
                                                              const Index maxIterations, bool computeEigenvectors,
                                                              MatrixType& eivec) {
  ComputationInfo info;
  using Scalar = typename MatrixType::Scalar;

  Index n = diag.size();
  Index end = n - 1;
  Index start = 0;
  Index iter = 0;  // total number of iterations

  using RealScalar = typename DiagType::RealScalar;
  const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
  const RealScalar precision_inv = RealScalar(1) / NumTraits<RealScalar>::epsilon();

  // Helper lambda for the deflation test.
  auto deflate = [&](Index lo, Index hi) {
    for (Index i = lo; i < hi; ++i) {
      if (numext::abs(subdiag[i]) < considerAsZero) {
        subdiag[i] = RealScalar(0);
      } else {
        const RealScalar scaled_subdiag = precision_inv * subdiag[i];
        if (scaled_subdiag * scaled_subdiag <= (numext::abs(diag[i]) + numext::abs(diag[i + 1]))) {
          subdiag[i] = RealScalar(0);
        }
      }
    }
  };

  // For per-block scaling, track the currently scaled block and its scale factor.
  // When the outer loop identifies a block outside the scaled region, unscale the old
  // block and scale the new one. This keeps the same outer loop structure (one QR step
  // per iteration) while ensuring each block is processed in scaled coordinates.
  Index scaled_start = -1, scaled_end = -1;
  RealScalar block_scale = RealScalar(1);

  while (end > 0) {
    deflate(start, end);

    // Find the largest unreduced block at the end of the matrix.
    while (end > 0 && numext::is_exactly_zero(subdiag[end - 1])) {
      end--;
    }
    if (end <= 0) break;

    // if we spent too many iterations, we give up
    iter++;
    if (iter > maxIterations * n) break;

    start = end - 1;
    while (start > 0 && !numext::is_exactly_zero(subdiag[start - 1])) start--;

    if (PerBlockScaling) {
      // Check if we've moved to a different block than the one currently scaled.
      if (start != scaled_start || end != scaled_end) {
        // Unscale the previous block if it was scaled.
        if (block_scale != RealScalar(1)) {
          for (Index i = scaled_start; i <= scaled_end; ++i) diag[i] /= block_scale;
          for (Index i = scaled_start; i < scaled_end; ++i) {
            if (!numext::is_exactly_zero(subdiag[i])) subdiag[i] /= block_scale;
          }
          block_scale = RealScalar(1);
        }
        // Compute the norm and scale the new block to [-1:1].
        RealScalar block_norm = RealScalar(0);
        for (Index i = start; i <= end; ++i) block_norm = numext::maxi(block_norm, numext::abs(diag[i]));
        for (Index i = start; i < end; ++i) block_norm = numext::maxi(block_norm, numext::abs(subdiag[i]));
        if (block_norm > RealScalar(0) && block_norm != RealScalar(1)) {
          block_scale = RealScalar(1) / block_norm;
          for (Index i = start; i <= end; ++i) diag[i] *= block_scale;
          for (Index i = start; i < end; ++i) subdiag[i] *= block_scale;
        }
        scaled_start = start;
        scaled_end = end;
      }
    }

    internal::tridiagonal_qr_step(diag.data(), subdiag.data(), start, end,
                                  computeEigenvectors ? eivec.data() : (Scalar*)0, n);
  }

  // Unscale any remaining scaled block.
  if (PerBlockScaling && block_scale != RealScalar(1)) {
    for (Index i = scaled_start; i <= scaled_end; ++i) diag[i] /= block_scale;
    for (Index i = scaled_start; i < scaled_end; ++i) {
      if (!numext::is_exactly_zero(subdiag[i])) subdiag[i] /= block_scale;
    }
  }
  if (iter <= maxIterations * n)
    info = Success;
  else
    info = NoConvergence;

  // Sort eigenvalues and corresponding vectors.
  // TODO: make the sort optional and use a more efficient sorting algorithm.
  if (info == Success) {
    for (Index i = 0; i < n - 1; ++i) {
      // Scalar argmin: the vectorized minCoeff path can return the wrong
      // index on targets whose SIMD reduction flushes subnormals (32-bit ARM
      // NEON always treats subnormal inputs to vminq_f32 as zero), which
      // corrupts ordering when eigenvalues span the subnormal range.
      Index k = i;
      RealScalar min_val = diag[i];
      for (Index j = i + 1; j < n; ++j) {
        if (diag[j] < min_val) {
          min_val = diag[j];
          k = j;
        }
      }
      if (k != i) {
        numext::swap(diag[i], diag[k]);
        if (computeEigenvectors) eivec.col(i).swap(eivec.col(k));
      }
    }
  }
  return info;
}

template <typename SolverType, int Size, bool IsComplex>
struct direct_selfadjoint_eigenvalues {
  EIGEN_DEVICE_FUNC static inline void run(SolverType& eig, const typename SolverType::MatrixType& A, int options) {
    eig.compute(A, options);
  }
};

template <typename SolverType>
struct direct_selfadjoint_eigenvalues<SolverType, 3, false> {
  using MatrixType = typename SolverType::MatrixType;
  using VectorType = typename SolverType::RealVectorType;
  using Scalar = typename SolverType::Scalar;
  using EigenvectorsType = typename SolverType::EigenvectorsType;

  /** \internal
   * Computes the roots of the characteristic polynomial of \a m.
   * For numerical stability m.trace() should be near zero and to avoid over- or underflow m should be normalized.
   */
  EIGEN_DEVICE_FUNC static inline void computeRoots(const MatrixType& m, VectorType& roots) {
    EIGEN_USING_STD(sqrt)
    EIGEN_USING_STD(atan2)
    EIGEN_USING_STD(cos)
    EIGEN_USING_STD(sin)
    const Scalar s_inv3 = Scalar(1) / Scalar(3);
    const Scalar s_sqrt3 = sqrt(Scalar(3));

    // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0.  The
    // eigenvalues are the roots to this equation, all guaranteed to be
    // real-valued, because the matrix is symmetric.
    Scalar c0 = m(0, 0) * m(1, 1) * m(2, 2) + Scalar(2) * m(1, 0) * m(2, 0) * m(2, 1) - m(0, 0) * m(2, 1) * m(2, 1) -
                m(1, 1) * m(2, 0) * m(2, 0) - m(2, 2) * m(1, 0) * m(1, 0);
    Scalar c1 = m(0, 0) * m(1, 1) - m(1, 0) * m(1, 0) + m(0, 0) * m(2, 2) - m(2, 0) * m(2, 0) + m(1, 1) * m(2, 2) -
                m(2, 1) * m(2, 1);
    Scalar c2 = m(0, 0) + m(1, 1) + m(2, 2);

    // Construct the parameters used in classifying the roots of the equation
    // and in solving the equation for the roots in closed form.
    Scalar c2_over_3 = c2 * s_inv3;
    Scalar a_over_3 = (c2 * c2_over_3 - c1) * s_inv3;
    a_over_3 = numext::maxi(a_over_3, Scalar(0));

    Scalar half_b = Scalar(0.5) * (c0 + c2_over_3 * (Scalar(2) * c2_over_3 * c2_over_3 - c1));

    Scalar q = a_over_3 * a_over_3 * a_over_3 - half_b * half_b;
    q = numext::maxi(q, Scalar(0));

    // Compute the eigenvalues by solving for the roots of the polynomial.
    Scalar rho = sqrt(a_over_3);
    Scalar theta = atan2(sqrt(q), half_b) * s_inv3;  // since sqrt(q) > 0, atan2 is in [0, pi] and theta is in [0, pi/3]
    Scalar cos_theta = cos(theta);
    Scalar sin_theta = sin(theta);
    // roots are already sorted, since cos is monotonically decreasing on [0, pi]
    roots(0) = c2_over_3 - rho * (cos_theta + s_sqrt3 * sin_theta);  // == 2*rho*cos(theta+2pi/3)
    roots(1) = c2_over_3 - rho * (cos_theta - s_sqrt3 * sin_theta);  // == 2*rho*cos(theta+ pi/3)
    roots(2) = c2_over_3 + Scalar(2) * rho * cos_theta;
  }

  EIGEN_DEVICE_FUNC static inline bool extract_kernel(MatrixType& mat, Ref<VectorType> res,
                                                      Ref<VectorType> representative) {
    EIGEN_USING_STD(abs);
    EIGEN_USING_STD(sqrt);
    Index i0;
    // Find non-zero column i0 (by construction, there must exist a non zero coefficient on the diagonal):
    mat.diagonal().cwiseAbs().maxCoeff(&i0);
    // mat.col(i0) is a good candidate for an orthogonal vector to the current eigenvector,
    // so let's save it:
    representative = mat.col(i0);
    Scalar n0, n1;
    VectorType c0, c1;
    n0 = (c0 = representative.cross(mat.col((i0 + 1) % 3))).squaredNorm();
    n1 = (c1 = representative.cross(mat.col((i0 + 2) % 3))).squaredNorm();
    if (n0 > n1)
      res = c0 / sqrt(n0);
    else
      res = c1 / sqrt(n1);

    return true;
  }

  EIGEN_DEVICE_FUNC static inline void run(SolverType& solver, const MatrixType& mat, int options) {
    eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows());
    eigen_assert((options & ~(EigVecMask | GenEigMask)) == 0 && (options & EigVecMask) != EigVecMask &&
                 "invalid option parameter");
    bool computeEigenvectors = (options & ComputeEigenvectors) == ComputeEigenvectors;

    EigenvectorsType& eivecs = solver.m_eivec;
    VectorType& eivals = solver.m_eivalues;

    // Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow.
    Scalar shift = mat.trace() / Scalar(3);
    // TODO: avoid this copy. Currently necessary to suppress bogus values when determining maxCoeff and for
    // computing the eigenvectors later.
    MatrixType scaledMat = mat.template selfadjointView<Lower>();
    scaledMat.diagonal().array() -= shift;
    Scalar scale = scaledMat.cwiseAbs().maxCoeff();
    if (scale > 0) direct_selfadjoint_eigensolver_matrix_scaling<MatrixType>::run(scaledMat, scale);

    // compute the eigenvalues
    computeRoots(scaledMat, eivals);

    // computeRoots produces theoretically sorted roots, but floating-point
    // rounding in the trigonometric formulas can break the ordering.
    // Enforce sorting with a branchless min/max network (3 elements).
    {
      Scalar tmp;
      if (eivals(0) > eivals(1)) {
        tmp = eivals(0);
        eivals(0) = eivals(1);
        eivals(1) = tmp;
      }
      if (eivals(1) > eivals(2)) {
        tmp = eivals(1);
        eivals(1) = eivals(2);
        eivals(2) = tmp;
      }
      if (eivals(0) > eivals(1)) {
        tmp = eivals(0);
        eivals(0) = eivals(1);
        eivals(1) = tmp;
      }
    }

    // compute the eigenvectors
    if (computeEigenvectors) {
      if ((eivals(2) - eivals(0)) <= Eigen::NumTraits<Scalar>::epsilon()) {
        // All three eigenvalues are numerically the same
        eivecs.setIdentity();
      } else {
        MatrixType tmp;
        tmp = scaledMat;

        // Compute the eigenvector of the most distinct eigenvalue
        Scalar d0 = eivals(2) - eivals(1);
        Scalar d1 = eivals(1) - eivals(0);
        Index k(0), l(2);
        if (d0 > d1) {
          numext::swap(k, l);
          d0 = d1;
        }

        // Compute the eigenvector of index k
        {
          tmp.diagonal().array() -= eivals(k);
          // By construction, 'tmp' is of rank 2, and its kernel corresponds to the respective eigenvector.
          extract_kernel(tmp, eivecs.col(k), eivecs.col(l));
        }

        // Compute eigenvector of index l
        if (d0 <= 2 * Eigen::NumTraits<Scalar>::epsilon() * d1) {
          // If d0 is too small, then the two other eigenvalues are numerically the same,
          // and thus we only have to ortho-normalize the near orthogonal vector we saved above.
          eivecs.col(l) -= eivecs.col(k).dot(eivecs.col(l)) * eivecs.col(k);
          eivecs.col(l).normalize();
        } else {
          tmp = scaledMat;
          tmp.diagonal().array() -= eivals(l);

          VectorType dummy;
          extract_kernel(tmp, eivecs.col(l), dummy);
        }

        // Compute last eigenvector from the other two
        eivecs.col(1) = eivecs.col(2).cross(eivecs.col(0)).normalized();
      }
    }

    // Rescale back to the original size.
    eivals *= scale;
    eivals.array() += shift;

    solver.m_info = Success;
    solver.m_isInitialized = true;
    solver.m_eigenvectorsOk = computeEigenvectors;
  }
};

// 2x2 direct eigenvalues decomposition, code from Hauke Heibel
template <typename SolverType>
struct direct_selfadjoint_eigenvalues<SolverType, 2, false> {
  using MatrixType = typename SolverType::MatrixType;
  using VectorType = typename SolverType::RealVectorType;
  using Scalar = typename SolverType::Scalar;
  using EigenvectorsType = typename SolverType::EigenvectorsType;

  EIGEN_DEVICE_FUNC static inline void computeRoots(const MatrixType& m, VectorType& roots) {
    EIGEN_USING_STD(sqrt);
    const Scalar t0 = Scalar(0.5) * sqrt(numext::abs2(m(0, 0) - m(1, 1)) + Scalar(4) * numext::abs2(m(1, 0)));
    const Scalar t1 = Scalar(0.5) * (m(0, 0) + m(1, 1));
    roots(0) = t1 - t0;
    roots(1) = t1 + t0;
  }

  EIGEN_DEVICE_FUNC static inline void run(SolverType& solver, const MatrixType& mat, int options) {
    EIGEN_USING_STD(sqrt);
    EIGEN_USING_STD(abs);

    eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows());
    eigen_assert((options & ~(EigVecMask | GenEigMask)) == 0 && (options & EigVecMask) != EigVecMask &&
                 "invalid option parameter");
    bool computeEigenvectors = (options & ComputeEigenvectors) == ComputeEigenvectors;

    EigenvectorsType& eivecs = solver.m_eivec;
    VectorType& eivals = solver.m_eivalues;

    // Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow.
    Scalar shift = mat.trace() / Scalar(2);
    MatrixType scaledMat = mat;
    scaledMat.coeffRef(0, 1) = mat.coeff(1, 0);
    scaledMat.diagonal().array() -= shift;
    Scalar scale = scaledMat.cwiseAbs().maxCoeff();
    if (scale > Scalar(0)) direct_selfadjoint_eigensolver_matrix_scaling<MatrixType>::run(scaledMat, scale);

    // Compute the eigenvalues
    computeRoots(scaledMat, eivals);

    // compute the eigen vectors
    if (computeEigenvectors) {
      if ((eivals(1) - eivals(0)) <= abs(eivals(1)) * Eigen::NumTraits<Scalar>::epsilon()) {
        eivecs.setIdentity();
      } else {
        scaledMat.diagonal().array() -= eivals(1);
        Scalar a2 = numext::abs2(scaledMat(0, 0));
        Scalar c2 = numext::abs2(scaledMat(1, 1));
        Scalar b2 = numext::abs2(scaledMat(1, 0));
        if (a2 > c2) {
          eivecs.col(1) << -scaledMat(1, 0), scaledMat(0, 0);
          eivecs.col(1) /= sqrt(a2 + b2);
        } else {
          eivecs.col(1) << -scaledMat(1, 1), scaledMat(1, 0);
          eivecs.col(1) /= sqrt(c2 + b2);
        }

        eivecs.col(0) << eivecs.col(1).unitOrthogonal();
      }
    }

    // Rescale back to the original size.
    eivals *= scale;
    eivals.array() += shift;

    solver.m_info = Success;
    solver.m_isInitialized = true;
    solver.m_eigenvectorsOk = computeEigenvectors;
  }
};

}  // namespace internal

template <typename MatrixType>
EIGEN_DEVICE_FUNC SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>::computeDirect(
    const MatrixType& matrix, int options) {
  internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver, Size, NumTraits<Scalar>::IsComplex>::run(
      *this, matrix, options);
  return *this;
}

namespace internal {

// Francis implicit QR step. matrixQ, if non-null, is column-major: SelfAdjointEigenSolver's
// EigenvectorsType is hardcoded ColMajor regardless of the user's MatrixType storage order.
template <typename RealScalar, typename Scalar, typename Index>
EIGEN_DEVICE_FUNC static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end,
                                                  Scalar* matrixQ, Index n) {
  // Wilkinson Shift.
  RealScalar td = (diag[end - 1] - diag[end]) * RealScalar(0.5);
  RealScalar e = subdiag[end - 1];
  RealScalar mu = diag[end];
  if (numext::is_exactly_zero(td)) {
    mu -= numext::abs(e);
  } else if (!numext::is_exactly_zero(e)) {
    const RealScalar e2 = numext::abs2(e);
    if (numext::is_exactly_zero(e2)) {
      // Scaling prevents e^2 and td^2 from overflowing, but e^2 can still underflow. A subdiagonal that survives
      // deflation satisfies (e/epsilon)^2 > 2*abs(td), so td/e remains bounded in this branch. LAPACK's xSTEQR uses
      // this dimensionless form; keeping td/e inside hypot prevents fast-math from reassociating the correction into
      // an underflowing e^2 expression.
      const RealScalar ratio = td / e;
      const RealScalar h = numext::hypot(ratio, RealScalar(1));
      mu -= e / (ratio + (ratio > RealScalar(0) ? h : -h));
    } else {
      const RealScalar h = numext::hypot(td, e);
      mu -= e2 / (td + (td > RealScalar(0) ? h : -h));
    }
  }

  RealScalar x = diag[start] - mu;
  RealScalar z = subdiag[start];
  // If z ever becomes zero, the Givens rotation will be the identity and
  // z will stay zero for all future iterations.
  for (Index k = start; k < end && !numext::is_exactly_zero(z); ++k) {
    JacobiRotation<RealScalar> rot;
    rot.makeGivens(x, z);

    // do T = G' T G. The two new diagonal entries and the new off-diagonal are all expressed below
    // as functions of the original difference diff = diag[k] - diag[k+1] and the original subdiag[k],
    // so capture diff and compute delta/subdiag[k] before overwriting the diagonal.
    const RealScalar diff = diag[k] - diag[k + 1];

    // Update the 2x2 diagonal block by the symmetric change delta, applied with opposite signs to
    // diag[k] and diag[k+1]. A similarity leaves the trace invariant, so this preserves diag[k] +
    // diag[k+1] exactly. Forming the two new diagonal entries from independent explicit formulas
    // (diag[k] = c^2 d_k - 2 c s e_k + s^2 d_{k+1}, diag[k+1] = s^2 d_k + 2 c s e_k + c^2 d_{k+1})
    // instead lets the two roundings drift the trace a little on every rotation, an error that
    // accumulates over the O(n^2) rotations of a full solve and measurably degrades the eigenvalues.
    // Algebraically delta = s^2 (d_k - d_{k+1}) + 2 c s e_k, which is exactly d_k minus the formula above.
    const RealScalar delta = rot.s() * (rot.s() * diff + RealScalar(2) * rot.c() * subdiag[k]);
    // The exact (G' T G) off-diagonal, c*s*(d_k - d_{k+1}) + (c^2 - s^2)*e_k, written in the same diff
    // form rather than via the c*sdk - s*dkp1 temporaries.
    subdiag[k] = rot.c() * rot.s() * diff + (rot.c() * rot.c() - rot.s() * rot.s()) * subdiag[k];
    diag[k] -= delta;
    diag[k + 1] += delta;

    if (k > start) subdiag[k - 1] = rot.c() * subdiag[k - 1] - rot.s() * z;

    // "Chasing the bulge" to return to triangular form.
    x = subdiag[k];
    if (k < end - 1) {
      z = -rot.s() * subdiag[k + 1];
      subdiag[k + 1] = rot.c() * subdiag[k + 1];
    }

    // apply the givens rotation to the unit matrix Q = Q * G
    if (matrixQ) {
      Map<Matrix<Scalar, Dynamic, Dynamic, ColMajor> > q(matrixQ, n, n);
      q.applyOnTheRight(k, k + 1, rot);
    }
  }
}

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_SELFADJOINTEIGENSOLVER_H
