tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
FragmentedSparseMatrix.hpp
Go to the documentation of this file.
1#ifndef TATAMI_FRAGMENTED_SPARSE_MATRIX_H
2#define TATAMI_FRAGMENTED_SPARSE_MATRIX_H
3
4#include "../base/Matrix.hpp"
5#include "primary_extraction.hpp"
6#include "secondary_extraction.hpp"
9
10#include <vector>
11#include <algorithm>
12#include <memory>
13#include <utility>
14#include <stdexcept>
15
22namespace tatami {
23
27namespace FragmentedSparseMatrix_internal {
28
29/********************
30 *** Primary full ***
31 ********************/
32
33template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
34class PrimaryMyopicFullDense : public MyopicDenseExtractor<Value_, Index_> {
35public:
36 PrimaryMyopicFullDense(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary) :
37 my_values(values), my_indices(indices), my_secondary(secondary) {}
38
39 const Value_* fetch(Index_ i, Value_* buffer) {
40 const auto& curv = my_values[i];
41 const auto& curi = my_indices[i];
42
43 std::fill_n(buffer, my_secondary, static_cast<Value_>(0));
44 size_t end = curv.size();
45 for (size_t x = 0; x < end; ++x) {
46 buffer[curi[x]] = curv[x];
47 }
48 return buffer;
49 }
50
51private:
52 const ValueVectorStorage_& my_values;
53 const IndexVectorStorage_& my_indices;
54 Index_ my_secondary;
55};
56
57template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
58class PrimaryMyopicFullSparse : public MyopicSparseExtractor<Value_, Index_> {
59public:
60 PrimaryMyopicFullSparse(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, [[maybe_unused]] Index_ secondary /* for consistency only */, const Options& opt) :
61 my_values(values), my_indices(indices), my_needs_value(opt.sparse_extract_value), my_needs_index(opt.sparse_extract_index) {}
62
63 SparseRange<Value_, Index_> fetch(Index_ i, Value_* vbuffer, Index_* index_buffer) {
64 const auto& curv = my_values[i];
65 const auto& curi = my_indices[i];
66
67 SparseRange<Value_, Index_> output(curv.size(), NULL, NULL);
68 if (my_needs_value) {
69 output.value = sparse_utils::extract_primary_vector(curv, static_cast<size_t>(0), curv.size(), vbuffer);
70 }
71 if (my_needs_index) {
72 output.index = sparse_utils::extract_primary_vector(curi, static_cast<size_t>(0), curi.size(), index_buffer);
73 }
74 return output;
75 }
76
77private:
78 const ValueVectorStorage_& my_values;
79 const IndexVectorStorage_& my_indices;
80 bool my_needs_value, my_needs_index;
81};
82
83/*********************
84 *** Primary block ***
85 *********************/
86
87template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
88class PrimaryMyopicBlockDense : public MyopicDenseExtractor<Value_, Index_> {
89public:
90 PrimaryMyopicBlockDense(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary, Index_ block_start, Index_ block_length) :
91 my_values(values), my_indices(indices), my_secondary(secondary), my_block_start(block_start), my_block_length(block_length) {}
92
93 const Value_* fetch(Index_ i, Value_* buffer) {
94 const auto& curi = my_indices[i];
95 const auto& curv = my_values[i];
96
97 auto iStart = curi.begin();
98 auto iEnd = curi.end();
99 sparse_utils::refine_primary_block_limits(iStart, iEnd, my_secondary, my_block_start, my_block_length);
100 size_t offset = (iStart - curi.begin());
101 size_t number = iEnd - iStart;
102
103 std::fill_n(buffer, my_block_length, static_cast<Value_>(0));
104 for (size_t i = 0; i < number; ++i) {
105 auto cur_offset = offset + i;
106 buffer[curi[cur_offset] - my_block_start] = curv[cur_offset];
107 }
108 return buffer;
109 }
110
111private:
112 const ValueVectorStorage_& my_values;
113 const IndexVectorStorage_& my_indices;
114 Index_ my_secondary;
115 Index_ my_block_start, my_block_length;
116};
117
118template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
119class PrimaryMyopicBlockSparse : public MyopicSparseExtractor<Value_, Index_> {
120public:
121 PrimaryMyopicBlockSparse(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary, Index_ block_start, Index_ block_length, const Options& opt) :
122 my_values(values),
123 my_indices(indices),
124 my_secondary(secondary),
125 my_block_start(block_start),
126 my_block_length(block_length),
127 my_needs_value(opt.sparse_extract_value),
128 my_needs_index(opt.sparse_extract_index)
129 {}
130
131 SparseRange<Value_, Index_> fetch(Index_ i, Value_* vbuffer, Index_* index_buffer) {
132 const auto& curi = my_indices[i];
133 auto iStart = curi.begin();
134 auto iEnd = curi.end();
135 sparse_utils::refine_primary_block_limits(iStart, iEnd, my_secondary, my_block_start, my_block_length);
136 size_t offset = iStart - curi.begin();
137 size_t delta = iEnd - iStart;
138
139 SparseRange<Value_, Index_> output(delta, NULL, NULL);
140 if (my_needs_value) {
141 output.value = sparse_utils::extract_primary_vector(my_values[i], offset, delta, vbuffer);
142 }
143 if (my_needs_index) {
144 output.index = sparse_utils::extract_primary_vector(curi, offset, delta, index_buffer);
145 }
146 return output;
147 }
148
149private:
150 const ValueVectorStorage_& my_values;
151 const IndexVectorStorage_& my_indices;
152 Index_ my_secondary;
153 Index_ my_block_start, my_block_length;
154 bool my_needs_value, my_needs_index;
155};
156
157/***********************
158 *** Primary indexed ***
159 ***********************/
160
161template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
162class PrimaryMyopicIndexDense : public MyopicDenseExtractor<Value_, Index_> {
163public:
164 PrimaryMyopicIndexDense(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary, VectorPtr<Index_> indices_ptr) :
165 my_values(values), my_indices(indices), my_retriever(*indices_ptr, secondary), my_num_indices(indices_ptr->size()) {}
166
167 const Value_* fetch(Index_ i, Value_* buffer) {
168 const auto& curi = my_indices[i];
169 const auto& curv = my_values[i];
170 std::fill_n(buffer, my_num_indices, static_cast<Value_>(0));
171 my_retriever.populate(
172 curi.begin(),
173 curi.end(),
174 [&](size_t s, size_t offset) -> void {
175 buffer[s] = curv[offset];
176 }
177 );
178 return buffer;
179 }
180
181private:
182 const ValueVectorStorage_& my_values;
183 const IndexVectorStorage_& my_indices;
184 sparse_utils::RetrievePrimarySubsetDense<Index_> my_retriever;
185 size_t my_num_indices;
186};
187
188template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
189class PrimaryMyopicIndexSparse : public MyopicSparseExtractor<Value_, Index_> {
190public:
191 PrimaryMyopicIndexSparse(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary, VectorPtr<Index_> indices_ptr, const Options& opt) :
192 my_values(values), my_indices(indices), my_retriever(*indices_ptr, secondary), my_needs_value(opt.sparse_extract_value), my_needs_index(opt.sparse_extract_index) {}
193
194 SparseRange<Value_, Index_> fetch(Index_ i, Value_* vbuffer, Index_* index_buffer) {
195 const auto& curi = my_indices[i];
196 const auto& curv = my_values[i];
197 Index_ count = 0;
198 auto vcopy = vbuffer;
199 auto icopy = index_buffer;
200
201 my_retriever.populate(
202 curi.begin(),
203 curi.end(),
204 [&](size_t offset, Index_ ix) -> void {
205 ++count;
206 if (my_needs_value) {
207 *vcopy = curv[offset];
208 ++vcopy;
209 }
210 if (my_needs_index) {
211 *icopy = ix;
212 ++icopy;
213 }
214 }
215 );
216
217 return SparseRange<Value_, Index_>(count, my_needs_value ? vbuffer : NULL, my_needs_index ? index_buffer : NULL);
218 }
219
220private:
221 const ValueVectorStorage_& my_values;
222 const IndexVectorStorage_& my_indices;
223 sparse_utils::RetrievePrimarySubsetSparse<Index_> my_retriever;
224 bool my_needs_value, my_needs_index;
225};
226
227/**********************
228 *** Secondary full ***
229 **********************/
230
231template<typename Index_, class IndexVectorStorage_>
232class ServeIndices {
233public:
234 ServeIndices(const IndexVectorStorage_& indices) : my_indices(indices) {}
235
236private:
237 const IndexVectorStorage_& my_indices;
238
239public:
240 typedef size_t pointer_type;
241
242 pointer_type start_offset(Index_) const {
243 return 0;
244 }
245
246 pointer_type end_offset(Index_ primary) const {
247 return my_indices[primary].size();
248 }
249
250 auto raw(Index_ primary) const {
251 return my_indices[primary].begin();
252 }
253};
254
255template<typename Index_, class IndexVectorStorage_>
256auto make_ServeIndices(const IndexVectorStorage_& i) {
257 return ServeIndices<Index_, IndexVectorStorage_>(i);
258}
259
260template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
261class SecondaryMyopicFullDense : public MyopicDenseExtractor<Value_, Index_> {
262public:
263 SecondaryMyopicFullDense(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary) :
264 my_values(values), my_cache(make_ServeIndices<Index_>(indices), secondary, indices.size()) {}
265
266 const Value_* fetch(Index_ i, Value_* buffer) {
267 std::fill_n(buffer, my_cache.size(), static_cast<Value_>(0));
268 my_cache.search(
269 i,
270 [&](Index_ primary, Index_ index_primary, size_t ptr) -> void {
271 buffer[index_primary] = my_values[primary][ptr];
272 }
273 );
274 return buffer;
275 }
276
277private:
278 const ValueVectorStorage_& my_values;
279 sparse_utils::FullSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
280};
281
282template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
283class SecondaryMyopicFullSparse : public MyopicSparseExtractor<Value_, Index_> {
284public:
285 SecondaryMyopicFullSparse(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary, const Options& opt) :
286 my_values(values), my_cache(make_ServeIndices<Index_>(indices), secondary, indices.size()), my_needs_value(opt.sparse_extract_value), my_needs_index(opt.sparse_extract_index) {}
287
288 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
289 Index_ count = 0;
290 my_cache.search(
291 i,
292 [&](Index_ primary, Index_, size_t ptr) -> void {
293 if (my_needs_value) {
294 value_buffer[count] = my_values[primary][ptr];
295 }
296 if (my_needs_index) {
297 index_buffer[count] = primary;
298 }
299 ++count;
300 }
301 );
302 return SparseRange<Value_, Index_>(count, my_needs_value ? value_buffer : NULL, my_needs_index ? index_buffer : NULL);
303 }
304
305private:
306 const ValueVectorStorage_& my_values;
307 sparse_utils::FullSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
308 bool my_needs_value, my_needs_index;
309};
310
311/***********************
312 *** Secondary block ***
313 ***********************/
314
315template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
316class SecondaryMyopicBlockDense : public MyopicDenseExtractor<Value_, Index_> {
317public:
318 SecondaryMyopicBlockDense(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary, Index_ block_start, Index_ block_length) :
319 my_values(values), my_cache(make_ServeIndices<Index_>(indices), secondary, block_start, block_length) {}
320
321 const Value_* fetch(Index_ i, Value_* buffer) {
322 std::fill_n(buffer, my_cache.size(), static_cast<Value_>(0));
323 my_cache.search(
324 i,
325 [&](Index_ primary, Index_ index_primary, size_t ptr) -> void {
326 buffer[index_primary] = my_values[primary][ptr];
327 }
328 );
329 return buffer;
330 }
331
332private:
333 const ValueVectorStorage_& my_values;
334 sparse_utils::BlockSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
335};
336
337template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
338class SecondaryMyopicBlockSparse : public MyopicSparseExtractor<Value_, Index_> {
339public:
340 SecondaryMyopicBlockSparse(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary, Index_ block_start, Index_ block_length, const Options& opt) :
341 my_values(values), my_cache(make_ServeIndices<Index_>(indices), secondary, block_start, block_length), my_needs_value(opt.sparse_extract_value), my_needs_index(opt.sparse_extract_index) {}
342
343 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
344 Index_ count = 0;
345 my_cache.search(
346 i,
347 [&](Index_ primary, Index_, size_t ptr) -> void {
348 if (my_needs_value) {
349 value_buffer[count] = my_values[primary][ptr];
350 }
351 if (my_needs_index) {
352 index_buffer[count] = primary;
353 }
354 ++count;
355 }
356 );
357 return SparseRange<Value_, Index_>(count, my_needs_value ? value_buffer : NULL, my_needs_index ? index_buffer : NULL);
358 }
359
360private:
361 const ValueVectorStorage_& my_values;
362 sparse_utils::BlockSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
363 bool my_needs_value, my_needs_index;
364};
365
366/***********************
367 *** Secondary index ***
368 ***********************/
369
370template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
371class SecondaryMyopicIndexDense : public MyopicDenseExtractor<Value_, Index_> {
372public:
373 SecondaryMyopicIndexDense(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary, VectorPtr<Index_> indices_ptr) :
374 my_values(values), my_cache(make_ServeIndices<Index_>(indices), secondary, std::move(indices_ptr)) {}
375
376 const Value_* fetch(Index_ i, Value_* buffer) {
377 std::fill_n(buffer, my_cache.size(), static_cast<Value_>(0));
378 my_cache.search(
379 i,
380 [&](Index_ primary, Index_ index_primary, size_t ptr) -> void {
381 buffer[index_primary] = my_values[primary][ptr];
382 }
383 );
384 return buffer;
385 }
386
387private:
388 const ValueVectorStorage_& my_values;
389 sparse_utils::IndexSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
390};
391
392template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
393class SecondaryMyopicIndexSparse : public MyopicSparseExtractor<Value_, Index_> {
394public:
395 SecondaryMyopicIndexSparse(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, Index_ secondary, VectorPtr<Index_> indices_ptr, const Options& opt) :
396 my_values(values), my_cache(make_ServeIndices<Index_>(indices), secondary, std::move(indices_ptr)), my_needs_value(opt.sparse_extract_value), my_needs_index(opt.sparse_extract_index) {}
397
398 SparseRange<Value_, Index_> fetch(Index_ i, Value_* vbuffer, Index_* index_buffer) {
399 Index_ count = 0;
400 my_cache.search(
401 i,
402 [&](Index_ primary, Index_, size_t ptr) -> void {
403 if (my_needs_value) {
404 vbuffer[count] = my_values[primary][ptr];
405 }
406 if (my_needs_index) {
407 index_buffer[count] = primary;
408 }
409 ++count;
410 }
411 );
412 return SparseRange<Value_, Index_>(count, my_needs_value ? vbuffer : NULL, my_needs_index ? index_buffer : NULL);
413 }
414
415private:
416 const ValueVectorStorage_& my_values;
417 sparse_utils::IndexSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
418 bool my_needs_value, my_needs_index;
419};
420
421}
447template<
448 typename Value_,
449 typename Index_,
450 class ValueVectorStorage_ = std::vector<std::vector<Value_> >,
451 class IndexVectorStorage_ = std::vector<std::vector<Index_> >
452>
453class FragmentedSparseMatrix : public Matrix<Value_, Index_> {
454public:
468 FragmentedSparseMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool row_sparse, bool check = true) :
469 my_nrow(nrow), my_ncol(ncol), my_values(std::move(values)), my_indices(std::move(indices)), my_row_sparse(row_sparse)
470 {
471 if (check) {
472 if (my_values.size() != my_indices.size()) {
473 throw std::runtime_error("'values' and 'indices' should be of the same length");
474 }
475
476 if (my_row_sparse) {
477 if (my_indices.size() != static_cast<size_t>(my_nrow)) {
478 throw std::runtime_error("length of 'indices' should be equal to number of rows'");
479 }
480 } else {
481 if (my_indices.size() != static_cast<size_t>(my_ncol)) {
482 throw std::runtime_error("length of 'indices' should be equal to number of columns");
483 }
484 }
485
486 ElementType<ElementType<IndexVectorStorage_> > max_index = (my_row_sparse ? my_ncol : my_nrow);
487 for (size_t i = 0, end = my_indices.size(); i < end; ++i) {
488 const auto& curv = my_values[i];
489 const auto& curi = my_indices[i];
490 if (curv.size() != curi.size()) {
491 throw std::runtime_error("corresponding elements of 'values' and 'indices' should have the same length");
492 }
493
494 for (auto x : curi) {
495 if (x < 0 || x >= max_index) {
496 throw std::runtime_error("'indices' should contain non-negative integers less than the number of " + (my_row_sparse ? std::string("columns") : std::string("rows")));
497 }
498 }
499
500 for (size_t j = 1, jend = curi.size(); j < jend; ++j) {
501 if (curi[j] <= curi[j - 1]) {
502 throw std::runtime_error("my_indices should be strictly increasing within each element of 'indices'");
503 }
504 }
505 }
506 }
507 }
508
509private:
510 Index_ my_nrow, my_ncol;
511 ValueVectorStorage_ my_values;
512 IndexVectorStorage_ my_indices;
513 bool my_row_sparse;
514
515public:
516 Index_ nrow() const { return my_nrow; }
517
518 Index_ ncol() const { return my_ncol; }
519
520 bool is_sparse() const { return true; }
521
522 double is_sparse_proportion() const { return 1; }
523
524 bool prefer_rows() const { return my_row_sparse; }
525
526 double prefer_rows_proportion() const { return static_cast<double>(my_row_sparse); }
527
528 bool uses_oracle(bool) const { return false; }
529
530 using Matrix<Value_, Index_>::dense;
531
532 using Matrix<Value_, Index_>::sparse;
533
534private:
535 Index_ secondary() const {
536 if (my_row_sparse) {
537 return my_ncol;
538 } else {
539 return my_nrow;
540 }
541 }
542
543 /*****************************
544 ******* Dense myopic ********
545 *****************************/
546private:
547 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, const Options&) const {
548 if (my_row_sparse == row) {
549 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicFullDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
550 my_values, my_indices, secondary()
551 );
552 } else {
553 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicFullDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
554 my_values, my_indices, secondary()
555 );
556 }
557 }
558
559 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, Index_ block_start, Index_ block_end, const Options&) const {
560 if (my_row_sparse == row) {
561 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicBlockDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
562 my_values, my_indices, secondary(), block_start, block_end
563 );
564 } else {
565 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicBlockDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
566 my_values, my_indices, secondary(), block_start, block_end
567 );
568 }
569 }
570
571 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, VectorPtr<Index_> subset_ptr, const Options&) const {
572 if (my_row_sparse == row) {
573 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicIndexDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
574 my_values, my_indices, secondary(), std::move(subset_ptr)
575 );
576 } else {
577 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicIndexDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
578 my_values, my_indices, secondary(), std::move(subset_ptr)
579 );
580 }
581 }
582
583 /******************************
584 ******* Sparse myopic ********
585 ******************************/
586private:
587 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, const Options& opt) const {
588 if (my_row_sparse == row) {
589 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicFullSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
590 my_values, my_indices, secondary(), opt
591 );
592 } else {
593 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicFullSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
594 my_values, my_indices, secondary(), opt
595 );
596 }
597 }
598
599 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, Index_ block_start, Index_ block_end, const Options& opt) const {
600 if (my_row_sparse == row) {
601 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicBlockSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
602 my_values, my_indices, secondary(), block_start, block_end, opt
603 );
604 } else {
605 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicBlockSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
606 my_values, my_indices, secondary(), block_start, block_end, opt
607 );
608 }
609 }
610
611 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, VectorPtr<Index_> subset_ptr, const Options& opt) const {
612 if (my_row_sparse == row) {
613 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicIndexSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
614 my_values, my_indices, secondary(), std::move(subset_ptr), opt
615 );
616 } else {
617 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicIndexSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
618 my_values, my_indices, secondary(), std::move(subset_ptr), opt
619 );
620 }
621 }
622
623 /*******************************
624 ******* Dense oracular ********
625 *******************************/
626public:
627 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, const Options& opt) const {
628 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, opt));
629 }
630
631 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, Index_ block_start, Index_ block_end, const Options& opt) const {
632 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, block_start, block_end, opt));
633 }
634
635 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, VectorPtr<Index_> subset_ptr, const Options& opt) const {
636 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, std::move(subset_ptr), opt));
637 }
638
639 /********************************
640 ******* Sparse oracular ********
641 ********************************/
642public:
643 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, const Options& opt) const {
644 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, opt));
645 }
646
647 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, Index_ block_start, Index_ block_end, const Options& opt) const {
648 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, block_start, block_end, opt));
649 }
650
651 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, VectorPtr<Index_> subset_ptr, const Options& opt) const {
652 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, std::move(subset_ptr), opt));
653 }
654};
655
661template<typename Value_, typename Index_, class ValueVectorStorage_ = std::vector<std::vector<Value_> >, class IndexVectorStorage_ = std::vector<std::vector<Index_> > >
662class FragmentedSparseColumnMatrix : public FragmentedSparseMatrix<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> {
663public:
671 FragmentedSparseColumnMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool check = true) :
672 FragmentedSparseMatrix<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_>(nrow, ncol, std::move(values), std::move(indices), false, check) {}
673};
674
680template<typename Value_, typename Index_, class ValueVectorStorage_ = std::vector<std::vector<Value_> >, class IndexVectorStorage_ = std::vector<std::vector<Index_> > >
681class FragmentedSparseRowMatrix : public FragmentedSparseMatrix<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> {
682public:
690 FragmentedSparseRowMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool check = true) :
691 FragmentedSparseMatrix<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_>(nrow, ncol, std::move(values), std::move(indices), true, check) {}
692};
693
694
695}
696
697#endif
Get type of elements in an array.
Virtual class for a matrix of some numeric type.
Mimic the oracle-aware extractor interface.
Fragmented sparse column matrix.
Definition FragmentedSparseMatrix.hpp:662
FragmentedSparseColumnMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool check=true)
Definition FragmentedSparseMatrix.hpp:671
Fragmented sparse matrix representation.
Definition FragmentedSparseMatrix.hpp:453
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:627
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > subset_ptr, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:651
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:643
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_end, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:647
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_end, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:631
Index_ ncol() const
Definition FragmentedSparseMatrix.hpp:518
double prefer_rows_proportion() const
Definition FragmentedSparseMatrix.hpp:526
bool uses_oracle(bool) const
Definition FragmentedSparseMatrix.hpp:528
double is_sparse_proportion() const
Definition FragmentedSparseMatrix.hpp:522
Index_ nrow() const
Definition FragmentedSparseMatrix.hpp:516
bool is_sparse() const
Definition FragmentedSparseMatrix.hpp:520
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > subset_ptr, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:635
FragmentedSparseMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool row_sparse, bool check=true)
Definition FragmentedSparseMatrix.hpp:468
bool prefer_rows() const
Definition FragmentedSparseMatrix.hpp:524
Fragmented sparse row matrix.
Definition FragmentedSparseMatrix.hpp:681
FragmentedSparseRowMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool check=true)
Definition FragmentedSparseMatrix.hpp:690
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
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< Array_ >()[0])>::type >::type ElementType
Definition ElementType.hpp:17
Options for accessing data from a Matrix instance.
Definition Options.hpp:30