akreon-linalg
Fixed-size linear algebra and numerical methods in C++26.
Loading...
Searching...
No Matches
hessenberg.hpp
Go to the documentation of this file.
1/*
2 * Copyright © 2025-2026 Akreon LLC
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#pragma once
7
8#include "endomorphism.hpp"
10
11namespace linalg {
20template <SquareMatrix Mat>
21struct Hessenberg : Endomorphism<Mat, Hessenberg<Mat>> {
25
27 using OperatorBase::N;
28
34 constexpr explicit Hessenberg(const Mat& A) {
35 H_pack = A;
36 constexpr_for<0, N - 2>([&]<std::size_t k>(
37 std::integral_constant<std::size_t, k>) {
38 const auto& H_block = get_n_rows<k + 1, N>(H_pack);
39 const auto& H_col = get_col(H_block, k);
40 // Reflect the column tail onto its first subdiagonal entry.
41 const auto h = HouseholderVector(H_col);
42
43 const auto& v = as_col_vector(h.v);
44 beta(k) = h.beta;
45
46 if (beta(k) == real_type_t<T>(0)) return;
47
48 // Left update: H <- (I - beta*v*v^*) H on the active rows.
50 if constexpr (Complex<T>)
53 else H_block_kn = H_block_kn - (beta(k) * v * transpose(v)) * H_block_kn;
54
55 for (std::size_t i = k + 1, a = 0; i < N; ++i, ++a)
56 for (std::size_t j = k, b = 0; j < N; ++j, ++b)
57 H_pack(i, j) = H_block_kn(a, b);
58
59 // Right update: H <- H (I - beta*v*v^*) completes the similarity.
61 if constexpr (Complex<T>)
63 else H_zn_kn = H_zn_kn - H_zn_kn * (beta(k) * v * transpose(v));
64
65 for (std::size_t i = 0, a = 0; i < N; ++i, ++a)
66 for (std::size_t j = k + 1, b = 0; j < N; ++j, ++b)
67 H_pack(i, j) = H_zn_kn(a, b);
68
69 // Pack reflector tails below the band; H() restores these zeros.
70 for (std::size_t j = k + 2, a = 1; j < N; ++j, ++a)
71 H_pack(j, k) = v(a, 0);
72 });
73 }
74
80 constexpr auto H() const {
82 for (std::size_t i = 0; i < N; ++i) {
83 for (std::size_t j = 0; j < N; ++j) {
84 if (i >= 2 && j <= (i - 2)) continue;
85 res(i, j) = H_pack(i, j);
86 }
87 }
88 return res;
89 }
90
96 constexpr auto U() const {
97 auto U = make_identity<T, N>();
98 constexpr_for<0, N - 2>([&]<std::size_t k>(
99 std::integral_constant<std::size_t, k>) {
100 const std::size_t j = N - k - 1;
101 Vector<T, j> v;
102 v(0) = T(1);
103 for (std::size_t i = k + 2, a = 1; i < N; ++i, ++a) v(a) = H_pack(i, k);
104
105 const auto& v_col = as_col_vector(v);
106
107 // Accumulate the same column-space changes used in the reduction.
109 if constexpr (Complex<T>)
110 U_block = U_block -
112 else U_block = U_block - beta(k) * (U_block * (v_col * transpose(v_col)));
113
114 for (std::size_t r = 0; r < N; ++r)
115 for (std::size_t c = k + 1, a = 0; c < N; ++c, ++a)
116 U(r, c) = U_block(r, a);
117 });
118 return U;
119 }
120
128 constexpr auto operator()(std::size_t i, std::size_t j) const {
129 if (i >= 2 && j <= (i - 2)) return T(0);
130 return H_pack(i, j);
131 }
132
135private:
137 H_pack;
138};
139
140} // namespace linalg
Field classified by scalar_traits as complex.
typename scalar_traits_t< T >::real_type real_type_t
Associated real component type registered for T.
constexpr auto conjugate_transpose(const Mat &A)
conjugate transpose of a matrix
constexpr void constexpr_for(Func &&f)
constexpr for loop which recursively unrolls a dynamic for loop into compile time recursive loop
constexpr auto transpose(const Vec &x)
tranpose of a vector
constexpr std::size_t mat_rows_v
Registered compile-time row count after cv/ref normalization.
constexpr auto get_col(const Mat &A, std::size_t idx)
get the column of matrix A based on given index
constexpr auto as_col_vector(const Vec &X)
express the vector X as a column vector (N x 1)
Endomorphism operator CRTP base.
matrix_scalar_t< Mat > T
alias helpers for types
static constexpr std::size_t N
helper to extract N
Reduces A to upper Hessenberg form H = U^* A U.
constexpr auto U() const
Reconstruct the orthogonal or unitary similarity basis.
constexpr Hessenberg(const Mat &A)
Reduce A by two-sided Householder similarities.
Vector< T, N > beta
Vector member variables.
constexpr auto operator()(std::size_t i, std::size_t j) const
Read an entry of the Hessenberg matrix.
constexpr auto H() const
Extract the upper Hessenberg matrix.
Compact representation of a real or complex Householder reflector.
Owning, fixed-size, row-major matrix container over a scalar field.
Definition matrix.hpp:44
Owning, fixed-size vector container.
Definition vector.hpp:36