<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
unmq_level2.hpp
Go to the documentation of this file.
1
6//
7// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
8//
9// This file is part of <T>LAPACK.
10// <T>LAPACK is free software: you can redistribute it and/or modify it under
11// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
12
13#ifndef TLAPACK_UNMQ_LV2_HH
14#define TLAPACK_UNMQ_LV2_HH
15
18
19namespace tlapack {
20
61template <class T,
62 TLAPACK_SMATRIX matrixV_t,
63 TLAPACK_SMATRIX matrixC_t,
64 TLAPACK_VECTOR vector_t,
65 TLAPACK_SIDE side_t,
66 TLAPACK_OP trans_t,
67 TLAPACK_DIRECTION direction_t,
68 TLAPACK_STOREV storage_t>
71 direction_t direction,
73 const matrixV_t& V,
74 const vector_t& tau,
75 const matrixC_t& C)
76{
77 using idx_t = size_type<matrixC_t>;
79
80 // Constants
81 const idx_t m = nrows(C);
82 const idx_t n = ncols(C);
83 const idx_t nQ = (side == Side::Left) ? m : n;
84
85 if (storeMode == StoreV::Columnwise)
86 return larf_worksize<T>(side, direction, storeMode,
87 slice(V, range{0, nQ}, 0), tau[0], C);
88 else
89 return larf_worksize<T>(side, direction, storeMode,
90 slice(V, 0, range{0, nQ}), tau[0], C);
91}
92
101template <TLAPACK_SMATRIX matrixV_t,
102 TLAPACK_SMATRIX matrixC_t,
103 TLAPACK_VECTOR vector_t,
104 TLAPACK_SIDE side_t,
105 TLAPACK_OP trans_t,
106 TLAPACK_DIRECTION direction_t,
107 TLAPACK_STOREV storage_t,
108 TLAPACK_WORKSPACE work_t>
111 direction_t direction,
113 const matrixV_t& V,
114 const vector_t& tau,
115 matrixC_t& C,
116 work_t& work)
117{
118 using idx_t = size_type<matrixC_t>;
120
121 // constants
122 const idx_t m = nrows(C);
123 const idx_t n = ncols(C);
124 const idx_t k = size(tau);
125 const idx_t nQ = (side == Side::Left) ? m : n;
126
127 // check arguments
128 tlapack_check_false(side != Side::Left && side != Side::Right);
130 trans != Op::NoTrans && trans != Op::ConjTrans &&
131 ((trans != Op::Trans) || is_complex<type_t<matrixV_t>>));
132 tlapack_check_false(direction != Direction::Backward &&
133 direction != Direction::Forward);
134 tlapack_check((storeMode == StoreV::Columnwise)
135 ? ((ncols(V) == k) && (nrows(V) == nQ))
136 : ((nrows(V) == k) && (ncols(V) == nQ)));
137
138 // quick return
139 if (m <= 0 || n <= 0 || k <= 0) return 0;
140
141 // const expressions
142 const bool positiveIncLeft =
143 (storeMode == StoreV::Columnwise)
144 ? ((direction == Direction::Backward) ? (trans == Op::NoTrans)
145 : (trans != Op::NoTrans))
146 : ((direction == Direction::Forward) ? (trans == Op::NoTrans)
147 : (trans != Op::NoTrans));
148 const bool positiveInc =
149 (side == Side::Left) ? positiveIncLeft : !positiveIncLeft;
150 const idx_t i0 = (positiveInc) ? 0 : k - 1;
151 const idx_t iN = (positiveInc) ? k : -1;
152 const idx_t inc = (positiveInc) ? 1 : -1;
153
154 if (storeMode == StoreV::Columnwise) {
155 if (side == Side::Left) {
156 for (idx_t i = i0; i != iN; i += inc) {
157 const auto rangev = (direction == Direction::Forward)
158 ? range{i, nQ}
159 : range{0, nQ - k + i + 1};
160 const auto v = slice(V, rangev, i);
161 auto Ci = rows(C, rangev);
163 (trans == Op::ConjTrans) ? conj(tau[i]) : tau[i], Ci,
164 work);
165 }
166 }
167 else {
168 for (idx_t i = i0; i != iN; i += inc) {
169 const auto rangev = (direction == Direction::Forward)
170 ? range{i, nQ}
171 : range{0, nQ - k + i + 1};
172 const auto v = slice(V, rangev, i);
173 auto Ci = cols(C, rangev);
175 (trans == Op::ConjTrans) ? conj(tau[i]) : tau[i], Ci,
176 work);
177 }
178 }
179 }
180 else {
181 if (side == Side::Left) {
182 for (idx_t i = i0; i != iN; i += inc) {
183 const auto rangev = (direction == Direction::Forward)
184 ? range{i, nQ}
185 : range{0, nQ - k + i + 1};
186 const auto v = slice(V, i, rangev);
187 auto Ci = rows(C, rangev);
189 (trans == Op::NoTrans) ? conj(tau[i]) : tau[i], Ci,
190 work);
191 }
192 }
193 else {
194 for (idx_t i = i0; i != iN; i += inc) {
195 const auto rangev = (direction == Direction::Forward)
196 ? range{i, nQ}
197 : range{0, nQ - k + i + 1};
198 const auto v = slice(V, i, rangev);
199 auto Ci = cols(C, rangev);
201 (trans == Op::NoTrans) ? conj(tau[i]) : tau[i], Ci,
202 work);
203 }
204 }
205 }
206
207 return 0;
208}
209
301template <TLAPACK_SMATRIX matrixV_t,
302 TLAPACK_SMATRIX matrixC_t,
303 TLAPACK_VECTOR vector_t,
304 TLAPACK_SIDE side_t,
305 TLAPACK_OP trans_t,
306 TLAPACK_DIRECTION direction_t,
307 TLAPACK_STOREV storage_t>
310 direction_t direction,
312 const matrixV_t& V,
313 const vector_t& tau,
314 matrixC_t& C)
315{
316 using idx_t = size_type<matrixC_t>;
318 using T = type_t<work_t>;
319
320 // Functor
322
323 // constants
324 const idx_t m = nrows(C);
325 const idx_t n = ncols(C);
326 const idx_t k = size(tau);
327
328 // quick return
329 if ((m <= 0) || (n <= 0) || (k <= 0)) return 0;
330
331 // Allocates workspace
334 std::vector<T> work_;
335 auto work = new_matrix(work_, workinfo.m, workinfo.n);
336
337 return unmq_level2_work(side, trans, direction, storeMode, V, tau, C, work);
338}
339
340} // namespace tlapack
341
342#endif // TLAPACK_UNMQ_LV2_HH
constexpr internal::RightSide RIGHT_SIDE
right side
Definition types.hpp:291
constexpr internal::RowwiseStorage ROWWISE_STORAGE
Rowwise storage.
Definition types.hpp:411
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_STOREV
Macro for tlapack::concepts::StoreV compatible with C++17.
Definition concepts.hpp:936
#define TLAPACK_SIDE
Macro for tlapack::concepts::Side compatible with C++17.
Definition concepts.hpp:927
#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_OP
Macro for tlapack::concepts::Op compatible with C++17.
Definition concepts.hpp:933
#define TLAPACK_WORKSPACE
Macro for tlapack::concepts::Workspace compatible with C++17.
Definition concepts.hpp:912
#define TLAPACK_VECTOR
Macro for tlapack::concepts::Vector compatible with C++17.
Definition concepts.hpp:906
int unmq_level2(side_t side, trans_t trans, direction_t direction, storage_t storeMode, const matrixV_t &V, const vector_t &tau, matrixC_t &C)
Applies unitary matrix Q to a matrix C.
Definition unmq_level2.hpp:308
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
int unmq_level2_work(side_t side, trans_t trans, direction_t direction, storage_t storeMode, const matrixV_t &V, const vector_t &tau, matrixC_t &C, work_t &work)
Applies unitary matrix Q to a matrix C. Workspace is provided as an argument.
Definition unmq_level2.hpp:109
#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 unmq_level2_worksize(side_t side, trans_t trans, direction_t direction, storage_t storeMode, const matrixV_t &V, const vector_t &tau, const matrixC_t &C)
Worspace query of unmq_level2()
Definition unmq_level2.hpp:69
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
constexpr bool is_complex
True if T is a complex scalar type.
Definition scalar_type_traits.hpp:192
Output information in the workspace query.
Definition workspace.hpp:16