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


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;
  };
  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
  * 
  * This class is used to perform a left-looking QR decomposition 
  * of sparse matrices. The result is then used to solve linear leasts_square systems.
  * Clearly, a QR factorization is returned such that A*P = Q*R where :
  * 
  * P is the column permutation. Use colsPermutation() to get it.
  * 
  * Q is the orthogonal matrix represented as Householder reflectors. 
  * Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose.
  * You can then apply it to a vector.
  * 
  * R is the sparse triangular factor. Use matrixR() to get it as SparseMatrix.
  * 
  * \note This is not a rank-revealing QR decomposition.
  * 
  * \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.
  * 
  * 
  */
template<typename _MatrixType, typename _OrderingType>
class SparseQR
{
  public:
    typedef _MatrixType MatrixType;
    typedef _OrderingType OrderingType;
    typedef typename MatrixType::Scalar Scalar;
    typedef typename MatrixType::RealScalar RealScalar;
    typedef typename MatrixType::Index Index;
    typedef SparseMatrix<Scalar,ColMajor,Index> QRMatrixType;
    typedef Matrix<Index, Dynamic, 1> IndexVector;
    typedef Matrix<Scalar, Dynamic, 1> ScalarVector;
    typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;
  public:
    SparseQR () : m_isInitialized(false),m_analysisIsok(false)
    { }
    
    SparseQR(const MatrixType& mat) : m_isInitialized(false),m_analysisIsok(false)
    {
      compute(mat);
    }
    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.
      */
    const MatrixType& matrixR() const { return m_R; }
    
    /** \returns an expression of the matrix Q as products of sparse Householder reflectors.
      * You can do the following to get an actual SparseMatrix representation of Q:
      * \code
      * SparseMatrix<double> Q = SparseQR<SparseMatrix<double> >(A).matrixQ();
      * \endcode
      */
    SparseQRMatrixQReturnType<SparseQR> matrixQ() const 
    { return SparseQRMatrixQReturnType<SparseQR>(*this); }
    
    /** \returns a const reference to the fill-in reducing permutation that was applied to the columns of A
      */
    const PermutationType& colsPermutation() const
    { 
      eigen_assert(m_isInitialized && "Decomposition is not initialized.");
      return m_perm_c;
    }
    
    /** \internal */
    template<typename Rhs, typename Dest>
    bool _solve(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->matrixR().cols();
      // Compute Q^T * b;
      dest = this->matrixQ().transpose() * B;      
      // Solve with the triangular matrix R
      Dest y;
      y = this->matrixR().template triangularView<Upper>().solve(dest.derived().topRows(rank));
      
      // Apply the column permutation
      if (m_perm_c.size())  dest.topRows(rank) =  colsPermutation().inverse() * y;
      else                  dest = y;
      
      m_info = Success;
      return true;
    }
    
    /** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
      *
      * \sa compute()
      */
    template<typename Rhs>
    inline const internal::solve_retval<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 internal::solve_retval<SparseQR, Rhs>(*this, B.derived());
    }
    
    /** \brief Reports whether previous computation was successful.
      *
      * \returns \c Success if computation was succesful,
      *          \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;
    }
    
  protected:
    bool m_isInitialized;
    bool m_analysisIsok;
    bool m_factorizationIsok;
    mutable ComputationInfo m_info;
    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;       // Column  permutation 
    PermutationType m_perm_r;       // Column permutation 
    IndexVector m_etree;            // Column elimination tree
    IndexVector m_firstRowElt;      // First element in each row
    IndexVector m_found_diag_elem;  // Existence of diagonal elements
    template <typename, typename > friend struct SparseQR_QProduct;
    
};

/** \brief Preprocessing step of a QR factorization 
  * 
  * 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 sparcity 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)
{
  // Compute the column fill reducing ordering
  OrderingType ord; 
  ord(mat, m_perm_c); 
  Index n = mat.cols();
  Index m = mat.rows();
  // Permute the input matrix... only the column pointers are permuted
  // FIXME: directly send "m_perm.inverse() * mat" to coletree -> need an InnerIterator to the sparse-permutation-product expression.
  m_pmat = mat;
  m_pmat.uncompress();
  for (int i = 0; i < n; i++)
  {
    Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i;
    m_pmat.outerIndexPtr()[p] = mat.outerIndexPtr()[i]; 
    m_pmat.innerNonZeroPtr()[p] = mat.outerIndexPtr()[i+1] - mat.outerIndexPtr()[i]; 
  }
  // Compute the column elimination tree of the permuted matrix
  internal::coletree(m_pmat, m_etree, m_firstRowElt);
  
  m_R.resize(n, n);
  m_Q.resize(m, m);
  // 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(n);
  m_analysisIsok = true;
}

/** \brief Perform 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 sparcity pattern than \a mat.
  * 
  * \param mat The sparse column-major matrix
  */
template <typename MatrixType, typename OrderingType>
void SparseQR<MatrixType,OrderingType>::factorize(const MatrixType& mat)
{
  eigen_assert(m_analysisIsok && "analyzePattern() should be called before this step");
  Index m = mat.rows();
  Index n = mat.cols();
  IndexVector mark(m); 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
  Index pcol;
  ScalarVector tval(m); tval.setZero();       // Temporary vector
  IndexVector iperm(n);
  bool found_diag;
  if (m_perm_c.size())
    for(int i = 0; i < n; i++) iperm(m_perm_c.indices()(i)) = i;
  else
    iperm.setLinSpaced(n, 0, n-1);
      
  // Left looking QR factorization : Compute a column of R and Q at a time
  for (Index col = 0; col < n; col++)
  {
    m_R.startVec(col);
    m_Q.startVec(col);
    mark(col) = col;
    Qidx(0) = col; 
    nzcolR = 0; nzcolQ = 1;
    pcol = iperm(col);
    found_diag = false;
    // Find the nonzero locations of the column k of R, 
    // i.e All the nodes (with indexes lower than k) reachable through the col etree rooted at node k
    for (typename MatrixType::InnerIterator itp(mat, pcol); itp || !found_diag; ++itp)
    {
      Index curIdx = col;
      if (itp) curIdx = itp.row();
      if(curIdx == col) found_diag = true;
      // Get the nonzeros indexes  of the current column of R
      Index st = m_firstRowElt(curIdx); // The traversal of the etree starts here 
      if (st < 0 )
      {
        std::cerr << " Empty row found during Numerical factorization ... Abort \n";
        m_info = NumericalIssue;
        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; // Mark this row as visited
        nzcolR++;
      }
      // Reverse the list to get the topological ordering
      Index nt = nzcolR-bi;
      for(int i = 0; i < nt/2; i++) std::swap(Ridx(bi+i), Ridx(nzcolR-i-1));
       
      // Copy the current row value of mat
      if (itp) tval(curIdx) = itp.value();
      else tval(curIdx) = Scalar(0.);
      
      // Compute the pattern of Q(:,k)
      if (curIdx > col && 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> householder vector  to tval
      Scalar tdot(0.);
      //First compute q'*tval
      for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq)
      {
        tdot += internal::conj(itq.value()) * tval(itq.row());
      }
      tdot *= m_hcoeffs(curIdx);
      // Then compute tval = tval - q*tau
      for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq)
      {
        tval(itq.row()) -= itq.value() * tdot;
      }
      //With the topological ordering, updates for curIdx are fully done at this point
      m_R.insertBackByOuterInnerUnordered(col, curIdx) = tval(curIdx);
      tval(curIdx) = Scalar(0.);
      
      // Detect fill-in for the current column of Q
      if(m_etree(curIdx) == col)
      {
        for (typename QRMatrixType::InnerIterator itq(m_Q, curIdx); itq; ++itq)
        {
          Index iQ = 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 of R
    
    // Record the current (unscaled) column of V.
    for (Index itq = 0; itq < nzcolQ; ++itq)
    {
      Index iQ = Qidx(itq);      
      m_Q.insertBackByOuterInnerUnordered(col,iQ) = tval(iQ);
      tval(iQ) = Scalar(0.);
    }
    // Compute the new Householder reflection
    RealScalar sqrNorm =0.;
    Scalar tau; RealScalar beta;
    typename QRMatrixType::InnerIterator itq(m_Q, col);
    Scalar c0 = (itq) ? itq.value() : Scalar(0.);
    //First, the squared norm of Q((col+1):m, col)
    if(itq) ++itq;
    for (; itq; ++itq)
    {
      sqrNorm += internal::abs2(itq.value());
    }
    if(sqrNorm == RealScalar(0) && internal::imag(c0) == RealScalar(0))
    {
      tau = RealScalar(0);
      beta = internal::real(c0);
      typename QRMatrixType::InnerIterator it(m_Q,col);
      it.valueRef() = 1; //FIXME A row permutation should be performed at this point
    }
    else
    {
      beta = std::sqrt(internal::abs2(c0) + sqrNorm);
      if(internal::real(c0) >= RealScalar(0))
        beta = -beta;
      typename QRMatrixType::InnerIterator it(m_Q,col);
      it.valueRef() = 1;
      for (++it; it; ++it)
      {
        it.valueRef() /= (c0 - beta);
      }
      tau = internal::conj((beta-c0) / beta);
        
    }
    m_hcoeffs(col) = tau;
    m_R.insertBackByOuterInnerUnordered(col, col) = beta;
  }
  // Finalize the column pointers of the sparse matrices R and Q
  m_R.finalize(); m_R.makeCompressed();
  m_Q.finalize(); m_Q.makeCompressed();
  m_isInitialized = true; 
  m_factorizationIsok = true;
  m_info = Success;
  
}

namespace internal {
  
template<typename _MatrixType, typename OrderingType, typename Rhs>
struct solve_retval<SparseQR<_MatrixType,OrderingType>, Rhs>
  : solve_retval_base<SparseQR<_MatrixType,OrderingType>, Rhs>
{
  typedef SparseQR<_MatrixType,OrderingType> Dec;
  EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)

  template<typename Dest> void evalTo(Dest& dst) const
  {
    dec()._solve(rhs(),dst);
  }
};

} // end namespace internal

template <typename SparseQRType, typename Derived>
struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived> >
{
  typedef typename SparseQRType::QRMatrixType MatrixType;
  typedef typename SparseQRType::Scalar Scalar;
  typedef typename SparseQRType::Index Index;
  // 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_transpose ? m_qr.rowsQ() : m_qr.cols(); }
  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(); 
    if (m_transpose)
    {
      eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes");
      // Compute res = Q' * other :
      res =  m_other;
      for (Index k = 0; k < n; k++)
      {
        Scalar tau; 
        // Or alternatively 
        tau = m_qr.m_Q.col(k).tail(m-k).dot(res.tail(m-k)); 
        tau = tau * m_qr.m_hcoeffs(k);
        res -= tau * m_qr.m_Q.col(k);
      }
    }
    else
    {
      eigen_assert(m_qr.m_Q.cols() == m_other.rows() && "Non conforming object sizes");
      // Compute res = Q * other :
      res = m_other;
      for (Index k = n-1; k >=0; k--)
      {
        Scalar tau;
        tau = m_qr.m_Q.col(k).tail(m-k).dot(res.tail(m-k));
        tau = tau * m_qr.m_hcoeffs(k);
        res -= tau * m_qr.m_Q.col(k);
      }
    }
  }
  
  const SparseQRType& m_qr;
  const Derived& m_other;
  bool m_transpose;
};

template<typename SparseQRType>
struct SparseQRMatrixQReturnType
{  
  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);
  }
  SparseQRMatrixQTransposeReturnType<SparseQRType> adjoint() const
  {
    return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
  }
  // To use for operations with the transpose of Q
  SparseQRMatrixQTransposeReturnType<SparseQRType> transpose() const
  {
    return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
  }
  const SparseQRType& m_qr;
};

template<typename SparseQRType>
struct SparseQRMatrixQTransposeReturnType
{
  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;
};

} // end namespace Eigen

#endif
