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
7#include <algorithm>
8#include <numeric>
9#include <memory>
10
19namespace tatami {
20
25
26template<typename Index_>
28 std::vector<Index_> collapsed;
29 std::vector<Index_> expansion;
30};
31
32template<typename Index_, class SubsetStorage_, class ToIndex_>
35 output.expansion.reserve(len);
36 output.collapsed.reserve(len);
37
38 if (len) {
39 auto last = indices[to_index(0)];
40 output.expansion.push_back(1);
41 output.collapsed.push_back(last);
42
43 for (Index_ i = 1; i < len; ++i) {
44 auto current = indices[to_index(i)];
45 if (current == last) {
46 ++(output.expansion.back());
47 } else {
48 last = current;
49 output.expansion.push_back(1);
50 output.collapsed.push_back(last);
51 }
52 }
53 }
54
55 return output;
56}
57
58template<bool oracle_, typename Value_, typename Index_>
59class ParallelDense : public DenseExtractor<oracle_, Value_, Index_> {
60public:
61 template<class SubsetStorage_>
62 ParallelDense(const Matrix<Value_, Index_>* matrix, const SubsetStorage_& subset, bool row, MaybeOracle<oracle_, Index_> oracle, const Options& opt) {
63 auto processed = format_dense_parallel<Index_>(subset, subset.size(), [&](Index_ i) -> Index_ { return i; });
64 initialize(matrix, std::move(processed), subset.size(), row, std::move(oracle), opt);
65 }
66
67 template<class SubsetStorage_>
68 ParallelDense(const Matrix<Value_, Index_>* matrix, const SubsetStorage_& subset, bool row, MaybeOracle<oracle_, Index_> oracle, Index_ block_start, Index_ block_length, const Options& opt) {
69 auto processed = format_dense_parallel<Index_>(subset, block_length, [&](Index_ i) -> Index_ { return i + block_start; });
70 initialize(matrix, std::move(processed), block_length, row, std::move(oracle), opt);
71 }
72
73 template<class SubsetStorage_>
74 ParallelDense(const Matrix<Value_, Index_>* matrix, const SubsetStorage_& subset, bool row, MaybeOracle<oracle_, Index_> oracle, VectorPtr<Index_> indices_ptr, const Options& opt) {
75 const auto& indices = *indices_ptr;
76 auto processed = format_dense_parallel<Index_>(subset, indices.size(), [&](Index_ i) -> Index_ { return indices[i]; });
77 initialize(matrix, std::move(processed), indices.size(), row, std::move(oracle), opt);
78 }
79
80private:
81 void initialize(const Matrix<Value_, Index_>* mat, DenseParallelResults<Index_> processed, size_t extent, bool row, MaybeOracle<oracle_, Index_> oracle, const Options& opt) {
82 my_shift = extent - processed.collapsed.size();
83 my_ext = new_extractor<false, oracle_>(mat, row, std::move(oracle), std::move(processed.collapsed), opt);
84 my_expansion = std::move(processed.expansion);
85 }
86
87public:
88 const Value_* fetch(Index_ i, Value_* buffer) {
89 auto input = my_ext->fetch(i, buffer + my_shift);
90
91 // 'input' and 'buffer' may optionally point to overlapping arrays as long
92 // as 'buffer' precedes 'input'. The idea is that the expansion of values
93 // into 'buffer' will cause it to "catch up" to 'input' without clobbering
94 // any values in the latter. This assumes that 'input' has been shifted
95 // enough to make space for expansion; the required shift depends on the
96 // number of duplicates in 'expansion'.
97
98 auto copy = buffer;
99 for (auto e : my_expansion) {
100 // Once we've caught up, everything else must be a non-duplicate,
101 // otherwise we'd be clobbering as-yet-unread values from the input.
102 // So we might as well just quit at this point.
103 if (input == copy) {
104 break;
105 }
106
107 auto val = *input;
108 std::fill_n(copy, e, val);
109 ++input;
110 copy += e;
111 }
112
113 return buffer;
114 }
115
116private:
117 std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > my_ext;
118 std::vector<Index_> my_expansion;
119 size_t my_shift;
120};
121
122template<typename Index_>
124 // This is a bit complicated to explain.
125 // Let 'x = start[i - offset]'.
126 // Let 'y = lengths[i - offset]'.
127 // Let 'z' denote any integer in '[x, x + y)'.
128 // Let 'f' be the selection-specific function such that 'f(a)' is the a-th element of the selection
129 // (i.e., 'a' for full selection, 'a + start' for block selection and 'subset[a]' for indexed selection).
130 // In which case, 'indices[f(z)]' is equal to 'i'.
131 // The general idea is that 'f(z)' can be used to fill the 'SparseRange::index' on output.
132 std::vector<Index_> start;
133 std::vector<Index_> length;
134
135 Index_ offset = 0;
136};
137
138template<typename Index_>
140 std::vector<Index_> collapsed;
141 SparseParallelExpansion<Index_> expansion;
142};
143
144template<typename Index_, class SubsetStorage_, class ToIndex_>
147
148 if (len) {
149 output.collapsed.reserve(len);
150 auto first = indices[to_index(0)];
151
152 // 'start' and 'length' are vectors that enable look-up according to
153 // the indices of the underlying array. To avoid the need to allocate a
154 // vector of length equal to the underlying array's dimension, we only
155 // consider the extremes of 'indices'; we allocate the two vectors to
156 // have length equal to the range of 'indices'. The 'offset' defines
157 // the lower bound that must be subtracted from the array indices to
158 // get an index into 'start' or 'length'.
159 output.expansion.offset = first;
160 auto allocation = indices[to_index(len - 1)] - output.expansion.offset + 1;
161 output.expansion.start.resize(allocation);
162 output.expansion.length.resize(allocation);
163
164 Index_ lookup = 0;
165 output.expansion.start[0] = 0;
166 output.expansion.length[0] = 1;
167 output.collapsed.push_back(first);
168 auto last = first;
169
170 for (Index_ i = 1; i < len; ++i) {
171 auto current = indices[to_index(i)];
172 if (current == last) {
173 ++(output.expansion.length[lookup]);
174 continue;
175 }
176
177 lookup = current - output.expansion.offset;
178 output.expansion.start[lookup] = i;
179 output.expansion.length[lookup] = 1;
180 output.collapsed.push_back(current);
181 last = current;
182 }
183 }
184
185 return output;
186}
187
188template<bool oracle_, typename Value_, typename Index_>
189class ParallelSparseCore {
190public:
191 template<class SubsetStorage_, class ToIndex_>
192 ParallelSparseCore(const Matrix<Value_, Index_>* matrix, const SubsetStorage_& subset, size_t extent, bool row, MaybeOracle<oracle_, Index_> oracle, Options opt, ToIndex_ to_index) {
193 auto processed = format_sparse_parallel<Index_>(subset, extent, std::forward<ToIndex_>(to_index));
194 my_shift = extent - processed.collapsed.size();
195
196 my_needs_value = opt.sparse_extract_value;
197 my_needs_index = opt.sparse_extract_index;
198 opt.sparse_extract_index = true; // must extract the indices for proper my_expansion.
199 if (!my_needs_index) {
200 my_holding_ibuffer.reserve(processed.collapsed.size()); // need a holding space for indices if 'ibuffer' is not supplied.
201 }
202
203 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), std::move(processed.collapsed), opt);
204 my_expansion = std::move(processed.expansion);
205 }
206
207 template<class ToIndex_>
208 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer, ToIndex_ to_index) {
209 // Shifting so that there's enough space for my_expansion, but only doing
210 // so if these pointers are guaranteed to be non-NULL.
211 auto vinit = (my_needs_value ? value_buffer + my_shift : NULL);
212 auto iinit = (my_needs_index ? index_buffer + my_shift : my_holding_ibuffer.data());
213 auto input = my_ext->fetch(i, vinit, iinit);
214
215 auto vcopy = value_buffer;
216 auto icopy = index_buffer;
217 Index_ count = 0;
218
219 auto vsrc = input.value;
220 bool replace_value = my_needs_value && vsrc != vcopy;
221
222 // Pointers in 'input' and the two 'buffer' pointers may optionally point
223 // to overlapping arrays as long as each 'buffer' pointer precede its
224 // corresponding pointer in 'input'. The idea is that the expansion of
225 // values into 'buffer' will cause it to "catch up" to 'input' without
226 // clobbering any values in the latter. This assumes that 'input' has been
227 // shift enough to make space for expansion; the required shift depends
228 // on the number of duplicates.
229 for (Index_ i = 0; i < input.number; ++i) {
230 auto eindex = input.index[i] - my_expansion.offset;
231 auto nexpand = my_expansion.length[eindex];
232 count += nexpand;
233
234 if (replace_value) {
235 auto v = *vsrc; // make a copy just in case 'vcopy' and 'input.value' overlap.
236 std::fill_n(vcopy, nexpand, v);
237 vcopy += nexpand;
238 ++vsrc;
239 replace_value = (vcopy != vsrc); // if we've caught up, there no need to do this replacement.
240 }
241
242 if (my_needs_index) {
243 auto sexpand = my_expansion.start[eindex];
244 for (Index_ e = 0; e < nexpand; ++e, ++icopy) {
245 *icopy = to_index(sexpand + e);
246 }
247 }
248 }
249
250 return SparseRange<Value_, Index_>(
251 count,
252 (my_needs_value ? value_buffer : NULL),
253 (my_needs_index ? index_buffer : NULL)
254 );
255 }
256
257private:
258 bool my_needs_value, my_needs_index;
259 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > my_ext;
260 std::vector<Index_> my_holding_ibuffer;
261 SparseParallelExpansion<Index_> my_expansion;
262 size_t my_shift;
263};
264
265template<bool oracle_, typename Value_, typename Index_>
266class ParallelFullSparse : public SparseExtractor<oracle_, Value_, Index_> {
267public:
268 template<class SubsetStorage_>
269 ParallelFullSparse(const Matrix<Value_, Index_>* matrix, const SubsetStorage_& subset, bool row, MaybeOracle<oracle_, Index_> oracle, const Options& opt) :
270 my_core(matrix, subset, subset.size(), row, std::move(oracle), opt, [](Index_ i) -> Index_ { return i; }) {}
271
273 return my_core.fetch(i, value_buffer, index_buffer, [](Index_ i) -> Index_ { return i; });
274 }
275
276private:
278};
279
280template<bool oracle_, typename Value_, typename Index_>
281class ParallelBlockSparse : public SparseExtractor<oracle_, Value_, Index_> {
282public:
283 template<class SubsetStorage_>
284 ParallelBlockSparse(const Matrix<Value_, Index_>* matrix, const SubsetStorage_& subset, bool row, MaybeOracle<oracle_, Index_> oracle, Index_ block_start, Index_ block_length, const Options& opt) :
286 my_block_start(block_start)
287 {}
288
290 return my_core.fetch(i, value_buffer, index_buffer, [&](Index_ i) -> Index_ { return i + my_block_start; });
291 }
292
293private:
295 Index_ my_block_start;
296};
297
298template<bool oracle_, typename Value_, typename Index_>
299class ParallelIndexSparse : public SparseExtractor<oracle_, Value_, Index_> {
300public:
301 template<class SubsetStorage_>
302 ParallelIndexSparse(const Matrix<Value_, Index_>* matrix, const SubsetStorage_& subset, bool row, MaybeOracle<oracle_, Index_> oracle, VectorPtr<Index_> indices_ptr, const Options& opt) :
303 my_core(matrix, subset, indices_ptr->size(), row, std::move(oracle), opt, [&](Index_ i) -> Index_ { return indices_ptr->operator[](i); }),
304 my_indices_ptr(std::move(indices_ptr))
305 {}
306
307 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
308 const auto& indices = *my_indices_ptr;
309 return my_core.fetch(i, value_buffer, index_buffer, [&](Index_ i) -> Index_ { return indices[i]; });
310 }
311
312private:
313 ParallelSparseCore<oracle_, Value_, Index_> my_core;
314 VectorPtr<Index_> my_indices_ptr;
315};
316
317}
333template<typename Value_, typename Index_, class SubsetStorage_>
334class DelayedSubsetSorted : public Matrix<Value_, Index_> {
335public:
344 DelayedSubsetSorted(std::shared_ptr<const Matrix<Value_, Index_> > matrix, SubsetStorage_ subset, bool by_row, bool check = true) :
345 my_matrix(std::move(matrix)), my_subset(std::move(subset)), my_by_row(by_row)
346 {
347 if (check) {
348 for (Index_ i = 1, end = my_subset.size(); i < end; ++i) {
349 if (my_subset[i] < my_subset[i-1]) {
350 throw std::runtime_error("my_subset should be sorted");
351 }
352 }
353 }
354 }
355
356private:
357 std::shared_ptr<const Matrix<Value_, Index_> > my_matrix;
358 SubsetStorage_ my_subset;
359 bool my_by_row;
360
361 Index_ get_mapping_dim() const {
362 if (my_by_row) {
363 return my_matrix->nrow();
364 } else {
365 return my_matrix->ncol();
366 }
367 }
368
369public:
370 Index_ nrow() const {
371 if (my_by_row) {
372 return my_subset.size();
373 } else {
374 return my_matrix->nrow();
375 }
376 }
377
378 Index_ ncol() const {
379 if (my_by_row) {
380 return my_matrix->ncol();
381 } else {
382 return my_subset.size();
383 }
384 }
385
386 bool is_sparse() const {
387 return my_matrix->is_sparse();
388 }
389
390 double is_sparse_proportion() const {
391 return my_matrix->is_sparse_proportion();
392 }
393
394 bool prefer_rows() const {
395 return my_matrix->prefer_rows();
396 }
397
398 double prefer_rows_proportion() const {
399 return my_matrix->prefer_rows_proportion();
400 }
401
402 bool uses_oracle(bool row) const {
403 return my_matrix->uses_oracle(row);
404 }
405
406 using Matrix<Value_, Index_>::dense_column;
407
408 using Matrix<Value_, Index_>::dense_row;
409
410 using Matrix<Value_, Index_>::sparse_column;
411
412 using Matrix<Value_, Index_>::sparse_row;
413
414 /********************
415 *** Myopic dense ***
416 ********************/
417private:
418 template<typename ... Args_>
419 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > populate_myopic_dense(bool row, Args_&& ... args) const {
420 if (row == my_by_row) {
421 return std::make_unique<subset_utils::MyopicPerpendicularDense<Value_, Index_, SubsetStorage_> >(my_matrix.get(), my_subset, row, std::forward<Args_>(args)...);
422 } else {
423 return std::make_unique<DelayedSubsetSorted_internal::ParallelDense<false, Value_, Index_> >(my_matrix.get(), my_subset, row, false, std::forward<Args_>(args)...);
424 }
425 }
426
427public:
428 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, const Options& opt) const {
429 return populate_myopic_dense(row, opt);
430 }
431
432 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, Index_ block_start, Index_ block_length, const Options& opt) const {
433 return populate_myopic_dense(row, block_start, block_length, opt);
434 }
435
436 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, VectorPtr<Index_> indices_ptr, const Options& opt) const {
437 return populate_myopic_dense(row, std::move(indices_ptr), opt);
438 }
439
440 /*********************
441 *** Myopic sparse ***
442 *********************/
443private:
444 template<DimensionSelectionType selection_, bool oracle_, typename ... Args_>
445 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > populate_sparse(bool row, MaybeOracle<oracle_, Index_> oracle, Args_&& ... args) const {
446 if constexpr(selection_ == DimensionSelectionType::FULL) {
447 return std::make_unique<DelayedSubsetSorted_internal::ParallelFullSparse<oracle_, Value_, Index_> >(my_matrix.get(), my_subset, row, std::move(oracle), std::forward<Args_>(args)...);
448 } else if constexpr(selection_ == DimensionSelectionType::BLOCK) {
449 return std::make_unique<DelayedSubsetSorted_internal::ParallelBlockSparse<oracle_, Value_, Index_> >(my_matrix.get(), my_subset, row, std::move(oracle), std::forward<Args_>(args)...);
450 } else {
451 return std::make_unique<DelayedSubsetSorted_internal::ParallelIndexSparse<oracle_, Value_, Index_> >(my_matrix.get(), my_subset, row, std::move(oracle), std::forward<Args_>(args)...);
452 }
453 }
454
455 template<DimensionSelectionType selection_, typename ... Args_>
456 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > populate_myopic_sparse(bool row, Args_&& ... args) const {
457 if (row == my_by_row) {
458 return std::make_unique<subset_utils::MyopicPerpendicularSparse<Value_, Index_, SubsetStorage_> >(my_matrix.get(), my_subset, row, std::forward<Args_>(args)...);
459 } else {
460 return populate_sparse<selection_, false>(row, false, std::forward<Args_>(args)...);
461 }
462 }
463
464public:
465 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, const Options& opt) const {
466 return populate_myopic_sparse<DimensionSelectionType::FULL>(row, opt);
467 }
468
469 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, Index_ block_start, Index_ block_length, const Options& opt) const {
470 return populate_myopic_sparse<DimensionSelectionType::BLOCK>(row, block_start, block_length, opt);
471 }
472
473 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, VectorPtr<Index_> indices_ptr, const Options& opt) const {
474 return populate_myopic_sparse<DimensionSelectionType::INDEX>(row, std::move(indices_ptr), opt);
475 }
476
477 /**********************
478 *** Oracular dense ***
479 **********************/
480private:
481 template<typename ... Args_>
482 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > populate_oracular_dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, Args_&& ... args) const {
483 if (row == my_by_row) {
484 return std::make_unique<subset_utils::OracularPerpendicularDense<Value_, Index_> >(my_matrix.get(), my_subset, row, std::move(oracle), std::forward<Args_>(args)...);
485 } else {
486 return std::make_unique<DelayedSubsetSorted_internal::ParallelDense<true, Value_, Index_> >(my_matrix.get(), my_subset, row, std::move(oracle), std::forward<Args_>(args)...);
487 }
488 }
489
490public:
491 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, const Options& opt) const {
492 return populate_oracular_dense(row, std::move(oracle), opt);
493 }
494
495 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, Index_ block_start, Index_ block_length, const Options& opt) const {
496 return populate_oracular_dense(row, std::move(oracle), block_start, block_length, opt);
497 }
498
499 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, VectorPtr<Index_> indices_ptr, const Options& opt) const {
500 return populate_oracular_dense(row, std::move(oracle), std::move(indices_ptr), opt);
501 }
502
503 /***********************
504 *** Oracular sparse ***
505 ***********************/
506private:
507 template<DimensionSelectionType selection_, typename ... Args_>
508 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > populate_oracular_sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, Args_&& ... args) const {
509 if (row == my_by_row) {
510 return std::make_unique<subset_utils::OracularPerpendicularSparse<Value_, Index_> >(my_matrix.get(), my_subset, row, std::move(oracle), std::forward<Args_>(args)...);
511 } else {
512 return populate_sparse<selection_, true>(row, std::move(oracle), std::forward<Args_>(args)...);
513 }
514 }
515
516public:
517 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, const Options& opt) const {
518 return populate_oracular_sparse<DimensionSelectionType::FULL>(row, std::move(oracle), opt);
519 }
520
521 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, Index_ block_start, Index_ block_length, const Options& opt) const {
522 return populate_oracular_sparse<DimensionSelectionType::BLOCK>(row, std::move(oracle), block_start, block_length, opt);
523 }
524
525 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, VectorPtr<Index_> indices_ptr, const Options& opt) const {
526 return populate_oracular_sparse<DimensionSelectionType::INDEX>(row, std::move(oracle), std::move(indices_ptr), opt);
527 }
528};
529
530}
531
532#endif
Delayed subsetting of a matrix with sorted indices.
Definition DelayedSubsetSorted.hpp:334
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubsetSorted.hpp:495
double prefer_rows_proportion() const
Definition DelayedSubsetSorted.hpp:398
Index_ nrow() const
Definition DelayedSubsetSorted.hpp:370
bool prefer_rows() const
Definition DelayedSubsetSorted.hpp:394
DelayedSubsetSorted(std::shared_ptr< const Matrix< Value_, Index_ > > matrix, SubsetStorage_ subset, bool by_row, bool check=true)
Definition DelayedSubsetSorted.hpp:344
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSorted.hpp:499
double is_sparse_proportion() const
Definition DelayedSubsetSorted.hpp:390
bool is_sparse() const
Definition DelayedSubsetSorted.hpp:386
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubsetSorted.hpp:469
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubsetSorted.hpp:432
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSorted.hpp:473
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubsetSorted.hpp:521
bool uses_oracle(bool row) const
Definition DelayedSubsetSorted.hpp:402
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, const Options &opt) const
Definition DelayedSubsetSorted.hpp:428
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetSorted.hpp:491
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetSorted.hpp:517
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSorted.hpp:436
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSorted.hpp:525
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, const Options &opt) const
Definition DelayedSubsetSorted.hpp:465
Index_ ncol() const
Definition DelayedSubsetSorted.hpp:378
Virtual class for a matrix.
Definition Matrix.hpp:59
Predict future access requests on the target dimension.
Definition Oracle.hpp:21
Flexible representations for matrix data.
Definition Extractor.hpp:15
DimensionSelectionType
Definition Options.hpp:25
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
typename std::conditional< oracle_, OracularSparseExtractor< Value_, Index_ >, MyopicSparseExtractor< Value_, Index_ > >::type SparseExtractor
Definition Extractor.hpp:284
typename std::conditional< oracle_, std::shared_ptr< const Oracle< Index_ > >, bool >::type MaybeOracle
Definition new_extractor.hpp:20
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
auto consecutive_extractor(const Matrix< Value_, Index_ > *mat, bool row, Index_ iter_start, Index_ iter_length, Args_ &&... args)
Definition consecutive_extractor.hpp:35
Options for accessing data from a Matrix instance.
Definition Options.hpp:30