12 constexpr real householder_tol = 1
e-14;
15 const idx r = (m > n) ? n : m - 1;
19 std::vector<std::vector<real>> vs(r);
21 for (
idx k = 0; k < r; ++k) {
22 const idx len = m - k;
24 std::vector<real> x(len);
25 for (
idx i = 0; i < len; ++i)
29 for (
idx i = 0; i < len; ++i)
30 norm_x += x[i] * x[i];
31 norm_x = std::sqrt(norm_x);
33 std::vector<real> v = x;
34 v[0] += (x[0] >=
real(0)) ? norm_x : -norm_x;
37 for (
idx i = 0; i < len; ++i)
38 norm_v += v[i] * v[i];
39 norm_v = std::sqrt(norm_v);
41 if (norm_v < householder_tol) {
42 vs[k].assign(len,
real(0));
45 for (
idx i = 0; i < len; ++i)
49 for (
idx j = k; j < n; ++j) {
51 for (
idx i = 0; i < len; ++i)
52 vTr += v[i] * R(k + i, j);
54 for (
idx i = 0; i < len; ++i)
55 R(k + i, j) -= two_vTr * v[i];
60 for (
idx i = 0; i < m; ++i)
63 for (
idx k = r; k-- > 0;) {
64 const std::vector<real>& v = vs[k];
65 const idx len =
static_cast<idx>(v.size());
67 for (
idx j = k; j < m; ++j) {
69 for (
idx i = 0; i < len; ++i)
70 vTq += v[i] * Q(k + i, j);
72 for (
idx i = 0; i < len; ++i)
73 Q(k + i, j) -= two_vTq * v[i];
77 for (
idx i = 1; i < m; ++i)
78 for (
idx j = 0; j < std::min(i, n); ++j)
81 return {std::move(Q), std::move(R)};