tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
DelayedSubsetBlock.hpp
Go to the documentation of this file.
1#ifndef TATAMI_DELAYED_SUBSET_BLOCK
2#define TATAMI_DELAYED_SUBSET_BLOCK
3
4#include "../base/Matrix.hpp"
6
7#include <vector>
8#include <algorithm>
9#include <memory>
10#include <cstddef>
11
20namespace tatami {
21
25namespace DelayedSubsetBlock_internal {
26
27template<typename Index_>
28void bump_indices(VectorPtr<Index_>& indices_ptr, Index_ subset_start) {
29 if (subset_start) {
30 auto ptr2 = new std::vector<Index_>(*indices_ptr);
31 indices_ptr.reset(ptr2);
32 for (auto& i : *ptr2) {
33 i += subset_start;
34 }
35 }
36}
37
38template<bool oracle_, typename Value_, typename Index_>
39class AlongDense final : public DenseExtractor<oracle_, Value_, Index_> {
40public:
41 AlongDense(const Matrix<Value_, Index_>* matrix, Index_ subset_start, Index_ subset_length, bool row, MaybeOracle<oracle_, Index_> oracle, const Options& opt) :
42 my_ext(new_extractor<false, oracle_>(matrix, row, std::move(oracle), subset_start, subset_length, opt)) {}
43
44 AlongDense(const Matrix<Value_, Index_>* matrix, Index_ subset_start, Index_ /* for consistency */, bool row, MaybeOracle<oracle_, Index_> oracle, Index_ block_start, Index_ block_length, const Options& opt) :
45 my_ext(new_extractor<false, oracle_>(matrix, row, std::move(oracle), subset_start + block_start, block_length, opt)) {}
46
47 AlongDense(const Matrix<Value_, Index_>* matrix, Index_ subset_start, Index_ /* for consistency */, bool row, MaybeOracle<oracle_, Index_> oracle, VectorPtr<Index_> indices_ptr, const Options& opt) {
48 bump_indices(indices_ptr, subset_start);
49 my_ext = new_extractor<false, oracle_>(matrix, row, std::move(oracle), std::move(indices_ptr), opt);
50 }
51
52 const Value_* fetch(Index_ i, Value_* buffer) {
53 return my_ext->fetch(i, buffer);
54 }
55
56private:
57 std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > my_ext;
58};
59
60template<bool oracle_, typename Value_, typename Index_>
61class AlongSparse final : public SparseExtractor<oracle_, Value_, Index_> {
62public:
63 AlongSparse(const Matrix<Value_, Index_>* matrix, Index_ subset_start, Index_ subset_length, bool row, MaybeOracle<oracle_, Index_> oracle, const Options& opt) :
64 my_ext(new_extractor<true, oracle_>(matrix, row, std::move(oracle), subset_start, subset_length, opt)), my_shift(subset_start) {}
65
66 AlongSparse(const Matrix<Value_, Index_>* matrix, Index_ subset_start, Index_ /* for consistency */, bool row, MaybeOracle<oracle_, Index_> oracle, Index_ block_start, Index_ block_length, const Options& opt) :
67 my_ext(new_extractor<true, oracle_>(matrix, row, std::move(oracle), subset_start + block_start, block_length, opt)), my_shift(subset_start) {}
68
69 AlongSparse(const Matrix<Value_, Index_>* matrix, Index_ subset_start, Index_ /* for consistency */, bool row, MaybeOracle<oracle_, Index_> oracle, VectorPtr<Index_> indices_ptr, const Options& opt) :
70 my_shift(subset_start)
71 {
72 bump_indices(indices_ptr, subset_start);
73 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), std::move(indices_ptr), opt);
74 }
75
76 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
77 auto output = my_ext->fetch(i, value_buffer, index_buffer);
78 if (output.index && my_shift) {
79 for (Index_ i = 0; i < output.number; ++i) {
80 index_buffer[i] = output.index[i] - my_shift;
81 }
82 output.index = index_buffer;
83 }
84 return output;
85 }
86
87private:
88 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > my_ext;
89 Index_ my_shift;
90};
91
92template<typename Index_>
93class SubsetOracle final : public Oracle<Index_> {
94public:
95 SubsetOracle(std::shared_ptr<const Oracle<Index_> > oracle, Index_ shift) : my_oracle(std::move(oracle)), my_shift(shift) {}
96
97 std::size_t total() const {
98 return my_oracle->total();
99 }
100
101 Index_ get(std::size_t i) const {
102 return my_oracle->get(i) + my_shift;
103 }
104
105private:
106 std::shared_ptr<const Oracle<Index_> > my_oracle;
107 Index_ my_shift;
108};
109
110template<bool oracle_, typename Value_, typename Index_>
111class AcrossDense final : public DenseExtractor<oracle_, Value_, Index_> {
112public:
113 template<typename ... Args_>
114 AcrossDense(const Matrix<Value_, Index_>* matrix, Index_ subset_start, bool row, MaybeOracle<oracle_, Index_> oracle, Args_&& ... args) : my_shift(subset_start) {
115 if constexpr(oracle_) {
116 auto ptr = new SubsetOracle(std::move(oracle), my_shift);
117 oracle.reset(ptr);
118 }
119 my_ext = new_extractor<false, oracle_>(matrix, row, std::move(oracle), std::forward<Args_>(args)...);
120 }
121
122 const Value_* fetch(Index_ i, Value_* buffer) {
123 return my_ext->fetch(i + my_shift, buffer);
124 }
125
126private:
127 std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > my_ext;
128 Index_ my_shift;
129};
130
131template<bool oracle_, typename Value_, typename Index_>
132class AcrossSparse final : public SparseExtractor<oracle_, Value_, Index_> {
133public:
134 template<typename ... Args_>
135 AcrossSparse(const Matrix<Value_, Index_>* matrix, Index_ subset_start, bool row, MaybeOracle<oracle_, Index_> oracle, Args_&& ... args) : my_shift(subset_start) {
136 if constexpr(oracle_) {
137 auto ptr = new SubsetOracle(std::move(oracle), my_shift);
138 oracle.reset(ptr);
139 }
140 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), std::forward<Args_>(args)...);
141 }
142
143 SparseRange<Value_, Index_> fetch(Index_ i, Value_* value_buffer, Index_* index_buffer) {
144 return my_ext->fetch(i + my_shift, value_buffer, index_buffer);
145 }
146
147private:
148 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > my_ext;
149 Index_ my_shift;
150};
151
152}
167template<typename Value_, typename Index_>
168class DelayedSubsetBlock final : public Matrix<Value_, Index_> {
169public:
177 DelayedSubsetBlock(std::shared_ptr<const Matrix<Value_, Index_> > matrix, Index_ subset_start, Index_ subset_length, bool by_row) :
178 my_matrix(std::move(matrix)), my_subset_start(subset_start), my_subset_length(subset_length), my_by_row(by_row) {}
179
180private:
181 std::shared_ptr<const Matrix<Value_, Index_> > my_matrix;
182 Index_ my_subset_start, my_subset_length;
183 bool my_by_row;
184
185public:
186 Index_ nrow() const {
187 if (my_by_row) {
188 return my_subset_length;
189 } else {
190 return my_matrix->nrow();
191 }
192 }
193
194 Index_ ncol() const {
195 if (my_by_row) {
196 return my_matrix->ncol();
197 } else {
198 return my_subset_length;
199 }
200 }
201
202 bool is_sparse() const {
203 return my_matrix->is_sparse();
204 }
205
206 double is_sparse_proportion() const {
207 return my_matrix->is_sparse_proportion();
208 }
209
210 bool prefer_rows() const {
211 return my_matrix->prefer_rows();
212 }
213
214 double prefer_rows_proportion() const {
215 return my_matrix->prefer_rows_proportion();
216 }
217
218 bool uses_oracle(bool row) const {
219 return my_matrix->uses_oracle(row);
220 }
221
222 using Matrix<Value_, Index_>::dense_column;
223
224 using Matrix<Value_, Index_>::dense_row;
225
226 using Matrix<Value_, Index_>::sparse_column;
227
228 using Matrix<Value_, Index_>::sparse_row;
229
230 /************************
231 ***** Myopic dense *****
232 ************************/
233private:
234 template<bool oracle_, typename ... Args_>
235 std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > dense_internal(bool row, Args_&&... args) const {
236 if (row != my_by_row) {
237 return std::make_unique<DelayedSubsetBlock_internal::AlongDense<oracle_, Value_, Index_> >(my_matrix.get(), my_subset_start, my_subset_length, row, std::forward<Args_>(args)...);
238 } else {
239 return std::make_unique<DelayedSubsetBlock_internal::AcrossDense<oracle_, Value_, Index_> >(my_matrix.get(), my_subset_start, row, std::forward<Args_>(args)...);
240 }
241 }
242
243public:
244 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, const Options& opt) const {
245 return dense_internal<false>(row, false, opt);
246 }
247
248 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, Index_ block_start, Index_ block_length, const Options& opt) const {
249 return dense_internal<false>(row, false, block_start, block_length, opt);
250 }
251
252 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(bool row, VectorPtr<Index_> indices_ptr, const Options& opt) const {
253 return dense_internal<false>(row, false, std::move(indices_ptr), opt);
254 }
255
256 /*************************
257 ***** Myopic sparse *****
258 *************************/
259private:
260 template<bool oracle_, typename ... Args_>
261 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > sparse_internal(bool row, Args_&&... args) const {
262 if (row != my_by_row) {
263 return std::make_unique<DelayedSubsetBlock_internal::AlongSparse<oracle_, Value_, Index_> >(my_matrix.get(), my_subset_start, my_subset_length, row, std::forward<Args_>(args)...);
264 } else {
265 return std::make_unique<DelayedSubsetBlock_internal::AcrossSparse<oracle_, Value_, Index_> >(my_matrix.get(), my_subset_start, row, std::forward<Args_>(args)...);
266 }
267 }
268
269public:
270 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, const Options& opt) const {
271 return sparse_internal<false>(row, false, opt);
272 }
273
274 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, Index_ block_start, Index_ block_length, const Options& opt) const {
275 return sparse_internal<false>(row, false, block_start, block_length, opt);
276 }
277
278 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(bool row, VectorPtr<Index_> indices_ptr, const Options& opt) const {
279 return sparse_internal<false>(row, false, std::move(indices_ptr), opt);
280 }
281
282 /**************************
283 ***** Oracular dense *****
284 **************************/
285public:
286 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, const Options& opt) const {
287 return dense_internal<true>(row, std::move(oracle), opt);
288 }
289
290 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, Index_ block_start, Index_ block_length, const Options& opt) const {
291 return dense_internal<true>(row, std::move(oracle), block_start, block_length, opt);
292 }
293
294 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const Oracle<Index_> > oracle, VectorPtr<Index_> indices_ptr, const Options& opt) const {
295 return dense_internal<true>(row, std::move(oracle), std::move(indices_ptr), opt);
296 }
297
298 /***************************
299 ***** Oracular sparse *****
300 ***************************/
301public:
302 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, const Options& opt) const {
303 return sparse_internal<true>(row, std::move(oracle), opt);
304 }
305
306 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, Index_ block_start, Index_ block_length, const Options& opt) const {
307 return sparse_internal<true>(row, std::move(oracle), block_start, block_length, opt);
308 }
309
310 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const Oracle<Index_> > oracle, VectorPtr<Index_> indices_ptr, const Options& opt) const {
311 return sparse_internal<true>(row, std::move(oracle), std::move(indices_ptr), opt);
312 }
313};
314
329template<typename Value_, typename Index_>
330std::shared_ptr<Matrix<Value_, Index_> > make_DelayedSubsetBlock(std::shared_ptr<const Matrix<Value_, Index_> > matrix, Index_ subset_start, Index_ subset_length, bool by_row) {
331 return std::shared_ptr<Matrix<Value_, Index_> >(new DelayedSubsetBlock<Value_, Index_>(std::move(matrix), subset_start, subset_length, by_row));
332}
333
337template<typename Value_, typename Index_>
338std::shared_ptr<Matrix<Value_, Index_> > make_DelayedSubsetBlock(std::shared_ptr<Matrix<Value_, Index_> > matrix, Index_ subset_start, Index_ subset_length, bool by_row) {
339 return std::shared_ptr<Matrix<Value_, Index_> >(new DelayedSubsetBlock<Value_, Index_>(std::move(matrix), subset_start, subset_length, by_row));
340}
348template<int margin_, typename Value_, typename Index_>
349std::shared_ptr<Matrix<Value_, Index_> > make_DelayedSubsetBlock(std::shared_ptr<const Matrix<Value_, Index_> > matrix, Index_ subset_start, Index_ subset_length) {
350 return make_DelayedSubsetBlock(std::move(matrix), subset_start, subset_length, margin_ == 0);
351}
352
353template<int margin_, typename Value_, typename Index_>
354std::shared_ptr<Matrix<Value_, Index_> > make_DelayedSubsetBlock(std::shared_ptr<Matrix<Value_, Index_> > matrix, Index_ subset_start, Index_ subset_length) {
355 return make_DelayedSubsetBlock(std::move(matrix), subset_start, subset_length, margin_ == 0);
356}
361}
362
363#endif
Virtual class for a matrix of some numeric type.
Delayed subsetting to a contiguous block.
Definition DelayedSubsetBlock.hpp:168
Index_ nrow() const
Definition DelayedSubsetBlock.hpp:186
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetBlock.hpp:294
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubsetBlock.hpp:248
double prefer_rows_proportion() const
Definition DelayedSubsetBlock.hpp:214
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetBlock.hpp:302
Index_ ncol() const
Definition DelayedSubsetBlock.hpp:194
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, const Options &opt) const
Definition DelayedSubsetBlock.hpp:244
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetBlock.hpp:278
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetBlock.hpp:310
double is_sparse_proportion() const
Definition DelayedSubsetBlock.hpp:206
bool is_sparse() const
Definition DelayedSubsetBlock.hpp:202
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubsetBlock.hpp:306
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetBlock.hpp:252
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetBlock.hpp:286
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, const Options &opt) const
Definition DelayedSubsetBlock.hpp:270
DelayedSubsetBlock(std::shared_ptr< const Matrix< Value_, Index_ > > matrix, Index_ subset_start, Index_ subset_length, bool by_row)
Definition DelayedSubsetBlock.hpp:177
bool uses_oracle(bool row) const
Definition DelayedSubsetBlock.hpp:218
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubsetBlock.hpp:290
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedSubsetBlock.hpp:274
bool prefer_rows() const
Definition DelayedSubsetBlock.hpp:210
Virtual class for a matrix.
Definition Matrix.hpp:59
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense_row() const
Definition Matrix.hpp:287
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense_column() const
Definition Matrix.hpp:328
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse_column() const
Definition Matrix.hpp:537
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse_row() const
Definition Matrix.hpp:496
Predict future access requests on the target dimension.
Definition Oracle.hpp:23
Flexible representations for matrix data.
Definition Extractor.hpp:15
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
auto new_extractor(const Matrix< Value_, Index_ > &matrix, bool row, MaybeOracle< oracle_, Index_ > oracle, Args_ &&... args)
Definition new_extractor.hpp:42
std::shared_ptr< Matrix< Value_, Index_ > > make_DelayedSubsetBlock(std::shared_ptr< const Matrix< Value_, Index_ > > matrix, Index_ subset_start, Index_ subset_length, bool by_row)
Definition DelayedSubsetBlock.hpp:330
Templated construction of a new extractor.
Options for accessing data from a Matrix instance.
Definition Options.hpp:30