Linear Algebra  master
Accessible implementations of linear algebra algorithms
HouseholderQR.ipp
Go to the documentation of this file.
2 
3 #include <cassert>
4 #include <iomanip>
5 #include <iostream>
6 
7 void HouseholderQR::compute(Matrix &&matrix) {
8  RW = std::move(matrix);
9  R_diag.resize(RW.cols());
11 }
12 
13 void HouseholderQR::compute(const Matrix &matrix) {
14  RW = matrix;
15  R_diag.resize(RW.cols());
17 }
18 
20  Matrix result = B;
21  apply_QT_inplace(result);
22  return result;
23 }
24 
27  return std::move(B);
28 }
29 
31  Matrix result = X;
32  apply_Q_inplace(result);
33  return result;
34 }
35 
37  apply_Q_inplace(B);
38  return std::move(B);
39 }
40 
42  assert(is_factored());
43  assert(R.rows() == RW.rows());
44  assert(R.cols() == RW.cols());
45  for (size_t r = 0; r < R.cols(); ++r) {
46  for (size_t c = 0; c < r; ++c)
47  R(r, c) = 0;
48  R(r, r) = R_diag(r);
49  for (size_t c = r + 1; c < R.cols(); ++c)
50  R(r, c) = RW(r, c);
51  }
52  for (size_t r = R.cols(); r < R.rows(); ++r) {
53  for (size_t c = 0; c < R.cols(); ++c)
54  R(r, c) = 0;
55  }
56 }
57 
59  Matrix R(RW.rows(), RW.cols());
60  get_R_inplace(R);
61  return R;
62 }
63 
66  for (size_t r = 0; r < RW.cols(); ++r) {
67  for (size_t c = 0; c < r; ++c)
68  RW(r, c) = 0;
69  RW(r, r) = R_diag(r);
70  }
71  for (size_t r = RW.cols(); r < RW.rows(); ++r) {
72  for (size_t c = 0; c < RW.cols(); ++c)
73  RW(r, c) = 0;
74  }
75  return std::move(RW);
76 }
77 
79  assert(Q.rows() == RW.rows());
80  assert(Q.cols() == RW.rows());
81  Q.fill_identity();
82  apply_Q_inplace(Q);
83 }
84 
86  SquareMatrix Q(RW.rows());
87  get_Q_inplace(Q);
88  return Q;
89 }
90 
92  Matrix B_cpy = apply_QT(B);
93  Matrix X(RW.cols(), B.cols());
94  back_subs(B_cpy, X);
95  return X;
96 }
97 
99  solve_inplace(B);
100  return std::move(B);
101 }
102 
104  return Vector(solve(static_cast<const Matrix &>(b)));
105 }
106 
108  solve_inplace(b);
109  return std::move(b);
110 }
111 
112 // LCOV_EXCL_START
113 
114 std::ostream &operator<<(std::ostream &os, const HouseholderQR &qr) {
115  if (!qr.is_factored()) {
116  os << "Not factored." << std::endl;
117  return os;
118  }
119 
120  Matrix Q = qr.get_Q();
121  os << "Q = " << std::endl;
122  Q.print(os);
123 
124  // Output field width (characters)
125  int w = os.precision() + 9;
126 
127  const auto &RW = qr.get_RW();
128  const auto &R_diag = qr.get_R_diag();
129  os << "R = " << std::endl;
130  for (size_t r = 0; r < RW.cols(); ++r) {
131  for (size_t c = 0; c < r; ++c)
132  os << std::setw(w) << 0;
133  os << std::setw(w) << R_diag(r);
134  for (size_t c = r + 1; c < RW.cols(); ++c)
135  os << std::setw(w) << RW(r, c);
136  os << std::endl;
137  }
138  for (size_t r = RW.cols(); r < RW.rows(); ++r) {
139  for (size_t c = 0; c < RW.cols(); ++c)
140  os << std::setw(w) << 0;
141  }
142  return os;
143 }
144 
145 // LCOV_EXCL_STOP
QR factorization using Householder reflectors.
Vector R_diag
Contains the diagonal elements of R.
std::ostream & operator<<(std::ostream &os, const HouseholderQR &qr)
Print the Q and R matrices of a HouseholderQR object.
void apply_QT_inplace(Matrix &B) const
Compute the product QᵀB, overwriting B with the result.
void get_Q_inplace(SquareMatrix &Q) const
Compute the unitary matrix Q and copy it to the given matrix.
Matrix solve(const Matrix &B) const
Solve the system AX = B or QRX = B.
Matrix apply_Q(const Matrix &X) const
Compute the product QB.
Matrix get_R() const &
Get a copy of the upper-triangular matrix R.
const Vector & get_R_diag() const &
Get the internal storage of the diagonal elements of R.
Matrix && steal_R()
Get the upper-triangular matrix R, reusing the internal storage.
enum HouseholderQR::State state
void back_subs(const Matrix &B, Matrix &X) const
Back substitution algorithm for solving upper-triangular systems RX = B.
Matrix RW
Result of a Householder QR factorization: stores the strict upper-triangular part of matrix R and the...
Matrix apply_QT(const Matrix &B) const
Compute the product QᵀB.
void solve_inplace(Matrix &B) const
Solve the system AX = B or QRX = B.
bool is_factored() const
Check if this object contains a valid factorization.
void compute_factorization()
The actual QR factorization algorithm.
SquareMatrix get_Q() const
Compute the unitary matrix Q.
const Matrix & get_RW() const &
Get the internal storage of the strict upper-triangular part of R and the Householder reflector vecto...
void compute(Matrix &&matrix)
Perform the QR factorization of the given matrix.
void get_R_inplace(Matrix &R) const
Copy the upper-triangular matrix R to the given matrix.
void apply_Q_inplace(Matrix &X) const
Compute the product QB, overwriting B with the result.
General matrix class.
Definition: Matrix.hpp:25
size_t rows() const
Get the number of rows of the matrix.
Definition: Matrix.hpp:69
void fill_identity()
Fill the matrix as an identity matrix (all zeros except the diagonal which is one).
Definition: Matrix.cpp:125
size_t cols() const
Get the number of columns of the matrix.
Definition: Matrix.hpp:71
void print(std::ostream &os, uint8_t precision=0, uint8_t width=0) const
Print a matrix.
Definition: Matrix.cpp:232
Square matrix class.
Definition: Matrix.hpp:529
A column vector (n×1 matrix).
Definition: Matrix.hpp:241
void resize(size_t size)
Resize the vector.
Definition: Matrix.hpp:270