KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
eigen_dense_householder_qr_decomposition.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Ruben Zorrilla
11 //
12 
13 #if !defined(KRATOS_EIGEN_DENSE_HOUSEHOLDER_QR_H_INCLUDED)
14 #define KRATOS_EIGEN_DENSE_HOUSEHOLDER_QR_H_INCLUDED
15 
16 // External includes
17 #include <Eigen/QR>
18 
19 // Project includes
20 #include "includes/define.h"
21 #include "linear_solvers_define.h"
23 
24 namespace Kratos {
25 
28 
32 
36 
40 
44 
45 template<class TDenseSpace>
47 {
48 public:
49 
52 
55 
56  typedef typename TDenseSpace::DataType DataType;
59 
62 
66 
68 
72 
73 
77 
78  static std::string Name()
79  {
80  return "dense_householder_qr_decomposition";
81  }
82 
83  void Compute(MatrixType& rInputMatrix) override
84  {
85  // Householder QR requires m >= n
86  const std::size_t m = rInputMatrix.size1();
87  const std::size_t n = rInputMatrix.size2();
88  KRATOS_ERROR_IF(m < n) << "Householder QR decomposition requires m >= n. Input matrix size is (" << m << "," << n << ")." << std::endl;
89 
90  // Compute the Householder QR decomposition
91  // Note that the QR is computed when constructing the pointer
92  Eigen::Map<EigenMatrix> eigen_input_matrix_map(rInputMatrix.data().begin(), m, n);
93  mpHouseholderQR = Kratos::make_unique<Eigen::HouseholderQR<Eigen::Ref<EigenMatrix>>>(eigen_input_matrix_map);
94  }
95 
96  void Compute(
97  MatrixType& rInputMatrix,
98  MatrixType& rMatrixQ,
99  MatrixType& rMatrixR) override
100  {
101  KRATOS_ERROR << "Householder QR decomposition does not implement the R matrix return. Call the \'Compute()\' and the \'MatrixQ\' methods sequentially." << std::endl;
102  }
103 
104  void Solve(
105  MatrixType& rB,
106  MatrixType& rX) const override
107  {
108  // Check that QR decomposition has been already computed
109  KRATOS_ERROR_IF(!mpHouseholderQR) << "QR decomposition not computed yet. Please call 'Compute' before 'Solve'." << std::endl;
110 
111  // Check output matrix size
112  std::size_t n = rB.size2();
113  const std::size_t k = mpHouseholderQR->matrixQR().cols();
114  if (rX.size1() != k || rX.size2() != n) {
115  rX.resize(k,n,false);
116  }
117 
118  // Solve the problem Ax = b
119  Eigen::Map<EigenMatrix> eigen_x_map(rX.data().begin(), k, n);
120  Eigen::Map<EigenMatrix> eigen_rhs_map(rB.data().begin(), rB.size1(), n);
121  eigen_x_map = mpHouseholderQR->solve(eigen_rhs_map);
122  }
123 
124  void Solve(
125  const VectorType& rB,
126  VectorType& rX) const override
127  {
128  // Check that QR decomposition has been already computed
129  KRATOS_ERROR_IF(!mpHouseholderQR) << "QR decomposition not computed yet. Please call 'Compute' before 'Solve'." << std::endl;
130 
131  // Check output matrix size
132  const std::size_t k = mpHouseholderQR->matrixQR().cols();
133  if (rX.size() != k) {
134  rX.resize(k,false);
135  }
136 
137  // Solve the problem Ax = b
138  Eigen::Map<EigenMatrix> eigen_x_map(rX.data().begin(), k, 1);
139  Eigen::Map<EigenMatrix> eigen_rhs_map(const_cast<VectorType&>(rB).data().begin(), rB.size(), 1);
140  eigen_x_map = mpHouseholderQR->solve(eigen_rhs_map);
141  }
142 
143  void MatrixQ(MatrixType& rMatrixQ) const override
144  {
145  // Check that QR decomposition has been already computed
146  KRATOS_ERROR_IF(!mpHouseholderQR) << "QR decomposition not computed yet. Please call 'Compute' before 'MatrixQ'." << std::endl;
147 
148  // Set the thin Q to be returned
149  const std::size_t Q_rows = mpHouseholderQR->householderQ().rows();
150  const std::size_t n = mpHouseholderQR->matrixQR().cols();
151  if (rMatrixQ.size1() != Q_rows || rMatrixQ.size2() != n) {
152  rMatrixQ.resize(Q_rows,n,false);
153  }
154 
155  // Get the thin unitary matrix Q from the complete one
156  // Note that Eigen stores it not as matrix type but as a sequence of Householder transformations (householderQ())
157  Eigen::Map<EigenMatrix> thin_Q(rMatrixQ.data().begin(), Q_rows, n);
158  thin_Q = EigenMatrix::Identity(Q_rows,n);
159  thin_Q = mpHouseholderQR->householderQ() * thin_Q;
160  }
161 
162  void MatrixR(MatrixType& rMatrixR) const override
163  {
164  // Check that QR decomposition has been already computed
165  KRATOS_ERROR_IF(!mpHouseholderQR) << "QR decomposition not computed yet. Please call 'Compute' before 'MatrixR'." << std::endl;
166 
167  // Set the matrix R to be returned
168  const std::size_t n = mpHouseholderQR->matrixQR().cols();
169  if (rMatrixR.size1() != n || rMatrixR.size2() != n) {
170  rMatrixR.resize(n,n,false);
171  }
172 
173  // Get the upper triangular matrix
174  // Note that we specify Eigen to return the upper triangular part as the bottom part are auxiliary internal values
175  Eigen::Map<EigenMatrix> matrix_R_map(rMatrixR.data().begin(), n, n);
176  matrix_R_map = mpHouseholderQR->matrixQR().topLeftCorner(n, n).template triangularView<Eigen::Upper>();
177  }
178 
179  void MatrixP(MatrixType& rMatrixP) const override
180  {
181  KRATOS_ERROR << "Householder QR decomposition does not implement the P matrix return" << std::endl;
182  }
183 
184  std::size_t Rank() const override
185  {
186  KRATOS_ERROR << "Householder QR decomposition is not rank revealing." << std::endl;
187  }
188 
189  void PrintInfo(std::ostream &rOStream) const override
190  {
191  rOStream << "EigenDecomposition <" << Name() << "> finished.";
192  }
193 
197 
198 
202 
203 
207 
208 
212 
213 
215 private:
218 
219 
223 
224  std::unique_ptr<Eigen::HouseholderQR<Eigen::Ref<EigenMatrix>>> mpHouseholderQR = std::unique_ptr<Eigen::HouseholderQR<Eigen::Ref<EigenMatrix>>>(nullptr);
225 
229 
230 
234 
235 
239 
240 
244 
245 
249 
250 
254 
255 
257 };
258 
261 
262 
266 
267 
269 } // namespace Kratos
270 
271 #endif // defined(KRATOS_EIGEN_DENSE_HOUSEHOLDER_QR_H_INCLUDED)
Definition: dense_qr_decomposition.h:44
Definition: eigen_dense_householder_qr_decomposition.h:47
void Compute(MatrixType &rInputMatrix) override
Definition: eigen_dense_householder_qr_decomposition.h:83
TDenseSpace::VectorType VectorType
Definition: eigen_dense_householder_qr_decomposition.h:57
void MatrixR(MatrixType &rMatrixR) const override
Definition: eigen_dense_householder_qr_decomposition.h:162
void Compute(MatrixType &rInputMatrix, MatrixType &rMatrixQ, MatrixType &rMatrixR) override
Definition: eigen_dense_householder_qr_decomposition.h:96
std::size_t Rank() const override
Rank of the provided array Calculates and returns the rank of the array decomposed with the QR.
Definition: eigen_dense_householder_qr_decomposition.h:184
void MatrixP(MatrixType &rMatrixP) const override
Definition: eigen_dense_householder_qr_decomposition.h:179
static std::string Name()
Definition: eigen_dense_householder_qr_decomposition.h:78
KRATOS_CLASS_POINTER_DEFINITION(EigenDenseHouseholderQRDecomposition)
Definition of the shared pointer of the class.
TDenseSpace::DataType DataType
Definition: eigen_dense_householder_qr_decomposition.h:56
void Solve(const VectorType &rB, VectorType &rX) const override
Definition: eigen_dense_householder_qr_decomposition.h:124
Kratos::EigenDynamicVector< DataType > EigenVector
Definition: eigen_dense_householder_qr_decomposition.h:60
void Solve(MatrixType &rB, MatrixType &rX) const override
Definition: eigen_dense_householder_qr_decomposition.h:104
void PrintInfo(std::ostream &rOStream) const override
QR information Outputs the QR class information.
Definition: eigen_dense_householder_qr_decomposition.h:189
Kratos::EigenDynamicMatrix< DataType > EigenMatrix
Definition: eigen_dense_householder_qr_decomposition.h:61
TDenseSpace::MatrixType MatrixType
Definition: eigen_dense_householder_qr_decomposition.h:58
void MatrixQ(MatrixType &rMatrixQ) const override
Definition: eigen_dense_householder_qr_decomposition.h:143
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
Vector VectorType
Definition: geometrical_transformation_utilities.h:56
Matrix MatrixType
Definition: geometrical_transformation_utilities.h:55
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > EigenDynamicMatrix
Definition: linear_solvers_define.h:32
Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > EigenDynamicVector
Definition: linear_solvers_define.h:33
data
Definition: mesh_to_mdpa_converter.py:59
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
int k
Definition: quadrature.py:595
int m
Definition: run_marine_rain_substepping.py:8