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