<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
hetd2.hpp
Go to the documentation of this file.
1
5//
6// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
7//
8// This file is part of <T>LAPACK.
9// <T>LAPACK is free software: you can redistribute it and/or modify it under
10// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
11
12#ifndef TLAPACK_HETD2_HH
13#define TLAPACK_HETD2_HH
14
16#include "tlapack/blas/axpy.hpp"
17#include "tlapack/blas/dot.hpp"
18#include "tlapack/blas/hemv.hpp"
19#include "tlapack/blas/her2.hpp"
21
22namespace tlapack {
23
46template <TLAPACK_SMATRIX A_t, TLAPACK_SVECTOR tau_t, class uplo_t>
48{
49 using T = type_t<A_t>;
50 using real_t = real_type<T>;
51 using idx_t = size_type<A_t>;
52 using pair = pair<idx_t, idx_t>;
53
54 // constants
55 const idx_t n = ncols(A);
56 const real_t one(1);
57 const real_t zero(0);
58 const real_t half(0.5);
59
60 // check arguments
61 tlapack_check_false(uplo != Uplo::Lower && uplo != Uplo::Upper);
62 tlapack_check(nrows(A) == ncols(A));
63 tlapack_check((idx_t)size(tau) >= n - 1);
64
65 // quick return
66 if (n <= 0) return 0;
67
68 if (uplo == Uplo::Upper) {
69 //
70 // Reduce upper triangle of A
71 //
72
73 // Only access real part of the main diagonal
74 A(n - 1, n - 1) = real(A(n - 1, n - 1));
75
76 for (idx_t i = n - 2; i != idx_t(-1); --i) {
77 // Define v := A[0:i,i+1]
78 auto v = slice(A, pair{0, i + 1}, i + 1);
79
80 // Generate elementary reflector H(i) = I - tau * v * v**T
81 // to annihilate A(0:i-1,i+1)
82 T taui;
84
85 if (taui != zero) {
86 // Apply H(i) from both sides to A(0:i, 0:i)
87 auto C = slice(A, pair{0, i + 1}, pair{0, i + 1});
88 auto w = slice(tau, pair{0, i + 1});
89
90 // Store the offdiagonal element
91 auto beta = A(i, i + 1);
92 A(i, i + 1) = one;
93
94 // Compute x:= taui * C * v storing x in w
96
97 // Compute w := w - (1/2) * tau * (w**H * v) * v
98 axpy(-half * taui * dot(w, v), v, w);
99
100 // Apply the transformation as a rank-2 update:
101 // C := C - v * w**H - w * v**H
102 her2(UPPER_TRIANGLE, -one, v, w, C);
103
104 // Reload the offdiagonal element
105 A(i, i + 1) = beta;
106 }
107 else {
108 // Only access real part of the main diagonal
109 A(i, i) = real(A(i, i));
110 }
111
112 tau[i] = taui;
113 }
114 }
115 else {
116 //
117 // Reduce lower triangle of A
118 //
119
120 // Only access real part of the main diagonal
121 A(0, 0) = real(A(0, 0));
122
123 for (idx_t i = 0; i < n - 1; ++i) {
124 // Define v := A[i+1:n,i]
125 auto v = slice(A, pair{i + 1, n}, i);
126
127 // Generate elementary reflector H(i) = I - tau * v * v**T
128 // to annihilate A(i+2:n,i)
129 T taui;
131
132 if (taui != zero) {
133 // Apply H(i) from both sides to A(i+1:n, i+1:n)
134 auto C = slice(A, pair{i + 1, n}, pair{i + 1, n});
135 auto w = slice(tau, pair{i, n - 1});
136
137 // Store the offdiagonal element
138 auto beta = A(i + 1, i);
139 A(i + 1, i) = one;
140
141 // Compute x:= taui * C * v storing x in w
143
144 // Compute w := w - (1/2) * tau * (w**H * v) * v
145 axpy(-half * taui * dot(w, v), v, w);
146
147 // Apply the transformation as a rank-2 update:
148 // C := C - v * w**H - w * v**H
149 her2(LOWER_TRIANGLE, -one, v, w, C);
150
151 // Reload the offdiagonal element
152 A(i + 1, i) = beta;
153 }
154 else {
155 // Only access real part of the main diagonal
156 A(i + 1, i + 1) = real(A(i + 1, i + 1));
157 }
158
159 tau[i] = taui;
160 }
161 }
162
163 return 0;
164}
165
166} // namespace tlapack
167
168#endif // TLAPACK_HETD2_HH
constexpr internal::LowerTriangle LOWER_TRIANGLE
Lower Triangle access.
Definition types.hpp:183
constexpr internal::UpperTriangle UPPER_TRIANGLE
Upper Triangle access.
Definition types.hpp:181
constexpr internal::Backward BACKWARD
Backward direction.
Definition types.hpp:378
constexpr internal::Forward FORWARD
Forward direction.
Definition types.hpp:376
constexpr internal::ColumnwiseStorage COLUMNWISE_STORAGE
Columnwise storage.
Definition types.hpp:409
constexpr real_type< T > real(const T &x) noexcept
Extends std::real() to real datatypes.
Definition utils.hpp:71
void larfg(storage_t storeMode, type_t< vector_t > &alpha, vector_t &x, type_t< vector_t > &tau)
Generates a elementary Householder reflection.
Definition larfg.hpp:73
auto dot(const vectorX_t &x, const vectorY_t &y)
Definition dot.hpp:32
void axpy(const alpha_t &alpha, const vectorX_t &x, vectorY_t &y)
Add scaled vector, .
Definition axpy.hpp:34
void her2(Uplo uplo, const alpha_t &alpha, const vectorX_t &x, const vectorY_t &y, matrixA_t &A)
Hermitian matrix rank-2 update:
Definition her2.hpp:50
void hemv(Uplo uplo, const alpha_t &alpha, const matrixA_t &A, const vectorX_t &x, const beta_t &beta, vectorY_t &y)
Hermitian matrix-vector multiply:
Definition hemv.hpp:53
int hetd2(uplo_t uplo, A_t &A, tau_t &tau)
Reduce a hermitian matrix to real symmetric tridiagonal form by a unitary similarity transformation: ...
Definition hetd2.hpp:47
#define tlapack_check(cond)
Throw an error if cond is false.
Definition exceptionHandling.hpp:98
#define tlapack_check_false(cond)
Throw an error if cond is true.
Definition exceptionHandling.hpp:113
typename traits::real_type_traits< Types..., int >::type real_type
The common real type of the list of types.
Definition scalar_type_traits.hpp:113