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