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"
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 CompressedSparseMatrix_internal {
33
34/********************
35 *** Primary full ***
36 ********************/
37
38template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
39class PrimaryMyopicFullDense final : public MyopicDenseExtractor<Value_, Index_> {
40public:
41 PrimaryMyopicFullDense(const ValueStorage_& values, const IndexStorage_& indices, const PointerStorage_& pointers, Index_ secondary) :
42 my_values(values),
43 my_indices(indices),
44 my_pointers(pointers),
45 my_secondary(secondary)
46 {}
47
48 const Value_* fetch(Index_ i, Value_* buffer) {
49 auto start_pos = my_pointers[i], end_pos = my_pointers[i+1];
50 std::fill_n(buffer, my_secondary, static_cast<Value_>(0));
51 for (auto x = start_pos; x < end_pos; ++x) {
52 buffer[my_indices[x]] = my_values[x];
53 }
54 return buffer;
55 }
56
57private:
58 const ValueStorage_& my_values;
59 const IndexStorage_& my_indices;
60 const PointerStorage_& my_pointers;
61 Index_ my_secondary;
62};
63
64template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
65class PrimaryMyopicFullSparse final : public MyopicSparseExtractor<Value_, Index_> {
66public:
67 PrimaryMyopicFullSparse(const ValueStorage_& values, const IndexStorage_& indices, const PointerStorage_& pointers, Index_ secondary, const Options& opt) :
68 my_values(values),
69 my_indices(indices),
70 my_pointers(pointers),
71 my_secondary(secondary),
72 my_needs_value(opt.sparse_extract_value),
73 my_needs_index(opt.sparse_extract_index)
74 {}
75
76 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
77 auto offset = my_pointers[i];
78 decltype(offset) delta = my_pointers[i+1] - offset;
79
80 SparseRange<Value_, Index_> output(delta, NULL, NULL);
81 if (my_needs_value) {
82 output.value = sparse_utils::extract_primary_vector(my_values, offset, delta, value_buffer);
83 }
84 if (my_needs_index) {
85 output.index = sparse_utils::extract_primary_vector(my_indices, offset, delta, index_buffer);
86 }
87 return output;
88 }
89
90private:
91 const ValueStorage_& my_values;
92 const IndexStorage_& my_indices;
93 const PointerStorage_& my_pointers;
94 Index_ my_secondary;
95 bool my_needs_value, my_needs_index;
96};
97
98/*********************
99 *** Primary block ***
100 *********************/
101
102template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
103class PrimaryMyopicBlockDense final : public MyopicDenseExtractor<Value_, Index_> {
104public:
105 PrimaryMyopicBlockDense(const ValueStorage_& values, const IndexStorage_& indices, const PointerStorage_& pointers, Index_ secondary, Index_ block_start, Index_ block_length) :
106 my_values(values),
107 my_indices(indices),
108 my_pointers(pointers),
109 my_secondary(secondary),
110 my_block_start(block_start),
111 my_block_length(block_length)
112 {}
113
114 const Value_* fetch(Index_ i, Value_* buffer) {
115 auto iStart = my_indices.begin() + my_pointers[i];
116 auto iEnd = my_indices.begin() + my_pointers[i + 1];
117 sparse_utils::refine_primary_block_limits(iStart, iEnd, my_secondary, my_block_start, my_block_length);
118 auto start_pos = (iStart - my_indices.begin());
119 auto end_pos = (iEnd - my_indices.begin());
120
121 std::fill_n(buffer, my_block_length, static_cast<Value_>(0));
122 for (auto x = start_pos; x < end_pos; ++x) {
123 buffer[my_indices[x] - my_block_start] = my_values[x];
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 final : 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 auto offset = iStart - my_indices.begin();
155 auto 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 final : 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 [&](auto s, auto offset) -> void {
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 std::size_t my_num_indices;
210};
211
212template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
213class PrimaryMyopicIndexSparse final : 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 [&](auto offset, auto ix) -> void {
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:
270 typedef ElementType<PointerStorage_> pointer_type;
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_>
286auto make_ServeIndices(const IndexStorage_& i, const PointerStorage_& p) {
287 return ServeIndices<Index_, IndexStorage_, PointerStorage_>(i, p);
288}
289
290template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
291class SecondaryMyopicFullDense final : 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));
300 my_cache.search(
301 i,
302 [&](Index_, Index_ index_primary, auto ptr) -> void {
303 buffer[index_primary] = my_values[ptr];
304 }
305 );
306 return buffer;
307 }
308
309private:
310 const ValueStorage_& my_values;
311 sparse_utils::FullSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexStorage_, PointerStorage_> > my_cache;
312};
313
314template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
315class SecondaryMyopicFullSparse final : public MyopicSparseExtractor<Value_, Index_> {
316public:
317 SecondaryMyopicFullSparse(const ValueStorage_& values, const IndexStorage_& indices, const PointerStorage_& pointers, Index_ secondary, const Options& opt) :
318 my_values(values),
319 my_cache(make_ServeIndices<Index_>(indices, pointers), secondary, pointers.size() - 1),
320 my_needs_value(opt.sparse_extract_value),
321 my_needs_index(opt.sparse_extract_index)
322 {}
323
324 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
325 Index_ count = 0;
326 my_cache.search(i, [&](Index_ primary, Index_, ElementType<PointerStorage_> ptr) -> void {
327 if (my_needs_value) {
328 value_buffer[count] = my_values[ptr];
329 }
330 if (my_needs_index) {
331 index_buffer[count] = primary;
332 }
333 ++count;
334 });
335 return SparseRange<Value_, Index_>(count, my_needs_value ? value_buffer : NULL, my_needs_index ? index_buffer : NULL);
336 }
337
338private:
339 const ValueStorage_& my_values;
340 sparse_utils::FullSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexStorage_, PointerStorage_> > my_cache;
341 bool my_needs_value, my_needs_index;
342};
343
344/***********************
345 *** Secondary block ***
346 ***********************/
347
348template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
349class SecondaryMyopicBlockDense final : public MyopicDenseExtractor<Value_, Index_> {
350public:
351 SecondaryMyopicBlockDense(const ValueStorage_& values, const IndexStorage_& indices, const PointerStorage_& pointers, Index_ secondary, Index_ block_start, Index_ block_length) :
352 my_values(values),
353 my_cache(make_ServeIndices<Index_>(indices, pointers), secondary, block_start, block_length)
354 {}
355
356 const Value_* fetch(Index_ i, Value_* buffer) {
357 std::fill_n(buffer, my_cache.size(), static_cast<Value_>(0));
358 my_cache.search(
359 i,
360 [&](Index_, Index_ index_primary, auto ptr) -> void {
361 buffer[index_primary] = my_values[ptr];
362 }
363 );
364 return buffer;
365 }
366
367private:
368 const ValueStorage_& my_values;
369 sparse_utils::BlockSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexStorage_, PointerStorage_> > my_cache;
370};
371
372template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
373class SecondaryMyopicBlockSparse final : public MyopicSparseExtractor<Value_, Index_> {
374public:
375 SecondaryMyopicBlockSparse(const ValueStorage_& values, const IndexStorage_& indices, const PointerStorage_& pointers, Index_ secondary, Index_ block_start, Index_ block_length, const Options& opt) :
376 my_values(values),
377 my_cache(make_ServeIndices<Index_>(indices, pointers), secondary, block_start, block_length),
378 my_needs_value(opt.sparse_extract_value),
379 my_needs_index(opt.sparse_extract_index)
380 {}
381
382 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
383 Index_ count = 0;
384 my_cache.search(
385 i,
386 [&](Index_ primary, Index_, auto ptr) -> void {
387 if (my_needs_value) {
388 value_buffer[count] = my_values[ptr];
389 }
390 if (my_needs_index) {
391 index_buffer[count] = primary;
392 }
393 ++count;
394 }
395 );
396 return SparseRange<Value_, Index_>(count, my_needs_value ? value_buffer : NULL, my_needs_index ? index_buffer : NULL);
397 }
398
399private:
400 const ValueStorage_& my_values;
401 sparse_utils::BlockSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexStorage_, PointerStorage_> > my_cache;
402 bool my_needs_value, my_needs_index;
403};
404
405/***********************
406 *** Secondary index ***
407 ***********************/
408
409template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
410class SecondaryMyopicIndexDense final : public MyopicDenseExtractor<Value_, Index_> {
411public:
412 SecondaryMyopicIndexDense(const ValueStorage_& values, const IndexStorage_& indices, const PointerStorage_& pointers, Index_ secondary, VectorPtr<Index_> sub_ptr) :
413 my_values(values), my_cache(make_ServeIndices<Index_>(indices, pointers), secondary, std::move(sub_ptr)) {}
414
415 const Value_* fetch(Index_ i, Value_* buffer) {
416 std::fill_n(buffer, my_cache.size(), static_cast<Value_>(0));
417 my_cache.search(
418 i,
419 [&](Index_, Index_ index_primary, ElementType<PointerStorage_> ptr) -> void {
420 buffer[index_primary] = my_values[ptr];
421 }
422 );
423 return buffer;
424 }
425
426private:
427 const ValueStorage_& my_values;
428 sparse_utils::IndexSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexStorage_, PointerStorage_> > my_cache;
429};
430
431template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
432class SecondaryMyopicIndexSparse final : public MyopicSparseExtractor<Value_, Index_> {
433public:
434 SecondaryMyopicIndexSparse(const ValueStorage_& values, const IndexStorage_& indices, const PointerStorage_& pointers, Index_ secondary, VectorPtr<Index_> sub_ptr, const Options& opt) :
435 my_values(values),
436 my_cache(make_ServeIndices<Index_>(indices, pointers), secondary, std::move(sub_ptr)),
437 my_needs_value(opt.sparse_extract_value),
438 my_needs_index(opt.sparse_extract_index)
439 {}
440
441 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
442 Index_ count = 0;
443 my_cache.search(
444 i,
445 [&](Index_ primary, Index_, ElementType<PointerStorage_> ptr) -> void {
446 if (my_needs_value) {
447 value_buffer[count] = my_values[ptr];
448 }
449 if (my_needs_index) {
450 index_buffer[count] = primary;
451 }
452 ++count;
453 }
454 );
455 return SparseRange<Value_, Index_>(count, my_needs_value ? value_buffer : NULL, my_needs_index ? index_buffer : NULL);
456 }
457
458private:
459 const ValueStorage_& my_values;
460 sparse_utils::IndexSecondaryExtractionCache<Index_, ServeIndices<Index_, IndexStorage_, PointerStorage_> > my_cache;
461 bool my_needs_value, my_needs_index;
462};
463
464}
485 bool check = true;
486};
487
504template<typename Value_, typename Index_, class ValueStorage_, class IndexStorage_, class PointerStorage_>
505class CompressedSparseMatrix : public Matrix<Value_, Index_> {
506public:
516 CompressedSparseMatrix(Index_ nrow, Index_ ncol, ValueStorage_ values, IndexStorage_ indices, PointerStorage_ pointers, bool csr, const CompressedSparseMatrixOptions& options) :
517 my_nrow(nrow), my_ncol(ncol), my_values(std::move(values)), my_indices(std::move(indices)), my_pointers(std::move(pointers)), my_csr(csr)
518 {
519 if (options.check) {
520 auto nnzero = my_values.size();
521 if (!safe_non_negative_equal(nnzero, my_indices.size())) {
522 throw std::runtime_error("'my_values' and 'my_indices' should be of the same length");
523 }
524
525 // Check that iterator subtraction is safe.
526 // Various functions in 'sparse_utils' will subtract iterators when converting the lower_bound return value to an index.
527 sanisizer::can_ptrdiff<decltype(my_indices.begin())>(nnzero);
528
529 auto npointers = my_pointers.size();
530 auto check_pointers = [&](auto dim) {
531 // subtracting 1 from npointers (once we know it's >= 1) instead of adding 1 to dim, as the latter might overflow.
532 return npointers >= 1 && safe_non_negative_equal(npointers - 1, dim);
533 };
534 if (my_csr) {
535 if (!check_pointers(my_nrow)) {
536 throw std::runtime_error("length of 'pointers' should be equal to 'nrow + 1'");
537 }
538 } else {
539 if (!check_pointers(my_ncol)){
540 throw std::runtime_error("length of 'pointers' should be equal to 'ncols + 1'");
541 }
542 }
543
544 if (my_pointers[0] != 0) {
545 throw std::runtime_error("first element of 'pointers' should be zero");
546 }
547 auto last = my_pointers[npointers - 1]; // don't use back() as this is not guaranteed to be available for arbitrary PointerStorage_.
548 if (!safe_non_negative_equal(nnzero, last)) {
549 throw std::runtime_error("last element of 'pointers' should be equal to length of 'indices'");
550 }
551
552 ElementType<IndexStorage_> max_index = (my_csr ? my_ncol : my_nrow);
553 for (decltype(npointers) i = 1; i < npointers; ++i) {
554 auto start = my_pointers[i - 1], end = my_pointers[i];
555 if (end < start || end > last) {
556 throw std::runtime_error("'pointers' should be in non-decreasing order");
557 }
558
559 for (auto x = start; x < end; ++x) {
560 if (my_indices[x] < 0 || my_indices[x] >= max_index) {
561 throw std::runtime_error("'indices' should contain non-negative integers less than the number of " + (my_csr ? std::string("columns") : std::string("rows")));
562 }
563 }
564
565 for (decltype(start) j = start + 1; j < end; ++j) {
566 if (my_indices[j] <= my_indices[j - 1]) {
567 throw std::runtime_error("'indices' should be strictly increasing within each " + (my_csr ? std::string("row") : std::string("column")));
568 }
569 }
570 }
571 }
572 }
573
577 // For back-compatibility only
578 CompressedSparseMatrix(Index_ nrow, Index_ ncol, ValueStorage_ values, IndexStorage_ indices, PointerStorage_ pointers, bool csr, bool check = true) :
579 CompressedSparseMatrix(
580 nrow,
581 ncol,
582 std::move(values),
583 std::move(indices),
584 std::move(pointers),
585 csr,
586 [&]{
587 CompressedSparseMatrixOptions options;
588 options.check = check;
589 return options;
590 }()
591 )
592 {}
597private:
598 Index_ my_nrow, my_ncol;
599 ValueStorage_ my_values;
600 IndexStorage_ my_indices;
601 PointerStorage_ my_pointers;
602 bool my_csr;
603
604public:
605 Index_ nrow() const { return my_nrow; }
606
607 Index_ ncol() const { return my_ncol; }
608
609 bool is_sparse() const { return true; }
610
611 double is_sparse_proportion() const { return 1; }
612
613 bool prefer_rows() const { return my_csr; }
614
615 double prefer_rows_proportion() const { return static_cast<double>(my_csr); }
616
617 bool uses_oracle(bool) const { return false; }
618
619 using Matrix<Value_, Index_>::dense_row;
620
621 using Matrix<Value_, Index_>::dense_column;
622
623 using Matrix<Value_, Index_>::sparse_row;
624
625 using Matrix<Value_, Index_>::sparse_column;
626
627private:
628 Index_ secondary() const {
629 if (my_csr) {
630 return my_ncol;
631 } else {
632 return my_nrow;
633 }
634 }
635
636 /*****************************
637 ******* Dense myopic ********
638 *****************************/
639public:
640 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, const Options&) const {
641 if (my_csr == row) {
642 return std::make_unique<CompressedSparseMatrix_internal::PrimaryMyopicFullDense<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
643 my_values, my_indices, my_pointers, secondary()
644 );
645 } else {
646 return std::make_unique<CompressedSparseMatrix_internal::SecondaryMyopicFullDense<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
647 my_values, my_indices, my_pointers, secondary()
648 );
649 }
650 }
651
652 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, Index_ block_start, Index_ block_end, const Options&) const {
653 if (my_csr == row) {
654 return std::make_unique<CompressedSparseMatrix_internal::PrimaryMyopicBlockDense<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
655 my_values, my_indices, my_pointers, secondary(), block_start, block_end
656 );
657 } else {
658 return std::make_unique<CompressedSparseMatrix_internal::SecondaryMyopicBlockDense<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
659 my_values, my_indices, my_pointers, secondary(), block_start, block_end
660 );
661 }
662 }
663
664 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, VectorPtr<Index_> indices_ptr, const Options&) const {
665 if (my_csr == row) {
666 return std::make_unique<CompressedSparseMatrix_internal::PrimaryMyopicIndexDense<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
667 my_values, my_indices, my_pointers, secondary(), std::move(indices_ptr)
668 );
669 } else {
670 return std::make_unique<CompressedSparseMatrix_internal::SecondaryMyopicIndexDense<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
671 my_values, my_indices, my_pointers, secondary(), std::move(indices_ptr)
672 );
673 }
674 }
675
676 /******************************
677 ******* Sparse myopic ********
678 ******************************/
679public:
680 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, const Options& opt) const {
681 if (my_csr == row) {
682 return std::make_unique<CompressedSparseMatrix_internal::PrimaryMyopicFullSparse<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
683 my_values, my_indices, my_pointers, secondary(), opt
684 );
685 } else {
686 return std::make_unique<CompressedSparseMatrix_internal::SecondaryMyopicFullSparse<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
687 my_values, my_indices, my_pointers, secondary(), opt
688 );
689 }
690 }
691
692 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, Index_ block_start, Index_ block_end, const Options& opt) const {
693 if (my_csr == row) {
694 return std::make_unique<CompressedSparseMatrix_internal::PrimaryMyopicBlockSparse<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
695 my_values, my_indices, my_pointers, secondary(), block_start, block_end, opt
696 );
697 } else {
698 return std::make_unique<CompressedSparseMatrix_internal::SecondaryMyopicBlockSparse<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
699 my_values, my_indices, my_pointers, secondary(), block_start, block_end, opt
700 );
701 }
702 }
703
704 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, VectorPtr<Index_> indices_ptr, const Options& opt) const {
705 if (my_csr == row) {
706 return std::make_unique<CompressedSparseMatrix_internal::PrimaryMyopicIndexSparse<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
707 my_values, my_indices, my_pointers, secondary(), std::move(indices_ptr), opt
708 );
709 } else {
710 return std::make_unique<CompressedSparseMatrix_internal::SecondaryMyopicIndexSparse<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> >(
711 my_values, my_indices, my_pointers, secondary(), std::move(indices_ptr), opt
712 );
713 }
714 }
715
716 /*******************************
717 ******* Dense oracular ********
718 *******************************/
719public:
720 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, const Options& opt) const {
721 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, opt));
722 }
723
724 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 {
725 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, block_start, block_end, opt));
726 }
727
728 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 {
729 return std::make_unique<PseudoOracularDenseExtractor<Value_, Index_> >(std::move(oracle), dense(row, std::move(my_indices_ptr), opt));
730 }
731
732 /********************************
733 ******* Sparse oracular ********
734 ********************************/
735public:
736 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, const Options& opt) const {
737 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, opt));
738 }
739
740 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 {
741 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, block_start, block_end, opt));
742 }
743
744 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 {
745 return std::make_unique<PseudoOracularSparseExtractor<Value_, Index_> >(std::move(oracle), sparse(row, std::move(my_indices_ptr), opt));
746 }
747};
748
754template<typename Value_, typename Index_, class ValueStorage_ = std::vector<Value_>, class IndexStorage_ = std::vector<Index_>, class PointerStorage_ = std::vector<std::size_t> >
755class CompressedSparseColumnMatrix final : public CompressedSparseMatrix<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> {
756public:
765 CompressedSparseColumnMatrix(Index_ nrow, Index_ ncol, ValueStorage_ values, IndexStorage_ indices, PointerStorage_ pointers, bool check = true) :
766 CompressedSparseMatrix<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_>(nrow, ncol, std::move(values), std::move(indices), std::move(pointers), false, check) {}
767};
768
774template<typename Value_, typename Index_, class ValueStorage_ = std::vector<Value_>, class IndexStorage_ = std::vector<Index_>, class PointerStorage_ = std::vector<std::size_t> >
775class CompressedSparseRowMatrix final : public CompressedSparseMatrix<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_> {
776public:
785 CompressedSparseRowMatrix(Index_ nrow, Index_ ncol, ValueStorage_ values, IndexStorage_ indices, PointerStorage_ pointers, bool check = true) :
786 CompressedSparseMatrix<Value_, Index_, ValueStorage_, IndexStorage_, PointerStorage_>(nrow, ncol, std::move(values), std::move(indices), std::move(pointers), true, check) {}
787};
788
789}
790
791#endif
Get type of elements in an array.
Virtual class for a matrix of some numeric type.
Mimic the oracle-aware extractor interface.
Compressed sparse column matrix.
Definition CompressedSparseMatrix.hpp:755
CompressedSparseColumnMatrix(Index_ nrow, Index_ ncol, ValueStorage_ values, IndexStorage_ indices, PointerStorage_ pointers, bool check=true)
Definition CompressedSparseMatrix.hpp:765
Compressed sparse matrix representation.
Definition CompressedSparseMatrix.hpp:505
CompressedSparseMatrix(Index_ nrow, Index_ ncol, ValueStorage_ values, IndexStorage_ indices, PointerStorage_ pointers, bool csr, const CompressedSparseMatrixOptions &options)
Definition CompressedSparseMatrix.hpp:516
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition CompressedSparseMatrix.hpp:736
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, const Options &opt) const
Definition CompressedSparseMatrix.hpp:680
Index_ nrow() const
Definition CompressedSparseMatrix.hpp:605
bool prefer_rows() const
Definition CompressedSparseMatrix.hpp:613
double prefer_rows_proportion() const
Definition CompressedSparseMatrix.hpp:615
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, Index_ block_start, Index_ block_end, const Options &opt) const
Definition CompressedSparseMatrix.hpp: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
Definition CompressedSparseMatrix.hpp:744
bool uses_oracle(bool) const
Definition CompressedSparseMatrix.hpp:617
double is_sparse_proportion() const
Definition CompressedSparseMatrix.hpp:611
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, Index_ block_start, Index_ block_end, const Options &) const
Definition CompressedSparseMatrix.hpp:652
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition CompressedSparseMatrix.hpp:720
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:740
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:724
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:728
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, VectorPtr< Index_ > indices_ptr, const Options &) const
Definition CompressedSparseMatrix.hpp:664
bool is_sparse() const
Definition CompressedSparseMatrix.hpp:609
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition CompressedSparseMatrix.hpp:704
Index_ ncol() const
Definition CompressedSparseMatrix.hpp:607
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, const Options &) const
Definition CompressedSparseMatrix.hpp:640
Compressed sparse row matrix.
Definition CompressedSparseMatrix.hpp:775
CompressedSparseRowMatrix(Index_ nrow, Index_ ncol, ValueStorage_ values, IndexStorage_ indices, PointerStorage_ pointers, bool check=true)
Definition CompressedSparseMatrix.hpp:785
Virtual class for a matrix.
Definition Matrix.hpp:59
Predict future access requests on the target dimension.
Definition Oracle.hpp:29
Compile-time checks for the data() method.
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 the CompressedSparseMatrix.
Definition CompressedSparseMatrix.hpp:472
bool check
Definition CompressedSparseMatrix.hpp:485
Options for accessing data from a Matrix instance.
Definition Options.hpp:30