xref: /aosp_15_r20/external/eigen/Eigen/src/QR/HouseholderQR.h (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
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