11 #ifndef EIGEN_SPARSE_QR_H    12 #define EIGEN_SPARSE_QR_H    16 template<
typename MatrixType, 
typename OrderingType> 
class SparseQR;
    70 template<
typename _MatrixType, 
typename _OrderingType>
    75     using Base::m_isInitialized;
    77     using Base::_solve_impl;
    80     typedef typename MatrixType::Scalar 
Scalar;
    89       ColsAtCompileTime = MatrixType::ColsAtCompileTime,
    90       MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
    94     SparseQR () :  m_analysisIsok(false), m_lastError(
""), m_useDefaultThreshold(true),m_isQSorted(false),m_isEtreeOk(false)
   103     explicit SparseQR(
const MatrixType& mat) : m_analysisIsok(false), m_lastError(
""), m_useDefaultThreshold(true),m_isQSorted(false),m_isEtreeOk(false)
   119     void analyzePattern(
const MatrixType& mat);
   120     void factorize(
const MatrixType& mat);
   143     const QRMatrixType& 
matrixR()
 const { 
return m_R; }
   151       eigen_assert(m_isInitialized && 
"The factorization should be called first, use compute()");
   152       return m_nonzeropivots; 
   181       eigen_assert(m_isInitialized && 
"Decomposition is not initialized.");
   182       return m_outputPerm_c;
   191     template<
typename Rhs, 
typename Dest>
   194       eigen_assert(m_isInitialized && 
"The factorization should be called first, use compute()");
   195       eigen_assert(this->rows() == B.rows() && 
"SparseQR::solve() : invalid number of rows in the right hand side matrix");
   197       Index rank = this->rank();
   200       typename Dest::PlainObject y, b;
   201       y = this->matrixQ().transpose() * B; 
   205       y.
resize((std::max<Index>)(cols(),y.rows()),y.cols());
   206       y.topRows(rank) = this->matrixR().topLeftCorner(rank, rank).template triangularView<Upper>().solve(b.topRows(rank));
   207       y.bottomRows(y.rows()-rank).setZero();
   210       if (m_perm_c.size())  dest = colsPermutation() * y.
topRows(cols());
   224       m_useDefaultThreshold = 
false;
   225       m_threshold = threshold;
   232     template<
typename Rhs>
   235       eigen_assert(m_isInitialized && 
"The factorization should be called first, use compute()");
   236       eigen_assert(this->rows() == B.rows() && 
"SparseQR::solve() : invalid number of rows in the right hand side matrix");
   239     template<
typename Rhs>
   242           eigen_assert(m_isInitialized && 
"The factorization should be called first, use compute()");
   243           eigen_assert(this->rows() == B.
rows() && 
"SparseQR::solve() : invalid number of rows in the right hand side matrix");
   257       eigen_assert(m_isInitialized && 
"Decomposition is not initialized.");
   265       if(this->m_isQSorted) 
return;
   269       this->m_isQSorted = 
true;
   306 template <
typename MatrixType, 
typename OrderingType>
   309   eigen_assert(mat.isCompressed() && 
"SparseQR requires a sparse matrix in compressed mode. Call .makeCompressed() before passing it to SparseQR");
   314   ord(matCpy, m_perm_c); 
   315   Index n = mat.cols();
   316   Index m = mat.rows();
   319   if (!m_perm_c.size())
   322     m_perm_c.indices().setLinSpaced(n, 0,
StorageIndex(n-1));
   326   m_outputPerm_c = m_perm_c.inverse();
   331   m_Q.resize(m, diagSize);
   334   m_R.reserve(2*mat.nonZeros()); 
   335   m_Q.reserve(2*mat.nonZeros());
   336   m_hcoeffs.resize(diagSize);
   337   m_analysisIsok = 
true;
   347 template <
typename MatrixType, 
typename OrderingType>
   352   eigen_assert(m_analysisIsok && 
"analyzePattern() should be called before this step");
   358   Index nzcolR, nzcolQ;                                     
   367     m_outputPerm_c = m_perm_c.inverse();
   380     const StorageIndex *originalOuterIndices = mat.outerIndexPtr();
   381     if(MatrixType::IsRowMajor)
   383       originalOuterIndicesCpy = IndexVector::Map(m_pmat.outerIndexPtr(),n+1);
   384       originalOuterIndices = originalOuterIndicesCpy.
data();
   387     for (
int i = 0; i < n; i++)
   389       Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i;
   390       m_pmat.outerIndexPtr()[p] = originalOuterIndices[i]; 
   391       m_pmat.innerNonZeroPtr()[p] = originalOuterIndices[i+1] - originalOuterIndices[i]; 
   399   if(m_useDefaultThreshold) 
   402     for (
int j = 0; j < n; j++) max2Norm = numext::maxi(max2Norm, m_pmat.col(j).norm());
   409   m_pivotperm.setIdentity(n);
   419     mark(nonzeroCol) = 
col;
   420     Qidx(0) = nonzeroCol;
   421     nzcolR = 0; nzcolQ = 1;
   422     bool found_diag = nonzeroCol>=m;
   433       if(curIdx == nonzeroCol) found_diag = 
true;
   439         m_lastError = 
"Empty row found during numerical factorization";
   446       for (; mark(st) != 
col; st = m_etree(st))
   454       Index nt = nzcolR-bi;
   455       for(
Index i = 0; i < nt/2; i++) 
std::swap(Ridx(bi+i), Ridx(nzcolR-i-1));
   458       if(itp) tval(curIdx) = itp.value();
   459       else    tval(curIdx) = 
Scalar(0);
   462       if(curIdx > nonzeroCol && mark(curIdx) != 
col ) 
   464         Qidx(nzcolQ) = curIdx;  
   471     for (
Index i = nzcolR-1; i >= 0; i--)
   473       Index curIdx = Ridx(i);
   479       tdot = m_Q.col(curIdx).dot(tval);
   481       tdot *= m_hcoeffs(curIdx);
   486         tval(itq.row()) -= itq.value() * tdot;
   489       if(m_etree(Ridx(i)) == nonzeroCol)
   506     if(nonzeroCol < diagSize)
   514       for (
Index itq = 1; itq < nzcolQ; ++itq) sqrNorm += 
numext::abs2(tval(Qidx(itq)));
   527         for (
Index itq = 1; itq < nzcolQ; ++itq)
   528           tval(Qidx(itq)) /= (c0 - beta);
   529         tau = numext::conj((beta-c0) / beta);
   535     for (
Index  i = nzcolR-1; i >= 0; i--)
   537       Index curIdx = Ridx(i);
   538       if(curIdx < nonzeroCol) 
   540         m_R.insertBackByOuterInnerUnordered(
col, curIdx) = tval(curIdx);
   541         tval(curIdx) = 
Scalar(0.);
   545     if(nonzeroCol < diagSize && 
abs(beta) >= pivotThreshold)
   547       m_R.insertBackByOuterInner(
col, nonzeroCol) = beta;
   549       m_hcoeffs(nonzeroCol) = tau;
   551       for (
Index itq = 0; itq < nzcolQ; ++itq)
   553         Index iQ = Qidx(itq);
   554         m_Q.insertBackByOuterInnerUnordered(nonzeroCol,iQ) = tval(iQ);
   558       if(nonzeroCol<diagSize)
   559         m_Q.startVec(nonzeroCol);
   564       for (
Index j = nonzeroCol; j < n-1; j++) 
   565         std::swap(m_pivotperm.indices()(j), m_pivotperm.indices()[j+1]);
   573   m_hcoeffs.tail(diagSize-nonzeroCol).setZero();
   577   m_Q.makeCompressed();
   579   m_R.makeCompressed();
   582   m_nonzeropivots = nonzeroCol;
   588     m_R = tempR * m_pivotperm;
   591     m_outputPerm_c = m_outputPerm_c * m_pivotperm;
   594   m_isInitialized = 
true; 
   595   m_factorizationIsok = 
true;
   599 template <
typename SparseQRType, 
typename Derived>
   603   typedef typename SparseQRType::Scalar 
Scalar;
   606   m_qr(qr),m_other(other),m_transpose(transpose) {}
   607   inline Index rows()
 const { 
return m_transpose ? m_qr.rows() : m_qr.cols(); }
   611   template<
typename DesType>
   614     Index m = m_qr.rows();
   615     Index n = m_qr.cols();
   620       eigen_assert(m_qr.m_Q.rows() == m_other.rows() && 
"Non conforming object sizes");
   622       for(
Index j = 0; j < res.cols(); j++){
   623         for (
Index k = 0; k < diagSize; k++)
   625           Scalar tau = Scalar(0);
   626           tau = m_qr.m_Q.col(k).dot(res.col(j));
   627           if(tau==Scalar(0)) 
continue;
   628           tau = tau * m_qr.m_hcoeffs(k);
   629           res.col(j) -= tau * m_qr.m_Q.col(k);
   635       eigen_assert(m_qr.m_Q.rows() == m_other.rows() && 
"Non conforming object sizes");
   637       for(
Index j = 0; j < res.cols(); j++)
   639         for (
Index k = diagSize-1; k >=0; k--)
   641           Scalar tau = Scalar(0);
   642           tau = m_qr.m_Q.col(k).dot(res.col(j));
   643           if(tau==Scalar(0)) 
continue;
   644           tau = tau * m_qr.m_hcoeffs(k);
   645           res.col(j) -= tau * m_qr.m_Q.col(k);
   656 template<
typename SparseQRType>
   659   typedef typename SparseQRType::Scalar 
Scalar;
   666   template<
typename Derived>
   685 template<
typename SparseQRType>
   689   template<
typename Derived>
   699 template<
typename SparseQRType>
   707 template< 
typename DstXprType, 
typename SparseQRType>
   711   typedef typename DstXprType::Scalar 
Scalar;
   715     typename DstXprType::PlainObject idMat(src.
m_qr.rows(), src.
m_qr.rows());
   718     const_cast<SparseQRType *
>(&src.
m_qr)->_sort_matrix_Q();
   723 template< 
typename DstXprType, 
typename SparseQRType>
   727   typedef typename DstXprType::Scalar 
Scalar;
   731     dst = src.
m_qr.matrixQ() * DstXprType::Identity(src.
m_qr.rows(), src.
m_qr.rows());
 
_OrderingType OrderingType
MatrixType::StorageIndex StorageIndex
PermutationMatrix< Dynamic, Dynamic, StorageIndex > PermutationType
Matrix< Scalar, Dynamic, 1 > ScalarVector
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op< Scalar, Scalar > &)
EIGEN_DEVICE_FUNC RealReturnType real() const
Derived::PlainObject ReturnType
int coletree(const MatrixType &mat, IndexVector &parent, IndexVector &firstRowElt, typename MatrixType::StorageIndex *perm=0)
const SparseQRType & m_qr
SparseQRMatrixQReturnType< SparseQR > matrixQ() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data() const
SparseQRType::MatrixType ReturnType
ComputationInfo info() const
Reports whether previous computation was successful. 
SparseQRMatrixQReturnType(const SparseQRType &qr)
EIGEN_DEVICE_FUNC ColXpr col(Index i)
This is the const version of col(). */. 
Matrix< StorageIndex, Dynamic, 1 > IndexVector
const SparseQRType & m_qr
A base class for sparse solvers. 
storage_kind_to_evaluator_kind< typename MatrixType::StorageKind >::Kind Kind
SparseQR_QProduct(const SparseQRType &qr, const Derived &other, bool transpose)
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
const Solve< SparseQR, Rhs > solve(const SparseMatrixBase< Rhs > &B) const
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
EIGEN_DEVICE_FUNC void resize(Index newSize)
Eigen::Index Index
The interface type of indices. 
SparseQRMatrixQReturnType< SparseQRType > SrcXprType
SparseQRType::Scalar Scalar
EIGEN_DEVICE_FUNC RowsBlockXpr topRows(Index n)
DstXprType::Scalar Scalar
SparseQRType::QRMatrixType MatrixType
const QRMatrixType & matrixR() const
void factorize(const MatrixType &mat)
Performs the numerical QR factorization of the input matrix. 
SparseQR_QProduct< SparseQRType, Derived > operator*(const MatrixBase< Derived > &other)
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op< Scalar, Scalar > &)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
SparseQRType::MatrixType MatrixType
Sparse left-looking rank-revealing QR factorization. 
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Abs2ReturnType abs2() const
IndexVector m_firstRowElt
Base class of any sparse matrices or sparse expressions. 
SparseSolverBase< SparseQR< _MatrixType, _OrderingType > > Base
SparseQRMatrixQTransposeReturnType< SparseQRType > transpose() const
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API. 
bool _solve_impl(const MatrixBase< Rhs > &B, MatrixBase< Dest > &dest) const
Matrix< Scalar, Dynamic, Dynamic > DenseMatrix
void evalTo(DesType &res) const
PermutationType m_pivotperm
DstXprType::Scalar Scalar
EIGEN_DEVICE_FUNC Derived & setZero(Index size)
MatrixType::Scalar Scalar
EIGEN_DEVICE_FUNC Derived & setConstant(Index size, const Scalar &val)
void analyzePattern(const MatrixType &mat)
Preprocessing step of a QR factorization. 
SparseQRType::Scalar Scalar
Base::InnerIterator InnerIterator
PermutationType m_outputPerm_c
SparseQRMatrixQReturnType< SparseQRType > SrcXprType
SparseQRType::MatrixType ReturnType
int64_t max(int64_t a, const int b)
SparseQRMatrixQTransposeReturnType< SparseQRType > adjoint() const
DstXprType::StorageIndex StorageIndex
const Derived & derived() const
const SparseQRType & m_qr
EIGEN_DEVICE_FUNC const ImagReturnType imag() const
SparseQRMatrixQTransposeReturnType(const SparseQRType &qr)
ReturnType::StorageIndex StorageIndex
Pseudo expression representing a solving operation. 
const PermutationType & colsPermutation() const
MatrixType::RealScalar RealScalar
std::string lastErrorMessage() const
ReturnType::StorageKind StorageKind
SparseQR(const MatrixType &mat)
Base class for all dense matrices, vectors, and expressions. 
DstXprType::StorageIndex StorageIndex
void setPivotThreshold(const RealScalar &threshold)
bool m_useDefaultThreshold
void swap(scoped_array< T > &a, scoped_array< T > &b)
SparseMatrix< Scalar, ColMajor, StorageIndex > QRMatrixType
const Solve< SparseQR, Rhs > solve(const MatrixBase< Rhs > &B) const
SparseQR_QProduct< SparseQRType, Derived > operator*(const MatrixBase< Derived > &other)
void compute(const MatrixType &mat)