// 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,2012 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/.

#ifndef EIGEN_EIGENSOLVER_H
#define EIGEN_EIGENSOLVER_H

#include "./RealSchur.h"

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

namespace Eigen {

/** \eigenvalues_module \ingroup Eigenvalues_Module
 *
 *
 * \class EigenSolver
 *
 * \brief Computes eigenvalues and eigenvectors of general 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. Currently, only real matrices are supported.
 *
 * The eigenvalues and eigenvectors of a matrix \f$ A \f$ are scalars
 * \f$ \lambda \f$ and vectors \f$ v \f$ such that \f$ Av = \lambda v \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 =
 * V D \f$. The matrix \f$ V \f$ is almost always invertible, in which case we
 * have \f$ A = V D V^{-1} \f$. This is called the eigendecomposition.
 *
 * The eigenvalues and eigenvectors of a matrix may be complex, even when the
 * matrix is real. However, we can choose real matrices \f$ V \f$ and \f$ D
 * \f$ satisfying \f$ A V = V D \f$, just like the eigendecomposition, if the
 * matrix \f$ D \f$ is not required to be diagonal, but if it is allowed to
 * have blocks of the form
 * \f[ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} \f]
 * (where \f$ u \f$ and \f$ v \f$ are real numbers) on the diagonal.  These
 * blocks correspond to complex eigenvalue pairs \f$ u \pm iv \f$. We call
 * this variant of the eigendecomposition the pseudo-eigendecomposition.
 *
 * Call the function compute() to compute the eigenvalues and eigenvectors of
 * a given matrix. Alternatively, you can use the
 * EigenSolver(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. The pseudoEigenvalueMatrix() and
 * pseudoEigenvectors() methods allow the construction of the
 * pseudo-eigendecomposition.
 *
 * The documentation for EigenSolver(const MatrixType&, bool) contains an
 * example of the typical use of this class.
 *
 * \note The implementation is adapted from
 * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> (public domain).
 * Their code is based on EISPACK.
 *
 * \sa MatrixBase::eigenvalues(), class ComplexEigenSolver, class SelfAdjointEigenSolver
 */
template <typename MatrixType_>
class EigenSolver {
 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 eigenvalues as returned by eigenvalues().
   *
   * 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> 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.
   */
  EigenSolver()
      : m_eivec(), m_eivalues(), m_isInitialized(false), m_eigenvectorsOk(false), m_realSchur(), m_matT(), m_tmp() {}

  /** \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 EigenSolver()
   */
  explicit EigenSolver(Index size)
      : m_eivec(size, size),
        m_eivalues(size),
        m_isInitialized(false),
        m_eigenvectorsOk(false),
        m_realSchur(size),
        m_matT(size, size),
        m_tmp(size) {}

  /** \brief Constructor; computes eigendecomposition of given matrix.
   *
   * \param[in]  matrix  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 eigenvalues
   * and eigenvectors.
   *
   * Example: \include EigenSolver_EigenSolver_MatrixType.cpp
   * Output: \verbinclude EigenSolver_EigenSolver_MatrixType.out
   *
   * \sa compute()
   */
  template <typename InputType>
  explicit EigenSolver(const EigenBase<InputType>& matrix, bool computeEigenvectors = true)
      : m_eivec(matrix.rows(), matrix.cols()),
        m_eivalues(matrix.cols()),
        m_isInitialized(false),
        m_eigenvectorsOk(false),
        m_realSchur(matrix.cols()),
        m_matT(matrix.rows(), matrix.cols()),
        m_tmp(matrix.cols()) {
    compute(matrix.derived(), computeEigenvectors);
  }

  /** \brief Returns the eigenvectors of given matrix.
   *
   * \returns  %Matrix whose columns are the (possibly complex) eigenvectors.
   *
   * \pre Either the constructor
   * EigenSolver(const MatrixType&,bool) or the member function
   * compute(const MatrixType&, bool) has been called before, and
   * \p computeEigenvectors was set to true (the default).
   *
   * 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. The
   * matrix returned by this function is the matrix \f$ V \f$ in the
   * eigendecomposition \f$ A = V D V^{-1} \f$, if it exists.
   *
   * Example: \include EigenSolver_eigenvectors.cpp
   * Output: \verbinclude EigenSolver_eigenvectors.out
   *
   * \sa eigenvalues(), pseudoEigenvectors()
   */
  EigenvectorsType eigenvectors() const;

  /** \brief Returns the pseudo-eigenvectors of given matrix.
   *
   * \returns  Const reference to matrix whose columns are the pseudo-eigenvectors.
   *
   * \pre Either the constructor
   * EigenSolver(const MatrixType&,bool) or the member function
   * compute(const MatrixType&, bool) has been called before, and
   * \p computeEigenvectors was set to true (the default).
   *
   * The real matrix \f$ V \f$ returned by this function and the
   * block-diagonal matrix \f$ D \f$ returned by pseudoEigenvalueMatrix()
   * satisfy \f$ AV = VD \f$.
   *
   * Example: \include EigenSolver_pseudoEigenvectors.cpp
   * Output: \verbinclude EigenSolver_pseudoEigenvectors.out
   *
   * \sa pseudoEigenvalueMatrix(), eigenvectors()
   */
  const MatrixType& pseudoEigenvectors() const {
    eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
    eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
    return m_eivec;
  }

  /** \brief Returns the block-diagonal matrix in the pseudo-eigendecomposition.
   *
   * \returns  A block-diagonal matrix.
   *
   * \pre Either the constructor
   * EigenSolver(const MatrixType&,bool) or the member function
   * compute(const MatrixType&, bool) has been called before.
   *
   * The matrix \f$ D \f$ returned by this function is real and
   * block-diagonal. The blocks on the diagonal are either 1-by-1 or 2-by-2
   * blocks of the form
   * \f$ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} \f$.
   * These blocks are not sorted in any particular order.
   * The matrix \f$ D \f$ and the matrix \f$ V \f$ returned by
   * pseudoEigenvectors() satisfy \f$ AV = VD \f$.
   *
   * \sa pseudoEigenvectors() for an example, eigenvalues()
   */
  MatrixType pseudoEigenvalueMatrix() const;

  /** \brief Returns the eigenvalues of given matrix.
   *
   * \returns A const reference to the column vector containing the eigenvalues.
   *
   * \pre Either the constructor
   * EigenSolver(const MatrixType&,bool) or the member function
   * compute(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.
   *
   * Example: \include EigenSolver_eigenvalues.cpp
   * Output: \verbinclude EigenSolver_eigenvalues.out
   *
   * \sa eigenvectors(), pseudoEigenvalueMatrix(),
   *     MatrixBase::eigenvalues()
   */
  const EigenvalueType& eigenvalues() const {
    eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
    return m_eivalues;
  }

  /** \brief Computes eigendecomposition of given matrix.
   *
   * \param[in]  matrix  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 Schur form using the RealSchur
   * class. The Schur decomposition is then used to compute the eigenvalues
   * and eigenvectors.
   *
   * The cost of the computation is dominated by the cost of the
   * Schur decomposition, which is very approximately \f$ 25n^3 \f$
   * (where \f$ n \f$ is the size of the matrix) if \p computeEigenvectors
   * is true, and \f$ 10n^3 \f$ if \p computeEigenvectors is false.
   *
   * This method reuses of the allocated data in the EigenSolver object.
   *
   * Example: \include EigenSolver_compute.cpp
   * Output: \verbinclude EigenSolver_compute.out
   */
  template <typename InputType>
  EigenSolver& compute(const EigenBase<InputType>& matrix, bool computeEigenvectors = true);

  /** \returns NumericalIssue if the input contains INF or NaN values or overflow occurred. Returns Success otherwise.
   */
  ComputationInfo info() const {
    eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
    return m_info;
  }

  /** \brief Sets the maximum number of iterations allowed. */
  EigenSolver& setMaxIterations(Index maxIters) {
    m_realSchur.setMaxIterations(maxIters);
    return *this;
  }

  /** \brief Returns the maximum number of iterations. */
  Index getMaxIterations() { return m_realSchur.getMaxIterations(); }

 private:
  void doComputeEigenvectors();

 protected:
  static void check_template_parameters() {
    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
    EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL);
  }

  MatrixType m_eivec;
  EigenvalueType m_eivalues;
  bool m_isInitialized;
  bool m_eigenvectorsOk;
  ComputationInfo m_info;
  RealSchur<MatrixType> m_realSchur;
  MatrixType m_matT;

  typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ColumnVectorType;
  ColumnVectorType m_tmp;
};

template <typename MatrixType>
MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const {
  eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
  const RealScalar precision = RealScalar(2) * NumTraits<RealScalar>::epsilon();
  const Index n = m_eivalues.rows();
  MatrixType matD = MatrixType::Zero(n, n);
  Index i = 0;
  for (; i < n - 1; ++i) {
    RealScalar real = numext::real(m_eivalues.coeff(i));
    RealScalar imag = numext::imag(m_eivalues.coeff(i));
    matD.coeffRef(i, i) = real;
    if (!internal::isMuchSmallerThan(imag, real, precision)) {
      matD.coeffRef(i, i + 1) = imag;
      matD.coeffRef(i + 1, i) = -imag;
      matD.coeffRef(i + 1, i + 1) = real;
      ++i;
    }
  }
  if (i == n - 1) {
    matD.coeffRef(i, i) = numext::real(m_eivalues.coeff(i));
  }

  return matD;
}

template <typename MatrixType>
typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eigenvectors() const {
  eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
  eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
  const RealScalar precision = RealScalar(2) * NumTraits<RealScalar>::epsilon();
  Index n = m_eivec.cols();
  EigenvectorsType matV(n, n);
  for (Index j = 0; j < n; ++j) {
    if (internal::isMuchSmallerThan(numext::imag(m_eivalues.coeff(j)), numext::real(m_eivalues.coeff(j)), precision) ||
        j + 1 == n) {
      // we have a real eigen value
      matV.col(j) = m_eivec.col(j).template cast<ComplexScalar>();
      matV.col(j).normalize();
    } else {
      // we have a pair of complex eigen values
      for (Index i = 0; i < n; ++i) {
        matV.coeffRef(i, j) = ComplexScalar(m_eivec.coeff(i, j), m_eivec.coeff(i, j + 1));
        matV.coeffRef(i, j + 1) = ComplexScalar(m_eivec.coeff(i, j), -m_eivec.coeff(i, j + 1));
      }
      matV.col(j).normalize();
      matV.col(j + 1).normalize();
      ++j;
    }
  }
  return matV;
}

template <typename MatrixType>
template <typename InputType>
EigenSolver<MatrixType>& EigenSolver<MatrixType>::compute(const EigenBase<InputType>& matrix,
                                                          bool computeEigenvectors) {
  check_template_parameters();

  using numext::isfinite;
  using std::abs;
  using std::sqrt;
  eigen_assert(matrix.cols() == matrix.rows());

  // Reduce to real Schur form.
  m_realSchur.compute(matrix.derived(), computeEigenvectors);

  m_info = m_realSchur.info();

  if (m_info == Success) {
    m_matT = m_realSchur.matrixT();
    if (computeEigenvectors) m_eivec = m_realSchur.matrixU();

    // Compute eigenvalues from matT
    m_eivalues.resize(matrix.cols());
    Index i = 0;
    while (i < matrix.cols()) {
      if (i == matrix.cols() - 1 || m_matT.coeff(i + 1, i) == Scalar(0)) {
        m_eivalues.coeffRef(i) = m_matT.coeff(i, i);
        if (!(isfinite)(m_eivalues.coeffRef(i))) {
          m_isInitialized = true;
          m_eigenvectorsOk = false;
          m_info = NumericalIssue;
          return *this;
        }
        ++i;
      } else {
        Scalar p = Scalar(0.5) * (m_matT.coeff(i, i) - m_matT.coeff(i + 1, i + 1));
        Scalar z;
        // Compute z = sqrt(abs(p * p + m_matT.coeff(i+1, i) * m_matT.coeff(i, i+1)));
        // without overflow
        {
          Scalar t0 = m_matT.coeff(i + 1, i);
          Scalar t1 = m_matT.coeff(i, i + 1);
          Scalar maxval = numext::maxi<Scalar>(abs(p), numext::maxi<Scalar>(abs(t0), abs(t1)));
          t0 /= maxval;
          t1 /= maxval;
          Scalar p0 = p / maxval;
          z = maxval * sqrt(abs(p0 * p0 + t0 * t1));
        }

        m_eivalues.coeffRef(i) = ComplexScalar(m_matT.coeff(i + 1, i + 1) + p, z);
        m_eivalues.coeffRef(i + 1) = ComplexScalar(m_matT.coeff(i + 1, i + 1) + p, -z);
        if (!((isfinite)(m_eivalues.coeffRef(i)) && (isfinite)(m_eivalues.coeffRef(i + 1)))) {
          m_isInitialized = true;
          m_eigenvectorsOk = false;
          m_info = NumericalIssue;
          return *this;
        }
        i += 2;
      }
    }

    // Compute eigenvectors.
    if (computeEigenvectors) doComputeEigenvectors();
  }

  m_isInitialized = true;
  m_eigenvectorsOk = computeEigenvectors;

  return *this;
}

template <typename MatrixType>
void EigenSolver<MatrixType>::doComputeEigenvectors() {
  using std::abs;
  const Index size = m_eivec.cols();
  const Scalar eps = NumTraits<Scalar>::epsilon();

  // inefficient! this is already computed in RealSchur
  Scalar norm(0);
  for (Index j = 0; j < size; ++j) {
    norm += m_matT.row(j).segment((std::max)(j - 1, Index(0)), size - (std::max)(j - 1, Index(0))).cwiseAbs().sum();
  }

  // Backsubstitute to find vectors of upper triangular form
  if (norm == Scalar(0)) {
    return;
  }

  for (Index n = size - 1; n >= 0; n--) {
    Scalar p = m_eivalues.coeff(n).real();
    Scalar q = m_eivalues.coeff(n).imag();

    // Scalar vector
    if (q == Scalar(0)) {
      Scalar lastr(0), lastw(0);
      Index l = n;

      m_matT.coeffRef(n, n) = Scalar(1);
      for (Index i = n - 1; i >= 0; i--) {
        Scalar w = m_matT.coeff(i, i) - p;
        Scalar r = m_matT.row(i).segment(l, n - l + 1).dot(m_matT.col(n).segment(l, n - l + 1));

        if (m_eivalues.coeff(i).imag() < Scalar(0)) {
          lastw = w;
          lastr = r;
        } else {
          l = i;
          if (m_eivalues.coeff(i).imag() == Scalar(0)) {
            if (w != Scalar(0))
              m_matT.coeffRef(i, n) = -r / w;
            else
              m_matT.coeffRef(i, n) = -r / (eps * norm);
          } else  // Solve real equations
          {
            Scalar x = m_matT.coeff(i, i + 1);
            Scalar y = m_matT.coeff(i + 1, i);
            Scalar denom = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) +
                           m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag();
            Scalar t = (x * lastr - lastw * r) / denom;
            m_matT.coeffRef(i, n) = t;
            if (abs(x) > abs(lastw))
              m_matT.coeffRef(i + 1, n) = (-r - w * t) / x;
            else
              m_matT.coeffRef(i + 1, n) = (-lastr - y * t) / lastw;
          }

          // Overflow control
          Scalar t = abs(m_matT.coeff(i, n));
          if ((eps * t) * t > Scalar(1)) m_matT.col(n).tail(size - i) /= t;
        }
      }
    } else if (q < Scalar(0) && n > 0)  // Complex vector
    {
      Scalar lastra(0), lastsa(0), lastw(0);
      Index l = n - 1;

      // Last vector component imaginary so matrix is triangular
      if (abs(m_matT.coeff(n, n - 1)) > abs(m_matT.coeff(n - 1, n))) {
        m_matT.coeffRef(n - 1, n - 1) = q / m_matT.coeff(n, n - 1);
        m_matT.coeffRef(n - 1, n) = -(m_matT.coeff(n, n) - p) / m_matT.coeff(n, n - 1);
      } else {
        ComplexScalar cc =
            ComplexScalar(Scalar(0), -m_matT.coeff(n - 1, n)) / ComplexScalar(m_matT.coeff(n - 1, n - 1) - p, q);
        m_matT.coeffRef(n - 1, n - 1) = numext::real(cc);
        m_matT.coeffRef(n - 1, n) = numext::imag(cc);
      }
      m_matT.coeffRef(n, n - 1) = Scalar(0);
      m_matT.coeffRef(n, n) = Scalar(1);
      for (Index i = n - 2; i >= 0; i--) {
        Scalar ra = m_matT.row(i).segment(l, n - l + 1).dot(m_matT.col(n - 1).segment(l, n - l + 1));
        Scalar sa = m_matT.row(i).segment(l, n - l + 1).dot(m_matT.col(n).segment(l, n - l + 1));
        Scalar w = m_matT.coeff(i, i) - p;

        if (m_eivalues.coeff(i).imag() < Scalar(0)) {
          lastw = w;
          lastra = ra;
          lastsa = sa;
        } else {
          l = i;
          if (m_eivalues.coeff(i).imag() == RealScalar(0)) {
            ComplexScalar cc = ComplexScalar(-ra, -sa) / ComplexScalar(w, q);
            m_matT.coeffRef(i, n - 1) = numext::real(cc);
            m_matT.coeffRef(i, n) = numext::imag(cc);
          } else {
            // Solve complex equations
            Scalar x = m_matT.coeff(i, i + 1);
            Scalar y = m_matT.coeff(i + 1, i);
            Scalar vr = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) +
                        m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag() - q * q;
            Scalar vi = (m_eivalues.coeff(i).real() - p) * Scalar(2) * q;
            if ((vr == Scalar(0)) && (vi == Scalar(0)))
              vr = eps * norm * (abs(w) + abs(q) + abs(x) + abs(y) + abs(lastw));

            ComplexScalar cc = ComplexScalar(x * lastra - lastw * ra + q * sa, x * lastsa - lastw * sa - q * ra) /
                               ComplexScalar(vr, vi);
            m_matT.coeffRef(i, n - 1) = numext::real(cc);
            m_matT.coeffRef(i, n) = numext::imag(cc);
            if (abs(x) > (abs(lastw) + abs(q))) {
              m_matT.coeffRef(i + 1, n - 1) = (-ra - w * m_matT.coeff(i, n - 1) + q * m_matT.coeff(i, n)) / x;
              m_matT.coeffRef(i + 1, n) = (-sa - w * m_matT.coeff(i, n) - q * m_matT.coeff(i, n - 1)) / x;
            } else {
              cc = ComplexScalar(-lastra - y * m_matT.coeff(i, n - 1), -lastsa - y * m_matT.coeff(i, n)) /
                   ComplexScalar(lastw, q);
              m_matT.coeffRef(i + 1, n - 1) = numext::real(cc);
              m_matT.coeffRef(i + 1, n) = numext::imag(cc);
            }
          }

          // Overflow control
          Scalar t = numext::maxi<Scalar>(abs(m_matT.coeff(i, n - 1)), abs(m_matT.coeff(i, n)));
          if ((eps * t) * t > Scalar(1)) m_matT.block(i, n - 1, size - i, 2) /= t;
        }
      }

      // We handled a pair of complex conjugate eigenvalues, so need to skip them both
      n--;
    } else {
      eigen_assert(0 && "Internal bug in EigenSolver (INF or NaN has not been detected)");  // this should not happen
    }
  }

  // Back transformation to get eigenvectors of original matrix
  for (Index j = size - 1; j >= 0; j--) {
    m_tmp.noalias() = m_eivec.leftCols(j + 1) * m_matT.col(j).segment(0, j + 1);
    m_eivec.col(j) = m_tmp;
  }
}

}  // end namespace Eigen

#endif  // EIGEN_EIGENSOLVER_H
