1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType; 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<FullPivHouseholderQRMatrixQReturnType<MatrixType> > 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::PlainObject ReturnType; 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \ingroup QR_Module 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \class FullPivHouseholderQR 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \brief Householder rank-revealing QR decomposition of a matrix with full pivoting 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param MatrixType the type of the matrix of which we are computing the QR decomposition 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This class performs a rank-revealing QR decomposition of a matrix \b A into matrices \b P, \b Q and \b R 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * such that 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \f[ 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \mathbf{A} \, \mathbf{P} = \mathbf{Q} \, \mathbf{R} 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \f] 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * by using Householder transformations. Here, \b P is a permutation matrix, \b Q a unitary matrix and \b R an 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * upper triangular matrix. 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This decomposition performs a very prudent full pivoting in order to be rank-revealing and achieve optimal 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * numerical stability. The trade-off is that it is slower than HouseholderQR and ColPivHouseholderQR. 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa MatrixBase::fullPivHouseholderQr() 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _MatrixType> class FullPivHouseholderQR 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef _MatrixType MatrixType; 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowsAtCompileTime = MatrixType::RowsAtCompileTime, 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColsAtCompileTime = MatrixType::ColsAtCompileTime, 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Options = MatrixType::Options, 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Scalar Scalar; 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::RealScalar RealScalar; 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Index Index; 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef internal::FullPivHouseholderQRMatrixQReturnType<MatrixType> MatrixQReturnType; 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType; 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Index, 1, ColsAtCompileTime, RowMajor, 1, MaxColsAtCompileTime> IntRowVectorType; 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationType; 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::plain_col_type<MatrixType, Index>::type IntColVectorType; 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::plain_row_type<MatrixType>::type RowVectorType; 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::plain_col_type<MatrixType>::type ColVectorType; 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \brief Default Constructor. 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * The default constructor is useful in cases in which the user intends to 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * perform decompositions via FullPivHouseholderQR::compute(const MatrixType&). 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath FullPivHouseholderQR() 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_qr(), 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_hCoeffs(), 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_rows_transpositions(), 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_transpositions(), 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_permutation(), 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_temp(), 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_isInitialized(false), 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_usePrescribedThreshold(false) {} 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \brief Default Constructor with memory preallocation 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Like the default constructor but with preallocation of the internal data 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * according to the specified problem \a size. 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa FullPivHouseholderQR() 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath FullPivHouseholderQR(Index rows, Index cols) 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_qr(rows, cols), 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_hCoeffs((std::min)(rows,cols)), 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_rows_transpositions(rows), 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_transpositions(cols), 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_permutation(cols), 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_temp((std::min)(rows,cols)), 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_isInitialized(false), 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_usePrescribedThreshold(false) {} 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath FullPivHouseholderQR(const MatrixType& matrix) 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_qr(matrix.rows(), matrix.cols()), 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_hCoeffs((std::min)(matrix.rows(), matrix.cols())), 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_rows_transpositions(matrix.rows()), 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_transpositions(matrix.cols()), 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_permutation(matrix.cols()), 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_temp((std::min)(matrix.rows(), matrix.cols())), 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_isInitialized(false), 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_usePrescribedThreshold(false) 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath compute(matrix); 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** This method finds a solution x to the equation Ax=b, where A is the matrix of which 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * *this is the QR decomposition, if any exists. 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param b the right-hand-side of the equation to solve. 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \returns a solution. 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note The case where b is a matrix is not yet implemented. Also, this 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * code is space inefficient. 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note_about_checking_solutions 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note_about_arbitrary_choice_of_solution 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Example: \include FullPivHouseholderQR_solve.cpp 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Output: \verbinclude FullPivHouseholderQR_solve.out 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Rhs> 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline const internal::solve_retval<FullPivHouseholderQR, Rhs> 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath solve(const MatrixBase<Rhs>& b) const 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::solve_retval<FullPivHouseholderQR, Rhs>(*this, b.derived()); 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns Expression object representing the matrix Q 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixQReturnType matrixQ(void) const; 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a reference to the matrix where the Householder QR decomposition is stored 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const MatrixType& matrixQR() const 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_qr; 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath FullPivHouseholderQR& compute(const MatrixType& matrix); 154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const PermutationType& colsPermutation() const 156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_cols_permutation; 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const IntColVectorType& rowsTranspositions() const 162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_rows_transpositions; 165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the absolute value of the determinant of the matrix of which 168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * *this is the QR decomposition. It has only linear complexity 169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * (that is, O(n) where n is the dimension of the square matrix) 170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * as the QR decomposition has already been computed. 171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note This is only for square matrices. 173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \warning a determinant can be very big or small, so for matrices 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * of large enough dimension, there is a risk of overflow/underflow. 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * One way to work around that is to use logAbsDeterminant() instead. 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa logAbsDeterminant(), MatrixBase::determinant() 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename MatrixType::RealScalar absDeterminant() const; 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the natural log of the absolute value of the determinant of the matrix of which 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * *this is the QR decomposition. It has only linear complexity 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * (that is, O(n) where n is the dimension of the square matrix) 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * as the QR decomposition has already been computed. 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note This is only for square matrices. 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note This method is useful to work around the risk of overflow/underflow that's inherent 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * to determinant computation. 191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa absDeterminant(), MatrixBase::determinant() 193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename MatrixType::RealScalar logAbsDeterminant() const; 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the rank of the matrix of which *this is the QR decomposition. 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note This method has to determine which pivots should be considered nonzero. 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * For that, it uses the threshold value that you can control by calling 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * setThreshold(const RealScalar&). 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index rank() const 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold(); 206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index result = 0; 207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index i = 0; i < m_nonzero_pivots; ++i) 208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result += (internal::abs(m_qr.coeff(i,i)) > premultiplied_threshold); 209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return result; 210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition. 213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note This method has to determine which pivots should be considered nonzero. 215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * For that, it uses the threshold value that you can control by calling 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * setThreshold(const RealScalar&). 217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index dimensionOfKernel() const 219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return cols() - rank(); 222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns true if the matrix of which *this is the QR decomposition represents an injective 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * linear map, i.e. has trivial kernel; false otherwise. 226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note This method has to determine which pivots should be considered nonzero. 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * For that, it uses the threshold value that you can control by calling 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * setThreshold(const RealScalar&). 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline bool isInjective() const 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return rank() == cols(); 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns true if the matrix of which *this is the QR decomposition represents a surjective 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * linear map; false otherwise. 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note This method has to determine which pivots should be considered nonzero. 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * For that, it uses the threshold value that you can control by calling 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * setThreshold(const RealScalar&). 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline bool isSurjective() const 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return rank() == rows(); 248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns true if the matrix of which *this is the QR decomposition is invertible. 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note This method has to determine which pivots should be considered nonzero. 253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * For that, it uses the threshold value that you can control by calling 254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * setThreshold(const RealScalar&). 255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline bool isInvertible() const 257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return isInjective() && isSurjective(); 260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the inverse of the matrix of which *this is the QR decomposition. 263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \note If this matrix is not invertible, the returned matrix has undefined coefficients. 265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Use isInvertible() to first determine whether this matrix is invertible. 266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ inline const 267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::solve_retval<FullPivHouseholderQR, typename MatrixType::IdentityReturnType> 268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inverse() const 269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::solve_retval<FullPivHouseholderQR,typename MatrixType::IdentityReturnType> 272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols())); 273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index rows() const { return m_qr.rows(); } 276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index cols() const { return m_qr.cols(); } 277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const HCoeffsType& hCoeffs() const { return m_hCoeffs; } 278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Allows to prescribe a threshold to be used by certain methods, such as rank(), 280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * who need to determine when pivots are to be considered nonzero. This is not used for the 281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * QR decomposition itself. 282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * When it needs to get the threshold value, Eigen calls threshold(). By default, this 284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * uses a formula to automatically determine a reasonable threshold. 285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Once you have called the present method setThreshold(const RealScalar&), 286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * your value is used instead. 287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param threshold The new value to use as the threshold. 289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * A pivot will be considered nonzero if its absolute value is strictly greater than 291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$ 292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * where maxpivot is the biggest pivot. 293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * If you want to come back to the default behavior, call setThreshold(Default_t) 295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath FullPivHouseholderQR& setThreshold(const RealScalar& threshold) 297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_usePrescribedThreshold = true; 299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_prescribedThreshold = threshold; 300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return *this; 301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Allows to come back to the default behavior, letting Eigen use its default formula for 304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * determining the threshold. 305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * You should pass the special object Eigen::Default as parameter here. 307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \code qr.setThreshold(Eigen::Default); \endcode 308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * See the documentation of setThreshold(const RealScalar&). 310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath FullPivHouseholderQR& setThreshold(Default_t) 312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_usePrescribedThreshold = false; 314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return *this; 315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Returns the threshold that will be used by certain methods such as rank(). 318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * See the documentation of setThreshold(const RealScalar&). 320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar threshold() const 322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized || m_usePrescribedThreshold); 324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_usePrescribedThreshold ? m_prescribedThreshold 325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // this formula comes from experimenting (see "LU precision tuning" thread on the list) 326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // and turns out to be identical to Higham's formula used already in LDLt. 327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : NumTraits<Scalar>::epsilon() * m_qr.diagonalSize(); 328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the number of nonzero pivots in the QR decomposition. 331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Here nonzero is meant in the exact sense, not in a fuzzy sense. 332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * So that notion isn't really intrinsically interesting, but it is 333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * still useful when implementing algorithms. 334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa rank() 336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index nonzeroPivots() const 338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "LU is not initialized."); 340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_nonzero_pivots; 341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the absolute value of the biggest pivot, i.e. the biggest 344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * diagonal coefficient of U. 345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar maxPivot() const { return m_maxpivot; } 347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixType m_qr; 350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath HCoeffsType m_hCoeffs; 351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath IntColVectorType m_rows_transpositions; 352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath IntRowVectorType m_cols_transpositions; 353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath PermutationType m_cols_permutation; 354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowVectorType m_temp; 355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool m_isInitialized, m_usePrescribedThreshold; 356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar m_prescribedThreshold, m_maxpivot; 357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_nonzero_pivots; 358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar m_precision; 359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_det_pq; 360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> 363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtypename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::absDeterminant() const 364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); 367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return internal::abs(m_qr.diagonal().prod()); 368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> 371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtypename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::logAbsDeterminant() const 372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); 375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_qr.diagonal().cwiseAbs().array().log().sum(); 376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> 379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathFullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix) 380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index rows = matrix.rows(); 382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index cols = matrix.cols(); 383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index size = (std::min)(rows,cols); 384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_qr = matrix; 386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_hCoeffs.resize(size); 387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_temp.resize(cols); 389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_precision = NumTraits<Scalar>::epsilon() * size; 391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_rows_transpositions.resize(matrix.rows()); 393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_transpositions.resize(matrix.cols()); 394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index number_of_transpositions = 0; 395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar biggest(0); 397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case) 399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_maxpivot = RealScalar(0); 400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index k = 0; k < size; ++k) 402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 403c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index row_of_biggest_in_corner, col_of_biggest_in_corner; 404c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar biggest_in_corner; 405c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 406c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath biggest_in_corner = m_qr.bottomRightCorner(rows-k, cols-k) 407c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath .cwiseAbs() 408c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner); 409c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath row_of_biggest_in_corner += k; 410c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath col_of_biggest_in_corner += k; 411c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(k==0) biggest = biggest_in_corner; 412c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 413c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // if the corner is negligible, then we have less than full rank, and we can finish early 414c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(internal::isMuchSmallerThan(biggest_in_corner, biggest, m_precision)) 415c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_nonzero_pivots = k; 417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index i = k; i < size; i++) 418c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_rows_transpositions.coeffRef(i) = i; 420c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_transpositions.coeffRef(i) = i; 421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_hCoeffs.coeffRef(i) = Scalar(0); 422c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 423c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath break; 424c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 425c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 426c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_rows_transpositions.coeffRef(k) = row_of_biggest_in_corner; 427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_transpositions.coeffRef(k) = col_of_biggest_in_corner; 428c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(k != row_of_biggest_in_corner) { 429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_qr.row(k).tail(cols-k).swap(m_qr.row(row_of_biggest_in_corner).tail(cols-k)); 430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++number_of_transpositions; 431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(k != col_of_biggest_in_corner) { 433c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_qr.col(k).swap(m_qr.col(col_of_biggest_in_corner)); 434c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++number_of_transpositions; 435c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 436c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 437c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar beta; 438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta); 439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_qr.coeffRef(k,k) = beta; 440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 441c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // remember the maximum absolute value of diagonal coefficients 442c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(internal::abs(beta) > m_maxpivot) m_maxpivot = internal::abs(beta); 443c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 444c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_qr.bottomRightCorner(rows-k, cols-k-1) 445c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1)); 446c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 447c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 448c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_permutation.setIdentity(cols); 449c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index k = 0; k < size; ++k) 450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cols_permutation.applyTranspositionOnTheRight(k, m_cols_transpositions.coeff(k)); 451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 452c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_det_pq = (number_of_transpositions%2) ? -1 : 1; 453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_isInitialized = true; 454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return *this; 456c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 457c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 458c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 459c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 460c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _MatrixType, typename Rhs> 461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs> 462c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : solve_retval_base<FullPivHouseholderQR<_MatrixType>, Rhs> 463c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_MAKE_SOLVE_HELPERS(FullPivHouseholderQR<_MatrixType>,Rhs) 465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Dest> void evalTo(Dest& dst) const 467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index rows = dec().rows(), cols = dec().cols(); 469c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(rhs().rows() == rows); 470c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 471c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // FIXME introduce nonzeroPivots() and use it here. and more generally, 472c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // make the same improvements in this dec as in FullPivLU. 473c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(dec().rank()==0) 474c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 475c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dst.setZero(); 476c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return; 477c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 478c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 479c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename Rhs::PlainObject c(rhs()); 480c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 481c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Matrix<Scalar,1,Rhs::ColsAtCompileTime> temp(rhs().cols()); 482c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index k = 0; k < dec().rank(); ++k) 483c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 484c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index remainingSize = rows-k; 485c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath c.row(k).swap(c.row(dec().rowsTranspositions().coeff(k))); 486c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath c.bottomRightCorner(remainingSize, rhs().cols()) 487c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath .applyHouseholderOnTheLeft(dec().matrixQR().col(k).tail(remainingSize-1), 488c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dec().hCoeffs().coeff(k), &temp.coeffRef(0)); 489c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 490c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!dec().isSurjective()) 492c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 493c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // is c is in the image of R ? 494c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar biggest_in_upper_part_of_c = c.topRows( dec().rank() ).cwiseAbs().maxCoeff(); 495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar biggest_in_lower_part_of_c = c.bottomRows(rows-dec().rank()).cwiseAbs().maxCoeff(); 496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // FIXME brain dead 497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const RealScalar m_precision = NumTraits<Scalar>::epsilon() * (std::min)(rows,cols); 498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // this internal:: prefix is needed by at least gcc 3.4 and ICC 499c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!internal::isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision)) 500c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return; 501c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 502c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dec().matrixQR() 503c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath .topLeftCorner(dec().rank(), dec().rank()) 504c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath .template triangularView<Upper>() 505c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath .solveInPlace(c.topRows(dec().rank())); 506c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 507c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i); 508c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero(); 509c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 510c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 511c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 512c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \ingroup QR_Module 513c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 514c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \brief Expression type for return value of FullPivHouseholderQR::matrixQ() 515c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 516c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \tparam MatrixType type of underlying dense matrix 517c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 518c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType 519c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : public ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> > 520c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 521c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic: 522c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Index Index; 523c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::plain_col_type<MatrixType, Index>::type IntColVectorType; 524c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType; 525c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<typename MatrixType::Scalar, 1, MatrixType::RowsAtCompileTime, RowMajor, 1, 526c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixType::MaxRowsAtCompileTime> WorkVectorType; 527c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 528c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath FullPivHouseholderQRMatrixQReturnType(const MatrixType& qr, 529c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const HCoeffsType& hCoeffs, 530c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const IntColVectorType& rowsTranspositions) 531c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_qr(qr), 532c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_hCoeffs(hCoeffs), 533c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_rowsTranspositions(rowsTranspositions) 534c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath {} 535c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 536c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template <typename ResultType> 537c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void evalTo(ResultType& result) const 538c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 539c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index rows = m_qr.rows(); 540c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath WorkVectorType workspace(rows); 541c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath evalTo(result, workspace); 542c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 543c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 544c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template <typename ResultType> 545c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void evalTo(ResultType& result, WorkVectorType& workspace) const 546c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 547c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // compute the product H'_0 H'_1 ... H'_n-1, 548c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // where H_k is the k-th Householder transformation I - h_k v_k v_k' 549c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...] 550c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index rows = m_qr.rows(); 551c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index cols = m_qr.cols(); 552c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index size = (std::min)(rows, cols); 553c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath workspace.resize(rows); 554c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.setIdentity(rows, rows); 555c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index k = size-1; k >= 0; k--) 556c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 557c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.block(k, k, rows-k, rows-k) 558c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), internal::conj(m_hCoeffs.coeff(k)), &workspace.coeffRef(k)); 559c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath result.row(k).swap(result.row(m_rowsTranspositions.coeff(k))); 560c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 561c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 562c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 563c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index rows() const { return m_qr.rows(); } 564c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index cols() const { return m_qr.rows(); } 565c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 566c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprotected: 567c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename MatrixType::Nested m_qr; 568c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename HCoeffsType::Nested m_hCoeffs; 569c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename IntColVectorType::Nested m_rowsTranspositions; 570c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 571c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 572c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 573c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 574c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType> 575c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline typename FullPivHouseholderQR<MatrixType>::MatrixQReturnType FullPivHouseholderQR<MatrixType>::matrixQ() const 576c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 577c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); 578c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return MatrixQReturnType(m_qr, m_hCoeffs, m_rows_transpositions); 579c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 580c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 581c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \return the full-pivoting Householder QR decomposition of \c *this. 582c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 583c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa class FullPivHouseholderQR 584c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 585c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 586c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathconst FullPivHouseholderQR<typename MatrixBase<Derived>::PlainObject> 587c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathMatrixBase<Derived>::fullPivHouseholderQr() const 588c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 589c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return FullPivHouseholderQR<PlainObject>(eval()); 590c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 591c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 592c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 593c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 594c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H 595