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