88 using idx_t = size_type<matrixC_t>;
89 using work_t = matrix_type<matrixV_t, vector_t>;
90 using range = pair<idx_t, idx_t>;
93 const idx_t m = nrows(C);
94 const idx_t n = ncols(C);
95 const idx_t k = size(tau);
96 const idx_t nQ = (side == Side::Left) ? m : n;
97 const idx_t nb = min((idx_t)opts.nb, k);
101 (is_same_v<T, type_t<work_t>>) ? WorkInfo(nb, nb) : WorkInfo(0);
103 auto&& Vi = (storeMode == StoreV::Columnwise)
104 ? slice(V, range{0, nQ}, range{0, nb})
105 : slice(V, range{0, nb}, range{0, nQ});
106 auto&& matrixTi = slice(V, range{0, nb}, range{0, nb});
109 workinfo += larfb_worksize<T>(side, NO_TRANS, direction, storeMode, Vi,
141 using idx_t = size_type<matrixC_t>;
142 using range = pair<idx_t, idx_t>;
145 const idx_t m = nrows(C);
146 const idx_t n = ncols(C);
147 const idx_t k = size(tau);
148 const idx_t nQ = (side == Side::Left) ? m : n;
149 const idx_t nb = min((idx_t)opts.nb, k);
154 trans != Op::NoTrans && trans != Op::ConjTrans &&
155 ((trans != Op::Trans) || is_complex<type_t<matrixV_t>>));
157 direction != Direction::Forward);
159 ? ((ncols(V) == k) && (nrows(V) == nQ))
160 : ((nrows(V) == k) && (ncols(V) == nQ)));
163 if (m <= 0 || n <= 0 || k <= 0)
return 0;
166 auto [matrixT, work1] = reshape(work, nb, nb);
169 const bool positiveIncLeft =
170 (storeMode == StoreV::Columnwise)
171 ? ((direction == Direction::Backward) ? (trans == Op::NoTrans)
172 : (trans !=
Op::NoTrans))
173 : ((direction ==
Direction::Forward) ? (trans ==
Op::NoTrans)
174 : (trans !=
Op::NoTrans));
175 const bool positiveInc =
176 (side == Side::Left) ? positiveIncLeft : !positiveIncLeft;
177 const idx_t i0 = (positiveInc) ? 0 : ((k - 1) / nb) * nb;
178 const idx_t iN = (positiveInc) ? ((k - 1) / nb + 1) * nb : -nb;
179 const idx_t inc = (positiveInc) ? nb : -nb;
181 if (storeMode == StoreV::Columnwise) {
182 for (idx_t i = i0; i != iN; i += inc) {
183 const idx_t ib = min(nb, k - i);
184 const auto rangev = (direction == Direction::Forward)
186 : range{0, nQ - k + i + ib};
187 const auto Vi = slice(V, rangev, range{i, i + ib});
188 const auto taui = slice(tau, range{i, i + ib});
189 auto matrixTi = slice(matrixT, range{0, ib}, range{0, ib});
192 larft(direction, COLUMNWISE_STORAGE, Vi, taui, matrixTi);
195 auto Ci = (side == Side::Left) ? slice(C, rangev, range{0, n})
196 : slice(C, range{0, m}, rangev);
197 larfb_work(side, trans, direction, COLUMNWISE_STORAGE, Vi, matrixTi,
202 for (idx_t i = i0; i != iN; i += inc) {
203 const idx_t ib = min(nb, k - i);
204 const auto rangev = (direction == Direction::Forward)
206 : range{0, nQ - k + i + ib};
207 const auto Vi = slice(V, range{i, i + ib}, rangev);
208 const auto taui = slice(tau, range{i, i + ib});
209 auto matrixTi = slice(matrixT, range{0, ib}, range{0, ib});
212 larft(direction, ROWWISE_STORAGE, Vi, taui, matrixTi);
215 auto Ci = (side == Side::Left) ? slice(C, rangev, range{0, n})
216 : slice(C, range{0, m}, rangev);
218 (trans == Op::NoTrans) ? Op::ConjTrans :
Op::
NoTrans,
291 using idx_t = size_type<matrixC_t>;
292 using work_t = matrix_type<matrixV_t, vector_t>;
293 using T = type_t<work_t>;
296 Create<work_t> new_matrix;
299 const idx_t m = nrows(C);
300 const idx_t n = ncols(C);
301 const idx_t k = size(tau);
304 if (m <= 0 || n <= 0 || k <= 0)
return 0;
308 unmq_worksize<T>(side, trans, direction, storeMode, V, tau, C, opts);
309 std::vector<T> work_;
310 auto work = new_matrix(work_, workinfo.m, workinfo.n);
312 return unmq_work(side, trans, direction, storeMode, V, tau, C, work, opts);
int unmq(side_t side, trans_t trans, direction_t direction, storage_t storeMode, const matrixV_t &V, const vector_t &tau, matrixC_t &C, const UnmqOpts &opts={})
Applies unitary matrix Q to a matrix C.
Definition unmq.hpp:282
int larfb_work(side_t side, trans_t trans, direction_t direction, storage_t storeMode, const matrixV_t &V, const matrixT_t &Tmatrix, matrixC_t &C, work_t &work)
Applies a block reflector or its conjugate transpose to a m-by-n matrix C, from either the left or ...
Definition larfb.hpp:111
int unmq_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, const UnmqOpts &opts={})
Applies unitary matrix Q to a matrix C. Workspace is provided as an argument.
Definition unmq.hpp:131