1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library 2*bf2c3715SXin Li // for linear algebra. 3*bf2c3715SXin Li // 4*bf2c3715SXin Li // Copyright (C) 2008-2010 Gael Guennebaud <[email protected]> 5*bf2c3715SXin Li // Copyright (C) 2009 Benoit Jacob <[email protected]> 6*bf2c3715SXin Li // Copyright (C) 2010 Vincent Lejeune 7*bf2c3715SXin Li // 8*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla 9*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed 10*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 11*bf2c3715SXin Li 12*bf2c3715SXin Li #ifndef EIGEN_QR_H 13*bf2c3715SXin Li #define EIGEN_QR_H 14*bf2c3715SXin Li 15*bf2c3715SXin Li namespace Eigen { 16*bf2c3715SXin Li 17*bf2c3715SXin Li namespace internal { 18*bf2c3715SXin Li template<typename _MatrixType> struct traits<HouseholderQR<_MatrixType> > 19*bf2c3715SXin Li : traits<_MatrixType> 20*bf2c3715SXin Li { 21*bf2c3715SXin Li typedef MatrixXpr XprKind; 22*bf2c3715SXin Li typedef SolverStorage StorageKind; 23*bf2c3715SXin Li typedef int StorageIndex; 24*bf2c3715SXin Li enum { Flags = 0 }; 25*bf2c3715SXin Li }; 26*bf2c3715SXin Li 27*bf2c3715SXin Li } // end namespace internal 28*bf2c3715SXin Li 29*bf2c3715SXin Li /** \ingroup QR_Module 30*bf2c3715SXin Li * 31*bf2c3715SXin Li * 32*bf2c3715SXin Li * \class HouseholderQR 33*bf2c3715SXin Li * 34*bf2c3715SXin Li * \brief Householder QR decomposition of a matrix 35*bf2c3715SXin Li * 36*bf2c3715SXin Li * \tparam _MatrixType the type of the matrix of which we are computing the QR decomposition 37*bf2c3715SXin Li * 38*bf2c3715SXin Li * This class performs a QR decomposition of a matrix \b A into matrices \b Q and \b R 39*bf2c3715SXin Li * such that 40*bf2c3715SXin Li * \f[ 41*bf2c3715SXin Li * \mathbf{A} = \mathbf{Q} \, \mathbf{R} 42*bf2c3715SXin Li * \f] 43*bf2c3715SXin Li * by using Householder transformations. Here, \b Q a unitary matrix and \b R an upper triangular matrix. 44*bf2c3715SXin Li * The result is stored in a compact way compatible with LAPACK. 45*bf2c3715SXin Li * 46*bf2c3715SXin Li * Note that no pivoting is performed. This is \b not a rank-revealing decomposition. 47*bf2c3715SXin Li * If you want that feature, use FullPivHouseholderQR or ColPivHouseholderQR instead. 48*bf2c3715SXin Li * 49*bf2c3715SXin Li * This Householder QR decomposition is faster, but less numerically stable and less feature-full than 50*bf2c3715SXin Li * FullPivHouseholderQR or ColPivHouseholderQR. 51*bf2c3715SXin Li * 52*bf2c3715SXin Li * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism. 53*bf2c3715SXin Li * 54*bf2c3715SXin Li * \sa MatrixBase::householderQr() 55*bf2c3715SXin Li */ 56*bf2c3715SXin Li template<typename _MatrixType> class HouseholderQR 57*bf2c3715SXin Li : public SolverBase<HouseholderQR<_MatrixType> > 58*bf2c3715SXin Li { 59*bf2c3715SXin Li public: 60*bf2c3715SXin Li 61*bf2c3715SXin Li typedef _MatrixType MatrixType; 62*bf2c3715SXin Li typedef SolverBase<HouseholderQR> Base; 63*bf2c3715SXin Li friend class SolverBase<HouseholderQR>; 64*bf2c3715SXin Li 65*bf2c3715SXin Li EIGEN_GENERIC_PUBLIC_INTERFACE(HouseholderQR) 66*bf2c3715SXin Li enum { 67*bf2c3715SXin Li MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, 68*bf2c3715SXin Li MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime 69*bf2c3715SXin Li }; 70*bf2c3715SXin Li typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, (MatrixType::Flags&RowMajorBit) ? RowMajor : ColMajor, MaxRowsAtCompileTime, MaxRowsAtCompileTime> MatrixQType; 71*bf2c3715SXin Li typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType; 72*bf2c3715SXin Li typedef typename internal::plain_row_type<MatrixType>::type RowVectorType; 73*bf2c3715SXin Li typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType; 74*bf2c3715SXin Li 75*bf2c3715SXin Li /** 76*bf2c3715SXin Li * \brief Default Constructor. 77*bf2c3715SXin Li * 78*bf2c3715SXin Li * The default constructor is useful in cases in which the user intends to 79*bf2c3715SXin Li * perform decompositions via HouseholderQR::compute(const MatrixType&). 80*bf2c3715SXin Li */ 81*bf2c3715SXin Li HouseholderQR() : m_qr(), m_hCoeffs(), m_temp(), m_isInitialized(false) {} 82*bf2c3715SXin Li 83*bf2c3715SXin Li /** \brief Default Constructor with memory preallocation 84*bf2c3715SXin Li * 85*bf2c3715SXin Li * Like the default constructor but with preallocation of the internal data 86*bf2c3715SXin Li * according to the specified problem \a size. 87*bf2c3715SXin Li * \sa HouseholderQR() 88*bf2c3715SXin Li */ 89*bf2c3715SXin Li HouseholderQR(Index rows, Index cols) 90*bf2c3715SXin Li : m_qr(rows, cols), 91*bf2c3715SXin Li m_hCoeffs((std::min)(rows,cols)), 92*bf2c3715SXin Li m_temp(cols), 93*bf2c3715SXin Li m_isInitialized(false) {} 94*bf2c3715SXin Li 95*bf2c3715SXin Li /** \brief Constructs a QR factorization from a given matrix 96*bf2c3715SXin Li * 97*bf2c3715SXin Li * This constructor computes the QR factorization of the matrix \a matrix by calling 98*bf2c3715SXin Li * the method compute(). It is a short cut for: 99*bf2c3715SXin Li * 100*bf2c3715SXin Li * \code 101*bf2c3715SXin Li * HouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols()); 102*bf2c3715SXin Li * qr.compute(matrix); 103*bf2c3715SXin Li * \endcode 104*bf2c3715SXin Li * 105*bf2c3715SXin Li * \sa compute() 106*bf2c3715SXin Li */ 107*bf2c3715SXin Li template<typename InputType> 108*bf2c3715SXin Li explicit HouseholderQR(const EigenBase<InputType>& matrix) 109*bf2c3715SXin Li : m_qr(matrix.rows(), matrix.cols()), 110*bf2c3715SXin Li m_hCoeffs((std::min)(matrix.rows(),matrix.cols())), 111*bf2c3715SXin Li m_temp(matrix.cols()), 112*bf2c3715SXin Li m_isInitialized(false) 113*bf2c3715SXin Li { 114*bf2c3715SXin Li compute(matrix.derived()); 115*bf2c3715SXin Li } 116*bf2c3715SXin Li 117*bf2c3715SXin Li 118*bf2c3715SXin Li /** \brief Constructs a QR factorization from a given matrix 119*bf2c3715SXin Li * 120*bf2c3715SXin Li * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when 121*bf2c3715SXin Li * \c MatrixType is a Eigen::Ref. 122*bf2c3715SXin Li * 123*bf2c3715SXin Li * \sa HouseholderQR(const EigenBase&) 124*bf2c3715SXin Li */ 125*bf2c3715SXin Li template<typename InputType> 126*bf2c3715SXin Li explicit HouseholderQR(EigenBase<InputType>& matrix) 127*bf2c3715SXin Li : m_qr(matrix.derived()), 128*bf2c3715SXin Li m_hCoeffs((std::min)(matrix.rows(),matrix.cols())), 129*bf2c3715SXin Li m_temp(matrix.cols()), 130*bf2c3715SXin Li m_isInitialized(false) 131*bf2c3715SXin Li { 132*bf2c3715SXin Li computeInPlace(); 133*bf2c3715SXin Li } 134*bf2c3715SXin Li 135*bf2c3715SXin Li #ifdef EIGEN_PARSED_BY_DOXYGEN 136*bf2c3715SXin Li /** This method finds a solution x to the equation Ax=b, where A is the matrix of which 137*bf2c3715SXin Li * *this is the QR decomposition, if any exists. 138*bf2c3715SXin Li * 139*bf2c3715SXin Li * \param b the right-hand-side of the equation to solve. 140*bf2c3715SXin Li * 141*bf2c3715SXin Li * \returns a solution. 142*bf2c3715SXin Li * 143*bf2c3715SXin Li * \note_about_checking_solutions 144*bf2c3715SXin Li * 145*bf2c3715SXin Li * \note_about_arbitrary_choice_of_solution 146*bf2c3715SXin Li * 147*bf2c3715SXin Li * Example: \include HouseholderQR_solve.cpp 148*bf2c3715SXin Li * Output: \verbinclude HouseholderQR_solve.out 149*bf2c3715SXin Li */ 150*bf2c3715SXin Li template<typename Rhs> 151*bf2c3715SXin Li inline const Solve<HouseholderQR, Rhs> 152*bf2c3715SXin Li solve(const MatrixBase<Rhs>& b) const; 153*bf2c3715SXin Li #endif 154*bf2c3715SXin Li 155*bf2c3715SXin Li /** This method returns an expression of the unitary matrix Q as a sequence of Householder transformations. 156*bf2c3715SXin Li * 157*bf2c3715SXin Li * The returned expression can directly be used to perform matrix products. It can also be assigned to a dense Matrix object. 158*bf2c3715SXin Li * Here is an example showing how to recover the full or thin matrix Q, as well as how to perform matrix products using operator*: 159*bf2c3715SXin Li * 160*bf2c3715SXin Li * Example: \include HouseholderQR_householderQ.cpp 161*bf2c3715SXin Li * Output: \verbinclude HouseholderQR_householderQ.out 162*bf2c3715SXin Li */ 163*bf2c3715SXin Li HouseholderSequenceType householderQ() const 164*bf2c3715SXin Li { 165*bf2c3715SXin Li eigen_assert(m_isInitialized && "HouseholderQR is not initialized."); 166*bf2c3715SXin Li return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate()); 167*bf2c3715SXin Li } 168*bf2c3715SXin Li 169*bf2c3715SXin Li /** \returns a reference to the matrix where the Householder QR decomposition is stored 170*bf2c3715SXin Li * in a LAPACK-compatible way. 171*bf2c3715SXin Li */ 172*bf2c3715SXin Li const MatrixType& matrixQR() const 173*bf2c3715SXin Li { 174*bf2c3715SXin Li eigen_assert(m_isInitialized && "HouseholderQR is not initialized."); 175*bf2c3715SXin Li return m_qr; 176*bf2c3715SXin Li } 177*bf2c3715SXin Li 178*bf2c3715SXin Li template<typename InputType> 179*bf2c3715SXin Li HouseholderQR& compute(const EigenBase<InputType>& matrix) { 180*bf2c3715SXin Li m_qr = matrix.derived(); 181*bf2c3715SXin Li computeInPlace(); 182*bf2c3715SXin Li return *this; 183*bf2c3715SXin Li } 184*bf2c3715SXin Li 185*bf2c3715SXin Li /** \returns the absolute value of the determinant of the matrix of which 186*bf2c3715SXin Li * *this is the QR decomposition. It has only linear complexity 187*bf2c3715SXin Li * (that is, O(n) where n is the dimension of the square matrix) 188*bf2c3715SXin Li * as the QR decomposition has already been computed. 189*bf2c3715SXin Li * 190*bf2c3715SXin Li * \note This is only for square matrices. 191*bf2c3715SXin Li * 192*bf2c3715SXin Li * \warning a determinant can be very big or small, so for matrices 193*bf2c3715SXin Li * of large enough dimension, there is a risk of overflow/underflow. 194*bf2c3715SXin Li * One way to work around that is to use logAbsDeterminant() instead. 195*bf2c3715SXin Li * 196*bf2c3715SXin Li * \sa logAbsDeterminant(), MatrixBase::determinant() 197*bf2c3715SXin Li */ 198*bf2c3715SXin Li typename MatrixType::RealScalar absDeterminant() const; 199*bf2c3715SXin Li 200*bf2c3715SXin Li /** \returns the natural log of the absolute value of the determinant of the matrix of which 201*bf2c3715SXin Li * *this is the QR decomposition. It has only linear complexity 202*bf2c3715SXin Li * (that is, O(n) where n is the dimension of the square matrix) 203*bf2c3715SXin Li * as the QR decomposition has already been computed. 204*bf2c3715SXin Li * 205*bf2c3715SXin Li * \note This is only for square matrices. 206*bf2c3715SXin Li * 207*bf2c3715SXin Li * \note This method is useful to work around the risk of overflow/underflow that's inherent 208*bf2c3715SXin Li * to determinant computation. 209*bf2c3715SXin Li * 210*bf2c3715SXin Li * \sa absDeterminant(), MatrixBase::determinant() 211*bf2c3715SXin Li */ 212*bf2c3715SXin Li typename MatrixType::RealScalar logAbsDeterminant() const; 213*bf2c3715SXin Li 214*bf2c3715SXin Li inline Index rows() const { return m_qr.rows(); } 215*bf2c3715SXin Li inline Index cols() const { return m_qr.cols(); } 216*bf2c3715SXin Li 217*bf2c3715SXin Li /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q. 218*bf2c3715SXin Li * 219*bf2c3715SXin Li * For advanced uses only. 220*bf2c3715SXin Li */ 221*bf2c3715SXin Li const HCoeffsType& hCoeffs() const { return m_hCoeffs; } 222*bf2c3715SXin Li 223*bf2c3715SXin Li #ifndef EIGEN_PARSED_BY_DOXYGEN 224*bf2c3715SXin Li template<typename RhsType, typename DstType> 225*bf2c3715SXin Li void _solve_impl(const RhsType &rhs, DstType &dst) const; 226*bf2c3715SXin Li 227*bf2c3715SXin Li template<bool Conjugate, typename RhsType, typename DstType> 228*bf2c3715SXin Li void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const; 229*bf2c3715SXin Li #endif 230*bf2c3715SXin Li 231*bf2c3715SXin Li protected: 232*bf2c3715SXin Li 233*bf2c3715SXin Li static void check_template_parameters() 234*bf2c3715SXin Li { 235*bf2c3715SXin Li EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); 236*bf2c3715SXin Li } 237*bf2c3715SXin Li 238*bf2c3715SXin Li void computeInPlace(); 239*bf2c3715SXin Li 240*bf2c3715SXin Li MatrixType m_qr; 241*bf2c3715SXin Li HCoeffsType m_hCoeffs; 242*bf2c3715SXin Li RowVectorType m_temp; 243*bf2c3715SXin Li bool m_isInitialized; 244*bf2c3715SXin Li }; 245*bf2c3715SXin Li 246*bf2c3715SXin Li template<typename MatrixType> 247*bf2c3715SXin Li typename MatrixType::RealScalar HouseholderQR<MatrixType>::absDeterminant() const 248*bf2c3715SXin Li { 249*bf2c3715SXin Li using std::abs; 250*bf2c3715SXin Li eigen_assert(m_isInitialized && "HouseholderQR is not initialized."); 251*bf2c3715SXin Li eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); 252*bf2c3715SXin Li return abs(m_qr.diagonal().prod()); 253*bf2c3715SXin Li } 254*bf2c3715SXin Li 255*bf2c3715SXin Li template<typename MatrixType> 256*bf2c3715SXin Li typename MatrixType::RealScalar HouseholderQR<MatrixType>::logAbsDeterminant() const 257*bf2c3715SXin Li { 258*bf2c3715SXin Li eigen_assert(m_isInitialized && "HouseholderQR is not initialized."); 259*bf2c3715SXin Li eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); 260*bf2c3715SXin Li return m_qr.diagonal().cwiseAbs().array().log().sum(); 261*bf2c3715SXin Li } 262*bf2c3715SXin Li 263*bf2c3715SXin Li namespace internal { 264*bf2c3715SXin Li 265*bf2c3715SXin Li /** \internal */ 266*bf2c3715SXin Li template<typename MatrixQR, typename HCoeffs> 267*bf2c3715SXin Li void householder_qr_inplace_unblocked(MatrixQR& mat, HCoeffs& hCoeffs, typename MatrixQR::Scalar* tempData = 0) 268*bf2c3715SXin Li { 269*bf2c3715SXin Li typedef typename MatrixQR::Scalar Scalar; 270*bf2c3715SXin Li typedef typename MatrixQR::RealScalar RealScalar; 271*bf2c3715SXin Li Index rows = mat.rows(); 272*bf2c3715SXin Li Index cols = mat.cols(); 273*bf2c3715SXin Li Index size = (std::min)(rows,cols); 274*bf2c3715SXin Li 275*bf2c3715SXin Li eigen_assert(hCoeffs.size() == size); 276*bf2c3715SXin Li 277*bf2c3715SXin Li typedef Matrix<Scalar,MatrixQR::ColsAtCompileTime,1> TempType; 278*bf2c3715SXin Li TempType tempVector; 279*bf2c3715SXin Li if(tempData==0) 280*bf2c3715SXin Li { 281*bf2c3715SXin Li tempVector.resize(cols); 282*bf2c3715SXin Li tempData = tempVector.data(); 283*bf2c3715SXin Li } 284*bf2c3715SXin Li 285*bf2c3715SXin Li for(Index k = 0; k < size; ++k) 286*bf2c3715SXin Li { 287*bf2c3715SXin Li Index remainingRows = rows - k; 288*bf2c3715SXin Li Index remainingCols = cols - k - 1; 289*bf2c3715SXin Li 290*bf2c3715SXin Li RealScalar beta; 291*bf2c3715SXin Li mat.col(k).tail(remainingRows).makeHouseholderInPlace(hCoeffs.coeffRef(k), beta); 292*bf2c3715SXin Li mat.coeffRef(k,k) = beta; 293*bf2c3715SXin Li 294*bf2c3715SXin Li // apply H to remaining part of m_qr from the left 295*bf2c3715SXin Li mat.bottomRightCorner(remainingRows, remainingCols) 296*bf2c3715SXin Li .applyHouseholderOnTheLeft(mat.col(k).tail(remainingRows-1), hCoeffs.coeffRef(k), tempData+k+1); 297*bf2c3715SXin Li } 298*bf2c3715SXin Li } 299*bf2c3715SXin Li 300*bf2c3715SXin Li /** \internal */ 301*bf2c3715SXin Li template<typename MatrixQR, typename HCoeffs, 302*bf2c3715SXin Li typename MatrixQRScalar = typename MatrixQR::Scalar, 303*bf2c3715SXin Li bool InnerStrideIsOne = (MatrixQR::InnerStrideAtCompileTime == 1 && HCoeffs::InnerStrideAtCompileTime == 1)> 304*bf2c3715SXin Li struct householder_qr_inplace_blocked 305*bf2c3715SXin Li { 306*bf2c3715SXin Li // This is specialized for LAPACK-supported Scalar types in HouseholderQR_LAPACKE.h 307*bf2c3715SXin Li static void run(MatrixQR& mat, HCoeffs& hCoeffs, Index maxBlockSize=32, 308*bf2c3715SXin Li typename MatrixQR::Scalar* tempData = 0) 309*bf2c3715SXin Li { 310*bf2c3715SXin Li typedef typename MatrixQR::Scalar Scalar; 311*bf2c3715SXin Li typedef Block<MatrixQR,Dynamic,Dynamic> BlockType; 312*bf2c3715SXin Li 313*bf2c3715SXin Li Index rows = mat.rows(); 314*bf2c3715SXin Li Index cols = mat.cols(); 315*bf2c3715SXin Li Index size = (std::min)(rows, cols); 316*bf2c3715SXin Li 317*bf2c3715SXin Li typedef Matrix<Scalar,Dynamic,1,ColMajor,MatrixQR::MaxColsAtCompileTime,1> TempType; 318*bf2c3715SXin Li TempType tempVector; 319*bf2c3715SXin Li if(tempData==0) 320*bf2c3715SXin Li { 321*bf2c3715SXin Li tempVector.resize(cols); 322*bf2c3715SXin Li tempData = tempVector.data(); 323*bf2c3715SXin Li } 324*bf2c3715SXin Li 325*bf2c3715SXin Li Index blockSize = (std::min)(maxBlockSize,size); 326*bf2c3715SXin Li 327*bf2c3715SXin Li Index k = 0; 328*bf2c3715SXin Li for (k = 0; k < size; k += blockSize) 329*bf2c3715SXin Li { 330*bf2c3715SXin Li Index bs = (std::min)(size-k,blockSize); // actual size of the block 331*bf2c3715SXin Li Index tcols = cols - k - bs; // trailing columns 332*bf2c3715SXin Li Index brows = rows-k; // rows of the block 333*bf2c3715SXin Li 334*bf2c3715SXin Li // partition the matrix: 335*bf2c3715SXin Li // A00 | A01 | A02 336*bf2c3715SXin Li // mat = A10 | A11 | A12 337*bf2c3715SXin Li // A20 | A21 | A22 338*bf2c3715SXin Li // and performs the qr dec of [A11^T A12^T]^T 339*bf2c3715SXin Li // and update [A21^T A22^T]^T using level 3 operations. 340*bf2c3715SXin Li // Finally, the algorithm continue on A22 341*bf2c3715SXin Li 342*bf2c3715SXin Li BlockType A11_21 = mat.block(k,k,brows,bs); 343*bf2c3715SXin Li Block<HCoeffs,Dynamic,1> hCoeffsSegment = hCoeffs.segment(k,bs); 344*bf2c3715SXin Li 345*bf2c3715SXin Li householder_qr_inplace_unblocked(A11_21, hCoeffsSegment, tempData); 346*bf2c3715SXin Li 347*bf2c3715SXin Li if(tcols) 348*bf2c3715SXin Li { 349*bf2c3715SXin Li BlockType A21_22 = mat.block(k,k+bs,brows,tcols); 350*bf2c3715SXin Li apply_block_householder_on_the_left(A21_22,A11_21,hCoeffsSegment, false); // false == backward 351*bf2c3715SXin Li } 352*bf2c3715SXin Li } 353*bf2c3715SXin Li } 354*bf2c3715SXin Li }; 355*bf2c3715SXin Li 356*bf2c3715SXin Li } // end namespace internal 357*bf2c3715SXin Li 358*bf2c3715SXin Li #ifndef EIGEN_PARSED_BY_DOXYGEN 359*bf2c3715SXin Li template<typename _MatrixType> 360*bf2c3715SXin Li template<typename RhsType, typename DstType> 361*bf2c3715SXin Li void HouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const 362*bf2c3715SXin Li { 363*bf2c3715SXin Li const Index rank = (std::min)(rows(), cols()); 364*bf2c3715SXin Li 365*bf2c3715SXin Li typename RhsType::PlainObject c(rhs); 366*bf2c3715SXin Li 367*bf2c3715SXin Li c.applyOnTheLeft(householderQ().setLength(rank).adjoint() ); 368*bf2c3715SXin Li 369*bf2c3715SXin Li m_qr.topLeftCorner(rank, rank) 370*bf2c3715SXin Li .template triangularView<Upper>() 371*bf2c3715SXin Li .solveInPlace(c.topRows(rank)); 372*bf2c3715SXin Li 373*bf2c3715SXin Li dst.topRows(rank) = c.topRows(rank); 374*bf2c3715SXin Li dst.bottomRows(cols()-rank).setZero(); 375*bf2c3715SXin Li } 376*bf2c3715SXin Li 377*bf2c3715SXin Li template<typename _MatrixType> 378*bf2c3715SXin Li template<bool Conjugate, typename RhsType, typename DstType> 379*bf2c3715SXin Li void HouseholderQR<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const 380*bf2c3715SXin Li { 381*bf2c3715SXin Li const Index rank = (std::min)(rows(), cols()); 382*bf2c3715SXin Li 383*bf2c3715SXin Li typename RhsType::PlainObject c(rhs); 384*bf2c3715SXin Li 385*bf2c3715SXin Li m_qr.topLeftCorner(rank, rank) 386*bf2c3715SXin Li .template triangularView<Upper>() 387*bf2c3715SXin Li .transpose().template conjugateIf<Conjugate>() 388*bf2c3715SXin Li .solveInPlace(c.topRows(rank)); 389*bf2c3715SXin Li 390*bf2c3715SXin Li dst.topRows(rank) = c.topRows(rank); 391*bf2c3715SXin Li dst.bottomRows(rows()-rank).setZero(); 392*bf2c3715SXin Li 393*bf2c3715SXin Li dst.applyOnTheLeft(householderQ().setLength(rank).template conjugateIf<!Conjugate>() ); 394*bf2c3715SXin Li } 395*bf2c3715SXin Li #endif 396*bf2c3715SXin Li 397*bf2c3715SXin Li /** Performs the QR factorization of the given matrix \a matrix. The result of 398*bf2c3715SXin Li * the factorization is stored into \c *this, and a reference to \c *this 399*bf2c3715SXin Li * is returned. 400*bf2c3715SXin Li * 401*bf2c3715SXin Li * \sa class HouseholderQR, HouseholderQR(const MatrixType&) 402*bf2c3715SXin Li */ 403*bf2c3715SXin Li template<typename MatrixType> 404*bf2c3715SXin Li void HouseholderQR<MatrixType>::computeInPlace() 405*bf2c3715SXin Li { 406*bf2c3715SXin Li check_template_parameters(); 407*bf2c3715SXin Li 408*bf2c3715SXin Li Index rows = m_qr.rows(); 409*bf2c3715SXin Li Index cols = m_qr.cols(); 410*bf2c3715SXin Li Index size = (std::min)(rows,cols); 411*bf2c3715SXin Li 412*bf2c3715SXin Li m_hCoeffs.resize(size); 413*bf2c3715SXin Li 414*bf2c3715SXin Li m_temp.resize(cols); 415*bf2c3715SXin Li 416*bf2c3715SXin Li internal::householder_qr_inplace_blocked<MatrixType, HCoeffsType>::run(m_qr, m_hCoeffs, 48, m_temp.data()); 417*bf2c3715SXin Li 418*bf2c3715SXin Li m_isInitialized = true; 419*bf2c3715SXin Li } 420*bf2c3715SXin Li 421*bf2c3715SXin Li /** \return the Householder QR decomposition of \c *this. 422*bf2c3715SXin Li * 423*bf2c3715SXin Li * \sa class HouseholderQR 424*bf2c3715SXin Li */ 425*bf2c3715SXin Li template<typename Derived> 426*bf2c3715SXin Li const HouseholderQR<typename MatrixBase<Derived>::PlainObject> 427*bf2c3715SXin Li MatrixBase<Derived>::householderQr() const 428*bf2c3715SXin Li { 429*bf2c3715SXin Li return HouseholderQR<PlainObject>(eval()); 430*bf2c3715SXin Li } 431*bf2c3715SXin Li 432*bf2c3715SXin Li } // end namespace Eigen 433*bf2c3715SXin Li 434*bf2c3715SXin Li #endif // EIGEN_QR_H 435