consteig
Compile-time eigenvalue and eigenvector computation for C++17
Loading...
Searching...
No Matches
householder.hpp
1#ifndef HOUSEHOLDER_HPP
2#define HOUSEHOLDER_HPP
3
4#include "../../math/constmath.hpp"
5#include "../matrix.hpp"
6#include "../operations.hpp"
7
8namespace consteig
9{
10
13
30template <typename T, Size R, Size C>
32
33// Algorithm: Householder Reflection
34// Computes a Householder reflector H = I - 2*v*v^T such that H*x = alpha*e1,
35// where x is the first column of the input matrix (below the diagonal), e1 is
36// the first standard basis vector, and alpha = -sign(x[1]) * ||x[1:]||_2.
37//
38// This zeros out all subdiagonal entries of the first column, which is used
39// repeatedly by hessenberg reduction and QR decomposition.
40//
41// The reflector vector v is computed as:
42// alpha = -sign(x[1]) * ||x[1:]||
43// r = sqrt(0.5 * (alpha^2 - x[1]*alpha))
44// v[1] = (x[1] - alpha) / (2r)
45// v[i] = x[i] / (2r) for i > 1
46//
47// Reference: Golub & Van Loan, "Matrix Computations" (4th ed.), sec. 5
48// See also:
49// https://pages.mtu.edu/~struther/Courses/OLD/Other/Sp2012/5627/BlockQR/Work/MA5629%20presentation.pdf
51template <typename T, Size R, Size C>
53{
54 static_assert(R == C, "Householder expects a square matrix");
55 static_assert(is_float<T>(),
56 "Householder Reflection expects floating point");
57
58 // Compute ||x[1:]||^2 (sum of squares of subdiagonal entries)
59 T alphaSum{0};
60 for (Size row{1}; row < R; row++)
61 {
62 alphaSum += (a(row, 0) * a(row, 0));
63 }
64
65 // If the subdiagonal is already zero, no reflection needed
67 {
68 return eye<T, R>();
69 }
70
71 // alpha = -sign(x[1]) * ||x[1:]||
72 T sign =
73 (a(1, 0) < static_cast<T>(0)) ? static_cast<T>(-1) : static_cast<T>(1);
74 T alpha{static_cast<T>(-1) * sign * sqrt(alphaSum)};
75
76 // r = sqrt(0.5 * (alpha^2 - x[1]*alpha)), the normalization factor for v
77 T r_sq{static_cast<T>(0.5) * ((alpha * alpha) - (a(1, 0) * alpha))};
78
80 {
81 return eye<T, R>();
82 }
83
84 T r = sqrt(r_sq);
85 T oneOverTwoR{1 / (static_cast<T>(2) * r)};
86
87 // Build the reflector vector v
88 Matrix<T, R, 1> v{}; // Zero init
89 for (Size row = 0; row < R; ++row)
90 {
91 v(row, 0) = 0;
92 }
93
94 v(1, 0) = (a(1, 0) - alpha) * oneOverTwoR;
95 for (Size row{2}; row < R; row++)
96 {
97 v(row, 0) = a(row, 0) * oneOverTwoR;
98 }
99
100 // H = I - 2*v*v^T
101 Matrix<T, R, R> p = eye<T, R>() - (static_cast<T>(2) * v * transpose(v));
102
103 return p;
104}
105
106template <typename T> constexpr Matrix<T, 2, 2> house(Matrix<T, 2, 2> /*a*/)
107{
109 ident(1, 1) = ident(1, 1) * static_cast<T>(-1);
110 return ident;
111}
112
114
115} // namespace consteig
116#endif
Fixed-size matrix with compile-time dimensions.
Definition matrix.hpp:56
constexpr Matrix< T, R, R > house(Matrix< T, R, C > a)
Compute a Householder reflector for a square matrix.
Definition householder.hpp:52
constexpr T sqrt(const T x)
Constexpr square root.
Definition sqrt.hpp:67
constexpr T abs(const T x)
Absolute value of a real number.
Definition abs.hpp:17
constexpr T epsilon()
Machine epsilon for type T.
Definition utilities.hpp:82
constexpr Matrix< T, C, R > transpose(const Matrix< T, R, C > &mat)
Matrix transpose.
Definition operations.hpp:154