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"
6#include "../utils/Index_to_container.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 sanisizer::can_cast<Index_>(my_subset.size());
434 if (check) {
435 const Index_ nsub = my_subset.size();
436 for (Index_ i = 1; i < nsub; ++i) {
437 if (my_subset[i] < my_subset[i-1]) {
438 throw std::runtime_error("subset should be sorted");
439 }
440 }
441 }
442 }
443
444private:
445 std::shared_ptr<const Matrix<Value_, Index_> > my_matrix;
446 SubsetStorage_ my_subset;
447 bool my_by_row;
448
449 Index_ get_mapping_dim() const {
450 if (my_by_row) {
451 return my_matrix->nrow();
452 } else {
453 return my_matrix->ncol();
454 }
455 }
456
457public:
458 Index_ nrow() const {
459 if (my_by_row) {
460 return my_subset.size();
461 } else {
462 return my_matrix->nrow();
463 }
464 }
465
466 Index_ ncol() const {
467 if (my_by_row) {
468 return my_matrix->ncol();
469 } else {
470 return my_subset.size();
471 }
472 }
473
474 bool is_sparse() const {
475 return my_matrix->is_sparse();
476 }
477
478 double is_sparse_proportion() const {
479 return my_matrix->is_sparse_proportion();
480 }
481
482 bool prefer_rows() const {
483 return my_matrix->prefer_rows();
484 }
485
486 double prefer_rows_proportion() const {
487 return my_matrix->prefer_rows_proportion();
488 }
489
490 bool uses_oracle(const bool row) const {
491 return my_matrix->uses_oracle(row);
492 }
493
494 using Matrix<Value_, Index_>::dense_column;
495
496 using Matrix<Value_, Index_>::dense_row;
497
498 using Matrix<Value_, Index_>::sparse_column;
499
500 using Matrix<Value_, Index_>::sparse_row;
501
502 /********************
503 *** Myopic dense ***
504 ********************/
505private:
506 template<typename ... Args_>
507 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > populate_myopic_dense(
508 const bool row,
509 Args_&& ... args
510 ) const {
511 if (row == my_by_row) {
512 return std::make_unique<subset_utils::MyopicPerpendicularDense<Value_, Index_, SubsetStorage_> >(
513 *my_matrix,
514 my_subset,
515 row,
516 std::forward<Args_>(args)...
517 );
518 } else {
519 return std::make_unique<DelayedSubsetSorted_internal::ParallelDense<false, Value_, Index_> >(
520 *my_matrix,
521 my_subset,
522 row,
523 false,
524 std::forward<Args_>(args)...
525 );
526 }
527 }
528
529public:
530 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
531 const bool row,
532 const Options& opt
533 ) const {
534 return populate_myopic_dense(row, opt);
535 }
536
537 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
538 const bool row,
539 const Index_ block_start,
540 const Index_ block_length,
541 const Options& opt
542 ) const {
543 return populate_myopic_dense(row, block_start, block_length, opt);
544 }
545
546 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
547 const bool row,
548 VectorPtr<Index_> indices_ptr,
549 const Options& opt
550 ) const {
551 return populate_myopic_dense(row, std::move(indices_ptr), opt);
552 }
553
554 /*********************
555 *** Myopic sparse ***
556 *********************/
557private:
558 template<DimensionSelectionType selection_, bool oracle_, typename ... Args_>
559 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > populate_sparse(
560 bool row,
562 Args_&& ... args
563 ) const {
564 if constexpr(selection_ == DimensionSelectionType::FULL) {
565 return std::make_unique<DelayedSubsetSorted_internal::ParallelFullSparse<oracle_, Value_, Index_> >(
566 *my_matrix,
567 my_subset,
568 row,
569 std::move(oracle),
570 std::forward<Args_>(args)...
571 );
572 } else if constexpr(selection_ == DimensionSelectionType::BLOCK) {
573 return std::make_unique<DelayedSubsetSorted_internal::ParallelBlockSparse<oracle_, Value_, Index_> >(
574 *my_matrix,
575 my_subset,
576 row,
577 std::move(oracle),
578 std::forward<Args_>(args)...
579 );
580 } else {
581 return std::make_unique<DelayedSubsetSorted_internal::ParallelIndexSparse<oracle_, Value_, Index_> >(
582 *my_matrix,
583 my_subset,
584 row,
585 std::move(oracle),
586 std::forward<Args_>(args)...
587 );
588 }
589 }
590
591 template<DimensionSelectionType selection_, typename ... Args_>
592 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > populate_myopic_sparse(
593 const bool row,
594 Args_&& ... args
595 ) const {
596 if (row == my_by_row) {
597 return std::make_unique<subset_utils::MyopicPerpendicularSparse<Value_, Index_, SubsetStorage_> >(
598 *my_matrix,
599 my_subset,
600 row,
601 std::forward<Args_>(args)...
602 );
603 } else {
604 return populate_sparse<selection_, false>(row, false, std::forward<Args_>(args)...);
605 }
606 }
607
608public:
609 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
610 const bool row,
611 const Options& opt
612 ) const {
613 return populate_myopic_sparse<DimensionSelectionType::FULL>(row, opt);
614 }
615
616 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
617 const bool row,
618 const Index_ block_start,
619 const Index_ block_length,
620 const Options& opt
621 ) const {
622 return populate_myopic_sparse<DimensionSelectionType::BLOCK>(row, block_start, block_length, opt);
623 }
624
625 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
626 const bool row,
627 VectorPtr<Index_> indices_ptr,
628 const Options& opt
629 ) const {
630 return populate_myopic_sparse<DimensionSelectionType::INDEX>(row, std::move(indices_ptr), opt);
631 }
632
633 /**********************
634 *** Oracular dense ***
635 **********************/
636private:
637 template<typename ... Args_>
638 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > populate_oracular_dense(
639 const bool row,
640 std::shared_ptr<const Oracle<Index_> > oracle,
641 Args_&& ... args
642 ) const {
643 if (row == my_by_row) {
644 return std::make_unique<subset_utils::OracularPerpendicularDense<Value_, Index_> >(
645 *my_matrix,
646 my_subset,
647 row,
648 std::move(oracle),
649 std::forward<Args_>(args)...
650 );
651 } else {
652 return std::make_unique<DelayedSubsetSorted_internal::ParallelDense<true, Value_, Index_> >(
653 *my_matrix,
654 my_subset,
655 row,
656 std::move(oracle),
657 std::forward<Args_>(args)...
658 );
659 }
660 }
661
662public:
663 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
664 const bool row,
665 std::shared_ptr<const Oracle<Index_> > oracle,
666 const Options& opt
667 ) const {
668 return populate_oracular_dense(row, std::move(oracle), opt);
669 }
670
671 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
672 const bool row,
673 std::shared_ptr<const Oracle<Index_> > oracle,
674 const Index_ block_start,
675 const Index_ block_length,
676 const Options& opt
677 ) const {
678 return populate_oracular_dense(row, std::move(oracle), block_start, block_length, opt);
679 }
680
681 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
682 const bool row,
683 std::shared_ptr<const Oracle<Index_> > oracle,
684 VectorPtr<Index_> indices_ptr,
685 const Options& opt
686 ) const {
687 return populate_oracular_dense(row, std::move(oracle), std::move(indices_ptr), opt);
688 }
689
690 /***********************
691 *** Oracular sparse ***
692 ***********************/
693private:
694 template<DimensionSelectionType selection_, typename ... Args_>
695 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > populate_oracular_sparse(
696 const bool row,
697 std::shared_ptr<const Oracle<Index_> > oracle,
698 Args_&& ... args
699 ) const {
700 if (row == my_by_row) {
701 return std::make_unique<subset_utils::OracularPerpendicularSparse<Value_, Index_> >(
702 *my_matrix,
703 my_subset,
704 row,
705 std::move(oracle),
706 std::forward<Args_>(args)...
707 );
708 } else {
709 return populate_sparse<selection_, true>(row, std::move(oracle), std::forward<Args_>(args)...);
710 }
711 }
712
713public:
714 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
715 const bool row,
716 std::shared_ptr<const Oracle<Index_> > oracle,
717 const Options& opt
718 ) const {
719 return populate_oracular_sparse<DimensionSelectionType::FULL>(row, std::move(oracle), opt);
720 }
721
722 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
723 const bool row,
724 std::shared_ptr<const Oracle<Index_> > oracle,
725 const Index_ block_start,
726 const Index_ block_length,
727 const Options& opt
728 ) const {
729 return populate_oracular_sparse<DimensionSelectionType::BLOCK>(row, std::move(oracle), block_start, block_length, opt);
730 }
731
732 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
733 const bool row,
734 std::shared_ptr<const Oracle<Index_> > oracle,
735 VectorPtr<Index_> indices_ptr,
736 const Options& opt
737 ) const {
738 return populate_oracular_sparse<DimensionSelectionType::INDEX>(row, std::move(oracle), std::move(indices_ptr), opt);
739 }
740};
741
742}
743
744#endif
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:714
double prefer_rows_proportion() const
Definition DelayedSubsetSorted.hpp:486
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, const Options &opt) const
Definition DelayedSubsetSorted.hpp:609
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:722
Index_ nrow() const
Definition DelayedSubsetSorted.hpp:458
bool prefer_rows() const
Definition DelayedSubsetSorted.hpp:482
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:537
double is_sparse_proportion() const
Definition DelayedSubsetSorted.hpp:478
bool is_sparse() const
Definition DelayedSubsetSorted.hpp:474
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:546
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetSorted.hpp:663
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:671
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Options &opt) const
Definition DelayedSubsetSorted.hpp:530
bool uses_oracle(const bool row) const
Definition DelayedSubsetSorted.hpp:490
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:616
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSorted.hpp:625
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:732
Index_ ncol() const
Definition DelayedSubsetSorted.hpp:466
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:681
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:92
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