numerics 0.1.0
Loading...
Searching...
No Matches
qr.cpp
Go to the documentation of this file.
1/// @file linalg/factorization/backends/seq/qr.cpp
2/// @brief Sequential Householder QR factorization.
3///
4/// See linalg/factorization/qr.cpp for the full algorithm commentary.
5#include "impl.hpp"
6#include <cmath>
7#include <vector>
8
9namespace num::backends::seq {
10
11QRResult qr(const Matrix& A) {
12 constexpr real householder_tol = 1e-14;
13 const idx m = A.rows();
14 const idx n = A.cols();
15 const idx r = (m > n) ? n : m - 1;
16
17 Matrix R = A;
18
19 std::vector<std::vector<real>> vs(r);
20
21 for (idx k = 0; k < r; ++k) {
22 const idx len = m - k;
23
24 std::vector<real> x(len);
25 for (idx i = 0; i < len; ++i)
26 x[i] = R(k + i, k);
27
28 real norm_x = real(0);
29 for (idx i = 0; i < len; ++i)
30 norm_x += x[i] * x[i];
31 norm_x = std::sqrt(norm_x);
32
33 std::vector<real> v = x;
34 v[0] += (x[0] >= real(0)) ? norm_x : -norm_x;
35
36 real norm_v = real(0);
37 for (idx i = 0; i < len; ++i)
38 norm_v += v[i] * v[i];
39 norm_v = std::sqrt(norm_v);
40
41 if (norm_v < householder_tol) {
42 vs[k].assign(len, real(0));
43 continue;
44 }
45 for (idx i = 0; i < len; ++i)
46 v[i] /= norm_v;
47 vs[k] = v;
48
49 for (idx j = k; j < n; ++j) {
50 real vTr = real(0);
51 for (idx i = 0; i < len; ++i)
52 vTr += v[i] * R(k + i, j);
53 const real two_vTr = real(2) * vTr;
54 for (idx i = 0; i < len; ++i)
55 R(k + i, j) -= two_vTr * v[i];
56 }
57 }
58
59 Matrix Q(m, m, real(0));
60 for (idx i = 0; i < m; ++i)
61 Q(i, i) = real(1);
62
63 for (idx k = r; k-- > 0;) {
64 const std::vector<real>& v = vs[k];
65 const idx len = static_cast<idx>(v.size());
66
67 for (idx j = k; j < m; ++j) {
68 real vTq = real(0);
69 for (idx i = 0; i < len; ++i)
70 vTq += v[i] * Q(k + i, j);
71 const real two_vTq = real(2) * vTq;
72 for (idx i = 0; i < len; ++i)
73 Q(k + i, j) -= two_vTq * v[i];
74 }
75 }
76
77 for (idx i = 1; i < m; ++i)
78 for (idx j = 0; j < std::min(i, n); ++j)
79 R(i, j) = real(0);
80
81 return {std::move(Q), std::move(R)};
82}
83
84} // namespace num::backends::seq
Dense row-major matrix with optional GPU storage.
Definition matrix.hpp:12
constexpr idx rows() const noexcept
Definition matrix.hpp:24
constexpr idx cols() const noexcept
Definition matrix.hpp:25
QRResult qr(const Matrix &A)
Definition qr.cpp:11
double real
Definition types.hpp:10
std::size_t idx
Definition types.hpp:11
constexpr real e
Definition math.hpp:43
std::experimental::simd butterfly for FFT.
Result of a QR factorization: A = Q * R.
Definition qr.hpp:18