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

#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 const 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 const 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 more accurate estimation through symbolic factorization with 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;
  }

  m_pmat.uncompress();  // To have the innerNonZeroPtr allocated

  // Apply the fill-in reducing permutation lazily:
  {
    // If the input is row major, copy the original column indices,
    // otherwise directly use the input matrix
    //
    IndexVector originalOuterIndicesCpy;
    const StorageIndex* originalOuterIndices = mat.outerIndexPtr();
    if (MatrixType::IsRowMajor) {
      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 = 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 = 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 = 0;

    if (nonzeroCol < diagSize) {
      // Compute the Householder reflection that eliminate the current column
      // FIXME this step should call the Householder module.
      Scalar c0 = nzcolQ ? tval(Qidx(0)) : Scalar(0);

      // First, the squared norm of Q((col+1):m, col)
      RealScalar sqrNorm = 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)) = 1;
      } else {
        using std::sqrt;
        beta = sqrt(numext::abs2(c0) + sqrNorm);
        if (numext::real(c0) >= RealScalar(0)) beta = -beta;
        tval(Qidx(0)) = 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 this actually means adjoint
};

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 this is the same as adjoint at the moment
  SparseQRMatrixQTransposeReturnType<SparseQRType> transpose() const {
    return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
  }
  const SparseQRType& m_qr;
};

// TODO this actually 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
