// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2016 Rasmus Munk Larsen <rmlarsen@google.com>
//
// 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_COMPLETEORTHOGONALDECOMPOSITION_H
#define EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H

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

namespace Eigen {

namespace internal {
template <typename MatrixType_, typename PermutationIndex_>
struct traits<CompleteOrthogonalDecomposition<MatrixType_, PermutationIndex_> >
    : traits<MatrixType_> {
  typedef MatrixXpr XprKind;
  typedef SolverStorage StorageKind;
  typedef PermutationIndex_ PermutationIndex;
  enum { Flags = 0 };
};

}  // end namespace internal

/** \ingroup QR_Module
  *
  * \class CompleteOrthogonalDecomposition
  *
  * \brief Complete orthogonal decomposition (COD) of a matrix.
  *
  * \tparam MatrixType_ the type of the matrix of which we are computing the COD.
  *
  * This class performs a rank-revealing complete orthogonal decomposition of a
  * matrix  \b A into matrices \b P, \b Q, \b T, and \b Z such that
  * \f[
  *  \mathbf{A} \, \mathbf{P} = \mathbf{Q} \,
  *                     \begin{bmatrix} \mathbf{T} &  \mathbf{0} \\
  *                                     \mathbf{0} & \mathbf{0} \end{bmatrix} \, \mathbf{Z}
  * \f]
  * by using Householder transformations. Here, \b P is a permutation matrix,
  * \b Q and \b Z are unitary matrices and \b T an upper triangular matrix of
  * size rank-by-rank. \b A may be rank deficient.
  *
  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
  * 
  * \sa MatrixBase::completeOrthogonalDecomposition()
  */
template <typename MatrixType_, typename PermutationIndex_> class CompleteOrthogonalDecomposition
          : public SolverBase<CompleteOrthogonalDecomposition<MatrixType_, PermutationIndex_> >
{
 public:
  typedef MatrixType_ MatrixType;
  typedef SolverBase<CompleteOrthogonalDecomposition> Base;

  template<typename Derived>
  friend struct internal::solve_assertion;
  typedef PermutationIndex_ PermutationIndex;
  EIGEN_GENERIC_PUBLIC_INTERFACE(CompleteOrthogonalDecomposition)
  enum {
    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
  };
  typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
  typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime, PermutationIndex>
      PermutationType;
  typedef typename internal::plain_row_type<MatrixType, Index>::type
      IntRowVectorType;
  typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
  typedef typename internal::plain_row_type<MatrixType, RealScalar>::type
      RealRowVectorType;
  typedef HouseholderSequence<
      MatrixType, internal::remove_all_t<
                      typename HCoeffsType::ConjugateReturnType>>
      HouseholderSequenceType;
  typedef typename MatrixType::PlainObject PlainObject;

 public:
  /**
   * \brief Default Constructor.
   *
   * The default constructor is useful in cases in which the user intends to
   * perform decompositions via
   * \c CompleteOrthogonalDecomposition::compute(const* MatrixType&).
   */
  CompleteOrthogonalDecomposition() : m_cpqr(), m_zCoeffs(), m_temp() {}

  /** \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 CompleteOrthogonalDecomposition()
   */
  CompleteOrthogonalDecomposition(Index rows, Index cols)
      : m_cpqr(rows, cols), m_zCoeffs((std::min)(rows, cols)), m_temp(cols) {}

  /** \brief Constructs a complete orthogonal decomposition from a given
   * matrix.
   *
   * This constructor computes the complete orthogonal decomposition of the
   * matrix \a matrix by calling the method compute(). The default
   * threshold for rank determination will be used. It is a short cut for:
   *
   * \code
   * CompleteOrthogonalDecomposition<MatrixType> cod(matrix.rows(),
   *                                                 matrix.cols());
   * cod.setThreshold(Default);
   * cod.compute(matrix);
   * \endcode
   *
   * \sa compute()
   */
  template <typename InputType>
  explicit CompleteOrthogonalDecomposition(const EigenBase<InputType>& matrix)
      : m_cpqr(matrix.rows(), matrix.cols()),
        m_zCoeffs((std::min)(matrix.rows(), matrix.cols())),
        m_temp(matrix.cols())
  {
    compute(matrix.derived());
  }

  /** \brief Constructs a complete orthogonal decomposition from a given matrix
    *
    * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when \c MatrixType is a Eigen::Ref.
    *
    * \sa CompleteOrthogonalDecomposition(const EigenBase&)
    */
  template<typename InputType>
  explicit CompleteOrthogonalDecomposition(EigenBase<InputType>& matrix)
    : m_cpqr(matrix.derived()),
      m_zCoeffs((std::min)(matrix.rows(), matrix.cols())),
      m_temp(matrix.cols())
  {
    computeInPlace();
  } 

  #ifdef EIGEN_PARSED_BY_DOXYGEN
  /** This method computes the minimum-norm solution X to a least squares
   * problem \f[\mathrm{minimize} \|A X - B\|, \f] where \b A is the matrix of
   * which \c *this is the complete orthogonal decomposition.
   *
   * \param b the right-hand sides of the problem to solve.
   *
   * \returns a solution.
   *
   */
  template <typename Rhs>
  inline const Solve<CompleteOrthogonalDecomposition, Rhs> solve(
      const MatrixBase<Rhs>& b) const;
  #endif

  HouseholderSequenceType householderQ(void) const;
  HouseholderSequenceType matrixQ(void) const { return m_cpqr.householderQ(); }

  /** \returns the matrix \b Z.
   */
  MatrixType matrixZ() const {
    MatrixType Z = MatrixType::Identity(m_cpqr.cols(), m_cpqr.cols());
    applyZOnTheLeftInPlace<false>(Z);
    return Z;
  }

  /** \returns a reference to the matrix where the complete orthogonal
   * decomposition is stored
   */
  const MatrixType& matrixQTZ() const { return m_cpqr.matrixQR(); }

  /** \returns a reference to the matrix where the complete orthogonal
   * decomposition is stored.
   * \warning The strict lower part and \code cols() - rank() \endcode right
   * columns of this matrix contains internal values.
   * Only the upper triangular part should be referenced. To get it, use
   * \code matrixT().template triangularView<Upper>() \endcode
   * For rank-deficient matrices, use
   * \code
   * matrixT().topLeftCorner(rank(), rank()).template triangularView<Upper>()
   * \endcode
   */
  const MatrixType& matrixT() const { return m_cpqr.matrixQR(); }

  template <typename InputType>
  CompleteOrthogonalDecomposition& compute(const EigenBase<InputType>& matrix) {
    // Compute the column pivoted QR factorization A P = Q R.
    m_cpqr.compute(matrix);
    computeInPlace();
    return *this;
  }

  /** \returns a const reference to the column permutation matrix */
  const PermutationType& colsPermutation() const {
    return m_cpqr.colsPermutation();
  }

    /** \returns the determinant of the matrix of which
   * *this is the complete orthogonal decomposition. It has only linear
   * complexity (that is, O(n) where n is the dimension of the square matrix)
   * as the complete orthogonal decomposition has already been computed.
   *
   * \note This is only for square matrices.
   *
   * \warning a determinant can be very big or small, so for matrices
   * of large enough dimension, there is a risk of overflow/underflow.
   * One way to work around that is to use logAbsDeterminant() instead.
   *
   * \sa absDeterminant(), logAbsDeterminant(), MatrixBase::determinant()
   */
  typename MatrixType::Scalar determinant() const;

  /** \returns the absolute value of the determinant of the matrix of which
   * *this is the complete orthogonal decomposition. It has only linear
   * complexity (that is, O(n) where n is the dimension of the square matrix)
   * as the complete orthogonal decomposition has already been computed.
   *
   * \note This is only for square matrices.
   *
   * \warning a determinant can be very big or small, so for matrices
   * of large enough dimension, there is a risk of overflow/underflow.
   * One way to work around that is to use logAbsDeterminant() instead.
   *
   * \sa determinant(), logAbsDeterminant(), MatrixBase::determinant()
   */
  typename MatrixType::RealScalar absDeterminant() const;

  /** \returns the natural log of the absolute value of the determinant of the
   * matrix of which *this is the complete orthogonal decomposition. It has
   * only linear complexity (that is, O(n) where n is the dimension of the
   * square matrix) as the complete orthogonal decomposition has already been
   * computed.
   *
   * \note This is only for square matrices.
   *
   * \note This method is useful to work around the risk of overflow/underflow
   * that's inherent to determinant computation.
   *
   * \sa determinant(), absDeterminant(), MatrixBase::determinant()
   */
  typename MatrixType::RealScalar logAbsDeterminant() const;

  /** \returns the rank of the matrix of which *this is the complete orthogonal
   * decomposition.
   *
   * \note This method has to determine which pivots should be considered
   * nonzero. For that, it uses the threshold value that you can control by
   * calling setThreshold(const RealScalar&).
   */
  inline Index rank() const { return m_cpqr.rank(); }

  /** \returns the dimension of the kernel of the matrix of which *this is the
   * complete orthogonal decomposition.
   *
   * \note This method has to determine which pivots should be considered
   * nonzero. For that, it uses the threshold value that you can control by
   * calling setThreshold(const RealScalar&).
   */
  inline Index dimensionOfKernel() const { return m_cpqr.dimensionOfKernel(); }

  /** \returns true if the matrix of which *this is the decomposition represents
   * an injective linear map, i.e. has trivial kernel; false otherwise.
   *
   * \note This method has to determine which pivots should be considered
   * nonzero. For that, it uses the threshold value that you can control by
   * calling setThreshold(const RealScalar&).
   */
  inline bool isInjective() const { return m_cpqr.isInjective(); }

  /** \returns true if the matrix of which *this is the decomposition represents
   * a surjective linear map; false otherwise.
   *
   * \note This method has to determine which pivots should be considered
   * nonzero. For that, it uses the threshold value that you can control by
   * calling setThreshold(const RealScalar&).
   */
  inline bool isSurjective() const { return m_cpqr.isSurjective(); }

  /** \returns true if the matrix of which *this is the complete orthogonal
   * decomposition is invertible.
   *
   * \note This method has to determine which pivots should be considered
   * nonzero. For that, it uses the threshold value that you can control by
   * calling setThreshold(const RealScalar&).
   */
  inline bool isInvertible() const { return m_cpqr.isInvertible(); }

  /** \returns the pseudo-inverse of the matrix of which *this is the complete
   * orthogonal decomposition.
   * \warning: Do not compute \c this->pseudoInverse()*rhs to solve a linear systems.
   * It is more efficient and numerically stable to call \c this->solve(rhs).
   */
  inline const Inverse<CompleteOrthogonalDecomposition> pseudoInverse() const
  {
    eigen_assert(m_cpqr.m_isInitialized && "CompleteOrthogonalDecomposition is not initialized.");
    return Inverse<CompleteOrthogonalDecomposition>(*this);
  }

  inline Index rows() const { return m_cpqr.rows(); }
  inline Index cols() const { return m_cpqr.cols(); }

  /** \returns a const reference to the vector of Householder coefficients used
   * to represent the factor \c Q.
   *
   * For advanced uses only.
   */
  inline const HCoeffsType& hCoeffs() const { return m_cpqr.hCoeffs(); }

  /** \returns a const reference to the vector of Householder coefficients
   * used to represent the factor \c Z.
   *
   * For advanced uses only.
   */
  const HCoeffsType& zCoeffs() const { return m_zCoeffs; }

  /** Allows to prescribe a threshold to be used by certain methods, such as
   * rank(), who need to determine when pivots are to be considered nonzero.
   * Most be called before calling compute().
   *
   * When it needs to get the threshold value, Eigen calls threshold(). By
   * default, this uses a formula to automatically determine a reasonable
   * threshold. Once you have called the present method
   * setThreshold(const RealScalar&), your value is used instead.
   *
   * \param threshold The new value to use as the threshold.
   *
   * A pivot will be considered nonzero if its absolute value is strictly
   * greater than
   *  \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$
   * where maxpivot is the biggest pivot.
   *
   * If you want to come back to the default behavior, call
   * setThreshold(Default_t)
   */
  CompleteOrthogonalDecomposition& setThreshold(const RealScalar& threshold) {
    m_cpqr.setThreshold(threshold);
    return *this;
  }

  /** Allows to come back to the default behavior, letting Eigen use its default
   * formula for determining the threshold.
   *
   * You should pass the special object Eigen::Default as parameter here.
   * \code qr.setThreshold(Eigen::Default); \endcode
   *
   * See the documentation of setThreshold(const RealScalar&).
   */
  CompleteOrthogonalDecomposition& setThreshold(Default_t) {
    m_cpqr.setThreshold(Default);
    return *this;
  }

  /** Returns the threshold that will be used by certain methods such as rank().
   *
   * See the documentation of setThreshold(const RealScalar&).
   */
  RealScalar threshold() const { return m_cpqr.threshold(); }

  /** \returns the number of nonzero pivots in the complete orthogonal
   * decomposition. Here nonzero is meant in the exact sense, not in a
   * fuzzy sense. So that notion isn't really intrinsically interesting,
   * but it is still useful when implementing algorithms.
   *
   * \sa rank()
   */
  inline Index nonzeroPivots() const { return m_cpqr.nonzeroPivots(); }

  /** \returns the absolute value of the biggest pivot, i.e. the biggest
   *          diagonal coefficient of R.
   */
  inline RealScalar maxPivot() const { return m_cpqr.maxPivot(); }

  /** \brief Reports whether the complete orthogonal decomposition was
   * successful.
   *
   * \note This function always returns \c Success. It is provided for
   * compatibility
   * with other factorization routines.
   * \returns \c Success
   */
  ComputationInfo info() const {
    eigen_assert(m_cpqr.m_isInitialized && "Decomposition is not initialized.");
    return Success;
  }

#ifndef EIGEN_PARSED_BY_DOXYGEN
  template <typename RhsType, typename DstType>
  void _solve_impl(const RhsType& rhs, DstType& dst) const;

  template<bool Conjugate, typename RhsType, typename DstType>
  void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
#endif

 protected:
  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)

  template<bool Transpose_, typename Rhs>
  void _check_solve_assertion(const Rhs& b) const {
      EIGEN_ONLY_USED_FOR_DEBUG(b);
      eigen_assert(m_cpqr.m_isInitialized && "CompleteOrthogonalDecomposition is not initialized.");
      eigen_assert((Transpose_?derived().cols():derived().rows())==b.rows() && "CompleteOrthogonalDecomposition::solve(): invalid number of rows of the right hand side matrix b");
  }

  void computeInPlace();

  /** Overwrites \b rhs with \f$ \mathbf{Z} * \mathbf{rhs} \f$ or
   *  \f$ \mathbf{\overline Z} * \mathbf{rhs} \f$ if \c Conjugate 
   *  is set to \c true.
   */
  template <bool Conjugate, typename Rhs>
  void applyZOnTheLeftInPlace(Rhs& rhs) const;

  /** Overwrites \b rhs with \f$ \mathbf{Z}^* * \mathbf{rhs} \f$.
   */
  template <typename Rhs>
  void applyZAdjointOnTheLeftInPlace(Rhs& rhs) const;

  ColPivHouseholderQR<MatrixType, PermutationIndex> m_cpqr;
  HCoeffsType m_zCoeffs;
  RowVectorType m_temp;
};

template <typename MatrixType, typename PermutationIndex>
typename MatrixType::Scalar
CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>::determinant() const {
  return m_cpqr.determinant();
}

template <typename MatrixType, typename PermutationIndex>
typename MatrixType::RealScalar
CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>::absDeterminant() const {
  return m_cpqr.absDeterminant();
}

template <typename MatrixType, typename PermutationIndex>
typename MatrixType::RealScalar
CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>::logAbsDeterminant() const {
  return m_cpqr.logAbsDeterminant();
}

/** Performs the complete orthogonal decomposition of the given matrix \a
 * matrix. The result of the factorization is stored into \c *this, and a
 * reference to \c *this is returned.
 *
 * \sa class CompleteOrthogonalDecomposition,
 * CompleteOrthogonalDecomposition(const MatrixType&)
 */
template <typename MatrixType, typename PermutationIndex>
void CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>::computeInPlace()
{
  eigen_assert(m_cpqr.cols() <= NumTraits<PermutationIndex>::highest());

  const Index rank = m_cpqr.rank();
  const Index cols = m_cpqr.cols();
  const Index rows = m_cpqr.rows();
  m_zCoeffs.resize((std::min)(rows, cols));
  m_temp.resize(cols);

  if (rank < cols) {
    // We have reduced the (permuted) matrix to the form
    //   [R11 R12]
    //   [ 0  R22]
    // where R11 is r-by-r (r = rank) upper triangular, R12 is
    // r-by-(n-r), and R22 is empty or the norm of R22 is negligible.
    // We now compute the complete orthogonal decomposition by applying
    // Householder transformations from the right to the upper trapezoidal
    // matrix X = [R11 R12] to zero out R12 and obtain the factorization
    // [R11 R12] = [T11 0] * Z, where T11 is r-by-r upper triangular and
    // Z = Z(0) * Z(1) ... Z(r-1) is an n-by-n orthogonal matrix.
    // We store the data representing Z in R12 and m_zCoeffs.
    for (Index k = rank - 1; k >= 0; --k) {
      if (k != rank - 1) {
        // Given the API for Householder reflectors, it is more convenient if
        // we swap the leading parts of columns k and r-1 (zero-based) to form
        // the matrix X_k = [X(0:k, k), X(0:k, r:n)]
        m_cpqr.m_qr.col(k).head(k + 1).swap(
            m_cpqr.m_qr.col(rank - 1).head(k + 1));
      }
      // Construct Householder reflector Z(k) to zero out the last row of X_k,
      // i.e. choose Z(k) such that
      // [X(k, k), X(k, r:n)] * Z(k) = [beta, 0, .., 0].
      RealScalar beta;
      m_cpqr.m_qr.row(k)
          .tail(cols - rank + 1)
          .makeHouseholderInPlace(m_zCoeffs(k), beta);
      m_cpqr.m_qr(k, rank - 1) = beta;
      if (k > 0) {
        // Apply Z(k) to the first k rows of X_k
        m_cpqr.m_qr.topRightCorner(k, cols - rank + 1)
            .applyHouseholderOnTheRight(
                m_cpqr.m_qr.row(k).tail(cols - rank).adjoint(), m_zCoeffs(k),
                &m_temp(0));
      }
      if (k != rank - 1) {
        // Swap X(0:k,k) back to its proper location.
        m_cpqr.m_qr.col(k).head(k + 1).swap(
            m_cpqr.m_qr.col(rank - 1).head(k + 1));
      }
    }
  }
}

template <typename MatrixType, typename PermutationIndex>
template <bool Conjugate, typename Rhs>
void CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>::applyZOnTheLeftInPlace(
    Rhs& rhs) const {
  const Index cols = this->cols();
  const Index nrhs = rhs.cols();
  const Index rank = this->rank();
  Matrix<typename Rhs::Scalar, Dynamic, 1> temp((std::max)(cols, nrhs));
  for (Index k = rank-1; k >= 0; --k) {
    if (k != rank - 1) {
      rhs.row(k).swap(rhs.row(rank - 1));
    }
    rhs.middleRows(rank - 1, cols - rank + 1)
        .applyHouseholderOnTheLeft(
            matrixQTZ().row(k).tail(cols - rank).transpose().template conjugateIf<!Conjugate>(), zCoeffs().template conjugateIf<Conjugate>()(k),
            &temp(0));
    if (k != rank - 1) {
      rhs.row(k).swap(rhs.row(rank - 1));
    }
  }
}

template <typename MatrixType, typename PermutationIndex>
template <typename Rhs>
void CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>::applyZAdjointOnTheLeftInPlace(
    Rhs& rhs) const {
  const Index cols = this->cols();
  const Index nrhs = rhs.cols();
  const Index rank = this->rank();
  Matrix<typename Rhs::Scalar, Dynamic, 1> temp((std::max)(cols, nrhs));
  for (Index k = 0; k < rank; ++k) {
    if (k != rank - 1) {
      rhs.row(k).swap(rhs.row(rank - 1));
    }
    rhs.middleRows(rank - 1, cols - rank + 1)
        .applyHouseholderOnTheLeft(
            matrixQTZ().row(k).tail(cols - rank).adjoint(), zCoeffs()(k),
            &temp(0));
    if (k != rank - 1) {
      rhs.row(k).swap(rhs.row(rank - 1));
    }
  }
}

#ifndef EIGEN_PARSED_BY_DOXYGEN
template <typename MatrixType_, typename PermutationIndex_>
template <typename RhsType, typename DstType>
void CompleteOrthogonalDecomposition<MatrixType_, PermutationIndex_>::_solve_impl(
    const RhsType& rhs, DstType& dst) const {
  const Index rank = this->rank();
  if (rank == 0) {
    dst.setZero();
    return;
  }

  // Compute c = Q^* * rhs
  typename RhsType::PlainObject c(rhs);
  c.applyOnTheLeft(matrixQ().setLength(rank).adjoint());

  // Solve T z = c(1:rank, :)
  dst.topRows(rank) = matrixT()
                          .topLeftCorner(rank, rank)
                          .template triangularView<Upper>()
                          .solve(c.topRows(rank));

  const Index cols = this->cols();
  if (rank < cols) {
    // Compute y = Z^* * [ z ]
    //                   [ 0 ]
    dst.bottomRows(cols - rank).setZero();
    applyZAdjointOnTheLeftInPlace(dst);
  }

  // Undo permutation to get x = P^{-1} * y.
  dst = colsPermutation() * dst;
}

template<typename MatrixType_, typename PermutationIndex_>
template<bool Conjugate, typename RhsType, typename DstType>
void CompleteOrthogonalDecomposition<MatrixType_, PermutationIndex_>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
{
  const Index rank = this->rank();

  if (rank == 0) {
    dst.setZero();
    return;
  }

  typename RhsType::PlainObject c(colsPermutation().transpose()*rhs);

  if (rank < cols()) {
    applyZOnTheLeftInPlace<!Conjugate>(c);
  }

  matrixT().topLeftCorner(rank, rank)
           .template triangularView<Upper>()
           .transpose().template conjugateIf<Conjugate>()
           .solveInPlace(c.topRows(rank));

  dst.topRows(rank) = c.topRows(rank);
  dst.bottomRows(rows()-rank).setZero();

  dst.applyOnTheLeft(householderQ().setLength(rank).template conjugateIf<!Conjugate>() );
}
#endif

namespace internal {

template<typename MatrixType, typename PermutationIndex>
struct traits<Inverse<CompleteOrthogonalDecomposition<MatrixType, PermutationIndex> > >
  : traits<typename Transpose<typename MatrixType::PlainObject>::PlainObject>
{
  enum { Flags = 0 };
};

template<typename DstXprType, typename MatrixType, typename PermutationIndex>
struct Assignment<DstXprType, Inverse<CompleteOrthogonalDecomposition<MatrixType, PermutationIndex> >, internal::assign_op<typename DstXprType::Scalar,typename CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>::Scalar>, Dense2Dense>
{
  typedef CompleteOrthogonalDecomposition<MatrixType, PermutationIndex> CodType;
  typedef Inverse<CodType> SrcXprType;
  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename CodType::Scalar> &)
  {
    typedef Matrix<typename CodType::Scalar, CodType::RowsAtCompileTime, CodType::RowsAtCompileTime, 0, CodType::MaxRowsAtCompileTime, CodType::MaxRowsAtCompileTime> IdentityMatrixType;
    dst = src.nestedExpression().solve(IdentityMatrixType::Identity(src.cols(), src.cols()));
  }
};

} // end namespace internal

/** \returns the matrix Q as a sequence of householder transformations */
template <typename MatrixType, typename PermutationIndex>
typename CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>::HouseholderSequenceType
CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>::householderQ() const {
  return m_cpqr.householderQ();
}

/** \return the complete orthogonal decomposition of \c *this.
  *
  * \sa class CompleteOrthogonalDecomposition
  */
template <typename Derived>
template <typename PermutationIndex>
const CompleteOrthogonalDecomposition<typename MatrixBase<Derived>::PlainObject, PermutationIndex>
MatrixBase<Derived>::completeOrthogonalDecomposition() const {
  return CompleteOrthogonalDecomposition<PlainObject>(eval());
}

}  // end namespace Eigen

#endif  // EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H
