// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2016 Rasmus Munk Larsen <rmlarsen@gmail.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/.
// SPDX-License-Identifier: 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_, template <typename, typename> class RankRevealingQR_>
class CompleteOrthogonalDecompositionImpl;

template <typename MatrixType_, typename PermutationIndex_, template <typename, typename> class RankRevealingQR_>
struct traits<CompleteOrthogonalDecompositionImpl<MatrixType_, PermutationIndex_, RankRevealingQR_>>
    : traits<MatrixType_> {
  using XprKind = MatrixXpr;
  using StorageKind = SolverStorage;
  using PermutationIndex = PermutationIndex_;
  enum { Flags = 0 };
};

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

template <typename MatrixType_, typename PermutationIndex_>
struct traits<RandCompleteOrthogonalDecomposition<MatrixType_, PermutationIndex_>> : traits<MatrixType_> {
  using XprKind = MatrixXpr;
  using StorageKind = SolverStorage;
  using PermutationIndex = PermutationIndex_;
  enum { Flags = 0 };
};

}  // end namespace internal

namespace internal {

/** \internal
 *
 * \class CompleteOrthogonalDecompositionImpl
 *
 * \brief Implementation backbone for CompleteOrthogonalDecomposition and
 * RandCompleteOrthogonalDecomposition.
 *
 * Parameterized over the rank-revealing QR engine \c RankRevealingQR_. The
 * public, source-compatible class \c CompleteOrthogonalDecomposition is a
 * thin shim around \c CompleteOrthogonalDecompositionImpl with
 * \c ColPivHouseholderQR; \c RandCompleteOrthogonalDecomposition is the
 * parallel shim with \c RandColPivHouseholderQR.
 */
template <typename MatrixType_, typename PermutationIndex_, template <typename, typename> class RankRevealingQR_>
class CompleteOrthogonalDecompositionImpl
    : public SolverBase<CompleteOrthogonalDecompositionImpl<MatrixType_, PermutationIndex_, RankRevealingQR_>> {
 public:
  using MatrixType = MatrixType_;
  using Base = SolverBase<CompleteOrthogonalDecompositionImpl>;

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

 public:
  CompleteOrthogonalDecompositionImpl() : m_cpqr(), m_zCoeffs(), m_temp() {}

  CompleteOrthogonalDecompositionImpl(Index rows, Index cols)
      : m_cpqr(rows, cols), m_zCoeffs((std::min)(rows, cols)), m_temp(cols) {}

  template <typename InputType>
  explicit CompleteOrthogonalDecompositionImpl(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());
  }

  template <typename InputType>
  explicit CompleteOrthogonalDecompositionImpl(EigenBase<InputType>& matrix)
      : m_cpqr(matrix.derived()), m_zCoeffs((std::min)(matrix.rows(), matrix.cols())), m_temp(matrix.cols()) {
    computeInPlace();
  }

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

  MatrixType matrixZ() const {
    MatrixType Z = MatrixType::Identity(m_cpqr.cols(), m_cpqr.cols());
    applyZOnTheLeftInPlace<false>(Z);
    return Z;
  }

  const MatrixType& matrixQTZ() const { return m_cpqr.matrixQR(); }
  const MatrixType& matrixT() const { return m_cpqr.matrixQR(); }

  template <typename InputType>
  CompleteOrthogonalDecompositionImpl& compute(const EigenBase<InputType>& matrix) {
    m_cpqr.compute(matrix);
    computeInPlace();
    return *this;
  }

  const PermutationType& colsPermutation() const { return m_cpqr.colsPermutation(); }

  typename MatrixType::Scalar determinant() const;
  typename MatrixType::RealScalar absDeterminant() const;
  typename MatrixType::RealScalar logAbsDeterminant() const;
  typename MatrixType::Scalar signDeterminant() const;

  inline Index rank() const { return m_cpqr.rank(); }
  inline Index dimensionOfKernel() const { return m_cpqr.dimensionOfKernel(); }
  inline bool isInjective() const { return m_cpqr.isInjective(); }
  inline bool isSurjective() const { return m_cpqr.isSurjective(); }
  inline bool isInvertible() const { return m_cpqr.isInvertible(); }

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

  inline const HCoeffsType& hCoeffs() const { return m_cpqr.hCoeffs(); }
  const HCoeffsType& zCoeffs() const { return m_zCoeffs; }

  CompleteOrthogonalDecompositionImpl& setThreshold(const RealScalar& threshold) {
    m_cpqr.setThreshold(threshold);
    return *this;
  }

  CompleteOrthogonalDecompositionImpl& setThreshold(Default_t) {
    m_cpqr.setThreshold(Default);
    return *this;
  }

  RealScalar threshold() const { return m_cpqr.threshold(); }

  inline Index nonzeroPivots() const { return m_cpqr.nonzeroPivots(); }
  inline RealScalar maxPivot() const { return m_cpqr.maxPivot(); }

  ComputationInfo info() const {
    eigen_assert(m_cpqr.m_isInitialized && "Decomposition is not initialized.");
    return Success;
  }

  /** \internal Asserts that compute() has been called. */
  void check_initialized() const {
    eigen_assert(m_cpqr.m_isInitialized && "CompleteOrthogonalDecomposition is not initialized.");
  }

#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_ ? this->cols() : this->rows()) == b.rows() &&
                 "CompleteOrthogonalDecomposition::solve(): invalid number of rows of the right hand side matrix b");
  }

  void computeInPlace();

  template <bool Conjugate, typename Rhs>
  void applyZOnTheLeftInPlace(Rhs& rhs) const;

  template <typename Rhs>
  void applyZAdjointOnTheLeftInPlace(Rhs& rhs) const;

  RankRevealingQRType m_cpqr;
  HCoeffsType m_zCoeffs;
  RowVectorType m_temp;
};

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

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

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

template <typename MatrixType, typename PermutationIndex, template <typename, typename> class RankRevealingQR_>
typename MatrixType::Scalar
CompleteOrthogonalDecompositionImpl<MatrixType, PermutationIndex, RankRevealingQR_>::signDeterminant() const {
  return m_cpqr.signDeterminant();
}

template <typename MatrixType, typename PermutationIndex, template <typename, typename> class RankRevealingQR_>
void CompleteOrthogonalDecompositionImpl<MatrixType, PermutationIndex, RankRevealingQR_>::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 <typename, typename> class RankRevealingQR_>
template <bool Conjugate, typename Rhs>
void CompleteOrthogonalDecompositionImpl<MatrixType, PermutationIndex, RankRevealingQR_>::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, typename> class RankRevealingQR_>
template <typename Rhs>
void CompleteOrthogonalDecompositionImpl<MatrixType, PermutationIndex, RankRevealingQR_>::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, typename> class RankRevealingQR_>
template <typename RhsType, typename DstType>
void CompleteOrthogonalDecompositionImpl<MatrixType, PermutationIndex, RankRevealingQR_>::_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 <typename, typename> class RankRevealingQR_>
template <bool Conjugate, typename RhsType, typename DstType>
void CompleteOrthogonalDecompositionImpl<MatrixType, PermutationIndex, RankRevealingQR_>::_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

template <typename MatrixType, typename PermutationIndex, template <typename, typename> class RankRevealingQR_>
typename CompleteOrthogonalDecompositionImpl<MatrixType, PermutationIndex, RankRevealingQR_>::HouseholderSequenceType
CompleteOrthogonalDecompositionImpl<MatrixType, PermutationIndex, RankRevealingQR_>::householderQ() const {
  return m_cpqr.householderQ();
}

}  // 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.
 *
 * Internally backed by ColPivHouseholderQR. For large matrices, see
 * RandCompleteOrthogonalDecomposition, which uses a randomized blocked
 * column-pivoted QR and is faster on level-3-BLAS-friendly inputs.
 *
 * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
 *
 * \sa MatrixBase::completeOrthogonalDecomposition(), RandCompleteOrthogonalDecomposition
 */
template <typename MatrixType_, typename PermutationIndex_>
class CompleteOrthogonalDecomposition
    : public internal::CompleteOrthogonalDecompositionImpl<MatrixType_, PermutationIndex_, ColPivHouseholderQR> {
 public:
  using Base =
      internal::CompleteOrthogonalDecompositionImpl<MatrixType_, PermutationIndex_, Eigen::ColPivHouseholderQR>;
  using typename Base::RealScalar;

  CompleteOrthogonalDecomposition() : Base() {}
  CompleteOrthogonalDecomposition(Index rows, Index cols) : Base(rows, cols) {}

  template <typename InputType>
  explicit CompleteOrthogonalDecomposition(const EigenBase<InputType>& matrix) : Base(matrix.derived()) {}

  template <typename InputType>
  explicit CompleteOrthogonalDecomposition(EigenBase<InputType>& matrix) : Base(matrix.derived()) {}

  /** \brief Computes the COD of \a matrix. \sa class CompleteOrthogonalDecomposition */
  template <typename InputType>
  CompleteOrthogonalDecomposition& compute(const EigenBase<InputType>& matrix) {
    Base::compute(matrix);
    return *this;
  }

  CompleteOrthogonalDecomposition& setThreshold(const RealScalar& threshold) {
    Base::setThreshold(threshold);
    return *this;
  }

  CompleteOrthogonalDecomposition& setThreshold(Default_t) {
    Base::setThreshold(Default);
    return *this;
  }

  /** \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 system.
   * It is more efficient and numerically stable to call \c this->solve(rhs).
   */
  inline Inverse<CompleteOrthogonalDecomposition> pseudoInverse() const {
    this->check_initialized();
    return Inverse<CompleteOrthogonalDecomposition>(*this);
  }
};

/** \ingroup QR_Module
 *
 * \class RandCompleteOrthogonalDecomposition
 *
 * \brief Complete orthogonal decomposition (COD) of a matrix, backed by
 * RandColPivHouseholderQR.
 *
 * Same factorization as CompleteOrthogonalDecomposition, but the rank-revealing
 * QR step uses the randomized blocked column-pivoted Householder QR
 * (BQRRP framework). On large matrices this is faster than the classical
 * Businger-Golub pivoting in CompleteOrthogonalDecomposition because almost
 * all work is performed in level-3 BLAS. The pivot-quality difference is
 * empirically minor; see RandColPivHouseholderQR for references and details.
 *
 * The block size and RNG seed of the underlying QR can be configured via
 * setBlockSize() and setSeed() before calling compute().
 *
 * For small or fixed-size matrices prefer CompleteOrthogonalDecomposition:
 * the sketch overhead dominates below roughly a few hundred rows/columns.
 *
 * \sa MatrixBase::randCompleteOrthogonalDecomposition(),
 *     CompleteOrthogonalDecomposition, RandColPivHouseholderQR
 */
template <typename MatrixType_, typename PermutationIndex_>
class RandCompleteOrthogonalDecomposition
    : public internal::CompleteOrthogonalDecompositionImpl<MatrixType_, PermutationIndex_, RandColPivHouseholderQR> {
 public:
  using Base =
      internal::CompleteOrthogonalDecompositionImpl<MatrixType_, PermutationIndex_, Eigen::RandColPivHouseholderQR>;
  using typename Base::RealScalar;

  RandCompleteOrthogonalDecomposition() : Base() {}
  RandCompleteOrthogonalDecomposition(Index rows, Index cols) : Base(rows, cols) {}

  template <typename InputType>
  explicit RandCompleteOrthogonalDecomposition(const EigenBase<InputType>& matrix) : Base(matrix.derived()) {}

  template <typename InputType>
  explicit RandCompleteOrthogonalDecomposition(EigenBase<InputType>& matrix) : Base(matrix.derived()) {}

  template <typename InputType>
  RandCompleteOrthogonalDecomposition& compute(const EigenBase<InputType>& matrix) {
    Base::compute(matrix);
    return *this;
  }

  RandCompleteOrthogonalDecomposition& setThreshold(const RealScalar& threshold) {
    Base::setThreshold(threshold);
    return *this;
  }

  RandCompleteOrthogonalDecomposition& setThreshold(Default_t) {
    Base::setThreshold(Default);
    return *this;
  }

  /** \brief Sets the panel block size of the underlying randomized QR.
   * \sa RandColPivHouseholderQR::setBlockSize
   */
  RandCompleteOrthogonalDecomposition& setBlockSize(Index b) {
    this->m_cpqr.setBlockSize(b);
    return *this;
  }

  /** \brief Fixes the RNG seed of the underlying randomized QR.
   * \sa RandColPivHouseholderQR::setSeed
   */
  RandCompleteOrthogonalDecomposition& setSeed(uint64_t seed) {
    this->m_cpqr.setSeed(seed);
    return *this;
  }

  inline Inverse<RandCompleteOrthogonalDecomposition> pseudoInverse() const {
    this->check_initialized();
    return Inverse<RandCompleteOrthogonalDecomposition>(*this);
  }
};

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> {
  using CodType = CompleteOrthogonalDecomposition<MatrixType, PermutationIndex>;
  using SrcXprType = Inverse<CodType>;
  static void run(DstXprType& dst, const SrcXprType& src,
                  const internal::assign_op<typename DstXprType::Scalar, typename CodType::Scalar>&) {
    using IdentityMatrixType = Matrix<typename CodType::Scalar, CodType::RowsAtCompileTime, CodType::RowsAtCompileTime,
                                      0, CodType::MaxRowsAtCompileTime, CodType::MaxRowsAtCompileTime>;
    dst = src.nestedExpression().solve(IdentityMatrixType::Identity(src.cols(), src.cols()));
  }
};

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

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

}  // end namespace internal

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

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

}  // end namespace Eigen

#endif  // EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H
