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 "../utils/copy.hpp"
9
10#include "primary_extraction.hpp"
11#include "secondary_extraction.hpp"
12
13#include <vector>
14#include <algorithm>
15#include <memory>
16#include <utility>
17#include <stdexcept>
18#include <cstddef>
19
20#include "sanisizer/sanisizer.hpp"
21
28namespace tatami {
29
33namespace FragmentedSparseMatrix_internal {
34
35/********************
36 *** Primary full ***
37 ********************/
38
39template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
40class PrimaryMyopicFullDense final : public MyopicDenseExtractor<Value_, Index_> {
41public:
42 PrimaryMyopicFullDense(const ValueVectorStorage_& values, const IndexVectorStorage_& indices, const Index_ secondary) :
43 my_values(values), my_indices(indices), my_secondary(secondary) {}
44
45 const Value_* fetch(const Index_ i, Value_* const buffer) {
46 const auto& curv = my_values[i];
47 const auto& curi = my_indices[i];
48
49 std::fill_n(buffer, my_secondary, static_cast<Value_>(0));
50 const auto curnnz = curv.size();
51 for (I<decltype(curnnz)> x = 0; x < curnnz; ++x) {
52 buffer[curi[x]] = curv[x];
53 }
54 return buffer;
55 }
56
57private:
58 const ValueVectorStorage_& my_values;
59 const IndexVectorStorage_& my_indices;
60 Index_ my_secondary;
61};
62
63template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
64class PrimaryMyopicFullSparse final : public MyopicSparseExtractor<Value_, Index_> {
65public:
66 PrimaryMyopicFullSparse(
67 const ValueVectorStorage_& values,
68 const IndexVectorStorage_& indices,
69 [[maybe_unused]] const Index_ secondary /* for consistency only */,
70 const Options& opt
71 ) :
72 my_values(values),
73 my_indices(indices),
74 my_needs_value(opt.sparse_extract_value),
75 my_needs_index(opt.sparse_extract_index)
76 {}
77
78 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
79 const auto& curv = my_values[i];
80 const auto& curi = my_indices[i];
81
82 SparseRange<Value_, Index_> output(curv.size(), NULL, NULL);
83 if (my_needs_value) {
84 const auto curnnz = curv.size();
85 output.value = sparse_utils::extract_primary_vector(curv, static_cast<I<decltype(curnnz)> >(0), curnnz, value_buffer);
86 }
87 if (my_needs_index) {
88 const auto curnnz = curi.size();
89 output.index = sparse_utils::extract_primary_vector(curi, static_cast<I<decltype(curnnz)> >(0), curnnz, index_buffer);
90 }
91 return output;
92 }
93
94private:
95 const ValueVectorStorage_& my_values;
96 const IndexVectorStorage_& my_indices;
97 bool my_needs_value, my_needs_index;
98};
99
100/*********************
101 *** Primary block ***
102 *********************/
103
104template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
105class PrimaryMyopicBlockDense final : public MyopicDenseExtractor<Value_, Index_> {
106public:
107 PrimaryMyopicBlockDense(
108 const ValueVectorStorage_& values,
109 const IndexVectorStorage_& indices,
110 const Index_ secondary,
111 const Index_ block_start,
112 const Index_ block_length
113 ) :
114 my_values(values),
115 my_indices(indices),
116 my_secondary(secondary),
117 my_block_start(block_start),
118 my_block_length(block_length)
119 {}
120
121 const Value_* fetch(const Index_ i, Value_* const buffer) {
122 const auto& curi = my_indices[i];
123 const auto& curv = my_values[i];
124
125 auto iStart = curi.begin();
126 auto iEnd = curi.end();
127 sparse_utils::refine_primary_block_limits(iStart, iEnd, my_secondary, my_block_start, my_block_length);
128 const auto start_pos = (iStart - curi.begin());
129 const auto end_pos = (iEnd - curi.begin());
130
131 std::fill_n(buffer, my_block_length, static_cast<Value_>(0));
132 for (auto x = start_pos; x < end_pos; ++x) {
133 buffer[curi[x] - my_block_start] = curv[x];
134 }
135 return buffer;
136 }
137
138private:
139 const ValueVectorStorage_& my_values;
140 const IndexVectorStorage_& my_indices;
141 Index_ my_secondary;
142 Index_ my_block_start, my_block_length;
143};
144
145template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
146class PrimaryMyopicBlockSparse final : public MyopicSparseExtractor<Value_, Index_> {
147public:
148 PrimaryMyopicBlockSparse(
149 const ValueVectorStorage_& values,
150 const IndexVectorStorage_& indices,
151 const Index_ secondary,
152 const Index_ block_start,
153 const Index_ block_length,
154 const Options& opt
155 ) :
156 my_values(values),
157 my_indices(indices),
158 my_secondary(secondary),
159 my_block_start(block_start),
160 my_block_length(block_length),
161 my_needs_value(opt.sparse_extract_value),
162 my_needs_index(opt.sparse_extract_index)
163 {}
164
165 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
166 const auto& curi = my_indices[i];
167 auto iStart = curi.begin();
168 auto iEnd = curi.end();
169 sparse_utils::refine_primary_block_limits(iStart, iEnd, my_secondary, my_block_start, my_block_length);
170 const auto offset = iStart - curi.begin();
171 const auto delta = iEnd - iStart;
172
173 SparseRange<Value_, Index_> output(delta, NULL, NULL);
174 if (my_needs_value) {
175 output.value = sparse_utils::extract_primary_vector(my_values[i], offset, delta, value_buffer);
176 }
177 if (my_needs_index) {
178 output.index = sparse_utils::extract_primary_vector(curi, offset, delta, index_buffer);
179 }
180 return output;
181 }
182
183private:
184 const ValueVectorStorage_& my_values;
185 const IndexVectorStorage_& my_indices;
186 Index_ my_secondary;
187 Index_ my_block_start, my_block_length;
188 bool my_needs_value, my_needs_index;
189};
190
191/***********************
192 *** Primary indexed ***
193 ***********************/
194
195template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
196class PrimaryMyopicIndexDense final : public MyopicDenseExtractor<Value_, Index_> {
197public:
198 PrimaryMyopicIndexDense(
199 const ValueVectorStorage_& values,
200 const IndexVectorStorage_& indices,
201 const Index_ secondary,
202 VectorPtr<Index_> indices_ptr
203 ) :
204 my_values(values),
205 my_indices(indices),
206 my_retriever(*indices_ptr, secondary),
207 my_num_indices(indices_ptr->size())
208 {}
209
210 const Value_* fetch(const Index_ i, Value_* const buffer) {
211 const auto& curi = my_indices[i];
212 const auto& curv = my_values[i];
213 std::fill_n(buffer, my_num_indices, static_cast<Value_>(0));
214 my_retriever.populate(
215 curi.begin(),
216 curi.end(),
217 [&](const auto s, const auto offset) -> void {
218 buffer[s] = curv[offset];
219 }
220 );
221 return buffer;
222 }
223
224private:
225 const ValueVectorStorage_& my_values;
226 const IndexVectorStorage_& my_indices;
227 sparse_utils::RetrievePrimarySubsetDense<Index_> my_retriever;
228 std::size_t my_num_indices;
229};
230
231template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
232class PrimaryMyopicIndexSparse final : public MyopicSparseExtractor<Value_, Index_> {
233public:
234 PrimaryMyopicIndexSparse(
235 const ValueVectorStorage_& values,
236 const IndexVectorStorage_& indices,
237 const Index_ secondary,
238 VectorPtr<Index_> indices_ptr,
239 const Options& opt
240 ) :
241 my_values(values),
242 my_indices(indices),
243 my_retriever(*indices_ptr, secondary),
244 my_needs_value(opt.sparse_extract_value),
245 my_needs_index(opt.sparse_extract_index)
246 {}
247
248 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
249 const auto& curi = my_indices[i];
250 const auto& curv = my_values[i];
251 Index_ count = 0;
252 auto vcopy = value_buffer;
253 auto icopy = index_buffer;
254
255 my_retriever.populate(
256 curi.begin(),
257 curi.end(),
258 [&](const auto offset, const auto ix) -> void {
259 ++count;
260 if (my_needs_value) {
261 *vcopy = curv[offset];
262 ++vcopy;
263 }
264 if (my_needs_index) {
265 *icopy = ix;
266 ++icopy;
267 }
268 }
269 );
270
271 return SparseRange<Value_, Index_>(count, my_needs_value ? value_buffer : NULL, my_needs_index ? index_buffer : NULL);
272 }
273
274private:
275 const ValueVectorStorage_& my_values;
276 const IndexVectorStorage_& my_indices;
277 sparse_utils::RetrievePrimarySubsetSparse<Index_> my_retriever;
278 bool my_needs_value, my_needs_index;
279};
280
281/**********************
282 *** Secondary full ***
283 **********************/
284
285template<typename Index_, class IndexVectorStorage_>
286class ServeIndices {
287public:
288 ServeIndices(const IndexVectorStorage_& indices) : my_indices(indices) {}
289
290private:
291 const IndexVectorStorage_& my_indices;
292
293public:
294 typedef I<decltype(std::declval<IndexVectorStorage_>()[0].size())> Pointer;
295
296 Pointer start_offset(const Index_) const {
297 return 0;
298 }
299
300 Pointer end_offset(const Index_ primary) const {
301 return my_indices[primary].size();
302 }
303
304 auto raw(const Index_ primary) const {
305 return my_indices[primary].begin();
306 }
307};
308
309template<typename Index_, class IndexVectorStorage_>
310auto make_ServeIndices(const IndexVectorStorage_& i) {
311 return ServeIndices<Index_, IndexVectorStorage_>(i);
312}
313
314template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
315class SecondaryMyopicFullDense final : public MyopicDenseExtractor<Value_, Index_> {
316public:
317 SecondaryMyopicFullDense(
318 const ValueVectorStorage_& values,
319 const IndexVectorStorage_& indices,
320 Index_ secondary
321 ) :
322 my_values(values),
323 my_cache(make_ServeIndices<Index_>(indices), secondary, indices.size())
324 {}
325
326 const Value_* fetch(const Index_ i, Value_* const buffer) {
327 std::fill_n(buffer, my_cache.size(), static_cast<Value_>(0));
328 my_cache.search(
329 i,
330 [&](Index_ primary, Index_ index_primary, auto ptr) -> void {
331 buffer[index_primary] = my_values[primary][ptr];
332 }
333 );
334 return buffer;
335 }
336
337private:
338 const ValueVectorStorage_& my_values;
339 sparse_utils::FullSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
340};
341
342template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
343class SecondaryMyopicFullSparse final : public MyopicSparseExtractor<Value_, Index_> {
344public:
345 SecondaryMyopicFullSparse(
346 const ValueVectorStorage_& values,
347 const IndexVectorStorage_& indices,
348 const Index_ secondary,
349 const Options& opt
350 ) :
351 my_values(values),
352 my_cache(make_ServeIndices<Index_>(indices), secondary, indices.size()),
353 my_needs_value(opt.sparse_extract_value),
354 my_needs_index(opt.sparse_extract_index)
355 {}
356
357 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
358 Index_ count = 0;
359 my_cache.search(
360 i,
361 [&](const Index_ primary, const Index_, const auto ptr) -> void {
362 if (my_needs_value) {
363 value_buffer[count] = my_values[primary][ptr];
364 }
365 if (my_needs_index) {
366 index_buffer[count] = primary;
367 }
368 ++count;
369 }
370 );
371 return SparseRange<Value_, Index_>(count, my_needs_value ? value_buffer : NULL, my_needs_index ? index_buffer : NULL);
372 }
373
374private:
375 const ValueVectorStorage_& my_values;
376 sparse_utils::FullSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
377 bool my_needs_value, my_needs_index;
378};
379
380/***********************
381 *** Secondary block ***
382 ***********************/
383
384template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
385class SecondaryMyopicBlockDense final : public MyopicDenseExtractor<Value_, Index_> {
386public:
387 SecondaryMyopicBlockDense(
388 const ValueVectorStorage_& values,
389 const IndexVectorStorage_& indices,
390 const Index_ secondary,
391 const Index_ block_start,
392 const Index_ block_length
393 ) :
394 my_values(values),
395 my_cache(make_ServeIndices<Index_>(indices), secondary, block_start, block_length)
396 {}
397
398 const Value_* fetch(const Index_ i, Value_* const buffer) {
399 std::fill_n(buffer, my_cache.size(), static_cast<Value_>(0));
400 my_cache.search(
401 i,
402 [&](const Index_ primary, const Index_ index_primary, const auto ptr) -> void {
403 buffer[index_primary] = my_values[primary][ptr];
404 }
405 );
406 return buffer;
407 }
408
409private:
410 const ValueVectorStorage_& my_values;
411 sparse_utils::BlockSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
412};
413
414template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
415class SecondaryMyopicBlockSparse final : public MyopicSparseExtractor<Value_, Index_> {
416public:
417 SecondaryMyopicBlockSparse(
418 const ValueVectorStorage_& values,
419 const IndexVectorStorage_& indices,
420 const Index_ secondary,
421 const Index_ block_start,
422 const Index_ block_length,
423 const Options& opt
424 ) :
425 my_values(values),
426 my_cache(make_ServeIndices<Index_>(indices), secondary, block_start, block_length),
427 my_needs_value(opt.sparse_extract_value),
428 my_needs_index(opt.sparse_extract_index)
429 {}
430
431 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
432 Index_ count = 0;
433 my_cache.search(
434 i,
435 [&](const Index_ primary, const Index_, const auto ptr) -> void {
436 if (my_needs_value) {
437 value_buffer[count] = my_values[primary][ptr];
438 }
439 if (my_needs_index) {
440 index_buffer[count] = primary;
441 }
442 ++count;
443 }
444 );
445 return SparseRange<Value_, Index_>(count, my_needs_value ? value_buffer : NULL, my_needs_index ? index_buffer : NULL);
446 }
447
448private:
449 const ValueVectorStorage_& my_values;
450 sparse_utils::BlockSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
451 bool my_needs_value, my_needs_index;
452};
453
454/***********************
455 *** Secondary index ***
456 ***********************/
457
458template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
459class SecondaryMyopicIndexDense final : public MyopicDenseExtractor<Value_, Index_> {
460public:
461 SecondaryMyopicIndexDense(
462 const ValueVectorStorage_& values,
463 const IndexVectorStorage_& indices,
464 const Index_ secondary,
465 VectorPtr<Index_> indices_ptr
466 ) :
467 my_values(values),
468 my_cache(make_ServeIndices<Index_>(indices), secondary, std::move(indices_ptr))
469 {}
470
471 const Value_* fetch(const Index_ i, Value_* const buffer) {
472 std::fill_n(buffer, my_cache.size(), static_cast<Value_>(0));
473 my_cache.search(
474 i,
475 [&](Index_ primary, Index_ index_primary, auto ptr) -> void {
476 buffer[index_primary] = my_values[primary][ptr];
477 }
478 );
479 return buffer;
480 }
481
482private:
483 const ValueVectorStorage_& my_values;
484 sparse_utils::IndexSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
485};
486
487template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
488class SecondaryMyopicIndexSparse final : public MyopicSparseExtractor<Value_, Index_> {
489public:
490 SecondaryMyopicIndexSparse(
491 const ValueVectorStorage_& values,
492 const IndexVectorStorage_& indices,
493 const Index_ secondary,
494 VectorPtr<Index_> indices_ptr,
495 const Options& opt
496 ) :
497 my_values(values),
498 my_cache(make_ServeIndices<Index_>(indices), secondary, std::move(indices_ptr)),
499 my_needs_value(opt.sparse_extract_value),
500 my_needs_index(opt.sparse_extract_index)
501 {}
502
503 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
504 Index_ count = 0;
505 my_cache.search(
506 i,
507 [&](const Index_ primary, const Index_, const auto ptr) -> void {
508 if (my_needs_value) {
509 value_buffer[count] = my_values[primary][ptr];
510 }
511 if (my_needs_index) {
512 index_buffer[count] = primary;
513 }
514 ++count;
515 }
516 );
517 return SparseRange<Value_, Index_>(count, my_needs_value ? value_buffer : NULL, my_needs_index ? index_buffer : NULL);
518 }
519
520private:
521 const ValueVectorStorage_& my_values;
522 sparse_utils::IndexSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexVectorStorage_> > my_cache;
523 bool my_needs_value, my_needs_index;
524};
525
526}
545 bool check = true;
546};
547
569template<typename Value_, typename Index_, class ValueVectorStorage_, class IndexVectorStorage_>
570class FragmentedSparseMatrix : public Matrix<Value_, Index_> {
571public:
582 const Index_ nrow,
583 const Index_ ncol,
584 ValueVectorStorage_ values,
585 IndexVectorStorage_ indices,
586 const bool row_sparse,
587 const FragmentedSparseMatrixOptions& options
588 ) :
589 my_nrow(nrow),
590 my_ncol(ncol),
591 my_values(std::move(values)),
592 my_indices(std::move(indices)),
593 my_row_sparse(row_sparse)
594 {
595 if (options.check) {
596 if (my_values.size() != my_indices.size()) {
597 throw std::runtime_error("'values' and 'indices' should be of the same length");
598 }
599
600 if (my_row_sparse) {
601 if (!safe_non_negative_equal(my_indices.size(), my_nrow)) {
602 throw std::runtime_error("length of 'indices' should be equal to number of rows'");
603 }
604 } else {
605 if (!safe_non_negative_equal(my_indices.size(), my_ncol)) {
606 throw std::runtime_error("length of 'indices' should be equal to number of columns");
607 }
608 }
609
610 const ElementType<ElementType<IndexVectorStorage_> > max_index = (my_row_sparse ? my_ncol : my_nrow);
611 const auto num_indices = my_indices.size();
612 for (I<decltype(num_indices)> i = 0; i < num_indices; ++i) {
613 const auto& curv = my_values[i];
614 const auto& curi = my_indices[i];
615 if (!safe_non_negative_equal(curv.size(), curi.size())) {
616 throw std::runtime_error("corresponding elements of 'values' and 'indices' should have the same length");
617 }
618
619 for (const auto x : curi) {
620 if (x < 0 || x >= max_index) {
621 throw std::runtime_error("'indices' should contain non-negative integers less than the number of " + (my_row_sparse ? std::string("columns") : std::string("rows")));
622 }
623 }
624
625 const auto curnnz = curi.size();
626 for (I<decltype(curnnz)> j = 1; j < curnnz; ++j) {
627 if (curi[j] <= curi[j - 1]) {
628 throw std::runtime_error("my_indices should be strictly increasing within each element of 'indices'");
629 }
630 }
631
632 // Check that iterator subtraction is safe.
633 // Various functions in 'sparse_utils' will subtract iterators when converting the lower_bound return value to an index.
634 // We cast to Index_ as it gives us a chance to skip the check at compile time, given that the size is no greater than the dimension extents.
635 sanisizer::can_ptrdiff<I<decltype(curi.begin())> >(attest_for_Index(static_cast<Index_>(curnnz)));
636 }
637 }
638 }
639
643 // Back-compatibility only.
644 FragmentedSparseMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool row_sparse, bool check = true) :
645 FragmentedSparseMatrix(
646 nrow,
647 ncol,
648 std::move(values),
649 std::move(indices),
650 row_sparse,
651 [&]{
652 FragmentedSparseMatrixOptions fopt;
653 fopt.check = check;
654 return fopt;
655 }()
656 )
657 {}
662private:
663 Index_ my_nrow, my_ncol;
664 ValueVectorStorage_ my_values;
665 IndexVectorStorage_ my_indices;
666 bool my_row_sparse;
667
668public:
669 Index_ nrow() const { return my_nrow; }
670
671 Index_ ncol() const { return my_ncol; }
672
673 bool is_sparse() const { return true; }
674
675 double is_sparse_proportion() const { return 1; }
676
677 bool prefer_rows() const { return my_row_sparse; }
678
679 double prefer_rows_proportion() const { return static_cast<double>(my_row_sparse); }
680
681 bool uses_oracle(const bool) const { return false; }
682
683 using Matrix<Value_, Index_>::dense;
684
685 using Matrix<Value_, Index_>::sparse;
686
687private:
688 Index_ secondary() const {
689 if (my_row_sparse) {
690 return my_ncol;
691 } else {
692 return my_nrow;
693 }
694 }
695
696 /*****************************
697 ******* Dense myopic ********
698 *****************************/
699private:
700 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
701 const bool row,
702 const Options&
703 ) const {
704 if (my_row_sparse == row) {
705 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicFullDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
706 my_values, my_indices, secondary()
707 );
708 } else {
709 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicFullDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
710 my_values, my_indices, secondary()
711 );
712 }
713 }
714
715 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
716 const bool row,
717 const Index_ block_start,
718 const Index_ block_end,
719 const Options&
720 ) const {
721 if (my_row_sparse == row) {
722 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicBlockDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
723 my_values, my_indices, secondary(), block_start, block_end
724 );
725 } else {
726 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicBlockDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
727 my_values, my_indices, secondary(), block_start, block_end
728 );
729 }
730 }
731
732 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
733 const bool row,
734 VectorPtr<Index_> subset_ptr,
735 const Options&
736 ) const {
737 if (my_row_sparse == row) {
738 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicIndexDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
739 my_values, my_indices, secondary(), std::move(subset_ptr)
740 );
741 } else {
742 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicIndexDense<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
743 my_values, my_indices, secondary(), std::move(subset_ptr)
744 );
745 }
746 }
747
748 /******************************
749 ******* Sparse myopic ********
750 ******************************/
751private:
752 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
753 const bool row,
754 const Options& opt
755 ) const {
756 if (my_row_sparse == row) {
757 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicFullSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
758 my_values, my_indices, secondary(), opt
759 );
760 } else {
761 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicFullSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
762 my_values, my_indices, secondary(), opt
763 );
764 }
765 }
766
767 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
768 const bool row,
769 const Index_ block_start,
770 const Index_ block_end,
771 const Options& opt
772 ) const {
773 if (my_row_sparse == row) {
774 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicBlockSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
775 my_values, my_indices, secondary(), block_start, block_end, opt
776 );
777 } else {
778 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicBlockSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
779 my_values, my_indices, secondary(), block_start, block_end, opt
780 );
781 }
782 }
783
784 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
785 const bool row,
786 VectorPtr<Index_> subset_ptr,
787 const Options& opt
788 ) const {
789 if (my_row_sparse == row) {
790 return std::make_unique<FragmentedSparseMatrix_internal::PrimaryMyopicIndexSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
791 my_values, my_indices, secondary(), std::move(subset_ptr), opt
792 );
793 } else {
794 return std::make_unique<FragmentedSparseMatrix_internal::SecondaryMyopicIndexSparse<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> >(
795 my_values, my_indices, secondary(), std::move(subset_ptr), opt
796 );
797 }
798 }
799
800 /*******************************
801 ******* Dense oracular ********
802 *******************************/
803public:
804 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
805 const bool row,
806 std::shared_ptr<const Oracle<Index_> > oracle,
807 const Options& opt
808 ) const {
809 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, opt));
810 }
811
812 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
813 const bool row,
814 std::shared_ptr<const Oracle<Index_> > oracle,
815 const Index_ block_start,
816 const Index_ block_end,
817 const Options& opt
818 ) const {
819 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, block_start, block_end, opt));
820 }
821
822 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
823 const bool row,
824 std::shared_ptr<const Oracle<Index_> > oracle,
825 VectorPtr<Index_> subset_ptr,
826 const Options& opt
827 ) const {
828 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, std::move(subset_ptr), opt));
829 }
830
831 /********************************
832 ******* Sparse oracular ********
833 ********************************/
834public:
835 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
836 const bool row,
837 std::shared_ptr<const Oracle<Index_> > oracle,
838 const Options& opt
839 ) const {
840 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, opt));
841 }
842
843 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
844 const bool row,
845 std::shared_ptr<const Oracle<Index_> > oracle,
846 const Index_ block_start,
847 const Index_ block_end,
848 const Options& opt
849 ) const {
850 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, block_start, block_end, opt));
851 }
852
853 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
854 const bool row,
855 std::shared_ptr<const Oracle<Index_> > oracle,
856 VectorPtr<Index_> subset_ptr,
857 const Options& opt
858 ) const {
859 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, std::move(subset_ptr), opt));
860 }
861};
862
868template<typename Value_, typename Index_, class ValueVectorStorage_ = std::vector<std::vector<Value_> >, class IndexVectorStorage_ = std::vector<std::vector<Index_> > >
869class FragmentedSparseColumnMatrix final : public FragmentedSparseMatrix<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> {
870public:
878 FragmentedSparseColumnMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool check = true) :
879 FragmentedSparseMatrix<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_>(nrow, ncol, std::move(values), std::move(indices), false, check) {}
880};
881
887template<typename Value_, typename Index_, class ValueVectorStorage_ = std::vector<std::vector<Value_> >, class IndexVectorStorage_ = std::vector<std::vector<Index_> > >
888class FragmentedSparseRowMatrix final : public FragmentedSparseMatrix<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_> {
889public:
897 FragmentedSparseRowMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool check = true) :
898 FragmentedSparseMatrix<Value_, Index_, ValueVectorStorage_, IndexVectorStorage_>(nrow, ncol, std::move(values), std::move(indices), true, check) {}
899};
900
901
902}
903
904#endif
Get type of elements in an array.
Convert index type to container size.
Virtual class for a matrix of some numeric type.
Mimic the oracle-aware extractor interface.
Fragmented sparse column matrix.
Definition FragmentedSparseMatrix.hpp:869
FragmentedSparseColumnMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool check=true)
Definition FragmentedSparseMatrix.hpp:878
Fragmented sparse matrix representation.
Definition FragmentedSparseMatrix.hpp:570
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:835
FragmentedSparseMatrix(const Index_ nrow, const Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, const bool row_sparse, const FragmentedSparseMatrixOptions &options)
Definition FragmentedSparseMatrix.hpp:581
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Index_ block_start, const Index_ block_end, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:812
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > subset_ptr, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:822
Index_ ncol() const
Definition FragmentedSparseMatrix.hpp:671
double prefer_rows_proportion() const
Definition FragmentedSparseMatrix.hpp:679
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > subset_ptr, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:853
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Index_ block_start, const Index_ block_end, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:843
double is_sparse_proportion() const
Definition FragmentedSparseMatrix.hpp:675
Index_ nrow() const
Definition FragmentedSparseMatrix.hpp:669
bool is_sparse() const
Definition FragmentedSparseMatrix.hpp:673
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition FragmentedSparseMatrix.hpp:804
bool prefer_rows() const
Definition FragmentedSparseMatrix.hpp:677
bool uses_oracle(const bool) const
Definition FragmentedSparseMatrix.hpp:681
Fragmented sparse row matrix.
Definition FragmentedSparseMatrix.hpp:888
FragmentedSparseRowMatrix(Index_ nrow, Index_ ncol, ValueVectorStorage_ values, IndexVectorStorage_ indices, bool check=true)
Definition FragmentedSparseMatrix.hpp:897
Virtual class for a matrix.
Definition Matrix.hpp:59
Predict future access requests on the target dimension.
Definition Oracle.hpp:29
Copy data from one buffer to another.
Flexible representations for matrix data.
Definition Extractor.hpp:15
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
I< decltype(std::declval< Array_ >()[0])> ElementType
Definition ElementType.hpp:19
Options for FragmentedSparseMatrix().
Definition FragmentedSparseMatrix.hpp:534
bool check
Definition FragmentedSparseMatrix.hpp:545
Options for accessing data from a Matrix instance.
Definition Options.hpp:30