QRMatrix.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016 OpenFOAM Foundation
9  Copyright (C) 2019-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Class
28  Foam::QRMatrix
29 
30 Description
31  QRMatrix (i.e. QR decomposition, QR factorisation or orthogonal-triangular
32  decomposition) decomposes a scalar/complex matrix \c A into the following
33  matrix product:
34 
35  \verbatim
36  A = Q*R,
37  \endverbatim
38 
39  where
40  \c Q is a unitary similarity matrix,
41  \c R is an upper triangular matrix.
42 
43  Reference:
44  \verbatim
45  QR decomposition:
46  mathworld.wolfram.com/QRDecomposition.html (Retrieved:17-06-19)
47  w.wiki/52X (Retrieved: 17-06-19)
48 
49  QR decomposition with Householder reflector (tag:M):
50  Monahan, J. F. (2011).
51  Numerical methods of statistics.
52  Cambridge: Cambridge University Press.
53  DOI:10.1017/CBO9780511977176
54 
55  QR decomposition with column pivoting (tag:QSB):
56  Quintana-Ortí, G., Sun, X., & Bischof, C. H. (1998).
57  A BLAS-3 version of the QR factorization with column pivoting.
58  SIAM Journal on Scientific Computing, 19(5), 1486-1494.
59  DOI:10.1137/S1064827595296732
60 
61  Moore-Penrose inverse algorithm (tags:KP; KPP):
62  Katsikis, V. N., & Pappas, D. (2008).
63  Fast computing of the Moore-Penrose inverse matrix.
64  Electronic Journal of Linear Algebra, 17(1), 637-650.
65  DOI:10.13001/1081-3810.1287
66 
67  Katsikis, V. N., Pappas, D., & Petralias, A. (2011).
68  An improved method for the computation of
69  the Moore–Penrose inverse matrix.
70  Applied Mathematics and Computation, 217(23), 9828-9834.
71  DOI:10.1016/j.amc.2011.04.080
72 
73  Tolerance for the Moore-Penrose inverse algorithm (tag:TA):
74  Toutounian, F., & Ataei, A. (2009).
75  A new method for computing Moore–Penrose inverse matrices.
76  Journal of Computational and applied Mathematics, 228(1), 412-417.
77  DOI:10.1016/j.cam.2008.10.008
78 
79  Operands of QR decomposition:
80  mathworld.wolfram.com/UnitaryMatrix.html (Retrieved:13-06-19)
81  mathworld.wolfram.com/UpperTriangularMatrix.html (Retrieved:16-06-19)
82  mathworld.wolfram.com/PermutationMatrix.html (Retrieved:20-06-19)
83 
84  Back substitution:
85  mathworld.wolfram.com/GaussianElimination.html (Retrieved:15-06-19)
86  \endverbatim
87 
88 Usage
89  Input types:
90  - \c A can be a \c SquareMatrix<Type> or \c RectangularMatrix<Type>
91 
92  Output types:
93  - \c Q is always of the type of the matrix \c A
94  - \c R is always of the type of the matrix \c A
95 
96  Options for the output forms of \c QRMatrix (for an (m-by-n) input matrix
97  \c A with k = min(m, n)):
98  - outputTypes::FULL_R: computes only \c R (m-by-n)
99  - outputTypes::FULL_QR: computes both \c R and \c Q (m-by-m)
100  - outputTypes::REDUCED_R: computes only reduced \c R (k-by-n)
101 
102  Options where to store \c R:
103  - storeMethods::IN_PLACE: replaces input matrix content with \c R
104  - storeMethods::OUT_OF_PLACE: creates new object of \c R
105 
106  Options for the computation of column pivoting:
107  - colPivoting::FALSE: switches off column pivoting
108  - colPivoting::TRUE: switches on column pivoting
109 
110  Direct solution of linear systems A x = b is possible by solve() alongside
111  the following limitations:
112  - \c A = a scalar square matrix
113  - output type = outputTypes::FULL_QR
114  - store method = storeMethods::IN_PLACE
115 
116 Notes
117  - QR decomposition is not unique if \c R is not positive diagonal \c R.
118  - The option combination:
119  - outputTypes::REDUCED_R
120  - storeMethods::IN_PLACE
121  will not modify the rows of input matrix \c A after its nth row.
122  - Both FULL_R and REDUCED_R QR decompositions execute the same number of
123  operations. Yet REDUCED_R QR decomposition returns only the first n rows
124  of \c R if m > n for an input m-by-n matrix \c A.
125  - For m <= n, FULL_R and REDUCED_R will produce the same matrices.
126 
127 See also
128  Test-QRMatrix.C
129 
130 SourceFiles
131  QRMatrix.C
132  QRMatrixI.H
133 
134 \*---------------------------------------------------------------------------*/
135 
136 #ifndef QRMatrix_H
137 #define QRMatrix_H
138 
139 #include "RectangularMatrix.H"
140 #include "SquareMatrix.H"
141 #include "complex.H"
142 
143 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
144 
145 namespace Foam
146 {
147 
148 /*---------------------------------------------------------------------------*\
149  Class QRMatrix Declaration
150 \*---------------------------------------------------------------------------*/
151 
152 template<class MatrixType>
153 class QRMatrix
154 {
155 
156 public:
157 
158  typedef typename MatrixType::cmptType cmptType;
161 
162  //- Options for the output matrix forms of QRMatrix
163  enum outputTypes : uint8_t
164  {
165  FULL_R = 1,
166  FULL_QR = 2,
167  REDUCED_R = 3
168  };
169 
170  //- Options where to store R
171  enum storeMethods : uint8_t
172  {
173  IN_PLACE = 1,
174  OUT_OF_PLACE = 2
175  };
176 
177  //- Options for the computation of column pivoting
178  enum colPivoting : bool
179  {
180  FALSE = false,
181  TRUE = true
182  };
183 
184 
185 private:
186 
187  // Private Data
188 
189  //- Selected option for the output matrix forms of QRMatrix
190  outputTypes outputType_;
191 
192  //- Selected option where to store R
193  const storeMethods storeMethod_;
194 
195  //- Selected option for the computation of column pivoting
196  const colPivoting colPivot_;
197 
198  //- Unitary similarity matrix
199  MatrixType Q_;
200 
201  //- Upper triangular matrix
202  MatrixType R_;
203 
204  //- Permutation list (if column-pivoting is on)
205  labelList P_;
206 
207 
208  // Private Member Functions
209 
210  //- Compute the QR decomposition without the column pivoting
211  void qr
212  (
213  MatrixType& A
214  );
215 
216  //- Compute the QR decomposition with the column pivoting
217  // (QSB:Fig. 1)
218  void qrPivot
219  (
220  MatrixType& A
221  );
222 
223  //- Compute output matrices in selected forms
224  //- using Householder reflectors
225  // (M:Section 4)
226  inline void applyHouseholder
227  (
228  MatrixType& A,
229  const RMatrix& reflector,
230  const label k = 0
231  );
232 
233  //- Solve the linear system with the Field argument x initialized to
234  //- the appropriate transformed source (e.g. Q.T()*source)
235  //- and return the solution in x
236  template<template<typename> class ListContainer>
237  void solvex(ListContainer<cmptType>& x) const;
238 
239  //- Solve the linear system with the given source
240  //- and return the solution in x
241  template<template<typename> class ListContainer>
242  void solveImpl
243  (
244  List<cmptType>& x,
245  const ListContainer<cmptType>& source
246  ) const;
247 
248 
249 protected:
250 
251  // Protected Member Functions
252 
253  //- Compute Householder reflector on a given matrix column, u
254  // (M:Eq.6.814)
256  (
257  RMatrix u
258  );
259 
260  //- Apply (in-place) Householder reflectors from the left side: u*A
261  inline void applyLeftReflector
262  (
263  MatrixType& A,
264  const RMatrix& reflector,
265  const label k = 0,
266  const label k1 = 0
267  );
268 
269  //- Apply (in-place) Householder reflectors from the right side: (u*A)*u
270  inline void applyRightReflector
271  (
272  MatrixType& A,
273  const RMatrix& reflector,
274  const label k = 0
275  );
276 
277 
278 public:
279 
280  // Constructors
281 
282  //- Construct null
283  QRMatrix();
284 
285  //- Construct QRMatrix without performing the decomposition
286  QRMatrix
287  (
288  const outputTypes outputType,
289  const storeMethods storeMethod = storeMethods::OUT_OF_PLACE,
290  const colPivoting colPivot = colPivoting::FALSE
291  );
292 
293  //- Construct QRMatrix and perform the QR decomposition
294  QRMatrix
295  (
296  MatrixType& A,
297  const outputTypes outputType,
298  const storeMethods storeMethod = storeMethods::OUT_OF_PLACE,
299  const colPivoting colPivot = colPivoting::FALSE
300  );
301 
302  //- Construct QRMatrix and perform the QR decomposition
303  QRMatrix
304  (
305  const MatrixType& A,
306  const outputTypes outputType,
307  const colPivoting colPivot = colPivoting::FALSE
308  );
309 
310 
311  // Member Functions
312 
313  // Information
314 
315  //- Return the unitary similarity matrix
316  // Includes implicit round-to-zero as mutable operation
317  inline const MatrixType& Q() const;
318 
319  //- Return the upper triangular matrix
320  inline const MatrixType& R() const;
321 
322  //- Return the permutation order (P) as a list
323  inline const labelList& orderP() const;
324 
325  //- Create and return the permutation matrix
326  inline SMatrix P() const;
327 
328 
329  // Algorithm
330 
331  //- Compute QR decomposition according to constructor settings
332  void decompose
333  (
334  MatrixType& A
335  );
336 
337  //- Compute QR decomposition according to constructor settings
338  void decompose
339  (
340  const MatrixType& A
341  );
342 
343  //- Solve the linear system with the given source
344  //- and return the solution in the argument x
345  void solve
346  (
347  List<cmptType>& x,
348  const UList<cmptType>& source
349  ) const;
350 
351  //- Solve the linear system with the given source
352  //- and return the solution in the argument x
353  template<class Addr>
354  void solve
355  (
356  List<cmptType>& x,
358  ) const;
359 
360  //- Solve the linear system with the given source
361  //- and return the solution
363  (
364  const UList<cmptType>& source
365  ) const;
366 
367  //- Solve the linear system with the given source
368  //- and return the solution
369  template<class Addr>
371  (
373  ) const;
374 
375  //- Return the inverse of (Q*R), so that solving x = (Q*R).inv()*source
376  SMatrix inv() const;
377 
378  //- Solve a row-echelon-form linear system starting from the bottom
379  // Back substitution: Ax = b where:
380  // A = Non-singular upper-triangular square matrix (m-by-m)
381  // x = Solution (m-by-p)
382  // b = Source (m-by-p)
384  (
385  const SMatrix& A,
386  const RMatrix& b
387  );
388 };
389 
390 
391 // * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
392 
393 //- (Out-of-place) Moore-Penrose inverse of singular/non-singular
394 //- square/rectangular scalar/complex matrices
395 // (KPP:p. 9834; KP:p. 648)
396 // The tolerance (i.e. tol) to ensure the R1 matrix full-rank is given as 1e-13
397 // in the original paper (KPP:p. 9834). Nonetheless, the tolerance = 1e-5
398 // given by (TA; mentioned in (KPP:p. 9832)) was observed to be more robust
399 // for the tested scenarios.
400 template<class MatrixType>
401 MatrixType pinv
402 (
403  const MatrixType& A,
404  const scalar tol = 1e-5
405 );
406 
407 
408 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
409 
410 } // End namespace Foam
411 
412 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
413 
414 #include "QRMatrixI.H"
415 
416 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
417 
418 #ifdef NoRepository
419  #include "QRMatrix.C"
420 #endif
421 
422 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
423 
424 #endif
425 
426 // ************************************************************************* //
Foam::QRMatrix::solve
void solve(List< cmptType > &x, const UList< cmptType > &source) const
Definition: QRMatrix.C:358
Foam::QRMatrix::RMatrix
RectangularMatrix< cmptType > RMatrix
Definition: QRMatrix.H:159
QRMatrix.C
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::QRMatrix::applyLeftReflector
void applyLeftReflector(MatrixType &A, const RMatrix &reflector, const label k=0, const label k1=0)
Apply (in-place) Householder reflectors from the left side: u*A.
Definition: QRMatrixI.H:97
Foam::QRMatrix::REDUCED_R
computes only reduced R
Definition: QRMatrix.H:166
Foam::pinv
MatrixType pinv(const MatrixType &A, const scalar tol=1e-5)
Definition: QRMatrix.C:493
Foam::QRMatrix::householderReflector
RMatrix householderReflector(RMatrix u)
Compute Householder reflector on a given matrix column, u.
Definition: QRMatrixI.H:52
Foam::QRMatrix::cmptType
MatrixType::cmptType cmptType
Definition: QRMatrix.H:157
A
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
Foam::QRMatrix::inv
SMatrix inv() const
Return the inverse of (Q*R), so that solving x = (Q*R).inv()*source.
Definition: QRMatrix.C:412
complex.H
Foam::QRMatrix::Q
const MatrixType & Q() const
Return the unitary similarity matrix.
Definition: QRMatrixI.H:155
QRMatrixI.H
Foam::QRMatrix::TRUE
switches on column pivoting
Definition: QRMatrix.H:180
Foam::QRMatrix
QRMatrix (i.e. QR decomposition, QR factorisation or orthogonal-triangular decomposition) decomposes ...
Definition: QRMatrix.H:152
Foam::QRMatrix::backSubstitution
RMatrix backSubstitution(const SMatrix &A, const RMatrix &b)
Solve a row-echelon-form linear system starting from the bottom.
Definition: QRMatrix.C:436
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::QRMatrix::applyRightReflector
void applyRightReflector(MatrixType &A, const RMatrix &reflector, const label k=0)
Apply (in-place) Householder reflectors from the right side: (u*A)*u.
Definition: QRMatrixI.H:126
Foam::QRMatrix::FULL_QR
computes both R and Q
Definition: QRMatrix.H:165
Foam::QRMatrix::FALSE
switches off column pivoting
Definition: QRMatrix.H:179
Foam::QRMatrix::IN_PLACE
replaces input matrix content with R
Definition: QRMatrix.H:172
Foam::RectangularMatrix
A templated (M x N) rectangular matrix of objects of <Type>, containing M*N elements,...
Definition: RectangularMatrix.H:57
Foam::QRMatrix::R
const MatrixType & R() const
Return the upper triangular matrix.
Definition: QRMatrixI.H:164
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::QRMatrix::colPivoting
colPivoting
Options for the computation of column pivoting.
Definition: QRMatrix.H:177
Foam::SquareMatrix< cmptType >
Foam::QRMatrix::storeMethods
storeMethods
Options where to store R.
Definition: QRMatrix.H:170
Foam::QRMatrix::SMatrix
SquareMatrix< cmptType > SMatrix
Definition: QRMatrix.H:158
Foam::QRMatrix::QRMatrix
QRMatrix()
Construct null.
Definition: QRMatrix.C:186
Foam::List< label >
Foam::QRMatrix::orderP
const labelList & orderP() const
Return the permutation order (P) as a list.
Definition: QRMatrixI.H:171
Foam::QRMatrix::FULL_R
computes only R
Definition: QRMatrix.H:164
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
k
label k
Boltzmann constant.
Definition: LISASMDCalcMethod2.H:41
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::IndirectListBase
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
Definition: IndirectListBase.H:56
Foam::QRMatrix::outputTypes
outputTypes
Options for the output matrix forms of QRMatrix.
Definition: QRMatrix.H:162
SquareMatrix.H
Foam::QRMatrix::decompose
void decompose(MatrixType &A)
Compute QR decomposition according to constructor settings.
Definition: QRMatrix.C:254
Foam::QRMatrix::OUT_OF_PLACE
creates new object of R
Definition: QRMatrix.H:173
Foam::QRMatrix::P
SMatrix P() const
Create and return the permutation matrix.
Definition: QRMatrixI.H:179
RectangularMatrix.H