// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 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_TRIDIAGONALIZATION_H
#define EIGEN_TRIDIAGONALIZATION_H

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

namespace Eigen {

namespace internal {

template <typename MatrixType>
struct TridiagonalizationMatrixTReturnType;
template <typename MatrixType>
struct traits<TridiagonalizationMatrixTReturnType<MatrixType>> : public traits<typename MatrixType::PlainObject> {
  // matrixT() returns a dense n x n matrix. A band-stored alternative (e.g. a
  // future matrixTBand() returning BandMatrix<Scalar, Dynamic, Dynamic, 1, 1>)
  // would be ~3n storage instead of n^2, but changing this ReturnType in place
  // would be API-breaking for callers that assume a dense matrix.
  typedef typename MatrixType::PlainObject ReturnType;
  enum { Flags = 0 };
};

template <typename MatrixType, typename CoeffVectorType>
EIGEN_DEVICE_FUNC void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs);
}  // namespace internal

/** \eigenvalues_module \ingroup Eigenvalues_Module
 *
 *
 * \class Tridiagonalization
 *
 * \brief Tridiagonal decomposition of a selfadjoint matrix
 *
 * \tparam MatrixType_ the type of the matrix of which we are computing the
 * tridiagonal decomposition; this is expected to be an instantiation of the
 * Matrix class template.
 *
 * This class performs a tridiagonal decomposition of a selfadjoint matrix \f$ A \f$ such that:
 * \f$ A = Q T Q^* \f$ where \f$ Q \f$ is unitary and \f$ T \f$ a real symmetric tridiagonal matrix.
 *
 * A tridiagonal matrix is a matrix which has nonzero elements only on the
 * main diagonal and the first diagonal below and above it. The Hessenberg
 * decomposition of a selfadjoint matrix is in fact a tridiagonal
 * decomposition. This class is used in SelfAdjointEigenSolver to compute the
 * eigenvalues and eigenvectors of a selfadjoint matrix.
 *
 * Call the function compute() to compute the tridiagonal decomposition of a
 * given matrix. Alternatively, you can use the Tridiagonalization(const MatrixType&)
 * constructor which computes the tridiagonal Schur decomposition at
 * construction time. Once the decomposition is computed, you can use the
 * matrixQ() and matrixT() functions to retrieve the matrices Q and T in the
 * decomposition.
 *
 * The documentation of Tridiagonalization(const MatrixType&) contains an
 * example of the typical use of this class.
 *
 * \sa class HessenbergDecomposition, class SelfAdjointEigenSolver
 */
template <typename MatrixType_>
class Tridiagonalization {
 public:
  /** \brief Synonym for the template parameter \p MatrixType_. */
  typedef MatrixType_ MatrixType;

  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Eigen::Index Index;  ///< \deprecated since Eigen 3.3

  enum {
    Size = MatrixType::RowsAtCompileTime,
    SizeMinusOne = Size == Dynamic ? Dynamic : (Size > 1 ? Size - 1 : 1),
    Options = internal::traits<MatrixType>::Options,
    MaxSize = MatrixType::MaxRowsAtCompileTime,
    MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : (MaxSize > 1 ? MaxSize - 1 : 1)
  };

  typedef Matrix<Scalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> CoeffVectorType;
  typedef typename internal::plain_col_type<MatrixType, RealScalar>::type DiagonalType;
  typedef Matrix<RealScalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> SubDiagonalType;
  typedef internal::remove_all_t<typename MatrixType::RealReturnType> MatrixTypeRealView;
  typedef internal::TridiagonalizationMatrixTReturnType<MatrixTypeRealView> MatrixTReturnType;

  typedef std::conditional_t<NumTraits<Scalar>::IsComplex,
                             internal::add_const_on_value_type_t<typename Diagonal<const MatrixType>::RealReturnType>,
                             const Diagonal<const MatrixType>>
      DiagonalReturnType;

  typedef std::conditional_t<
      NumTraits<Scalar>::IsComplex,
      internal::add_const_on_value_type_t<typename Diagonal<const MatrixType, -1>::RealReturnType>,
      const Diagonal<const MatrixType, -1>>
      SubDiagonalReturnType;

  /** \brief Return type of matrixQ() */
  typedef HouseholderSequence<MatrixType, internal::remove_all_t<typename CoeffVectorType::ConjugateReturnType>>
      HouseholderSequenceType;

  /** \brief Default constructor.
   *
   * \param [in]  size  Positive integer, size of the matrix whose tridiagonal
   * decomposition will be computed.
   *
   * The default constructor is useful in cases in which 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 Tridiagonalization(Index size = Size == Dynamic ? 2 : Size)
      : m_matrix(size, size), m_hCoeffs(size > 1 ? size - 1 : 1), m_isInitialized(false) {}

  /** \brief Constructor; computes tridiagonal decomposition of given matrix.
   *
   * \param[in]  matrix  Selfadjoint matrix whose tridiagonal decomposition
   * is to be computed.
   *
   * This constructor calls compute() to compute the tridiagonal decomposition.
   *
   * Example: \include Tridiagonalization_Tridiagonalization_MatrixType.cpp
   * Output: \verbinclude Tridiagonalization_Tridiagonalization_MatrixType.out
   */
  template <typename InputType>
  explicit Tridiagonalization(const EigenBase<InputType>& matrix)
      : m_matrix(matrix.derived()), m_hCoeffs(matrix.cols() > 1 ? matrix.cols() - 1 : 1), m_isInitialized(false) {
    internal::tridiagonalization_inplace(m_matrix, m_hCoeffs);
    m_isInitialized = true;
  }

  /** \brief Computes tridiagonal decomposition of given matrix.
   *
   * \param[in]  matrix  Selfadjoint matrix whose tridiagonal decomposition
   * is to be computed.
   * \returns    Reference to \c *this
   *
   * The tridiagonal decomposition is computed by bringing the columns of
   * the matrix successively in the required form using Householder
   * reflections. The cost is \f$ 4n^3/3 \f$ flops, where \f$ n \f$ denotes
   * the size of the given matrix.
   *
   * This method reuses of the allocated data in the Tridiagonalization
   * object, if the size of the matrix does not change.
   *
   * Example: \include Tridiagonalization_compute.cpp
   * Output: \verbinclude Tridiagonalization_compute.out
   */
  template <typename InputType>
  Tridiagonalization& compute(const EigenBase<InputType>& matrix) {
    m_matrix = matrix.derived();
    m_hCoeffs.resize(matrix.rows() - 1, 1);
    internal::tridiagonalization_inplace(m_matrix, m_hCoeffs);
    m_isInitialized = true;
    return *this;
  }

  /** \brief Returns the Householder coefficients.
   *
   * \returns a const reference to the vector of Householder coefficients
   *
   * \pre Either the constructor Tridiagonalization(const MatrixType&) or
   * the member function compute(const MatrixType&) has been called before
   * to compute the tridiagonal decomposition of a matrix.
   *
   * The Householder coefficients allow the reconstruction of the matrix
   * \f$ Q \f$ in the tridiagonal decomposition from the packed data.
   *
   * Example: \include Tridiagonalization_householderCoefficients.cpp
   * Output: \verbinclude Tridiagonalization_householderCoefficients.out
   *
   * \sa packedMatrix(), \ref Householder_Module "Householder module"
   */
  inline CoeffVectorType householderCoefficients() const {
    eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
    return m_hCoeffs;
  }

  /** \brief Returns the internal representation of the decomposition
   *
   *	\returns a const reference to a matrix with the internal representation
   *	         of the decomposition.
   *
   * \pre Either the constructor Tridiagonalization(const MatrixType&) or
   * the member function compute(const MatrixType&) has been called before
   * to compute the tridiagonal decomposition of a matrix.
   *
   * The returned matrix contains the following information:
   *  - the strict upper triangular part is equal to the input matrix A.
   *  - the diagonal and lower sub-diagonal represent the real tridiagonal
   *    symmetric matrix T.
   *  - the rest of the lower part contains the Householder vectors that,
   *    combined with Householder coefficients returned by
   *    householderCoefficients(), allows to reconstruct the matrix Q as
   *       \f$ Q = H_{N-1} \ldots H_1 H_0 \f$.
   *    Here, the matrices \f$ H_i \f$ are the Householder transformations
   *       \f$ H_i = (I - h_i v_i v_i^T) \f$
   *    where \f$ h_i \f$ is the \f$ i \f$th Householder coefficient and
   *    \f$ v_i \f$ is the Householder vector defined by
   *       \f$ v_i = [ 0, \ldots, 0, 1, M(i+2,i), \ldots, M(N-1,i) ]^T \f$
   *    with M the matrix returned by this function.
   *
   * See LAPACK for further details on this packed storage.
   *
   * Example: \include Tridiagonalization_packedMatrix.cpp
   * Output: \verbinclude Tridiagonalization_packedMatrix.out
   *
   * \sa householderCoefficients()
   */
  inline const MatrixType& packedMatrix() const {
    eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
    return m_matrix;
  }

  /** \brief Returns the unitary matrix Q in the decomposition
   *
   * \returns object representing the matrix Q
   *
   * \pre Either the constructor Tridiagonalization(const MatrixType&) or
   * the member function compute(const MatrixType&) has been called before
   * to compute the tridiagonal decomposition of a matrix.
   *
   * This function returns a light-weight object of template class
   * HouseholderSequence. You can either apply it directly to a matrix or
   * you can convert it to a matrix of type #MatrixType.
   *
   * \sa Tridiagonalization(const MatrixType&) for an example,
   *     matrixT(), class HouseholderSequence
   */
  HouseholderSequenceType matrixQ() const {
    eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
    return HouseholderSequenceType(m_matrix, m_hCoeffs.conjugate()).setLength(m_matrix.rows() - 1).setShift(1);
  }

  /** \brief Returns an expression of the tridiagonal matrix T in the decomposition
   *
   * \returns expression object representing the matrix T
   *
   * \pre Either the constructor Tridiagonalization(const MatrixType&) or
   * the member function compute(const MatrixType&) has been called before
   * to compute the tridiagonal decomposition of a matrix.
   *
   * Currently, this function can be used to extract the matrix T from internal
   * data and copy it to a dense matrix object. In most cases, it may be
   * sufficient to directly use the packed matrix or the vector expressions
   * returned by diagonal() and subDiagonal() instead of creating a new
   * dense copy matrix with this function.
   *
   * \sa Tridiagonalization(const MatrixType&) for an example,
   * matrixQ(), packedMatrix(), diagonal(), subDiagonal()
   */
  MatrixTReturnType matrixT() const {
    eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
    return MatrixTReturnType(m_matrix.real());
  }

  /** \brief Returns the diagonal of the tridiagonal matrix T in the decomposition.
   *
   * \returns expression representing the diagonal of T
   *
   * \pre Either the constructor Tridiagonalization(const MatrixType&) or
   * the member function compute(const MatrixType&) has been called before
   * to compute the tridiagonal decomposition of a matrix.
   *
   * Example: \include Tridiagonalization_diagonal.cpp
   * Output: \verbinclude Tridiagonalization_diagonal.out
   *
   * \sa matrixT(), subDiagonal()
   */
  DiagonalReturnType diagonal() const;

  /** \brief Returns the subdiagonal of the tridiagonal matrix T in the decomposition.
   *
   * \returns expression representing the subdiagonal of T
   *
   * \pre Either the constructor Tridiagonalization(const MatrixType&) or
   * the member function compute(const MatrixType&) has been called before
   * to compute the tridiagonal decomposition of a matrix.
   *
   * \sa diagonal() for an example, matrixT()
   */
  SubDiagonalReturnType subDiagonal() const;

 protected:
  MatrixType m_matrix;
  CoeffVectorType m_hCoeffs;
  bool m_isInitialized;
};

template <typename MatrixType>
typename Tridiagonalization<MatrixType>::DiagonalReturnType Tridiagonalization<MatrixType>::diagonal() const {
  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
  return m_matrix.diagonal().real();
}

template <typename MatrixType>
typename Tridiagonalization<MatrixType>::SubDiagonalReturnType Tridiagonalization<MatrixType>::subDiagonal() const {
  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
  return m_matrix.template diagonal<-1>().real();
}

namespace internal {

/** \internal
 * Unblocked tridiagonal decomposition of the selfadjoint matrix \a matA in-place.
 * Processes one column at a time using Level 2 BLAS operations (SYMV, SYR2).
 *
 * \param[in,out] matA On input the selfadjoint matrix. Only the \b lower triangular part is referenced.
 *                     On output, the strict upper part is left unchanged, and the lower triangular part
 *                     represents the T and Q matrices in packed format has detailed below.
 * \param[out]    hCoeffs returned Householder coefficients (see below)
 *
 * On output, the tridiagonal selfadjoint matrix T is stored in the diagonal
 * and lower sub-diagonal of the matrix \a matA.
 * The unitary matrix Q is represented in a compact way as a product of
 * Householder reflectors \f$ H_i \f$ such that:
 *       \f$ Q = H_{N-1} \ldots H_1 H_0 \f$.
 * The Householder reflectors are defined as
 *       \f$ H_i = (I - h_i v_i v_i^T) \f$
 * where \f$ h_i = hCoeffs[i]\f$ is the \f$ i \f$th Householder coefficient and
 * \f$ v_i \f$ is the Householder vector defined by
 *       \f$ v_i = [ 0, \ldots, 0, 1, matA(i+2,i), \ldots, matA(N-1,i) ]^T \f$.
 *
 * Implemented from Golub's "Matrix Computations", algorithm 8.3.1.
 *
 * \sa Tridiagonalization::packedMatrix()
 */
template <typename MatrixType, typename CoeffVectorType>
EIGEN_DEVICE_FUNC void tridiagonalization_inplace_unblocked(MatrixType& matA, CoeffVectorType& hCoeffs) {
  using numext::conj;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;
  Index n = matA.rows();
  eigen_assert(n == matA.cols());
  eigen_assert(n == hCoeffs.size() + 1 || n == 1);

  for (Index i = 0; i < n - 1; ++i) {
    Index remainingSize = n - i - 1;
    RealScalar beta;
    Scalar h;
    matA.col(i).tail(remainingSize).makeHouseholderInPlace(h, beta);

    // Apply similarity transformation to remaining columns,
    // i.e., A = H A H' where H = I - h v v' and v = matA.col(i).tail(n-i-1)
    matA.col(i).coeffRef(i + 1) = Scalar(1);

    hCoeffs.tail(n - i - 1).noalias() =
        (matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView<Lower>() *
         (conj(h) * matA.col(i).tail(remainingSize)));

    hCoeffs.tail(n - i - 1) +=
        (conj(h) * RealScalar(-0.5) * (hCoeffs.tail(remainingSize).dot(matA.col(i).tail(remainingSize)))) *
        matA.col(i).tail(n - i - 1);

    matA.bottomRightCorner(remainingSize, remainingSize)
        .template selfadjointView<Lower>()
        .rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), Scalar(-1));

    matA.col(i).coeffRef(i + 1) = beta;
    hCoeffs.coeffRef(i) = h;
  }
}

#if !defined(EIGEN_GPU_COMPILE_PHASE)
/** \internal
 * Blocked tridiagonal decomposition (analogous to LAPACK's dsytrd/dlatrd).
 * Processes columns in panels of BlockSize, accumulating Householder reflectors
 * and deferring the symmetric rank-2k update to use Level 3 BLAS (triangular GEMM).
 * Falls back to the unblocked algorithm for the last (partial) panel.
 */
template <typename MatrixType, typename CoeffVectorType>
void tridiagonalization_inplace_blocked(MatrixType& matA, CoeffVectorType& hCoeffs, Index nb = 16) {
  using numext::conj;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;
  const Index n = matA.rows();
  eigen_assert(n == matA.cols());
  eigen_assert(n == hCoeffs.size() + 1);
  eigen_assert(nb >= 2 && nb < n);

  enum {
    StorageOrder = (traits<MatrixType>::Flags & RowMajorBit) ? RowMajor : ColMajor,
    RhsStorageOrder = (StorageOrder == ColMajor) ? RowMajor : ColMajor
  };

  // Workspace: W matrix (n x nb) for deferred update vectors, temp vector (nb) for GEMV, betas (nb).
  typedef Matrix<Scalar, Dynamic, Dynamic, StorageOrder> WorkMatrixType;
  WorkMatrixType W(n, nb);
  Matrix<Scalar, Dynamic, 1> temp(nb);
  Matrix<RealScalar, Dynamic, 1> betas(nb);

  // Pre-allocate GEMM blocking workspace for the largest trailing matrix (first panel).
  // Reused across all panels to avoid repeated heap allocations.
  typedef gemm_blocking_space<StorageOrder, Scalar, Scalar, Dynamic, Dynamic, Dynamic> BlockingType;
  const Index maxTrailingSize = n - nb;
  BlockingType blocking(maxTrailingSize, maxTrailingSize, nb, 1, false);

  Index j0 = 0;
  for (; j0 + nb < n - 1; j0 += nb) {
    const Index j_end = j0 + nb;

    // ---- Panel factorization (dlatrd) ----
    // Process columns j0..j_end-1, computing Householder vectors (stored in matA)
    // and update vectors (stored in W). The rank-2k update to the trailing
    // submatrix is deferred until after the panel.
    for (Index j = j0; j < j_end; ++j) {
      const Index local_j = j - j0;
      const Index remainingSize = n - j - 1;

      // Step 1: Update column j for deferred rank-2 updates from columns j0..j-1.
      // A(j:n-1, j) -= V * W(j,:)^H + W * V(j,:)^H
      // where V = matA(j:n-1, j0:j-1) holds Householder vectors,
      // and W(j:n-1, 0:lj-1) holds the corresponding update vectors.
      if (local_j > 0) {
        auto col_j = matA.col(j).segment(j, n - j);
        col_j.noalias() -= matA.block(j, j0, n - j, local_j) * W.row(j).head(local_j).adjoint();
        col_j.noalias() -= W.block(j, 0, n - j, local_j) * matA.row(j).segment(j0, local_j).adjoint();
        // Keep diagonal real (for complex scalars; no-op for real).
        matA.coeffRef(j, j) = numext::real(matA.coeff(j, j));
      }

      // Step 2: Compute Householder reflector for column j.
      RealScalar beta;
      Scalar h;
      matA.col(j).tail(remainingSize).makeHouseholderInPlace(h, beta);
      betas(local_j) = beta;
      matA.col(j).coeffRef(j + 1) = Scalar(1);

      auto v = matA.col(j).tail(remainingSize);
      auto w = W.col(local_j).tail(remainingSize);

      // Step 3: Compute w = conj(h) * A_eff * v where A_eff accounts for deferred updates.
      // Start with SYMV on the stored (not yet updated) trailing submatrix.
      w.noalias() =
          matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView<Lower>() * (conj(h) * v);

      // GEMV corrections for deferred rank-2 updates within this panel.
      if (local_j > 0) {
        auto V_prev = matA.block(j + 1, j0, remainingSize, local_j);
        auto W_prev = W.block(j + 1, 0, remainingSize, local_j);

        // w -= conj(h) * V_prev * (W_prev^H * v)
        temp.head(local_j).noalias() = W_prev.adjoint() * v;
        w.noalias() -= conj(h) * (V_prev * temp.head(local_j));

        // w -= conj(h) * W_prev * (V_prev^H * v)
        temp.head(local_j).noalias() = V_prev.adjoint() * v;
        w.noalias() -= conj(h) * (W_prev * temp.head(local_j));
      }

      // Step 4: Half-dot correction: w -= 0.5 * conj(h) * (w^H * v) * v
      w += (conj(h) * RealScalar(-0.5) * w.dot(v)) * v;

      hCoeffs.coeffRef(j) = h;
    }

    // ---- Apply rank-2k update to trailing submatrix ----
    // A(j_end:n-1, j_end:n-1) -= V_trail * W_trail^H + W_trail * V_trail^H
    // using Level 3 BLAS (triangular GEMM).
    const Index trailingSize = n - j_end;
    if (trailingSize > 0) {
      const Scalar* V_data = &matA.coeffRef(j_end, j0);
      const Scalar* W_data = &W.coeffRef(j_end, 0);
      Scalar* C_data = &matA.coeffRef(j_end, j_end);
      const Index V_stride = matA.outerStride();
      const Index W_stride = W.outerStride();
      const Index C_stride = matA.outerStride();

      // C -= V * W^H
      general_matrix_matrix_triangular_product<Index, Scalar, StorageOrder, false, Scalar, RhsStorageOrder,
                                               NumTraits<Scalar>::IsComplex, StorageOrder, 1,
                                               Lower>::run(trailingSize, nb, V_data, V_stride, W_data, W_stride, C_data,
                                                           1, C_stride, Scalar(-1), blocking);

      // C -= W * V^H
      general_matrix_matrix_triangular_product<Index, Scalar, StorageOrder, false, Scalar, RhsStorageOrder,
                                               NumTraits<Scalar>::IsComplex, StorageOrder, 1,
                                               Lower>::run(trailingSize, nb, W_data, W_stride, V_data, V_stride, C_data,
                                                           1, C_stride, Scalar(-1), blocking);
    }

    // Restore subdiagonal entries (overwritten with 1 for Householder vectors).
    for (Index j = j0; j < j_end; ++j) {
      matA.coeffRef(j + 1, j) = betas(j - j0);
    }
  }

  // ---- Process remaining columns with unblocked algorithm ----
  if (j0 < n - 1) {
    const Index remaining = n - j0;
    auto trailing = matA.bottomRightCorner(remaining, remaining);
    auto hCoeffs_tail = hCoeffs.segment(j0, remaining - 1);
    tridiagonalization_inplace_unblocked(trailing, hCoeffs_tail);
  }
}
#endif  // !EIGEN_GPU_COMPILE_PHASE

/** \internal
 * Dispatches to blocked or unblocked tridiagonalization based on matrix size.
 * On GPU, always uses the unblocked algorithm.
 */
template <typename MatrixType, typename CoeffVectorType>
EIGEN_DEVICE_FUNC void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs) {
  Index n = matA.rows();
  eigen_assert(n == matA.cols());
  eigen_assert(n == hCoeffs.size() + 1 || n == 1);

#if !defined(EIGEN_GPU_COMPILE_PHASE)
  if ((MatrixType::RowsAtCompileTime == Dynamic || MatrixType::ColsAtCompileTime == Dynamic) && n >= 96) {
    tridiagonalization_inplace_blocked(matA, hCoeffs);
    return;
  }
#endif
  tridiagonalization_inplace_unblocked(matA, hCoeffs);
}

// forward declaration, implementation at the end of this file
template <typename MatrixType, int Size = MatrixType::ColsAtCompileTime,
          bool IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>
struct tridiagonalization_inplace_selector;

/** \brief Performs a full tridiagonalization in place
 *
 * \param[in,out]  mat  On input, the selfadjoint matrix whose tridiagonal
 *    decomposition is to be computed. Only the lower triangular part referenced.
 *    The rest is left unchanged. On output, the orthogonal matrix Q
 *    in the decomposition if \p extractQ is true.
 * \param[out]  diag  The diagonal of the tridiagonal matrix T in the
 *    decomposition.
 * \param[out]  subdiag  The subdiagonal of the tridiagonal matrix T in
 *    the decomposition.
 * \param[out]  hcoeffs
 * \param[out]  workspace
 * \param[in]  extractQ  If true, the orthogonal matrix Q in the
 *    decomposition is computed and stored in \p mat.
 *
 * Computes the tridiagonal decomposition of the selfadjoint matrix \p mat in place
 * such that \f$ mat = Q T Q^* \f$ where \f$ Q \f$ is unitary and \f$ T \f$ a real
 * symmetric tridiagonal matrix.
 *
 * The tridiagonal matrix T is passed to the output parameters \p diag and \p subdiag. If
 * \p extractQ is true, then the orthogonal matrix Q is passed to \p mat. Otherwise the lower
 * part of the matrix \p mat is destroyed.
 *
 * The vectors \p diag and \p subdiag are not resized. The function
 * assumes that they are already of the correct size. The length of the
 * vector \p diag should equal the number of rows in \p mat, and the
 * length of the vector \p subdiag should be one left.
 *
 * This implementation contains an optimized path for 3-by-3 matrices
 * which is especially useful for plane fitting.
 *
 * \note Currently, it requires two temporary vectors to hold the intermediate
 * Householder coefficients, and to reconstruct the matrix Q from the Householder
 * reflectors.
 *
 * Example (this uses the same matrix as the example in
 *    Tridiagonalization::Tridiagonalization(const MatrixType&)):
 *    \include Tridiagonalization_decomposeInPlace.cpp
 * Output: \verbinclude Tridiagonalization_decomposeInPlace.out
 *
 * \sa class Tridiagonalization
 */
template <typename MatrixType, typename DiagonalType, typename SubDiagonalType, typename CoeffVectorType,
          typename WorkSpaceType>
EIGEN_DEVICE_FUNC void tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag,
                                                  CoeffVectorType& hcoeffs, WorkSpaceType& workspace, bool extractQ) {
  eigen_assert(mat.cols() == mat.rows() && diag.size() == mat.rows() && subdiag.size() == mat.rows() - 1);
  tridiagonalization_inplace_selector<MatrixType>::run(mat, diag, subdiag, hcoeffs, workspace, extractQ);
}

/** \internal
 * General full tridiagonalization
 */
template <typename MatrixType, int Size, bool IsComplex>
struct tridiagonalization_inplace_selector {
  typedef typename Tridiagonalization<MatrixType>::HouseholderSequenceType HouseholderSequenceType;
  template <typename DiagonalType, typename SubDiagonalType, typename CoeffVectorType, typename WorkSpaceType>
  static EIGEN_DEVICE_FUNC void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag,
                                    CoeffVectorType& hCoeffs, WorkSpaceType& workspace, bool extractQ) {
    tridiagonalization_inplace(mat, hCoeffs);
    diag = mat.diagonal().real();
    subdiag = mat.template diagonal<-1>().real();
    if (extractQ) {
      HouseholderSequenceType(mat, hCoeffs.conjugate()).setLength(mat.rows() - 1).setShift(1).evalTo(mat, workspace);
    }
  }
};

/** \internal
 * Specialization for 3x3 real matrices.
 * Especially useful for plane fitting.
 */
template <typename MatrixType>
struct tridiagonalization_inplace_selector<MatrixType, 3, false> {
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;

  template <typename DiagonalType, typename SubDiagonalType, typename CoeffVectorType, typename WorkSpaceType>
  static EIGEN_DEVICE_FUNC void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, CoeffVectorType&,
                                    WorkSpaceType&, bool extractQ) {
    using std::sqrt;
    const RealScalar tol = (std::numeric_limits<RealScalar>::min)();
    diag[0] = mat(0, 0);
    RealScalar v1norm2 = numext::abs2(mat(2, 0));
    if (v1norm2 <= tol) {
      diag[1] = mat(1, 1);
      diag[2] = mat(2, 2);
      subdiag[0] = mat(1, 0);
      subdiag[1] = mat(2, 1);
      if (extractQ) mat.setIdentity();
    } else {
      RealScalar beta = sqrt(numext::abs2(mat(1, 0)) + v1norm2);
      RealScalar invBeta = RealScalar(1) / beta;
      Scalar m01 = mat(1, 0) * invBeta;
      Scalar m02 = mat(2, 0) * invBeta;
      Scalar q = RealScalar(2) * m01 * mat(2, 1) + m02 * (mat(2, 2) - mat(1, 1));
      diag[1] = mat(1, 1) + m02 * q;
      diag[2] = mat(2, 2) - m02 * q;
      subdiag[0] = beta;
      subdiag[1] = mat(2, 1) - m01 * q;
      if (extractQ) {
        mat << 1, 0, 0, 0, m01, m02, 0, m02, -m01;
      }
    }
  }
};

/** \internal
 * Trivial specialization for 1x1 matrices
 */
template <typename MatrixType, bool IsComplex>
struct tridiagonalization_inplace_selector<MatrixType, 1, IsComplex> {
  typedef typename MatrixType::Scalar Scalar;

  template <typename DiagonalType, typename SubDiagonalType, typename CoeffVectorType, typename WorkSpaceType>
  static EIGEN_DEVICE_FUNC void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType&, CoeffVectorType&,
                                    WorkSpaceType&, bool extractQ) {
    diag(0, 0) = numext::real(mat(0, 0));
    if (extractQ) mat(0, 0) = Scalar(1);
  }
};

/** \internal
 * \eigenvalues_module \ingroup Eigenvalues_Module
 *
 * \brief Expression type for return value of Tridiagonalization::matrixT()
 *
 * \tparam MatrixType type of underlying dense matrix
 */
template <typename MatrixType>
struct TridiagonalizationMatrixTReturnType : public ReturnByValue<TridiagonalizationMatrixTReturnType<MatrixType>> {
 public:
  /** \brief Constructor.
   *
   * \param[in] mat The underlying dense matrix
   */
  TridiagonalizationMatrixTReturnType(const MatrixType& mat) : m_matrix(mat) {}

  template <typename ResultType>
  inline void evalTo(ResultType& result) const {
    result.setZero();
    result.template diagonal<1>() = m_matrix.template diagonal<-1>().conjugate();
    result.diagonal() = m_matrix.diagonal();
    result.template diagonal<-1>() = m_matrix.template diagonal<-1>();
  }

  constexpr Index rows() const noexcept { return m_matrix.rows(); }
  constexpr Index cols() const noexcept { return m_matrix.cols(); }

 protected:
  typename MatrixType::Nested m_matrix;
};

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_TRIDIAGONALIZATION_H
