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