16#include "./InternalHeaderCheck.h"
21template <
typename MatrixType_>
22struct traits<HouseholderQR<MatrixType_>> : traits<MatrixType_> {
23 typedef MatrixXpr XprKind;
24 typedef SolverStorage StorageKind;
25 typedef int StorageIndex;
58template <
typename MatrixType_>
61 typedef MatrixType_ MatrixType;
67 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
68 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
71 MaxRowsAtCompileTime, MaxRowsAtCompileTime>
73 typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
74 typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
76 HouseholderSequenceType;
84 HouseholderQR() : m_qr(), m_hCoeffs(), m_temp(), m_isInitialized(false) {}
93 : m_qr(rows, cols), m_hCoeffs((std::min)(rows, cols)), m_temp(cols), m_isInitialized(false) {}
107 template <
typename InputType>
109 : m_qr(matrix.rows(), matrix.cols()),
110 m_hCoeffs((std::min)(matrix.rows(), matrix.cols())),
111 m_temp(matrix.cols()),
112 m_isInitialized(false) {
123 template <
typename InputType>
126 m_hCoeffs((std::min)(matrix.rows(), matrix.cols())),
127 m_temp(matrix.cols()),
128 m_isInitialized(false) {
132#ifdef EIGEN_PARSED_BY_DOXYGEN
147 template <
typename Rhs>
161 eigen_assert(m_isInitialized &&
"HouseholderQR is not initialized.");
162 return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
169 eigen_assert(m_isInitialized &&
"HouseholderQR is not initialized.");
173 template <
typename InputType>
248 inline Index rows()
const {
return m_qr.rows(); }
249 inline Index cols()
const {
return m_qr.cols(); }
255 const HCoeffsType&
hCoeffs()
const {
return m_hCoeffs; }
257#ifndef EIGEN_PARSED_BY_DOXYGEN
258 template <
typename RhsType,
typename DstType>
259 void _solve_impl(
const RhsType& rhs, DstType& dst)
const;
261 template <
bool Conjugate,
typename RhsType,
typename DstType>
262 void _solve_impl_transposed(
const RhsType& rhs, DstType& dst)
const;
266 EIGEN_STATIC_ASSERT_NON_INTEGER(
Scalar)
271 HCoeffsType m_hCoeffs;
272 RowVectorType m_temp;
273 bool m_isInitialized;
279template <
typename HCoeffs,
typename Scalar,
bool IsComplex>
280struct householder_determinant {
281 static void run(
const HCoeffs&
hCoeffs, Scalar& out_det) {
294template <
typename HCoeffs,
typename Scalar>
295struct householder_determinant<HCoeffs, Scalar, false> {
296 static void run(
const HCoeffs&
hCoeffs, Scalar& out_det) {
297 bool negated =
false;
301 if (
hCoeffs(i) != Scalar(0)) negated ^=
true;
303 out_det = negated ? Scalar(-1) : Scalar(1);
309template <
typename MatrixType>
311 eigen_assert(m_isInitialized &&
"HouseholderQR is not initialized.");
312 eigen_assert(m_qr.rows() == m_qr.cols() &&
"You can't take the determinant of a non-square matrix!");
314 internal::householder_determinant<HCoeffsType, Scalar, NumTraits<Scalar>::IsComplex>::run(m_hCoeffs, detQ);
315 return m_qr.diagonal().prod() * detQ;
318template <
typename MatrixType>
321 eigen_assert(m_isInitialized &&
"HouseholderQR is not initialized.");
322 eigen_assert(m_qr.rows() == m_qr.cols() &&
"You can't take the determinant of a non-square matrix!");
323 return abs(m_qr.diagonal().prod());
326template <
typename MatrixType>
328 eigen_assert(m_isInitialized &&
"HouseholderQR is not initialized.");
329 eigen_assert(m_qr.rows() == m_qr.cols() &&
"You can't take the determinant of a non-square matrix!");
330 return m_qr.diagonal().cwiseAbs().array().log().sum();
333template <
typename MatrixType>
335 eigen_assert(m_isInitialized &&
"HouseholderQR is not initialized.");
336 eigen_assert(m_qr.rows() == m_qr.cols() &&
"You can't take the determinant of a non-square matrix!");
338 internal::householder_determinant<HCoeffsType, Scalar, NumTraits<Scalar>::IsComplex>::run(m_hCoeffs, detQ);
339 return detQ * m_qr.diagonal().array().sign().prod();
345template <
typename MatrixQR,
typename HCoeffs>
346void householder_qr_inplace_unblocked(MatrixQR& mat, HCoeffs& hCoeffs,
typename MatrixQR::Scalar* tempData = 0) {
347 typedef typename MatrixQR::Scalar
Scalar;
348 typedef typename MatrixQR::RealScalar RealScalar;
349 Index rows = mat.rows();
350 Index cols = mat.cols();
351 Index size = (std::min)(rows, cols);
353 eigen_assert(hCoeffs.size() == size);
358 tempVector.resize(cols);
359 tempData = tempVector.data();
362 for (
Index k = 0; k < size; ++k) {
363 Index remainingRows = rows - k;
364 Index remainingCols = cols - k - 1;
367 mat.col(k).tail(remainingRows).makeHouseholderInPlace(hCoeffs.coeffRef(k), beta);
368 mat.coeffRef(k, k) = beta;
371 mat.bottomRightCorner(remainingRows, remainingCols)
372 .applyHouseholderOnTheLeft(mat.col(k).tail(remainingRows - 1), hCoeffs.coeffRef(k), tempData + k + 1);
385template <
typename MatrixQR,
typename HCoeffs,
typename VectorQR>
386void householder_qr_inplace_update(MatrixQR& mat, HCoeffs& hCoeffs,
const VectorQR& newColumn,
387 typename MatrixQR::Index k,
typename MatrixQR::Scalar* tempData) {
388 typedef typename MatrixQR::Index
Index;
389 typedef typename MatrixQR::RealScalar RealScalar;
390 Index rows = mat.rows();
392 eigen_assert(k < mat.cols());
393 eigen_assert(k < rows);
394 eigen_assert(hCoeffs.size() == mat.cols());
395 eigen_assert(newColumn.size() == rows);
396 eigen_assert(tempData);
399 mat.col(k) = newColumn;
401 for (Index i = 0; i < k; ++i) {
402 Index remainingRows = rows - i;
405 .applyHouseholderOnTheLeft(mat.col(i).tail(remainingRows - 1), hCoeffs.coeffRef(i), tempData + i + 1);
409 mat.col(k).tail(rows - k).makeHouseholderInPlace(hCoeffs.coeffRef(k), beta);
410 mat.coeffRef(k, k) = beta;
414template <
typename MatrixQR,
typename HCoeffs,
typename MatrixQRScalar =
typename MatrixQR::Scalar,
415 bool InnerStrideIsOne = (MatrixQR::InnerStrideAtCompileTime == 1 && HCoeffs::InnerStrideAtCompileTime == 1)>
416struct householder_qr_inplace_blocked {
418 static void run(MatrixQR& mat, HCoeffs& hCoeffs, Index maxBlockSize = 32,
typename MatrixQR::Scalar* tempData = 0) {
419 typedef typename MatrixQR::Scalar Scalar;
420 typedef Block<MatrixQR, Dynamic, Dynamic> BlockType;
422 Index rows = mat.rows();
423 Index cols = mat.cols();
424 Index size = (std::min)(rows, cols);
426 typedef Matrix<Scalar, Dynamic, 1, ColMajor, MatrixQR::MaxColsAtCompileTime, 1> TempType;
429 tempVector.resize(cols);
430 tempData = tempVector.data();
433 Index blockSize = (std::min)(maxBlockSize, size);
436 for (k = 0; k < size; k += blockSize) {
437 Index bs = (std::min)(size - k, blockSize);
438 Index tcols = cols - k - bs;
439 Index brows = rows - k;
449 BlockType A11_21 = mat.block(k, k, brows, bs);
450 Block<HCoeffs, Dynamic, 1> hCoeffsSegment = hCoeffs.segment(k, bs);
452 householder_qr_inplace_unblocked(A11_21, hCoeffsSegment, tempData);
455 BlockType A21_22 = mat.block(k, k + bs, brows, tcols);
456 apply_block_householder_on_the_left(A21_22, A11_21, hCoeffsSegment,
false);
464#ifndef EIGEN_PARSED_BY_DOXYGEN
465template <
typename MatrixType_>
466template <
typename RhsType,
typename DstType>
468 const Index rank = (std::min)(rows(), cols());
470 typename RhsType::PlainObject c(rhs);
474 m_qr.topLeftCorner(rank, rank).template triangularView<Upper>().solveInPlace(c.topRows(rank));
476 dst.topRows(rank) = c.topRows(rank);
477 dst.bottomRows(cols() - rank).setZero();
480template <
typename MatrixType_>
481template <
bool Conjugate,
typename RhsType,
typename DstType>
483 const Index rank = (std::min)(rows(), cols());
485 typename RhsType::PlainObject c(rhs);
487 m_qr.topLeftCorner(rank, rank)
488 .template triangularView<Upper>()
490 .template conjugateIf<Conjugate>()
491 .solveInPlace(c.topRows(rank));
493 dst.topRows(rank) = c.topRows(rank);
494 dst.bottomRows(rows() - rank).setZero();
496 dst.applyOnTheLeft(
householderQ().setLength(rank).
template conjugateIf<!Conjugate>());
506template <
typename MatrixType>
508 Index rows = m_qr.rows();
509 Index cols = m_qr.cols();
512 m_hCoeffs.resize(
size);
516 internal::householder_qr_inplace_blocked<MatrixType, HCoeffsType>::run(m_qr, m_hCoeffs, 48, m_temp.data());
518 m_isInitialized =
true;
525template <
typename Derived>
EvalReturnType eval() const
Definition DenseBase.h:381
Householder QR decomposition of a matrix.
Definition HouseholderQR.h:59
MatrixType::Scalar signDeterminant() const
Definition HouseholderQR.h:334
HouseholderQR(Index rows, Index cols)
Default Constructor with memory preallocation.
Definition HouseholderQR.h:92
HouseholderQR(EigenBase< InputType > &matrix)
Constructs a QR factorization from a given matrix.
Definition HouseholderQR.h:124
const HCoeffsType & hCoeffs() const
Definition HouseholderQR.h:255
void computeInPlace()
Definition HouseholderQR.h:507
HouseholderQR(const EigenBase< InputType > &matrix)
Constructs a QR factorization from a given matrix.
Definition HouseholderQR.h:108
const Solve< HouseholderQR, Rhs > solve(const MatrixBase< Rhs > &b) const
MatrixType::Scalar determinant() const
Definition HouseholderQR.h:310
HouseholderSequenceType householderQ() const
Definition HouseholderQR.h:160
const MatrixType & matrixQR() const
Definition HouseholderQR.h:168
HouseholderQR()
Default Constructor.
Definition HouseholderQR.h:84
MatrixType::RealScalar absDeterminant() const
Definition HouseholderQR.h:319
MatrixType::RealScalar logAbsDeterminant() const
Definition HouseholderQR.h:327
Sequence of Householder reflections acting on subspaces with decreasing size.
Definition HouseholderSequence.h:117
Base class for all dense matrices, vectors, and expressions.
Definition ForwardDeclarations.h:73
const HouseholderQR< PlainObject > householderQr() const
Definition HouseholderQR.h:526
The matrix class, also used for vectors and row-vectors.
Definition ForwardDeclarations.h:70
Pseudo expression representing a solving operation.
Definition ForwardDeclarations.h:112
constexpr Derived & derived()
Definition EigenBase.h:49
SolverBase()
Definition SolverBase.h:97
const AdjointReturnType adjoint() const
Definition SolverBase.h:136
@ ColMajor
Definition Constants.h:318
@ RowMajor
Definition Constants.h:320
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
Definition ForwardDeclarations.h:57
constexpr Derived & derived()
Definition EigenBase.h:49
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:43
EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT
Definition EigenBase.h:64