<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
ungq_level2.hpp
Go to the documentation of this file.
1
7//
8// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
9//
10// This file is part of <T>LAPACK.
11// <T>LAPACK is free software: you can redistribute it and/or modify it under
12// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
13
14#ifndef TLAPACK_UNGQ_LV2_HH
15#define TLAPACK_UNGQ_LV2_HH
16
18#include "tlapack/blas/scal.hpp"
21
22namespace tlapack {
23
46template <class T,
47 TLAPACK_SMATRIX matrix_t,
48 TLAPACK_SVECTOR vector_t,
49 TLAPACK_DIRECTION direction_t,
50 TLAPACK_STOREV storage_t>
53 const matrix_t& A,
54 const vector_t& tau)
55{
56 using idx_t = size_type<matrix_t>;
58
59 // Constants
60 const idx_t m = nrows(A);
61 const idx_t n = ncols(A);
62
63 if (storeMode == StoreV::Columnwise) {
64 return (n > 1)
66 col(A, 0), tau[0], cols(A, range{1, n}))
67 : WorkInfo(0);
68 }
69 else {
70 return (m > 1)
72 row(A, 0), tau[0], rows(A, range{1, m}))
73 : WorkInfo(0);
74 }
75}
76
85template <TLAPACK_SMATRIX matrix_t,
86 TLAPACK_SVECTOR vector_t,
87 TLAPACK_DIRECTION direction_t,
88 TLAPACK_STOREV storage_t,
89 TLAPACK_WORKSPACE work_t>
92 matrix_t& A,
93 const vector_t& tau,
94 work_t& work)
95{
96 using T = type_t<matrix_t>;
97 using real_t = real_type<T>;
98 using idx_t = size_type<matrix_t>;
100
101 // constants
102 const real_t zero(0);
103 const real_t one(1);
104 const idx_t m = nrows(A);
105 const idx_t n = ncols(A);
106 const idx_t k = size(tau);
107
108 // check arguments
109 tlapack_check_false(direction != Direction::Backward &&
110 direction != Direction::Forward);
111 tlapack_check((storeMode == StoreV::Columnwise) ? (m >= n && n >= k)
112 : (n >= m && m >= k));
113
114 // quick return
115 if (m <= 0 || n <= 0) return 0;
116
117 if (storeMode == StoreV::Columnwise) {
118 if (direction == Direction::Forward) {
119 // Initialize unit matrix
120 auto A0 = slice(A, range{0, k}, range{k, n});
121 auto A1 = slice(A, range{k, m}, range{k, n});
123 laset(GENERAL, zero, one, A1);
124
125 for (idx_t j = k - 1; j != idx_t(-1); --j) {
126 const T tauj = tau[j];
127
128 // Apply $H_{j+1}$ to $A( j:m, j+1:n )$ from the left
129 auto v = slice(A, range{j, m}, j);
130 auto C = slice(A, range{j, m}, range{j + 1, n});
132 work);
133
134 // Update column j
135 scal(-tauj, v);
136 A(j, j) = one - tauj;
137 for (idx_t i = 0; i < j; i++)
138 A(i, j) = zero;
139 }
140 }
141 else {
142 // Initialize unit matrix
143 auto A0 = slice(A, range{0, m - n}, range{0, n - k});
144 auto A1 = slice(A, range{m - n, m - k}, range{0, n - k});
145 auto A2 = slice(A, range{m - k, m}, range{0, n - k});
147 laset(GENERAL, zero, one, A1);
149
150 for (idx_t j = 0; j < k; ++j) {
151 const idx_t sizev = m - k + j + 1;
152 const idx_t jj = n - k + j;
153 const T tauj = tau[j];
154
155 // Apply $H_{j+1}$ to $A( 0:sizev, 0:jj )$ from the left
156 auto v = slice(A, range{0, sizev}, jj);
157 auto C = slice(A, range{0, sizev}, range{0, jj});
159 work);
160
161 // Update column jj
162 scal(-tauj, v);
163 A(sizev - 1, jj) = one - tauj;
164 for (idx_t i = sizev; i < m; i++)
165 A(i, jj) = zero;
166 }
167 }
168 }
169 else {
170 if (direction == Direction::Forward) {
171 // Initialize unit matrix
172 auto A0 = slice(A, range{k, m}, range{0, k});
173 auto A1 = slice(A, range{k, m}, range{k, n});
175 laset(GENERAL, zero, one, A1);
176
177 for (idx_t i = k - 1; i != idx_t(-1); --i) {
178 const T taui = conj(tau[i]);
179
180 // Apply $H_{i+1}$ to $A( i+1:m, i:n )$ from the right
181 auto v = slice(A, i, range{i, n});
182 auto C = slice(A, range{i + 1, m}, range{i, n});
184 work);
185
186 // Update row i
187 scal(-taui, v);
188 A(i, i) = one - taui;
189 for (idx_t j = 0; j < i; j++)
190 A(i, j) = zero;
191 }
192 }
193 else {
194 // Initialize unit matrix
195 auto A0 = slice(A, range{0, m - k}, range{0, n - m});
196 auto A1 = slice(A, range{0, m - k}, range{n - m, n - k});
197 auto A2 = slice(A, range{0, m - k}, range{n - k, n});
199 laset(GENERAL, zero, one, A1);
201
202 for (idx_t i = 0; i < k; ++i) {
203 const idx_t sizev = n - k + i + 1;
204 const idx_t ii = m - k + i;
205 const T taui = conj(tau[i]);
206
207 // Apply $H_{i+1}$ to $A( 0:jj, 0:sizev )$ from the right
208 auto v = slice(A, ii, range{0, sizev});
209 auto C = slice(A, range{0, ii}, range{0, sizev});
211 work);
212
213 // Update row ii
214 scal(-taui, v);
215 A(ii, sizev - 1) = one - taui;
216 for (idx_t j = sizev; j < n; j++)
217 A(ii, j) = zero;
218 }
219 }
220 }
221
222 return 0;
223}
224
285template <TLAPACK_SMATRIX matrix_t,
286 TLAPACK_SVECTOR vector_t,
287 TLAPACK_DIRECTION direction_t,
288 TLAPACK_STOREV storage_t>
291 matrix_t& A,
292 const vector_t& tau)
293{
294 using T = type_t<matrix_t>;
295 using idx_t = size_type<matrix_t>;
296
297 // Functor
299
300 // constants
301 const idx_t m = nrows(A);
302 const idx_t n = ncols(A);
303
304 // quick return
305 if (m <= 0 || n <= 0) return 0;
306
307 // Allocates workspace
309 std::vector<T> work_;
310 auto work = new_matrix(work_, workinfo.m, workinfo.n);
311
312 return ungq_level2_work(direction, storeMode, A, tau, work);
313}
314
315} // namespace tlapack
316
317#endif // TLAPACK_UNGQ_LV2_HH
constexpr internal::Backward BACKWARD
Backward direction.
Definition types.hpp:378
constexpr internal::RightSide RIGHT_SIDE
right side
Definition types.hpp:291
constexpr internal::RowwiseStorage ROWWISE_STORAGE
Rowwise storage.
Definition types.hpp:411
constexpr internal::Forward FORWARD
Forward direction.
Definition types.hpp:376
constexpr internal::GeneralAccess GENERAL
General access.
Definition types.hpp:175
constexpr internal::ColumnwiseStorage COLUMNWISE_STORAGE
Columnwise storage.
Definition types.hpp:409
constexpr internal::LeftSide LEFT_SIDE
left side
Definition types.hpp:289
constexpr T conj(const T &x) noexcept
Extends std::conj() to real datatypes.
Definition utils.hpp:100
#define TLAPACK_SVECTOR
Macro for tlapack::concepts::SliceableVector compatible with C++17.
Definition concepts.hpp:909
#define TLAPACK_STOREV
Macro for tlapack::concepts::StoreV compatible with C++17.
Definition concepts.hpp:936
#define TLAPACK_SMATRIX
Macro for tlapack::concepts::SliceableMatrix compatible with C++17.
Definition concepts.hpp:899
#define TLAPACK_DIRECTION
Macro for tlapack::concepts::Direction compatible with C++17.
Definition concepts.hpp:930
#define TLAPACK_WORKSPACE
Macro for tlapack::concepts::Workspace compatible with C++17.
Definition concepts.hpp:912
int ungq_level2(direction_t direction, storage_t storeMode, matrix_t &A, const vector_t &tau)
Generates a matrix Q that is the product of elementary reflectors.
Definition ungq_level2.hpp:289
void laset(uplo_t uplo, const type_t< matrix_t > &alpha, const type_t< matrix_t > &beta, matrix_t &A)
Initializes a matrix to diagonal and off-diagonal values.
Definition laset.hpp:38
void larf_work(side_t side, storage_t storeMode, vector_t const &x, const tau_t &tau, vectorC0_t &C0, matrixC1_t &C1, work_t &work)
Applies an elementary reflector defined by tau and v to a m-by-n matrix C decomposed into C0 and C1....
Definition larf.hpp:48
void scal(const alpha_t &alpha, vector_t &x)
Scale vector by constant, .
Definition scal.hpp:30
int ungq_level2_work(direction_t direction, storage_t storeMode, matrix_t &A, const vector_t &tau, work_t &work)
Generates a matrix Q that is the product of elementary reflectors. Workspace is provided as an argu...
Definition ungq_level2.hpp:90
#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
constexpr WorkInfo ungq_level2_worksize(direction_t direction, storage_t storeMode, const matrix_t &A, const vector_t &tau)
Worspace query of ungq_level2()
Definition ungq_level2.hpp:51
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
Output information in the workspace query.
Definition workspace.hpp:16