// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012-2013 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
// Copyright (C) 2012-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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_SPARSE_QR_H
#define EIGEN_SPARSE_QR_H

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

namespace Eigen {

template <typename MatrixType, typename OrderingType>
class SparseQR;
template <typename SparseQRType>
struct SparseQRMatrixQReturnType;
template <typename SparseQRType>
struct SparseQRMatrixQTransposeReturnType;
template <typename SparseQRType, typename Derived>
struct SparseQR_QProduct;
namespace internal {
template <typename SparseQRType>
struct traits<SparseQRMatrixQReturnType<SparseQRType> > {
  typedef typename SparseQRType::MatrixType ReturnType;
  typedef typename ReturnType::StorageIndex StorageIndex;
  typedef typename ReturnType::StorageKind StorageKind;
  enum { RowsAtCompileTime = Dynamic, ColsAtCompileTime = Dynamic };
};
template <typename SparseQRType>
struct traits<SparseQRMatrixQTransposeReturnType<SparseQRType> > {
  typedef typename SparseQRType::MatrixType ReturnType;
};
template <typename SparseQRType, typename Derived>
struct traits<SparseQR_QProduct<SparseQRType, Derived> > {
  typedef typename Derived::PlainObject ReturnType;
};
}  // End namespace internal

/**
 * \ingroup SparseQR_Module
 * \class SparseQR
 * \brief Sparse left-looking QR factorization with numerical column pivoting
 *
 * This class implements a left-looking QR decomposition of sparse matrices
 * with numerical column pivoting.
 * When a column has a norm less than a given tolerance
 * it is implicitly permuted to the end. The QR factorization thus obtained is
 * given by A*P = Q*R where R is upper triangular or trapezoidal.
 *
 * P is the column permutation which is the product of the fill-reducing and the
 * numerical permutations. Use colsPermutation() to get it.
 *
 * Q is the orthogonal matrix represented as products of Householder reflectors.
 * Use matrixQ() to get an expression and matrixQ().adjoint() to get the adjoint.
 * You can then apply it to a vector.
 *
 * R is the sparse triangular or trapezoidal matrix. The later occurs when A is rank-deficient.
 * matrixR().topLeftCorner(rank(), rank()) always returns a triangular factor of full rank.
 *
 * \tparam MatrixType_ The type of the sparse matrix A, must be a column-major SparseMatrix<>
 * \tparam OrderingType_ The fill-reducing ordering method. See the \link OrderingMethods_Module
 *  OrderingMethods \endlink module for the list of built-in and external ordering methods.
 *
 * \implsparsesolverconcept
 *
 * The numerical pivoting strategy and default threshold are the same as in SuiteSparse QR, and
 * detailed in the following paper:
 * <i>
 * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing
 * Sparse QR Factorization", ACM Trans. on Math. Soft. 38(1), 2011.
 * </i>
 * Even though it is qualified as "rank-revealing", this strategy might fail for some
 * rank deficient problems. When this class is used to solve linear or least-square problems
 * it is thus strongly recommended to check the accuracy of the computed solution. If it
 * failed, it usually helps to increase the threshold with setPivotThreshold.
 *
 * \warning The input sparse matrix A must be in compressed mode (see SparseMatrix::makeCompressed()).
 * \warning For complex matrices matrixQ().transpose() will actually return the adjoint matrix.
 *
 */
template <typename MatrixType_, typename OrderingType_>
class SparseQR : public SparseSolverBase<SparseQR<MatrixType_, OrderingType_> > {
 protected:
  typedef SparseSolverBase<SparseQR<MatrixType_, OrderingType_> > Base;
  using Base::m_isInitialized;

 public:
  using Base::_solve_impl;
  typedef MatrixType_ MatrixType;
  typedef OrderingType_ OrderingType;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;
  typedef typename MatrixType::StorageIndex StorageIndex;
  typedef SparseMatrix<Scalar, ColMajor, StorageIndex> QRMatrixType;
  typedef Matrix<StorageIndex, Dynamic, 1> IndexVector;
  typedef Matrix<Scalar, Dynamic, 1> ScalarVector;
  typedef PermutationMatrix<Dynamic, Dynamic, StorageIndex> PermutationType;

  enum { ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime };

 public:
  SparseQR()
      : m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true), m_isQSorted(false), m_isEtreeOk(false) {}

  /** Construct a QR factorization of the matrix \a mat.
   *
   * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
   *
   * \sa compute()
   */
  explicit SparseQR(const MatrixType& mat)
      : m_analysisIsok(false), m_lastError(""), m_useDefaultThreshold(true), m_isQSorted(false), m_isEtreeOk(false) {
    compute(mat);
  }

  /** Computes the QR factorization of the sparse matrix \a mat.
   *
   * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
   *
   * \sa analyzePattern(), factorize()
   */
  void compute(const MatrixType& mat) {
    analyzePattern(mat);
    factorize(mat);
  }
  void analyzePattern(const MatrixType& mat);
  void factorize(const MatrixType& mat);

  /** \returns the number of rows of the represented matrix.
   */
  inline Index rows() const { return m_pmat.rows(); }

  /** \returns the number of columns of the represented matrix.
   */
  inline Index cols() const { return m_pmat.cols(); }

  /** \returns a const reference to the \b sparse upper triangular matrix R of the QR factorization.
   * \warning The entries of the returned matrix are not sorted. This means that using it in algorithms
   *          expecting sorted entries will fail. This include random coefficient accesses (SpaseMatrix::coeff()),
   *          and coefficient-wise operations. Matrix products and triangular solves are fine though.
   *
   * To sort the entries, you can assign it to a row-major matrix, and if a column-major matrix
   * is required, you can copy it again:
   * \code
   * SparseMatrix<double>          R  = qr.matrixR();  // column-major, not sorted!
   * SparseMatrix<double,RowMajor> Rr = qr.matrixR();  // row-major, sorted
   * SparseMatrix<double>          Rc = Rr;            // column-major, sorted
   * \endcode
   */
  const QRMatrixType& matrixR() const { return m_R; }

  /** \returns the number of non linearly dependent columns as determined by the pivoting threshold.
   *
   * \sa setPivotThreshold()
   */
  Index rank() const {
    eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
    return m_nonzeropivots;
  }

  /** \returns an expression of the matrix Q as products of sparse Householder reflectors.
   * The common usage of this function is to apply it to a dense matrix or vector
   * \code
   * VectorXd B1, B2;
   * // Initialize B1
   * B2 = matrixQ() * B1;
   * \endcode
   *
   * To get a plain SparseMatrix representation of Q:
   * \code
   * SparseMatrix<double> Q;
   * Q = SparseQR<SparseMatrix<double> >(A).matrixQ();
   * \endcode
   * Internally, this call simply performs a sparse product between the matrix Q
   * and a sparse identity matrix. However, due to the fact that the sparse
   * reflectors are stored unsorted, two transpositions are needed to sort
   * them before performing the product.
   */
  SparseQRMatrixQReturnType<SparseQR> matrixQ() const { return SparseQRMatrixQReturnType<SparseQR>(*this); }

  /** \returns a const reference to the column permutation P that was applied to A such that A*P = Q*R
   * It is the combination of the fill-in reducing permutation and numerical column pivoting.
   */
  const PermutationType& colsPermutation() const {
    eigen_assert(m_isInitialized && "Decomposition is not initialized.");
    return m_outputPerm_c;
  }

  /** \returns A string describing the type of error.
   * This method is provided to ease debugging, not to handle errors.
   */
  std::string lastErrorMessage() const { return m_lastError; }

  /** \internal */
  template <typename Rhs, typename Dest>
  bool _solve_impl(const MatrixBase<Rhs>& B, MatrixBase<Dest>& dest) const {
    eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
    eigen_assert(this->rows() == B.rows() &&
                 "SparseQR::solve() : invalid number of rows in the right hand side matrix");

    Index rank = this->rank();

    // Compute Q^* * b;
    typename Dest::PlainObject y, b;
    y = this->matrixQ().adjoint() * B;
    b = y;

    // Solve with the triangular matrix R
    y.resize((std::max<Index>)(cols(), y.rows()), y.cols());
    y.topRows(rank) = this->matrixR().topLeftCorner(rank, rank).template triangularView<Upper>().solve(b.topRows(rank));
    y.bottomRows(y.rows() - rank).setZero();

    // Apply the column permutation
    if (m_perm_c.size())
      dest = colsPermutation() * y.topRows(cols());
    else
      dest = y.topRows(cols());

    m_info = Success;
    return true;
  }

  /** Sets the threshold that is used to determine linearly dependent columns during the factorization.
   *
   * In practice, if during the factorization the norm of the column that has to be eliminated is below
   * this threshold, then the entire column is treated as zero, and it is moved at the end.
   */
  void setPivotThreshold(const RealScalar& threshold) {
    m_useDefaultThreshold = false;
    m_threshold = threshold;
  }

  /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
   *
   * \sa compute()
   */
  template <typename Rhs>
  inline Solve<SparseQR, Rhs> solve(const MatrixBase<Rhs>& B) const {
    eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
    eigen_assert(this->rows() == B.rows() &&
                 "SparseQR::solve() : invalid number of rows in the right hand side matrix");
    return Solve<SparseQR, Rhs>(*this, B.derived());
  }
  template <typename Rhs>
  inline Solve<SparseQR, Rhs> solve(const SparseMatrixBase<Rhs>& B) const {
    eigen_assert(m_isInitialized && "The factorization should be called first, use compute()");
    eigen_assert(this->rows() == B.rows() &&
                 "SparseQR::solve() : invalid number of rows in the right hand side matrix");
    return Solve<SparseQR, Rhs>(*this, B.derived());
  }

  /** \brief Reports whether previous computation was successful.
   *
   * \returns \c Success if computation was successful,
   *          \c NumericalIssue if the QR factorization reports a numerical problem
   *          \c InvalidInput if the input matrix is invalid
   *
   * \sa iparm()
   */
  ComputationInfo info() const {
    eigen_assert(m_isInitialized && "Decomposition is not initialized.");
    return m_info;
  }

  /** \internal */
  inline void _sort_matrix_Q() {
    if (this->m_isQSorted) return;
    // The matrix Q is sorted during the transposition
    SparseMatrix<Scalar, RowMajor, Index> mQrm(this->m_Q);
    this->m_Q = mQrm;
    this->m_isQSorted = true;
  }

 protected:
  bool m_analysisIsok;
  bool m_factorizationIsok;
  mutable ComputationInfo m_info;
  std::string m_lastError;
  QRMatrixType m_pmat;             // Temporary matrix
  QRMatrixType m_R;                // The triangular factor matrix
  QRMatrixType m_Q;                // The orthogonal reflectors
  ScalarVector m_hcoeffs;          // The Householder coefficients
  PermutationType m_perm_c;        // Fill-reducing  Column  permutation
  PermutationType m_pivotperm;     // The permutation for rank revealing
  PermutationType m_outputPerm_c;  // The final column permutation
  RealScalar m_threshold;          // Threshold to determine null Householder reflections
  bool m_useDefaultThreshold;      // Use default threshold
  Index m_nonzeropivots;           // Number of non zero pivots found
  IndexVector m_etree;             // Column elimination tree
  IndexVector m_firstRowElt;       // First element in each row
  bool m_isQSorted;                // whether Q is sorted or not
  bool m_isEtreeOk;                // whether the elimination tree match the initial input matrix

  template <typename, typename>
  friend struct SparseQR_QProduct;
};

/** \brief Preprocessing step of a QR factorization
 *
 * \warning The matrix \a mat must be in compressed mode (see SparseMatrix::makeCompressed()).
 *
 * In this step, the fill-reducing permutation is computed and applied to the columns of A
 * and the column elimination tree is computed as well. Only the sparsity pattern of \a mat is exploited.
 *
 * \note In this step it is assumed that there is no empty row in the matrix \a mat.
 */
template <typename MatrixType, typename OrderingType>
void SparseQR<MatrixType, OrderingType>::analyzePattern(const MatrixType& mat) {
  eigen_assert(
      mat.isCompressed() &&
      "SparseQR requires a sparse matrix in compressed mode. Call .makeCompressed() before passing it to SparseQR");
  // Copy to a column major matrix if the input is rowmajor
  std::conditional_t<MatrixType::IsRowMajor, QRMatrixType, const MatrixType&> matCpy(mat);
  // Compute the column fill reducing ordering
  OrderingType ord;
  ord(matCpy, m_perm_c);
  Index n = mat.cols();
  Index m = mat.rows();
  Index diagSize = (std::min)(m, n);

  if (!m_perm_c.size()) {
    m_perm_c.resize(n);
    m_perm_c.indices().setLinSpaced(n, 0, StorageIndex(n - 1));
  }

  // Compute the column elimination tree of the permuted matrix
  m_outputPerm_c = m_perm_c.inverse();
  internal::coletree(matCpy, m_etree, m_firstRowElt, m_outputPerm_c.indices().data());
  m_isEtreeOk = true;

  m_R.resize(m, n);
  m_Q.resize(m, diagSize);

  // Allocate space for nonzero elements: rough estimation
  m_R.reserve(2 * mat.nonZeros());  // FIXME: get a tighter bound via symbolic factorization using the etree.
  m_Q.reserve(2 * mat.nonZeros());
  m_hcoeffs.resize(diagSize);
  m_analysisIsok = true;
}

/** \brief Performs the numerical QR factorization of the input matrix
 *
 * The function SparseQR::analyzePattern(const MatrixType&) must have been called beforehand with
 * a matrix having the same sparsity pattern than \a mat.
 *
 * \param mat The sparse column-major matrix
 */
template <typename MatrixType, typename OrderingType>
void SparseQR<MatrixType, OrderingType>::factorize(const MatrixType& mat) {
  using std::abs;

  eigen_assert(m_analysisIsok && "analyzePattern() should be called before this step");
  StorageIndex m = StorageIndex(mat.rows());
  StorageIndex n = StorageIndex(mat.cols());
  StorageIndex diagSize = (std::min)(m, n);
  IndexVector mark((std::max)(m, n));
  mark.setConstant(-1);          // Record the visited nodes
  IndexVector Ridx(n), Qidx(m);  // Store temporarily the row indexes for the current column of R and Q
  Index nzcolR, nzcolQ;          // Number of nonzero for the current column of R and Q
  ScalarVector tval(m);          // The dense vector used to compute the current column

  m_R.setZero();
  m_Q.setZero();
  m_pmat = mat;
  if (!m_isEtreeOk) {
    m_outputPerm_c = m_perm_c.inverse();
    internal::coletree(m_pmat, m_etree, m_firstRowElt, m_outputPerm_c.indices().data());
    m_isEtreeOk = true;
  }

  // Switch to uncompressed mode so innerNonZeroPtr() exists and can be
  // permuted consistently with outerIndexPtr().
  m_pmat.uncompress();

  // Apply the fill-in reducing permutation lazily:
  {
    // A compressed column-major input already exposes valid column pointers.
    // Otherwise snapshot the internal column-major structure before permuting in place.
    IndexVector originalOuterIndicesCpy;
    const bool useInputOuterIndices = !MatrixType::IsRowMajor && mat.isCompressed();
    const StorageIndex* originalOuterIndices = useInputOuterIndices ? mat.outerIndexPtr() : nullptr;
    if (!useInputOuterIndices) {
      originalOuterIndicesCpy = IndexVector::Map(m_pmat.outerIndexPtr(), n + 1);
      originalOuterIndices = originalOuterIndicesCpy.data();
    }

    for (int i = 0; i < n; i++) {
      Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i;
      m_pmat.outerIndexPtr()[p] = originalOuterIndices[i];
      m_pmat.innerNonZeroPtr()[p] = originalOuterIndices[i + 1] - originalOuterIndices[i];
    }
  }

  /* Compute the default threshold as in MatLab, see:
   * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing
   * Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3
   */
  RealScalar pivotThreshold;
  if (m_useDefaultThreshold) {
    RealScalar max2Norm = RealScalar(0.0);
    for (int j = 0; j < n; j++) max2Norm = numext::maxi(max2Norm, m_pmat.col(j).norm());
    if (max2Norm == RealScalar(0)) max2Norm = RealScalar(1);
    pivotThreshold = RealScalar(20 * (m + n)) * max2Norm * NumTraits<RealScalar>::epsilon();
  } else {
    pivotThreshold = m_threshold;
  }

  // Initialize the numerical permutation
  m_pivotperm.setIdentity(n);

  StorageIndex nonzeroCol = 0;  // Record the number of valid pivots
  m_Q.startVec(0);

  // Left looking rank-revealing QR factorization: compute a column of R and Q at a time
  for (StorageIndex col = 0; col < n; ++col) {
    mark.setConstant(-1);
    m_R.startVec(col);
    mark(nonzeroCol) = col;
    Qidx(0) = nonzeroCol;
    nzcolR = 0;
    nzcolQ = 1;
    bool found_diag = nonzeroCol >= m;
    tval.setZero();

    // Symbolic factorization: find the nonzero locations of the column k of the factors R and Q, i.e.,
    // all the nodes (with indexes lower than rank) reachable through the column elimination tree (etree) rooted at node
    // k. Note: if the diagonal entry does not exist, then its contribution must be explicitly added, thus the trick
    // with found_diag that permits to do one more iteration on the diagonal element if this one has not been found.
    for (typename QRMatrixType::InnerIterator itp(m_pmat, col); itp || !found_diag; ++itp) {
      StorageIndex curIdx = nonzeroCol;
      if (itp) curIdx = StorageIndex(itp.row());
      if (curIdx == nonzeroCol) found_diag = true;

      // Get the nonzeros indexes of the current column of R
      StorageIndex st = m_firstRowElt(curIdx);  // The traversal of the etree starts here
      if (st < 0) {
        m_lastError = "Empty row found during numerical factorization";
        m_info = InvalidInput;
        return;
      }

      // Traverse the etree
      Index bi = nzcolR;
      for (; mark(st) != col; st = m_etree(st)) {
        Ridx(nzcolR) = st;  // Add this row to the list,
        mark(st) = col;     // and mark this row as visited
        nzcolR++;
      }

      // Reverse the list to get the topological ordering
      Index nt = nzcolR - bi;
      for (Index i = 0; i < nt / 2; i++) std::swap(Ridx(bi + i), Ridx(nzcolR - i - 1));

      // Copy the current (curIdx,pcol) value of the input matrix
      if (itp)
        tval(curIdx) = itp.value();
      else
        tval(curIdx) = Scalar(0);

      // Compute the pattern of Q(:,k)
      if (curIdx > nonzeroCol && mark(curIdx) != col) {
        Qidx(nzcolQ) = curIdx;  // Add this row to the pattern of Q,
        mark(curIdx) = col;     // and mark it as visited
        nzcolQ++;
      }
    }

    // Browse all the indexes of R(:,col) in reverse order
    for (Index i = nzcolR - 1; i >= 0; i--) {
      Index curIdx = Ridx(i);

      // Apply the curIdx-th householder vector to the current column (temporarily stored into tval)
      Scalar tdot(0);

      // First compute q' * tval
      tdot = m_Q.col(curIdx).dot(tval);

      tdot *= m_hcoeffs(curIdx);

      // Then update tval = tval - q * tau
      tval -= tdot * m_Q.col(curIdx);

      // Detect fill-in for the current column of Q
      if (m_etree(Ridx(i)) == nonzeroCol) {
        for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq) {
          StorageIndex iQ = StorageIndex(itq.row());
          if (mark(iQ) != col) {
            Qidx(nzcolQ++) = iQ;  // Add this row to the pattern of Q,
            mark(iQ) = col;       // and mark it as visited
          }
        }
      }
    }  // End update current column

    Scalar tau = RealScalar(0);
    RealScalar beta = RealScalar(0);

    if (nonzeroCol < diagSize) {
      // Compute the Householder reflection that eliminate the current column
      // FIXME: refactor to use the Householder module's reflector computation.
      Scalar c0 = nzcolQ ? tval(Qidx(0)) : Scalar(0);

      // First, the squared norm of Q((col+1):m, col)
      RealScalar sqrNorm = RealScalar(0.);
      for (Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += numext::abs2(tval(Qidx(itq)));
      if (sqrNorm == RealScalar(0) && numext::imag(c0) == RealScalar(0)) {
        beta = numext::real(c0);
        tval(Qidx(0)) = Scalar(1);
      } else {
        using std::sqrt;
        beta = sqrt(numext::abs2(c0) + sqrNorm);
        if (numext::real(c0) >= RealScalar(0)) beta = -beta;
        tval(Qidx(0)) = Scalar(1);
        for (Index itq = 1; itq < nzcolQ; ++itq) tval(Qidx(itq)) /= (c0 - beta);
        tau = numext::conj((beta - c0) / beta);
      }
    }

    // Insert values in R
    for (Index i = nzcolR - 1; i >= 0; i--) {
      Index curIdx = Ridx(i);
      if (curIdx < nonzeroCol) {
        m_R.insertBackByOuterInnerUnordered(col, curIdx) = tval(curIdx);
        tval(curIdx) = Scalar(0.);
      }
    }

    if (nonzeroCol < diagSize && abs(beta) >= pivotThreshold) {
      m_R.insertBackByOuterInner(col, nonzeroCol) = beta;
      // The householder coefficient
      m_hcoeffs(nonzeroCol) = tau;
      // Record the householder reflections
      for (Index itq = 0; itq < nzcolQ; ++itq) {
        Index iQ = Qidx(itq);
        m_Q.insertBackByOuterInnerUnordered(nonzeroCol, iQ) = tval(iQ);
        tval(iQ) = Scalar(0.);
      }
      nonzeroCol++;
      if (nonzeroCol < diagSize) m_Q.startVec(nonzeroCol);
    } else {
      // Zero pivot found: move implicitly this column to the end
      for (Index j = nonzeroCol; j < n - 1; j++) std::swap(m_pivotperm.indices()(j), m_pivotperm.indices()[j + 1]);

      // Recompute the column elimination tree
      internal::coletree(m_pmat, m_etree, m_firstRowElt, m_pivotperm.indices().data());
      m_isEtreeOk = false;
    }
  }

  m_hcoeffs.tail(diagSize - nonzeroCol).setZero();

  // Finalize the column pointers of the sparse matrices R and Q
  m_Q.finalize();
  m_Q.makeCompressed();
  m_R.finalize();
  m_R.makeCompressed();
  m_isQSorted = false;

  m_nonzeropivots = nonzeroCol;

  if (nonzeroCol < n) {
    // Permute the triangular factor to put the 'dead' columns to the end
    QRMatrixType tempR(m_R);
    m_R = tempR * m_pivotperm;

    // Update the column permutation
    m_outputPerm_c = m_outputPerm_c * m_pivotperm;
  }

  m_isInitialized = true;
  m_factorizationIsok = true;
  m_info = Success;
}

template <typename SparseQRType, typename Derived>
struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived> > {
  typedef typename SparseQRType::QRMatrixType MatrixType;
  typedef typename SparseQRType::Scalar Scalar;
  // Get the references
  SparseQR_QProduct(const SparseQRType& qr, const Derived& other, bool transpose)
      : m_qr(qr), m_other(other), m_transpose(transpose) {}
  inline Index rows() const { return m_qr.matrixQ().rows(); }
  inline Index cols() const { return m_other.cols(); }

  // Assign to a vector
  template <typename DesType>
  void evalTo(DesType& res) const {
    Index m = m_qr.rows();
    Index n = m_qr.cols();
    Index diagSize = (std::min)(m, n);
    res = m_other;
    if (m_transpose) {
      eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes");
      // Compute res = Q' * other column by column
      for (Index j = 0; j < res.cols(); j++) {
        for (Index k = 0; k < diagSize; k++) {
          Scalar tau = Scalar(0);
          tau = m_qr.m_Q.col(k).dot(res.col(j));
          if (tau == Scalar(0)) continue;
          tau = tau * m_qr.m_hcoeffs(k);
          res.col(j) -= tau * m_qr.m_Q.col(k);
        }
      }
    } else {
      eigen_assert(m_qr.matrixQ().cols() == m_other.rows() && "Non conforming object sizes");

      res.conservativeResize(rows(), cols());

      // Compute res = Q * other column by column
      for (Index j = 0; j < res.cols(); j++) {
        Index start_k = internal::is_identity<Derived>::value ? numext::mini(j, diagSize - 1) : diagSize - 1;
        for (Index k = start_k; k >= 0; k--) {
          Scalar tau = Scalar(0);
          tau = m_qr.m_Q.col(k).dot(res.col(j));
          if (tau == Scalar(0)) continue;
          tau = tau * numext::conj(m_qr.m_hcoeffs(k));
          res.col(j) -= tau * m_qr.m_Q.col(k);
        }
      }
    }
  }

  const SparseQRType& m_qr;
  const Derived& m_other;
  bool m_transpose;  // TODO: rename to m_adjoint; this flag controls adjoint application.
};

template <typename SparseQRType>
struct SparseQRMatrixQReturnType : public EigenBase<SparseQRMatrixQReturnType<SparseQRType> > {
  typedef typename SparseQRType::Scalar Scalar;
  typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrix;
  enum { RowsAtCompileTime = Dynamic, ColsAtCompileTime = Dynamic };
  explicit SparseQRMatrixQReturnType(const SparseQRType& qr) : m_qr(qr) {}
  template <typename Derived>
  SparseQR_QProduct<SparseQRType, Derived> operator*(const MatrixBase<Derived>& other) {
    return SparseQR_QProduct<SparseQRType, Derived>(m_qr, other.derived(), false);
  }
  // To use for operations with the adjoint of Q
  SparseQRMatrixQTransposeReturnType<SparseQRType> adjoint() const {
    return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
  }
  inline Index rows() const { return m_qr.rows(); }
  inline Index cols() const { return m_qr.rows(); }
  // To use for operations with the transpose of Q. FIXME: currently identical to adjoint(); specialize for complex.
  SparseQRMatrixQTransposeReturnType<SparseQRType> transpose() const {
    return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
  }
  const SparseQRType& m_qr;
};

// TODO: rename to SparseQRMatrixQAdjointReturnType; this represents the adjoint of Q.
template <typename SparseQRType>
struct SparseQRMatrixQTransposeReturnType {
  explicit SparseQRMatrixQTransposeReturnType(const SparseQRType& qr) : m_qr(qr) {}
  template <typename Derived>
  SparseQR_QProduct<SparseQRType, Derived> operator*(const MatrixBase<Derived>& other) {
    return SparseQR_QProduct<SparseQRType, Derived>(m_qr, other.derived(), true);
  }
  const SparseQRType& m_qr;
};

namespace internal {

template <typename SparseQRType>
struct evaluator_traits<SparseQRMatrixQReturnType<SparseQRType> > {
  typedef typename SparseQRType::MatrixType MatrixType;
  typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind;
  typedef SparseShape Shape;
};

template <typename DstXprType, typename SparseQRType>
struct Assignment<DstXprType, SparseQRMatrixQReturnType<SparseQRType>,
                  internal::assign_op<typename DstXprType::Scalar, typename DstXprType::Scalar>, Sparse2Sparse> {
  typedef SparseQRMatrixQReturnType<SparseQRType> SrcXprType;
  typedef typename DstXprType::Scalar Scalar;
  typedef typename DstXprType::StorageIndex StorageIndex;
  static void run(DstXprType& dst, const SrcXprType& src, const internal::assign_op<Scalar, Scalar>& /*func*/) {
    typename DstXprType::PlainObject idMat(src.rows(), src.cols());
    idMat.setIdentity();
    // Sort the sparse householder reflectors if needed
    const_cast<SparseQRType*>(&src.m_qr)->_sort_matrix_Q();
    dst = SparseQR_QProduct<SparseQRType, DstXprType>(src.m_qr, idMat, false);
  }
};

template <typename DstXprType, typename SparseQRType>
struct Assignment<DstXprType, SparseQRMatrixQReturnType<SparseQRType>,
                  internal::assign_op<typename DstXprType::Scalar, typename DstXprType::Scalar>, Sparse2Dense> {
  typedef SparseQRMatrixQReturnType<SparseQRType> SrcXprType;
  typedef typename DstXprType::Scalar Scalar;
  typedef typename DstXprType::StorageIndex StorageIndex;
  static void run(DstXprType& dst, const SrcXprType& src, const internal::assign_op<Scalar, Scalar>& /*func*/) {
    dst = src.m_qr.matrixQ() * DstXprType::Identity(src.m_qr.rows(), src.m_qr.rows());
  }
};

}  // end namespace internal

}  // end namespace Eigen

#endif
