tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
DelayedSubsetSorted.hpp
Go to the documentation of this file.
1#ifndef TATAMI_DELAYED_SUBSET_SORTED_HPP
2#define TATAMI_DELAYED_SUBSET_SORTED_HPP
3
4#include "utils.hpp"
5#include "../base/Matrix.hpp"
7
8#include <algorithm>
9#include <numeric>
10#include <memory>
11
12#include "sanisizer/sanisizer.hpp"
13
22namespace tatami {
23
27namespace DelayedSubsetSorted_internal {
28
29template<typename Index_>
30struct DenseParallelResults {
31 std::vector<Index_> collapsed;
32 std::vector<Index_> expansion;
33};
34
35template<typename Index_, class SubsetStorage_, class ToIndex_>
36DenseParallelResults<Index_> format_dense_parallel(const SubsetStorage_& indices, const Index_ len, const ToIndex_ to_index) {
37 DenseParallelResults<Index_> output;
38 output.expansion.reserve(len);
39 output.collapsed.reserve(len);
40
41 if (len) {
42 auto last = indices[to_index(0)];
43 output.expansion.push_back(1);
44 output.collapsed.push_back(last);
45
46 for (Index_ i = 1; i < len; ++i) {
47 const auto current = indices[to_index(i)];
48 if (current == last) {
49 ++(output.expansion.back());
50 } else {
51 last = current;
52 output.expansion.push_back(1);
53 output.collapsed.push_back(last);
54 }
55 }
56 }
57
58 return output;
59}
60
61template<bool oracle_, typename Value_, typename Index_>
62class ParallelDense final : public DenseExtractor<oracle_, Value_, Index_> {
63public:
64 template<class SubsetStorage_>
65 ParallelDense(
66 const Matrix<Value_, Index_>& matrix,
67 const SubsetStorage_& subset,
68 const bool row,
69 MaybeOracle<oracle_, Index_> oracle,
70 const Options& opt
71 ) {
72 auto processed = format_dense_parallel<Index_>(subset, subset.size(), [&](const Index_ i) -> Index_ { return i; });
73 initialize(matrix, std::move(processed), subset.size(), row, std::move(oracle), opt);
74 }
75
76 template<class SubsetStorage_>
77 ParallelDense(
78 const Matrix<Value_, Index_>& matrix,
79 const SubsetStorage_& subset,
80 const bool row,
81 MaybeOracle<oracle_, Index_> oracle,
82 const Index_ block_start,
83 const Index_ block_length,
84 const Options& opt
85 ) {
86 auto processed = format_dense_parallel<Index_>(subset, block_length, [&](const Index_ i) -> Index_ { return i + block_start; });
87 initialize(matrix, std::move(processed), block_length, row, std::move(oracle), opt);
88 }
89
90 template<class SubsetStorage_>
91 ParallelDense(
92 const Matrix<Value_, Index_>& matrix,
93 const SubsetStorage_& subset,
94 const bool row,
95 MaybeOracle<oracle_, Index_> oracle,
96 VectorPtr<Index_> indices_ptr,
97 const Options& opt
98 ) {
99 const auto& indices = *indices_ptr;
100 auto processed = format_dense_parallel<Index_>(subset, indices.size(), [&](const Index_ i) -> Index_ { return indices[i]; });
101 initialize(matrix, std::move(processed), indices.size(), row, std::move(oracle), opt);
102 }
103
104private:
105 void initialize(
106 const Matrix<Value_, Index_>& mat,
107 DenseParallelResults<Index_> processed,
108 const Index_ extent,
109 const bool row,
110 MaybeOracle<oracle_, Index_> oracle,
111 const Options& opt
112 ) {
113 my_shift = extent - processed.collapsed.size();
114 my_ext = new_extractor<false, oracle_>(mat, row, std::move(oracle), std::move(processed.collapsed), opt);
115 my_expansion = std::move(processed.expansion);
116 }
117
118public:
119 const Value_* fetch(const Index_ i, Value_* const buffer) {
120 auto input = my_ext->fetch(i, buffer + my_shift);
121
122 // 'input' and 'buffer' may optionally point to overlapping arrays as long
123 // as 'buffer' precedes 'input'. The idea is that the expansion of values
124 // into 'buffer' will cause it to "catch up" to 'input' without clobbering
125 // any values in the latter. This assumes that 'input' has been shifted
126 // enough to make space for expansion; the required shift depends on the
127 // number of duplicates in 'expansion'.
128
129 auto copy = buffer;
130 for (const auto e : my_expansion) {
131 // Once we've caught up, everything else must be a non-duplicate,
132 // otherwise we'd be clobbering as-yet-unread values from the input.
133 // So we might as well just quit at this point.
134 if (input == copy) {
135 break;
136 }
137
138 std::fill_n(copy, e, *input);
139 ++input;
140 copy += e;
141 }
142
143 return buffer;
144 }
145
146private:
147 std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > my_ext;
148 std::vector<Index_> my_expansion;
149 Index_ my_shift;
150};
151
152template<typename Index_>
153struct SparseParallelExpansion {
154 // This is a bit complicated to explain.
155 // Let 'x = start[i - offset]'.
156 // Let 'y = lengths[i - offset]'.
157 // Let 'z' denote any integer in '[x, x + y)'.
158 // Let 'f' be the selection-specific function such that 'f(a)' is the a-th element of the selection
159 // (i.e., 'a' for full selection, 'a + start' for block selection and 'subset[a]' for indexed selection).
160 // In which case, 'indices[f(z)]' is equal to 'i'.
161 // The general idea is that 'f(z)' can be used to fill the 'SparseRange::index' on output.
162 std::vector<Index_> start;
163 std::vector<Index_> length;
164
165 Index_ offset = 0;
166};
167
168template<typename Index_>
169struct SparseParallelResults {
170 std::vector<Index_> collapsed;
171 SparseParallelExpansion<Index_> expansion;
172};
173
174template<typename Index_, class SubsetStorage_, class ToIndex_>
175SparseParallelResults<Index_> format_sparse_parallel(const SubsetStorage_& indices, const Index_ len, const ToIndex_ to_index) {
176 SparseParallelResults<Index_> output;
177
178 if (len) {
179 output.collapsed.reserve(len);
180 const auto first = indices[to_index(0)];
181
182 // 'start' and 'length' are vectors that enable look-up according to the indices of the underlying array.
183 // To avoid the need to allocate a vector of length equal to the underlying array's dimension, we only consider the extremes of 'indices'.
184 // We allocate both start/length vectors to have length equal to the range of 'indices'.
185 // The 'offset' defines the lower bound that must be subtracted from the array indices to get an index into 'start' or 'length'.
186 output.expansion.offset = first;
187 const Index_ allocation = indices[to_index(len - 1)] - output.expansion.offset + 1; // fits in an Index_ as it should be no greater than the input matrix's dimension extent.
188 resize_container_to_Index_size(output.expansion.start, allocation);
189 output.expansion.length.resize(output.expansion.start.size());
190
191 Index_ lookup = 0;
192 output.expansion.start[0] = 0;
193 output.expansion.length[0] = 1;
194 output.collapsed.push_back(first);
195 auto last = first;
196
197 for (Index_ i = 1; i < len; ++i) {
198 const auto current = indices[to_index(i)];
199 if (current == last) {
200 ++(output.expansion.length[lookup]);
201 continue;
202 }
203
204 lookup = current - output.expansion.offset;
205 output.expansion.start[lookup] = i;
206 output.expansion.length[lookup] = 1;
207 output.collapsed.push_back(current);
208 last = current;
209 }
210 }
211
212 return output;
213}
214
215template<bool oracle_, typename Value_, typename Index_>
216class ParallelSparseCore {
217public:
218 template<class SubsetStorage_, class ToIndex_>
219 ParallelSparseCore(
220 const Matrix<Value_, Index_>& matrix,
221 const SubsetStorage_& subset,
222 const Index_ extent,
223 const bool row,
224 MaybeOracle<oracle_, Index_> oracle,
225 Options opt,
226 ToIndex_&& to_index
227 ) {
228 auto processed = format_sparse_parallel<Index_>(subset, extent, std::forward<ToIndex_>(to_index));
229 my_shift = extent - processed.collapsed.size();
230
231 my_needs_value = opt.sparse_extract_value;
232 my_needs_index = opt.sparse_extract_index;
233 opt.sparse_extract_index = true; // must extract the indices for proper my_expansion.
234 if (!my_needs_index) {
235 // Need a holding space for indices if 'ibuffer' is not supplied.
236 resize_container_to_Index_size(my_holding_ibuffer, processed.collapsed.size()); // processed.collapsed.size() should fit in an Index_, hence the cast is safe.
237 }
238
239 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), std::move(processed.collapsed), opt);
240 my_expansion = std::move(processed.expansion);
241 }
242
243 template<class ToIndex_>
244 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer, const ToIndex_ to_index) {
245 // Shifting so that there's enough space for my_expansion, but only doing
246 // so if these pointers are guaranteed to be non-NULL.
247 const auto vinit = (my_needs_value ? value_buffer + my_shift : NULL);
248 const auto iinit = (my_needs_index ? index_buffer + my_shift : my_holding_ibuffer.data());
249 const auto input = my_ext->fetch(i, vinit, iinit);
250
251 auto vcopy = value_buffer;
252 auto icopy = index_buffer;
253 Index_ count = 0;
254
255 auto vsrc = input.value;
256 bool replace_value = my_needs_value && vsrc != vcopy;
257
258 // Pointers in 'input' and the two 'buffer' pointers may optionally point
259 // to overlapping arrays as long as each 'buffer' pointer precede its
260 // corresponding pointer in 'input'. The idea is that the expansion of
261 // values into 'buffer' will cause it to "catch up" to 'input' without
262 // clobbering any values in the latter. This assumes that 'input' has been
263 // shift enough to make space for expansion; the required shift depends
264 // on the number of duplicates.
265 for (Index_ i = 0; i < input.number; ++i) {
266 const auto eindex = input.index[i] - my_expansion.offset;
267 const auto nexpand = my_expansion.length[eindex];
268 count += nexpand;
269
270 if (replace_value) {
271 const auto v = *vsrc; // make a copy just in case 'vcopy' and 'input.value' overlap.
272 std::fill_n(vcopy, nexpand, v);
273 vcopy += nexpand;
274 ++vsrc;
275 replace_value = (vcopy != vsrc); // if we've caught up, there no need to do this replacement.
276 }
277
278 if (my_needs_index) {
279 const auto sexpand = my_expansion.start[eindex];
280 for (Index_ e = 0; e < nexpand; ++e, ++icopy) {
281 *icopy = to_index(sexpand + e);
282 }
283 }
284 }
285
286 return SparseRange<Value_, Index_>(
287 count,
288 (my_needs_value ? value_buffer : NULL),
289 (my_needs_index ? index_buffer : NULL)
290 );
291 }
292
293private:
294 bool my_needs_value, my_needs_index;
295 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > my_ext;
296 std::vector<Index_> my_holding_ibuffer;
297 SparseParallelExpansion<Index_> my_expansion;
298 Index_ my_shift;
299};
300
301template<bool oracle_, typename Value_, typename Index_>
302class ParallelFullSparse final : public SparseExtractor<oracle_, Value_, Index_> {
303public:
304 template<class SubsetStorage_>
305 ParallelFullSparse(
306 const Matrix<Value_, Index_>& matrix,
307 const SubsetStorage_& subset,
308 const bool row,
309 MaybeOracle<oracle_, Index_> oracle,
310 const Options& opt
311 ) :
312 my_core(matrix, subset, subset.size(), row, std::move(oracle), opt, Helper())
313 {}
314
315 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
316 return my_core.fetch(i, value_buffer, index_buffer, Helper());
317 }
318
319private:
320 ParallelSparseCore<oracle_, Value_, Index_> my_core;
321
322 struct Helper {
323 Index_ operator()(const Index_ i) const {
324 return i;
325 }
326 };
327};
328
329template<bool oracle_, typename Value_, typename Index_>
330class ParallelBlockSparse final : public SparseExtractor<oracle_, Value_, Index_> {
331public:
332 template<class SubsetStorage_>
333 ParallelBlockSparse(
334 const Matrix<Value_, Index_>& matrix,
335 const SubsetStorage_& subset,
336 const bool row,
337 MaybeOracle<oracle_, Index_> oracle,
338 const Index_ block_start,
339 const Index_ block_length,
340 const Options& opt
341 ) :
342 my_core(matrix, subset, block_length, row, std::move(oracle), opt, Helper(block_start)),
343 my_block_start(block_start)
344 {}
345
346 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
347 return my_core.fetch(i, value_buffer, index_buffer, Helper(my_block_start));
348 }
349
350private:
351 ParallelSparseCore<oracle_, Value_, Index_> my_core;
352 Index_ my_block_start;
353
354 struct Helper {
355 Helper(Index_ block_start) : block_start(block_start) {}
356 Index_ block_start;
357 Index_ operator()(const Index_ i) const {
358 return i + block_start;
359 }
360 };
361};
362
363template<bool oracle_, typename Value_, typename Index_>
364class ParallelIndexSparse final : public SparseExtractor<oracle_, Value_, Index_> {
365public:
366 template<class SubsetStorage_>
367 ParallelIndexSparse(
368 const Matrix<Value_, Index_>& matrix,
369 const SubsetStorage_& subset,
370 const bool row,
371 MaybeOracle<oracle_, Index_> oracle,
372 VectorPtr<Index_> indices_ptr,
373 const Options& opt
374 ) :
375 my_core(matrix, subset, indices_ptr->size(), row, std::move(oracle), opt, Helper(*indices_ptr)),
376 my_indices_ptr(std::move(indices_ptr))
377 {}
378
379 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
380 return my_core.fetch(i, value_buffer, index_buffer, Helper(*my_indices_ptr));
381 }
382
383private:
384 ParallelSparseCore<oracle_, Value_, Index_> my_core;
385 VectorPtr<Index_> my_indices_ptr;
386
387 struct Helper {
388 Helper(const std::vector<Index_>& indices) : indices(indices) {}
389 const std::vector<Index_>& indices;
390 Index_ operator()(const Index_ i) const {
391 return indices[i];
392 }
393 };
394};
395
396}
412template<typename Value_, typename Index_, class SubsetStorage_>
413class DelayedSubsetSorted final : public Matrix<Value_, Index_> {
414public:
424 std::shared_ptr<const Matrix<Value_, Index_> > matrix,
425 SubsetStorage_ subset,
426 const bool by_row,
427 const bool check = true
428 ) :
429 my_matrix(std::move(matrix)),
430 my_subset(std::move(subset)),
431 my_by_row(by_row)
432 {
433 // Check that we can still report the dimension extents of the subsetted matrix.
434 sanisizer::can_cast<Index_>(my_subset.size());
435
436 if (check) {
437 const Index_ nsub = my_subset.size();
438 for (Index_ i = 1; i < nsub; ++i) {
439 if (my_subset[i] < my_subset[i-1]) {
440 throw std::runtime_error("subset should be sorted");
441 }
442 }
443 }
444 }
445
446private:
447 std::shared_ptr<const Matrix<Value_, Index_> > my_matrix;
448 SubsetStorage_ my_subset;
449 bool my_by_row;
450
451 Index_ get_mapping_dim() const {
452 if (my_by_row) {
453 return my_matrix->nrow();
454 } else {
455 return my_matrix->ncol();
456 }
457 }
458
459public:
460 Index_ nrow() const {
461 if (my_by_row) {
462 return my_subset.size();
463 } else {
464 return my_matrix->nrow();
465 }
466 }
467
468 Index_ ncol() const {
469 if (my_by_row) {
470 return my_matrix->ncol();
471 } else {
472 return my_subset.size();
473 }
474 }
475
476 bool is_sparse() const {
477 return my_matrix->is_sparse();
478 }
479
480 double is_sparse_proportion() const {
481 return my_matrix->is_sparse_proportion();
482 }
483
484 bool prefer_rows() const {
485 return my_matrix->prefer_rows();
486 }
487
488 double prefer_rows_proportion() const {
489 return my_matrix->prefer_rows_proportion();
490 }
491
492 bool uses_oracle(const bool row) const {
493 return my_matrix->uses_oracle(row);
494 }
495
496 using Matrix<Value_, Index_>::dense_column;
497
498 using Matrix<Value_, Index_>::dense_row;
499
500 using Matrix<Value_, Index_>::sparse_column;
501
502 using Matrix<Value_, Index_>::sparse_row;
503
504 /********************
505 *** Myopic dense ***
506 ********************/
507private:
508 template<typename ... Args_>
509 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > populate_myopic_dense(
510 const bool row,
511 Args_&& ... args
512 ) const {
513 if (row == my_by_row) {
514 return std::make_unique<subset_utils::MyopicPerpendicularDense<Value_, Index_, SubsetStorage_> >(
515 *my_matrix,
516 my_subset,
517 row,
518 std::forward<Args_>(args)...
519 );
520 } else {
521 return std::make_unique<DelayedSubsetSorted_internal::ParallelDense<false, Value_, Index_> >(
522 *my_matrix,
523 my_subset,
524 row,
525 false,
526 std::forward<Args_>(args)...
527 );
528 }
529 }
530
531public:
532 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
533 const bool row,
534 const Options& opt
535 ) const {
536 return populate_myopic_dense(row, opt);
537 }
538
539 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
540 const bool row,
541 const Index_ block_start,
542 const Index_ block_length,
543 const Options& opt
544 ) const {
545 return populate_myopic_dense(row, block_start, block_length, opt);
546 }
547
548 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
549 const bool row,
550 VectorPtr<Index_> indices_ptr,
551 const Options& opt
552 ) const {
553 return populate_myopic_dense(row, std::move(indices_ptr), opt);
554 }
555
556 /*********************
557 *** Myopic sparse ***
558 *********************/
559private:
560 template<DimensionSelectionType selection_, bool oracle_, typename ... Args_>
561 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > populate_sparse(
562 bool row,
564 Args_&& ... args
565 ) const {
566 if constexpr(selection_ == DimensionSelectionType::FULL) {
567 return std::make_unique<DelayedSubsetSorted_internal::ParallelFullSparse<oracle_, Value_, Index_> >(
568 *my_matrix,
569 my_subset,
570 row,
571 std::move(oracle),
572 std::forward<Args_>(args)...
573 );
574 } else if constexpr(selection_ == DimensionSelectionType::BLOCK) {
575 return std::make_unique<DelayedSubsetSorted_internal::ParallelBlockSparse<oracle_, Value_, Index_> >(
576 *my_matrix,
577 my_subset,
578 row,
579 std::move(oracle),
580 std::forward<Args_>(args)...
581 );
582 } else {
583 return std::make_unique<DelayedSubsetSorted_internal::ParallelIndexSparse<oracle_, Value_, Index_> >(
584 *my_matrix,
585 my_subset,
586 row,
587 std::move(oracle),
588 std::forward<Args_>(args)...
589 );
590 }
591 }
592
593 template<DimensionSelectionType selection_, typename ... Args_>
594 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > populate_myopic_sparse(
595 const bool row,
596 Args_&& ... args
597 ) const {
598 if (row == my_by_row) {
599 return std::make_unique<subset_utils::MyopicPerpendicularSparse<Value_, Index_, SubsetStorage_> >(
600 *my_matrix,
601 my_subset,
602 row,
603 std::forward<Args_>(args)...
604 );
605 } else {
606 return populate_sparse<selection_, false>(row, false, std::forward<Args_>(args)...);
607 }
608 }
609
610public:
611 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
612 const bool row,
613 const Options& opt
614 ) const {
615 return populate_myopic_sparse<DimensionSelectionType::FULL>(row, opt);
616 }
617
618 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
619 const bool row,
620 const Index_ block_start,
621 const Index_ block_length,
622 const Options& opt
623 ) const {
624 return populate_myopic_sparse<DimensionSelectionType::BLOCK>(row, block_start, block_length, opt);
625 }
626
627 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
628 const bool row,
629 VectorPtr<Index_> indices_ptr,
630 const Options& opt
631 ) const {
632 return populate_myopic_sparse<DimensionSelectionType::INDEX>(row, std::move(indices_ptr), opt);
633 }
634
635 /**********************
636 *** Oracular dense ***
637 **********************/
638private:
639 template<typename ... Args_>
640 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > populate_oracular_dense(
641 const bool row,
642 std::shared_ptr<const Oracle<Index_> > oracle,
643 Args_&& ... args
644 ) const {
645 if (row == my_by_row) {
646 return std::make_unique<subset_utils::OracularPerpendicularDense<Value_, Index_> >(
647 *my_matrix,
648 my_subset,
649 row,
650 std::move(oracle),
651 std::forward<Args_>(args)...
652 );
653 } else {
654 return std::make_unique<DelayedSubsetSorted_internal::ParallelDense<true, Value_, Index_> >(
655 *my_matrix,
656 my_subset,
657 row,
658 std::move(oracle),
659 std::forward<Args_>(args)...
660 );
661 }
662 }
663
664public:
665 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
666 const bool row,
667 std::shared_ptr<const Oracle<Index_> > oracle,
668 const Options& opt
669 ) const {
670 return populate_oracular_dense(row, std::move(oracle), opt);
671 }
672
673 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
674 const bool row,
675 std::shared_ptr<const Oracle<Index_> > oracle,
676 const Index_ block_start,
677 const Index_ block_length,
678 const Options& opt
679 ) const {
680 return populate_oracular_dense(row, std::move(oracle), block_start, block_length, opt);
681 }
682
683 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
684 const bool row,
685 std::shared_ptr<const Oracle<Index_> > oracle,
686 VectorPtr<Index_> indices_ptr,
687 const Options& opt
688 ) const {
689 return populate_oracular_dense(row, std::move(oracle), std::move(indices_ptr), opt);
690 }
691
692 /***********************
693 *** Oracular sparse ***
694 ***********************/
695private:
696 template<DimensionSelectionType selection_, typename ... Args_>
697 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > populate_oracular_sparse(
698 const bool row,
699 std::shared_ptr<const Oracle<Index_> > oracle,
700 Args_&& ... args
701 ) const {
702 if (row == my_by_row) {
703 return std::make_unique<subset_utils::OracularPerpendicularSparse<Value_, Index_> >(
704 *my_matrix,
705 my_subset,
706 row,
707 std::move(oracle),
708 std::forward<Args_>(args)...
709 );
710 } else {
711 return populate_sparse<selection_, true>(row, std::move(oracle), std::forward<Args_>(args)...);
712 }
713 }
714
715public:
716 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
717 const bool row,
718 std::shared_ptr<const Oracle<Index_> > oracle,
719 const Options& opt
720 ) const {
721 return populate_oracular_sparse<DimensionSelectionType::FULL>(row, std::move(oracle), opt);
722 }
723
724 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
725 const bool row,
726 std::shared_ptr<const Oracle<Index_> > oracle,
727 const Index_ block_start,
728 const Index_ block_length,
729 const Options& opt
730 ) const {
731 return populate_oracular_sparse<DimensionSelectionType::BLOCK>(row, std::move(oracle), block_start, block_length, opt);
732 }
733
734 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
735 const bool row,
736 std::shared_ptr<const Oracle<Index_> > oracle,
737 VectorPtr<Index_> indices_ptr,
738 const Options& opt
739 ) const {
740 return populate_oracular_sparse<DimensionSelectionType::INDEX>(row, std::move(oracle), std::move(indices_ptr), opt);
741 }
742};
743
744}
745
746#endif
Convert index type to container size.
Virtual class for a matrix of some numeric type.
Delayed subsetting of a matrix with sorted indices.
Definition DelayedSubsetSorted.hpp:413
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetSorted.hpp:716
double prefer_rows_proportion() const
Definition DelayedSubsetSorted.hpp:488
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, const Options &opt) const
Definition DelayedSubsetSorted.hpp:611
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 DelayedSubsetSorted.hpp:724
Index_ nrow() const
Definition DelayedSubsetSorted.hpp:460
bool prefer_rows() const
Definition DelayedSubsetSorted.hpp:484
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetSorted.hpp:539
double is_sparse_proportion() const
Definition DelayedSubsetSorted.hpp:480
bool is_sparse() const
Definition DelayedSubsetSorted.hpp:476
DelayedSubsetSorted(std::shared_ptr< const Matrix< Value_, Index_ > > matrix, SubsetStorage_ subset, const bool by_row, const bool check=true)
Definition DelayedSubsetSorted.hpp:423
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSorted.hpp:548
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetSorted.hpp:665
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 DelayedSubsetSorted.hpp:673
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Options &opt) const
Definition DelayedSubsetSorted.hpp:532
bool uses_oracle(const bool row) const
Definition DelayedSubsetSorted.hpp:492
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetSorted.hpp:618
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSorted.hpp:627
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 DelayedSubsetSorted.hpp:734
Index_ ncol() const
Definition DelayedSubsetSorted.hpp:468
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 DelayedSubsetSorted.hpp:683
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
DimensionSelectionType
Definition Options.hpp:25
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
void resize_container_to_Index_size(Container_ &container, const Index_ x, Args_ &&... args)
Definition Index_to_container.hpp:99
typename std::conditional< oracle_, std::shared_ptr< const Oracle< Index_ > >, bool >::type MaybeOracle
Definition new_extractor.hpp:20
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
Options for accessing data from a Matrix instance.
Definition Options.hpp:30