11#ifndef EIGEN_SPARSE_QR_H
12#define EIGEN_SPARSE_QR_H
16template<
typename MatrixType,
typename OrderingType>
class SparseQR;
17template<
typename SparseQRType>
struct SparseQRMatrixQReturnType;
18template<
typename SparseQRType>
struct SparseQRMatrixQTransposeReturnType;
19template<
typename SparseQRType,
typename Derived>
struct SparseQR_QProduct;
23 typedef typename SparseQRType::MatrixType ReturnType;
24 typedef typename ReturnType::StorageIndex StorageIndex;
25 typedef typename ReturnType::StorageKind StorageKind;
27 RowsAtCompileTime = Dynamic,
28 ColsAtCompileTime = Dynamic
33 typedef typename SparseQRType::MatrixType ReturnType;
37 typedef typename Derived::PlainObject ReturnType;
70template<
typename _MatrixType,
typename _OrderingType>
75 using Base::m_isInitialized;
77 using Base::_solve_impl;
78 typedef _MatrixType MatrixType;
80 typedef typename MatrixType::Scalar Scalar;
81 typedef typename MatrixType::RealScalar RealScalar;
82 typedef typename MatrixType::StorageIndex StorageIndex;
89 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
90 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
94 SparseQR () : m_analysisIsok(
false), m_lastError(
""), m_useDefaultThreshold(
true),m_isQSorted(
false),m_isEtreeOk(
false)
124 inline Index
rows()
const {
return m_pmat.
rows(); }
140 eigen_assert(m_isInitialized &&
"The factorization should be called first, use compute()");
141 return m_nonzeropivots;
170 eigen_assert(m_isInitialized &&
"Decomposition is not initialized.");
171 return m_outputPerm_c;
180 template<
typename Rhs,
typename Dest>
183 eigen_assert(m_isInitialized &&
"The factorization should be called first, use compute()");
184 eigen_assert(this->
rows() == B.rows() &&
"SparseQR::solve() : invalid number of rows in the right hand side matrix");
189 typename Dest::PlainObject y, b;
190 y = this->
matrixQ().transpose() * B;
194 y.resize((std::max<Index>)(
cols(),y.rows()),y.cols());
196 y.bottomRows(y.rows()-
rank).setZero();
200 else dest = y.topRows(
cols());
213 m_useDefaultThreshold =
false;
214 m_threshold = threshold;
221 template<
typename Rhs>
224 eigen_assert(m_isInitialized &&
"The factorization should be called first, use compute()");
225 eigen_assert(this->
rows() == B.rows() &&
"SparseQR::solve() : invalid number of rows in the right hand side matrix");
228 template<
typename Rhs>
231 eigen_assert(m_isInitialized &&
"The factorization should be called first, use compute()");
232 eigen_assert(this->
rows() == B.rows() &&
"SparseQR::solve() : invalid number of rows in the right hand side matrix");
246 eigen_assert(m_isInitialized &&
"Decomposition is not initialized.");
252 inline void _sort_matrix_Q()
254 if(this->m_isQSorted)
return;
258 this->m_isQSorted =
true;
264 bool m_factorizationIsok;
266 std::string m_lastError;
270 ScalarVector m_hcoeffs;
271 PermutationType m_perm_c;
272 PermutationType m_pivotperm;
273 PermutationType m_outputPerm_c;
274 RealScalar m_threshold;
275 bool m_useDefaultThreshold;
276 Index m_nonzeropivots;
278 IndexVector m_firstRowElt;
282 template <
typename,
typename >
friend struct SparseQR_QProduct;
295template <
typename MatrixType,
typename OrderingType>
298 eigen_assert(
mat.isCompressed() &&
"SparseQR requires a sparse matrix in compressed mode. Call .makeCompressed() before passing it to SparseQR");
304 Index n =
mat.cols();
305 Index m =
mat.rows();
308 if (!m_perm_c.size())
311 m_perm_c.indices().setLinSpaced(n, 0,StorageIndex(n-1));
315 m_outputPerm_c = m_perm_c.inverse();
316 internal::coletree(
matCpy, m_etree, m_firstRowElt, m_outputPerm_c.indices().data());
323 m_R.reserve(2*
mat.nonZeros());
324 m_Q.reserve(2*
mat.nonZeros());
326 m_analysisIsok =
true;
336template <
typename MatrixType,
typename OrderingType>
341 eigen_assert(m_analysisIsok &&
"analyzePattern() should be called before this step");
342 StorageIndex m = StorageIndex(
mat.rows());
343 StorageIndex n = StorageIndex(
mat.cols());
344 StorageIndex
diagSize = (std::min)(m,n);
356 m_outputPerm_c = m_perm_c.inverse();
357 internal::coletree(m_pmat, m_etree, m_firstRowElt, m_outputPerm_c.indices().data());
370 if(MatrixType::IsRowMajor)
376 for (
int i = 0; i < n; i++)
378 Index p = m_perm_c.size() ? m_perm_c.indices()(i) : i;
388 if(m_useDefaultThreshold)
398 m_pivotperm.setIdentity(n);
404 for (StorageIndex col = 0; col < n; ++col)
425 StorageIndex
st = m_firstRowElt(
curIdx);
428 m_lastError =
"Empty row found during numerical factorization";
435 for (; mark(
st) != col;
st = m_etree(
st))
460 for (Index i =
nzcolR-1; i >= 0; i--)
474 for (
typename QRMatrixType::InnerIterator
itq(m_Q,
curIdx);
itq; ++
itq)
480 for (
typename QRMatrixType::InnerIterator
itq(m_Q,
curIdx);
itq; ++
itq)
482 StorageIndex
iQ = StorageIndex(
itq.row());
492 Scalar
tau = RealScalar(0);
504 if(
sqrNorm == RealScalar(0) && numext::imag(
c0) == RealScalar(0))
506 beta = numext::real(
c0);
513 if(numext::real(
c0) >= RealScalar(0))
518 tau = numext::conj((beta-
c0) / beta);
524 for (Index i =
nzcolR-1; i >= 0; i--)
536 m_R.insertBackByOuterInner(col,
nonzeroCol) = beta;
554 std::swap(m_pivotperm.indices()(
j), m_pivotperm.indices()[
j+1]);
557 internal::coletree(m_pmat, m_etree, m_firstRowElt, m_pivotperm.indices().data());
566 m_Q.makeCompressed();
568 m_R.makeCompressed();
577 m_R =
tempR * m_pivotperm;
580 m_outputPerm_c = m_outputPerm_c * m_pivotperm;
583 m_isInitialized =
true;
584 m_factorizationIsok =
true;
588template <
typename SparseQRType,
typename Derived>
591 typedef typename SparseQRType::QRMatrixType MatrixType;
592 typedef typename SparseQRType::Scalar Scalar;
595 m_qr(
qr),m_other(other),m_transpose(transpose) {}
596 inline Index rows()
const {
return m_transpose ? m_qr.rows() : m_qr.cols(); }
597 inline Index cols()
const {
return m_other.cols(); }
600 template<
typename DesType>
601 void evalTo(
DesType& res)
const
603 Index m = m_qr.rows();
604 Index n = m_qr.cols();
609 eigen_assert(m_qr.m_Q.rows() == m_other.rows() &&
"Non conforming object sizes");
611 for(Index
j = 0;
j < res.cols();
j++){
612 for (Index k = 0; k <
diagSize; k++)
614 Scalar
tau = Scalar(0);
615 tau = m_qr.m_Q.col(k).dot(res.col(
j));
616 if(
tau==Scalar(0))
continue;
617 tau =
tau * m_qr.m_hcoeffs(k);
618 res.col(
j) -=
tau * m_qr.m_Q.col(k);
624 eigen_assert(m_qr.m_Q.rows() == m_other.rows() &&
"Non conforming object sizes");
626 for(Index
j = 0;
j < res.cols();
j++)
628 for (Index k =
diagSize-1; k >=0; k--)
630 Scalar
tau = Scalar(0);
631 tau = m_qr.m_Q.col(k).dot(res.col(
j));
632 if(
tau==Scalar(0))
continue;
633 tau =
tau * m_qr.m_hcoeffs(k);
634 res.col(
j) -=
tau * m_qr.m_Q.col(k);
641 const Derived& m_other;
645template<
typename SparseQRType>
648 typedef typename SparseQRType::Scalar Scalar;
651 RowsAtCompileTime = Dynamic,
652 ColsAtCompileTime = Dynamic
655 template<
typename Derived>
664 inline Index rows()
const {
return m_qr.rows(); }
665 inline Index cols()
const {
return (std::min)(m_qr.rows(),m_qr.cols()); }
674template<
typename SparseQRType>
678 template<
typename Derived>
688template<
typename SparseQRType>
691 typedef typename SparseQRType::MatrixType MatrixType;
694 static const int AssumeAliasing = 0;
697template<
typename DstXprType,
typename SparseQRType>
701 typedef typename DstXprType::Scalar Scalar;
702 typedef typename DstXprType::StorageIndex StorageIndex;
705 typename DstXprType::PlainObject
idMat(
src.m_qr.rows(),
src.m_qr.rows());
713template<
typename DstXprType,
typename SparseQRType>
717 typedef typename DstXprType::Scalar Scalar;
718 typedef typename DstXprType::StorageIndex StorageIndex;
721 dst =
src.m_qr.matrixQ() * DstXprType::Identity(
src.m_qr.rows(),
src.m_qr.rows());
Index size() const
Definition PermutationMatrix.h:109
EIGEN_DEVICE_FUNC Derived & setConstant(Index size, const Scalar &value)
Resizes to the given size, and sets all coefficients in this expression to the given value.
Definition CwiseNullaryOp.h:352
Definition ReturnByValue.h:53
Pseudo expression representing a solving operation.
Definition Solve.h:63
Index rows() const
Definition SparseMatrix.h:131
Index cols() const
Definition SparseMatrix.h:133
Sparse left-looking rank-revealing QR factorization.
Definition SparseQR.h:72
std::string lastErrorMessage() const
Definition SparseQR.h:177
ComputationInfo info() const
Reports whether previous computation was successful.
Definition SparseQR.h:244
void analyzePattern(const MatrixType &mat)
Preprocessing step of a QR factorization.
Definition SparseQR.h:296
void factorize(const MatrixType &mat)
Performs the numerical QR factorization of the input matrix.
Definition SparseQR.h:337
Index cols() const
Definition SparseQR.h:128
const Solve< SparseQR, Rhs > solve(const MatrixBase< Rhs > &B) const
Definition SparseQR.h:222
const PermutationType & colsPermutation() const
Definition SparseQR.h:168
Index rank() const
Definition SparseQR.h:138
SparseQRMatrixQReturnType< SparseQR > matrixQ() const
Definition SparseQR.h:162
const QRMatrixType & matrixR() const
Definition SparseQR.h:132
Index rows() const
Definition SparseQR.h:124
SparseQR(const MatrixType &mat)
Construct a QR factorization of the matrix mat.
Definition SparseQR.h:103
void setPivotThreshold(const RealScalar &threshold)
Sets the threshold that is used to determine linearly dependent columns during the factorization.
Definition SparseQR.h:211
void compute(const MatrixType &mat)
Computes the QR factorization of the sparse matrix mat.
Definition SparseQR.h:114
A base class for sparse solvers.
Definition SparseSolverBase.h:54
ComputationInfo
Enum for reporting the status of a computation.
Definition Constants.h:430
@ InvalidInput
The inputs are invalid, or the algorithm has been improperly called.
Definition Constants.h:439
@ Success
Computation was successful.
Definition Constants.h:432
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.hpp:24418
Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor Matrix...
Definition EigenBase.h:29
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:37
Holds information about the various numeric (i.e.
Definition NumTraits.h:108
Definition SparseQR.h:647
Definition SparseQR.h:676
Definition SparseQR.h:590
Definition Constants.h:520
Definition AssignEvaluator.h:684
Definition Constants.h:525
Definition SparseAssign.h:62
Definition SparseAssign.h:61
Definition AssignmentFunctors.h:21
Definition CoreEvaluators.h:75
Definition ForwardDeclarations.h:17