<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
ungbr.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_UNGBR_HH
13#define TLAPACK_UNGBR_HH
14
17
18namespace tlapack {
19
23struct UngbrOpts {
24 size_t nb = 32;
25};
26
47template <class T, TLAPACK_SMATRIX matrix_t, TLAPACK_SVECTOR vector_t>
49 matrix_t& A,
50 const vector_t& tau,
51 const UngbrOpts& opts = {})
52{
53 using idx_t = size_type<matrix_t>;
54 using range = pair<idx_t, idx_t>;
55
56 // constants
57 const idx_t m = nrows(A);
58
59 if (m >= k) {
60 return ungq_worksize<T>(FORWARD, COLUMNWISE_STORAGE, A, tau,
61 UngqOpts{opts.nb});
62 }
63 else {
64 auto&& A2 = slice(A, range{0, m - 1}, range{0, m - 1});
65 auto&& tau2 = slice(tau, range{0, m - 1});
66 return ungq_worksize<T>(FORWARD, COLUMNWISE_STORAGE, A2, tau2,
67 UngqOpts{opts.nb});
68 }
69}
70
91template <class T, TLAPACK_SMATRIX matrix_t, TLAPACK_SVECTOR vector_t>
93 matrix_t& A,
94 const vector_t& tau,
95 const UngbrOpts& opts = {})
96{
97 using idx_t = size_type<matrix_t>;
98 using range = pair<idx_t, idx_t>;
99
100 // constants
101 const idx_t n = ncols(A);
102
103 if (n <= k) {
104 auto&& A2 = slice(A, range{0, n - 1}, range{0, n - 1});
105 auto&& tau2 = slice(tau, range{0, n - 1});
106 return ungq_worksize<T>(FORWARD, ROWWISE_STORAGE, A2, tau2,
107 UngqOpts{opts.nb});
108 }
109 else {
110 return ungq_worksize<T>(FORWARD, ROWWISE_STORAGE, A, tau,
111 UngqOpts{opts.nb});
112 }
113}
114
123template <TLAPACK_SMATRIX matrix_t,
124 TLAPACK_SVECTOR vector_t,
125 TLAPACK_WORKSPACE work_t>
127 matrix_t& A,
128 const vector_t& tau,
129 work_t& work,
130 const UngbrOpts& opts = {})
131{
132 using T = type_t<matrix_t>;
133 using real_t = real_type<T>;
134 using idx_t = size_type<matrix_t>;
135 using range = pair<idx_t, idx_t>;
136
137 // constants
138 const real_t zero(0);
139 const real_t one(1);
140 const idx_t m = nrows(A);
141
142 if (m >= k) {
143 // If m >= k, assume m >= n >= k
144 ungq_work(FORWARD, COLUMNWISE_STORAGE, A, tau, work, UngqOpts{opts.nb});
145 }
146 else {
147 // Shift the vectors which define the elementary reflectors one
148 // column to the right, and set the first row and column of Q
149 // to those of the unit matrix
150 for (idx_t j = m - 1; j > 0; --j) {
151 A(0, j) = zero;
152 for (idx_t i = j + 1; i < m; ++i)
153 A(i, j) = A(i, j - 1);
154 }
155 A(0, 0) = one;
156 for (idx_t i = 1; i < m; ++i)
157 A(i, 0) = zero;
158 if (m > 1) {
159 // Form Q(1:m,1:m)
160 auto A2 = slice(A, range{1, m}, range{1, m});
161 auto tau2 = slice(tau, range{0, m - 1});
162 ungq_work(FORWARD, COLUMNWISE_STORAGE, A2, tau2, work,
163 UngqOpts{opts.nb});
164 }
165 }
166
167 return 0;
168}
169
200template <TLAPACK_SMATRIX matrix_t, TLAPACK_SVECTOR vector_t>
202 matrix_t& A,
203 const vector_t& tau,
204 const UngbrOpts& opts = {})
205{
206 using work_t = matrix_type<matrix_t, vector_t>;
207 using T = type_t<work_t>;
208
209 // Functor
210 Create<work_t> new_matrix;
211
212 // Allocates workspace
213 WorkInfo workinfo = ungbr_q_worksize<T>(k, A, tau, opts);
214 std::vector<T> work_;
215 auto work = new_matrix(work_, workinfo.m, workinfo.n);
216
217 return ungbr_q_work(k, A, tau, work, opts);
218}
219
228template <TLAPACK_SMATRIX matrix_t,
229 TLAPACK_SVECTOR vector_t,
230 TLAPACK_WORKSPACE work_t>
232 matrix_t& A,
233 const vector_t& tau,
234 work_t& work,
235 const UngbrOpts& opts = {})
236{
237 using T = type_t<matrix_t>;
238 using real_t = real_type<T>;
239 using idx_t = size_type<matrix_t>;
240 using range = pair<idx_t, idx_t>;
241
242 // constants
243 const real_t zero(0);
244 const real_t one(1);
245 const idx_t n = ncols(A);
246
247 //
248 // Form P**H, determined by a call to gebrd to reduce a k-by-n
249 // matrix
250 //
251 if (k < n) {
252 // If m >= k, assume m >= n >= k
253 ungq_work(FORWARD, ROWWISE_STORAGE, A, tau, work, UngqOpts{opts.nb});
254 }
255 else {
256 // Shift the vectors which define the elementary reflectors one
257 // row downward, and set the first row and column of P**H to
258 // those of the unit matrix
259 A(0, 0) = one;
260 for (idx_t i = 1; i < n; ++i) {
261 A(i, 0) = zero;
262 }
263 for (idx_t j = 1; j < n; ++j) {
264 for (idx_t i = j - 1; i > 0; --i) {
265 A(i, j) = A(i - 1, j);
266 }
267 A(0, j) = zero;
268 }
269 if (n > 1) {
270 auto A2 = slice(A, range{1, n}, range{1, n});
271 auto tau2 = slice(tau, range{0, n - 1});
272 ungq_work(FORWARD, ROWWISE_STORAGE, A2, tau2, work,
273 UngqOpts{opts.nb});
274 }
275 }
276
277 return 0;
278}
279
310template <TLAPACK_SMATRIX matrix_t, TLAPACK_SVECTOR vector_t>
312 matrix_t& A,
313 const vector_t& tau,
314 const UngbrOpts& opts = {})
315{
316 using work_t = matrix_type<matrix_t, vector_t>;
317 using T = type_t<work_t>;
318
319 // Functor
320 Create<work_t> new_matrix;
321
322 // Allocates workspace
323 WorkInfo workinfo = ungbr_p_worksize<T>(k, A, tau, opts);
324 std::vector<T> work_;
325 auto work = new_matrix(work_, workinfo.m, workinfo.n);
326
327 return ungbr_p_work(k, A, tau, work, opts);
328}
329
330} // namespace tlapack
331
332#endif // TLAPACK_UNGBR_HH
#define TLAPACK_SVECTOR
Macro for tlapack::concepts::SliceableVector compatible with C++17.
Definition concepts.hpp:909
#define TLAPACK_SMATRIX
Macro for tlapack::concepts::SliceableMatrix compatible with C++17.
Definition concepts.hpp:899
#define TLAPACK_WORKSPACE
Macro for tlapack::concepts::Workspace compatible with C++17.
Definition concepts.hpp:912
int ungbr_q(const size_type< matrix_t > k, matrix_t &A, const vector_t &tau, const UngbrOpts &opts={})
Generates the unitary matrix Q determined by gebrd when reducing a matrix A to bidiagonal form: A = Q...
Definition ungbr.hpp:201
int ungbr_p(const size_type< matrix_t > k, matrix_t &A, const vector_t &tau, const UngbrOpts &opts={})
Generates the unitary matrix P**H determined by gebrd when reducing a matrix A to bidiagonal form: A ...
Definition ungbr.hpp:311
int ungbr_p_work(const size_type< matrix_t > k, matrix_t &A, const vector_t &tau, work_t &work, const UngbrOpts &opts={})
Generates the unitary matrix P**H determined by gebrd when reducing a matrix A to bidiagonal form: A ...
Definition ungbr.hpp:231
int ungq_work(direction_t direction, storage_t storeMode, matrix_t &A, const vector_t &tau, work_t &work, const UngqOpts &opts={})
Generates a matrix Q that is the product of elementary reflectors. Workspace is provided as an argu...
Definition ungq.hpp:138
int ungbr_q_work(const size_type< matrix_t > k, matrix_t &A, const vector_t &tau, work_t &work, const UngbrOpts &opts={})
Generates the unitary matrix Q determined by gebrd when reducing a matrix A to bidiagonal form: A = Q...
Definition ungbr.hpp:126
constexpr WorkInfo ungbr_p_worksize(const size_type< matrix_t > k, matrix_t &A, const vector_t &tau, const UngbrOpts &opts={})
Worspace query of ungbr_p()
Definition ungbr.hpp:92
constexpr WorkInfo ungbr_q_worksize(const size_type< matrix_t > k, matrix_t &A, const vector_t &tau, const UngbrOpts &opts={})
Worspace query of ungbr_q()
Definition ungbr.hpp:48
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
Options struct for ungbr.
Definition ungbr.hpp:23
size_t nb
Block size.
Definition ungbr.hpp:24
Output information in the workspace query.
Definition workspace.hpp:16