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