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