tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
DelayedSubsetBlock.hpp
Go to the documentation of this file.
1#ifndef TATAMI_DELAYED_SUBSET_BLOCK
2#define TATAMI_DELAYED_SUBSET_BLOCK
3
4#include "../base/Matrix.hpp"
6
7#include <vector>
8#include <algorithm>
9#include <memory>
10
19namespace tatami {
20
24namespace DelayedSubsetBlock_internal {
25
26template<typename Index_>
27void bump_indices(VectorPtr<Index_>& indices_ptr, const Index_ subset_start) {
28 if (subset_start) {
29 const auto ptr2 = new std::vector<Index_>(*indices_ptr);
30 indices_ptr.reset(ptr2);
31 for (auto& i : *ptr2) {
32 i += subset_start;
33 }
34 }
35}
36
37template<bool oracle_, typename Value_, typename Index_>
38class AlongDense final : public DenseExtractor<oracle_, Value_, Index_> {
39public:
40 AlongDense(
41 const Matrix<Value_, Index_>& matrix,
42 const Index_ subset_start,
43 const Index_ subset_length,
44 const bool row,
45 MaybeOracle<oracle_, Index_> oracle,
46 const Options& opt
47 ) :
48 my_ext(new_extractor<false, oracle_>(matrix, row, std::move(oracle), subset_start, subset_length, opt))
49 {}
50
51 AlongDense(
52 const Matrix<Value_, Index_>& matrix,
53 const Index_ subset_start,
54 const Index_ /* for consistency */,
55 const bool row,
56 MaybeOracle<oracle_, Index_> oracle,
57 const Index_ block_start,
58 const Index_ block_length,
59 const Options& opt
60 ) :
61 my_ext(new_extractor<false, oracle_>(matrix, row, std::move(oracle), subset_start + block_start, block_length, opt))
62 {}
63
64 AlongDense(
65 const Matrix<Value_, Index_>& matrix,
66 const Index_ subset_start,
67 const Index_ /* for consistency */,
68 const bool row,
69 MaybeOracle<oracle_, Index_> oracle,
70 VectorPtr<Index_> indices_ptr,
71 const Options& opt
72 ) {
73 bump_indices(indices_ptr, subset_start);
74 my_ext = new_extractor<false, oracle_>(matrix, row, std::move(oracle), std::move(indices_ptr), opt);
75 }
76
77 const Value_* fetch(const Index_ i, Value_* const buffer) {
78 return my_ext->fetch(i, buffer);
79 }
80
81private:
82 std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > my_ext;
83};
84
85template<bool oracle_, typename Value_, typename Index_>
86class AlongSparse final : public SparseExtractor<oracle_, Value_, Index_> {
87public:
88 AlongSparse(
89 const Matrix<Value_, Index_>& matrix,
90 const Index_ subset_start,
91 const Index_ subset_length,
92 const bool row,
93 MaybeOracle<oracle_, Index_> oracle,
94 const Options& opt
95 ) :
96 my_ext(new_extractor<true, oracle_>(matrix, row, std::move(oracle), subset_start, subset_length, opt)),
97 my_shift(subset_start)
98 {}
99
100 AlongSparse(
101 const Matrix<Value_, Index_>& matrix,
102 const Index_ subset_start,
103 const Index_ /* for consistency */,
104 const bool row,
105 MaybeOracle<oracle_, Index_> oracle,
106 const Index_ block_start,
107 const Index_ block_length,
108 const Options& opt
109 ) :
110 my_ext(new_extractor<true, oracle_>(matrix, row, std::move(oracle), subset_start + block_start, block_length, opt)),
111 my_shift(subset_start)
112 {}
113
114 AlongSparse(
115 const Matrix<Value_, Index_>& matrix,
116 const Index_ subset_start,
117 const Index_ /* for consistency */,
118 const bool row,
119 MaybeOracle<oracle_, Index_> oracle,
120 VectorPtr<Index_> indices_ptr,
121 const Options& opt
122 ) :
123 my_shift(subset_start)
124 {
125 bump_indices(indices_ptr, subset_start);
126 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), std::move(indices_ptr), opt);
127 }
128
129 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
130 auto output = my_ext->fetch(i, value_buffer, index_buffer);
131 if (output.index && my_shift) {
132 for (Index_ i = 0; i < output.number; ++i) {
133 index_buffer[i] = output.index[i] - my_shift;
134 }
135 output.index = index_buffer;
136 }
137 return output;
138 }
139
140private:
141 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > my_ext;
142 Index_ my_shift;
143};
144
145template<typename Index_>
146class SubsetOracle final : public Oracle<Index_> {
147public:
148 SubsetOracle(
149 std::shared_ptr<const Oracle<Index_> > oracle,
150 const Index_ shift
151 ) :
152 my_oracle(std::move(oracle)),
153 my_shift(shift)
154 {}
155
156 PredictionIndex total() const {
157 return my_oracle->total();
158 }
159
160 Index_ get(const PredictionIndex i) const {
161 return my_oracle->get(i) + my_shift;
162 }
163
164private:
165 std::shared_ptr<const Oracle<Index_> > my_oracle;
166 Index_ my_shift;
167};
168
169template<bool oracle_, typename Value_, typename Index_>
170class AcrossDense final : public DenseExtractor<oracle_, Value_, Index_> {
171public:
172 template<typename ... Args_>
173 AcrossDense(
174 const Matrix<Value_, Index_>& matrix,
175 const Index_ subset_start,
176 const bool row,
177 MaybeOracle<oracle_, Index_> oracle,
178 Args_&& ... args
179 ) :
180 my_shift(subset_start)
181 {
182 if constexpr(oracle_) {
183 oracle.reset(new SubsetOracle(std::move(oracle), my_shift));
184 }
185 my_ext = new_extractor<false, oracle_>(matrix, row, std::move(oracle), std::forward<Args_>(args)...);
186 }
187
188 const Value_* fetch(const Index_ i, Value_* const buffer) {
189 return my_ext->fetch(i + my_shift, buffer);
190 }
191
192private:
193 std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > my_ext;
194 Index_ my_shift;
195};
196
197template<bool oracle_, typename Value_, typename Index_>
198class AcrossSparse final : public SparseExtractor<oracle_, Value_, Index_> {
199public:
200 template<typename ... Args_>
201 AcrossSparse(
202 const Matrix<Value_, Index_>& matrix,
203 const Index_ subset_start,
204 const bool row,
205 MaybeOracle<oracle_, Index_> oracle,
206 Args_&& ... args
207 ) :
208 my_shift(subset_start)
209 {
210 if constexpr(oracle_) {
211 oracle.reset(new SubsetOracle(std::move(oracle), my_shift));
212 }
213 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), std::forward<Args_>(args)...);
214 }
215
216 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
217 return my_ext->fetch(i + my_shift, value_buffer, index_buffer);
218 }
219
220private:
221 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > my_ext;
222 Index_ my_shift;
223};
224
225}
240template<typename Value_, typename Index_>
241class DelayedSubsetBlock final : public Matrix<Value_, Index_> {
242public:
251 std::shared_ptr<const Matrix<Value_, Index_> > matrix,
252 const Index_ subset_start,
253 const Index_ subset_length,
254 const bool by_row
255 ) :
256 my_matrix(std::move(matrix)),
257 my_subset_start(subset_start),
258 my_subset_length(subset_length),
259 my_by_row(by_row)
260 {}
261
262private:
263 std::shared_ptr<const Matrix<Value_, Index_> > my_matrix;
264 Index_ my_subset_start, my_subset_length;
265 bool my_by_row;
266
267public:
268 Index_ nrow() const {
269 if (my_by_row) {
270 return my_subset_length;
271 } else {
272 return my_matrix->nrow();
273 }
274 }
275
276 Index_ ncol() const {
277 if (my_by_row) {
278 return my_matrix->ncol();
279 } else {
280 return my_subset_length;
281 }
282 }
283
284 bool is_sparse() const {
285 return my_matrix->is_sparse();
286 }
287
288 double is_sparse_proportion() const {
289 return my_matrix->is_sparse_proportion();
290 }
291
292 bool prefer_rows() const {
293 return my_matrix->prefer_rows();
294 }
295
296 double prefer_rows_proportion() const {
297 return my_matrix->prefer_rows_proportion();
298 }
299
300 bool uses_oracle(const bool row) const {
301 return my_matrix->uses_oracle(row);
302 }
303
304 using Matrix<Value_, Index_>::dense_column;
305
306 using Matrix<Value_, Index_>::dense_row;
307
308 using Matrix<Value_, Index_>::sparse_column;
309
310 using Matrix<Value_, Index_>::sparse_row;
311
312 /************************
313 ***** Myopic dense *****
314 ************************/
315private:
316 template<bool oracle_, typename ... Args_>
317 std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > dense_internal(
318 const bool row,
319 Args_&&... args
320 ) const {
321 if (row != my_by_row) {
322 return std::make_unique<DelayedSubsetBlock_internal::AlongDense<oracle_, Value_, Index_> >(
323 *my_matrix,
324 my_subset_start,
325 my_subset_length,
326 row,
327 std::forward<Args_>(args)...
328 );
329 } else {
330 return std::make_unique<DelayedSubsetBlock_internal::AcrossDense<oracle_, Value_, Index_> >(
331 *my_matrix,
332 my_subset_start,
333 row,
334 std::forward<Args_>(args)...
335 );
336 }
337 }
338
339public:
340 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
341 const bool row,
342 const Options& opt
343 ) const {
344 return dense_internal<false>(row, false, opt);
345 }
346
347 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
348 const bool row,
349 const Index_ block_start,
350 const Index_ block_length,
351 const Options& opt
352 ) const {
353 return dense_internal<false>(row, false, block_start, block_length, opt);
354 }
355
356 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
357 const bool row,
358 VectorPtr<Index_> indices_ptr,
359 const Options& opt
360 ) const {
361 return dense_internal<false>(row, false, std::move(indices_ptr), opt);
362 }
363
364 /*************************
365 ***** Myopic sparse *****
366 *************************/
367private:
368 template<bool oracle_, typename ... Args_>
369 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > sparse_internal(
370 const bool row,
371 Args_&&... args
372 ) const {
373 if (row != my_by_row) {
374 return std::make_unique<DelayedSubsetBlock_internal::AlongSparse<oracle_, Value_, Index_> >(
375 *my_matrix,
376 my_subset_start,
377 my_subset_length,
378 row,
379 std::forward<Args_>(args)...
380 );
381 } else {
382 return std::make_unique<DelayedSubsetBlock_internal::AcrossSparse<oracle_, Value_, Index_> >(
383 *my_matrix,
384 my_subset_start,
385 row,
386 std::forward<Args_>(args)...
387 );
388 }
389 }
390
391public:
392 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
393 const bool row,
394 const Options& opt
395 ) const {
396 return sparse_internal<false>(row, false, opt);
397 }
398
399 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
400 const bool row,
401 const Index_ block_start,
402 const Index_ block_length,
403 const Options& opt
404 ) const {
405 return sparse_internal<false>(row, false, block_start, block_length, opt);
406 }
407
408 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
409 const bool row,
410 VectorPtr<Index_> indices_ptr,
411 const Options& opt
412 ) const {
413 return sparse_internal<false>(row, false, std::move(indices_ptr), opt);
414 }
415
416 /**************************
417 ***** Oracular dense *****
418 **************************/
419public:
420 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
421 const bool row,
422 std::shared_ptr<const Oracle<Index_> > oracle,
423 const Options& opt
424 ) const {
425 return dense_internal<true>(row, std::move(oracle), opt);
426 }
427
428 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
429 const bool row,
430 std::shared_ptr<const Oracle<Index_> > oracle,
431 const Index_ block_start,
432 const Index_ block_length,
433 const Options& opt
434 ) const {
435 return dense_internal<true>(row, std::move(oracle), block_start, block_length, opt);
436 }
437
438 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
439 const bool row,
440 std::shared_ptr<const Oracle<Index_> > oracle,
441 VectorPtr<Index_> indices_ptr,
442 const Options& opt
443 ) const {
444 return dense_internal<true>(row, std::move(oracle), std::move(indices_ptr), opt);
445 }
446
447 /***************************
448 ***** Oracular sparse *****
449 ***************************/
450public:
451 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
452 const bool row,
453 std::shared_ptr<const Oracle<Index_> > oracle,
454 const Options& opt
455 ) const {
456 return sparse_internal<true>(row, std::move(oracle), opt);
457 }
458
459 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
460 const bool row,
461 std::shared_ptr<const Oracle<Index_> > oracle,
462 const Index_ block_start,
463 const Index_ block_length,
464 const Options& opt
465 ) const {
466 return sparse_internal<true>(row, std::move(oracle), block_start, block_length, opt);
467 }
468
469 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
470 const bool row,
471 std::shared_ptr<const Oracle<Index_> > oracle,
472 VectorPtr<Index_> indices_ptr,
473 const Options& opt
474 ) const {
475 return sparse_internal<true>(row, std::move(oracle), std::move(indices_ptr), opt);
476 }
477};
478
493template<typename Value_, typename Index_>
494std::shared_ptr<Matrix<Value_, Index_> > make_DelayedSubsetBlock(
495 std::shared_ptr<const Matrix<Value_, Index_> > matrix,
496 const Index_ subset_start,
497 const Index_ subset_length,
498 bool by_row
499) {
500 return std::shared_ptr<Matrix<Value_, Index_> >(new DelayedSubsetBlock<Value_, Index_>(std::move(matrix), subset_start, subset_length, by_row));
501}
502
506template<typename Value_, typename Index_>
507std::shared_ptr<Matrix<Value_, Index_> > make_DelayedSubsetBlock(std::shared_ptr<Matrix<Value_, Index_> > matrix, Index_ subset_start, Index_ subset_length, bool by_row) {
508 return std::shared_ptr<Matrix<Value_, Index_> >(new DelayedSubsetBlock<Value_, Index_>(std::move(matrix), subset_start, subset_length, by_row));
509}
517template<int margin_, typename Value_, typename Index_>
518std::shared_ptr<Matrix<Value_, Index_> > make_DelayedSubsetBlock(std::shared_ptr<const Matrix<Value_, Index_> > matrix, Index_ subset_start, Index_ subset_length) {
519 return make_DelayedSubsetBlock(std::move(matrix), subset_start, subset_length, margin_ == 0);
520}
521
522template<int margin_, typename Value_, typename Index_>
523std::shared_ptr<Matrix<Value_, Index_> > make_DelayedSubsetBlock(std::shared_ptr<Matrix<Value_, Index_> > matrix, Index_ subset_start, Index_ subset_length) {
524 return make_DelayedSubsetBlock(std::move(matrix), subset_start, subset_length, margin_ == 0);
525}
530}
531
532#endif
Virtual class for a matrix of some numeric type.
Delayed subsetting to a contiguous block.
Definition DelayedSubsetBlock.hpp:241
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetBlock.hpp:428
Index_ nrow() const
Definition DelayedSubsetBlock.hpp:268
bool uses_oracle(const bool row) const
Definition DelayedSubsetBlock.hpp:300
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Options &opt) const
Definition DelayedSubsetBlock.hpp:340
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetBlock.hpp:356
double prefer_rows_proportion() const
Definition DelayedSubsetBlock.hpp:296
Index_ ncol() const
Definition DelayedSubsetBlock.hpp:276
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, const Options &opt) const
Definition DelayedSubsetBlock.hpp:392
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetBlock.hpp:347
double is_sparse_proportion() const
Definition DelayedSubsetBlock.hpp:288
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetBlock.hpp:459
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetBlock.hpp:469
DelayedSubsetBlock(std::shared_ptr< const Matrix< Value_, Index_ > > matrix, const Index_ subset_start, const Index_ subset_length, const bool by_row)
Definition DelayedSubsetBlock.hpp:250
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetBlock.hpp:438
bool is_sparse() const
Definition DelayedSubsetBlock.hpp:284
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetBlock.hpp:399
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetBlock.hpp:408
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetBlock.hpp:451
bool prefer_rows() const
Definition DelayedSubsetBlock.hpp:292
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetBlock.hpp:420
Virtual class for a matrix.
Definition Matrix.hpp:59
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense_row() const
Definition Matrix.hpp:295
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense_column() const
Definition Matrix.hpp:336
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse_column() const
Definition Matrix.hpp:545
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse_row() const
Definition Matrix.hpp:504
Predict future access requests on the target dimension.
Definition Oracle.hpp:29
Flexible representations for matrix data.
Definition Extractor.hpp:15
auto new_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, MaybeOracle< oracle_, Index_ > oracle, Args_ &&... args)
Definition new_extractor.hpp:42
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
std::shared_ptr< Matrix< Value_, Index_ > > make_DelayedSubsetBlock(std::shared_ptr< const Matrix< Value_, Index_ > > matrix, const Index_ subset_start, const Index_ subset_length, bool by_row)
Definition DelayedSubsetBlock.hpp:494
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
std::size_t PredictionIndex
Definition Oracle.hpp:18
Templated construction of a new extractor.
Options for accessing data from a Matrix instance.
Definition Options.hpp:30