tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
DelayedCast.hpp
Go to the documentation of this file.
1#ifndef TATAMI_DELAYED_CAST_HPP
2#define TATAMI_DELAYED_CAST_HPP
3
4#include "../base/Matrix.hpp"
5#include "../utils/new_extractor.hpp"
6
7#include <memory>
8#include <type_traits>
9#include <algorithm>
10
17namespace tatami {
18
22namespace DelayedCast_internal {
23
24template<typename IndexIn_, typename IndexOut_>
25class CastOracle : public Oracle<IndexIn_> {
26public:
27 CastOracle(std::shared_ptr<const Oracle<IndexOut_> > oracle) : my_oracle(std::move(oracle)) {}
28
29 IndexIn_ get(size_t i) const {
30 return my_oracle->get(i);
31 }
32
33 size_t total() const {
34 return my_oracle->total();
35 }
36
37private:
38 std::shared_ptr<const Oracle<IndexOut_> > my_oracle;
39};
40
41template<bool oracle_, typename IndexIn_, typename IndexOut_>
43 if constexpr(!oracle_) {
44 return false;
45 } else if constexpr(std::is_same<IndexIn_, IndexOut_>::value) {
46 return oracle;
47 } else {
48 return std::make_shared<CastOracle<IndexIn_, IndexOut_> >(std::move(oracle));
49 }
50}
51
52template<typename IndexIn_, typename IndexOut_>
54 if constexpr(std::is_same<IndexIn_, IndexOut_>::value) {
55 return indices_ptr;
56 } else {
57 return std::make_shared<std::vector<IndexIn_> >(indices_ptr->begin(), indices_ptr->end());
58 }
59}
60
61template<bool oracle_, typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
62class Dense : public DenseExtractor<oracle_, ValueOut_, IndexOut_> {
63public:
64 Dense(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, const Options& opt) {
65 allocate(row ? matrix->ncol() : matrix->nrow());
66 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), opt);
67 }
68
69 Dense(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) {
70 allocate(block_length);
71 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), block_start, block_length, opt);
72 }
73
74 Dense(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, VectorPtr<IndexOut_> indices_ptr, const Options& opt) {
75 allocate(indices_ptr->size());
76 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), convert<IndexIn_>(std::move(indices_ptr)), opt);
77 }
78
79private:
80 void allocate(size_t n) {
81 if constexpr(!no_op) {
82 my_buffer.resize(n);
83 }
84 }
85
86public:
87 const ValueOut_* fetch(IndexOut_ i, ValueOut_* buffer) {
88 if constexpr(no_op) {
89 return my_ext->fetch(i, buffer);
90 } else {
91 auto ptr = my_ext->fetch(i, my_buffer.data());
92 std::copy_n(ptr, my_buffer.size(), buffer);
93 return buffer;
94 }
95 }
96
97private:
98 std::unique_ptr<DenseExtractor<oracle_, ValueIn_, IndexIn_> > my_ext;
99 static constexpr bool no_op = std::is_same<ValueOut_, ValueIn_>::value;
100 typename std::conditional<no_op, bool, std::vector<ValueIn_> >::type my_buffer;
101};
102
103template<bool oracle_, typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
104class Sparse : public SparseExtractor<oracle_, ValueOut_, IndexOut_> {
105public:
106 Sparse(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, const Options& opt) {
107 allocate(row ? matrix->ncol() : matrix->nrow(), opt);
108 my_ext = new_extractor<true, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), opt);
109 }
110
111 Sparse(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) {
112 allocate(block_length, opt);
113 my_ext = new_extractor<true, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), block_start, block_length, opt);
114 }
115
116 Sparse(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, VectorPtr<IndexOut_> indices_ptr, const Options& opt) {
117 allocate(indices_ptr->size(), opt);
118 my_ext = new_extractor<true, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), convert<IndexIn_>(std::move(indices_ptr)), opt);
119 }
120
121private:
122 void allocate(size_t n, const Options& opt) {
123 if constexpr(!no_op_value) {
124 if (opt.sparse_extract_value) {
125 my_vbuffer.resize(n);
126 }
127 }
128 if constexpr(!no_op_index) {
129 if (opt.sparse_extract_index) {
130 my_ibuffer.resize(n);
131 }
132 }
133 }
134
135public:
136 SparseRange<ValueOut_, IndexOut_> fetch(IndexOut_ i, ValueOut_* value_buffer, IndexOut_* index_buffer) {
137 IndexIn_* iptr = [&]() {
138 if constexpr(no_op_index) {
139 return index_buffer;
140 } else {
141 return my_ibuffer.data();
142 }
143 }();
144
145 ValueIn_* vptr = [&]() {
146 if constexpr(no_op_value) {
147 return value_buffer;
148 } else {
149 return my_vbuffer.data();
150 }
151 }();
152
153 auto range = my_ext->fetch(i, vptr, iptr);
154 SparseRange<ValueOut_, IndexOut_> output(range.number);
155
156 if constexpr(no_op_index) {
157 output.index = range.index;
158 } else if (range.index != NULL) {
159 std::copy_n(range.index, range.number, index_buffer);
160 output.index = index_buffer;
161 }
162
163 if constexpr(no_op_value) {
164 output.value = range.value;
165 } else if (range.value != NULL) {
166 std::copy_n(range.value, range.number, value_buffer);
167 output.value = value_buffer;
168 }
169
170 return output;
171 }
172
173private:
174 std::unique_ptr<SparseExtractor<oracle_, ValueIn_, IndexIn_> > my_ext;
175 static constexpr bool no_op_value = std::is_same<ValueOut_, ValueIn_>::value;
176 typename std::conditional<no_op_value, bool, std::vector<ValueIn_> >::type my_vbuffer;
177 static constexpr bool no_op_index = std::is_same<IndexOut_, IndexIn_>::value;
178 typename std::conditional<no_op_index, bool, std::vector<IndexIn_> >::type my_ibuffer;
179};
180
181}
199template<typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
200class DelayedCast : public Matrix<ValueOut_, IndexOut_> {
201public:
205 DelayedCast(std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > matrix) : my_matrix(std::move(matrix)) {}
206
207public:
208 IndexOut_ nrow() const {
209 return my_matrix->nrow();
210 }
211
212 IndexOut_ ncol() const {
213 return my_matrix->ncol();
214 }
215
216 bool is_sparse() const {
217 return my_matrix->is_sparse();
218 }
219
220 double is_sparse_proportion() const {
221 return my_matrix->is_sparse_proportion();
222 }
223
224 bool prefer_rows() const {
225 return my_matrix->prefer_rows();
226 }
227
228 double prefer_rows_proportion() const {
229 return my_matrix->prefer_rows_proportion();
230 }
231
232 bool uses_oracle(bool row) const {
233 return my_matrix->uses_oracle(row);
234 }
235
236private:
237 std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > my_matrix;
238
239 /********************
240 *** Myopic dense ***
241 ********************/
242public:
243 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, const Options& opt) const {
244 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, opt);
245 }
246
247 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) const {
248 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, block_start, block_length, opt);
249 }
250
251 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, VectorPtr<IndexOut_> indices_my_matrix, const Options& opt) const {
252 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, std::move(indices_my_matrix), opt);
253 }
254
255 /*********************
256 *** Myopic sparse ***
257 *********************/
258public:
259 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, const Options& opt) const {
260 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, opt);
261 }
262
263 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) const {
264 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, block_start, block_length, opt);
265 }
266
267 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, VectorPtr<IndexOut_> indices_my_matrix, const Options& opt) const {
268 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, std::move(indices_my_matrix), opt);
269 }
270
271 /**********************
272 *** Oracular dense ***
273 **********************/
274public:
275 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, std::shared_ptr<const Oracle<IndexOut_> > oracle, const Options& opt) const {
276 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), opt);
277 }
278
279 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, std::shared_ptr<const Oracle<IndexOut_> > oracle, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) const {
280 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), block_start, block_length, opt);
281 }
282
283 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, std::shared_ptr<const Oracle<IndexOut_> > oracle, VectorPtr<IndexOut_> indices_my_matrix, const Options& opt) const {
284 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), std::move(indices_my_matrix), opt);
285 }
286
287 /***********************
288 *** Oracular sparse ***
289 ***********************/
290public:
291 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, std::shared_ptr<const Oracle<IndexOut_> > oracle, const Options& opt) const {
292 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), opt);
293 }
294
295 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, std::shared_ptr<const Oracle<IndexOut_> > oracle, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) const {
296 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), block_start, block_length, opt);
297 }
298
299 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, std::shared_ptr<const Oracle<IndexOut_> > oracle, VectorPtr<IndexOut_> indices_my_matrix, const Options& opt) const {
300 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), std::move(indices_my_matrix), opt);
301 }
302};
303
315template<typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
316std::shared_ptr<Matrix<ValueOut_, IndexOut_> > make_DelayedCast(std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > p) {
317 return std::shared_ptr<Matrix<ValueOut_, IndexOut_> >(new DelayedCast<ValueOut_, IndexOut_, ValueIn_, IndexIn_>(std::move(p)));
318}
319
323template<typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
324std::shared_ptr<Matrix<ValueOut_, IndexOut_> > make_DelayedCast(std::shared_ptr<Matrix<ValueIn_, IndexIn_> > p) {
325 return std::shared_ptr<Matrix<ValueOut_, IndexOut_> >(new DelayedCast<ValueOut_, IndexOut_, ValueIn_, IndexIn_>(std::move(p)));
326}
331}
332
333#endif
Recast a Matrix to a different interface type.
Definition DelayedCast.hpp:200
std::unique_ptr< OracularDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, IndexOut_ block_start, IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:279
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, IndexOut_ block_start, IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:247
std::unique_ptr< OracularDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:283
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, const Options &opt) const
Definition DelayedCast.hpp:259
DelayedCast(std::shared_ptr< const Matrix< ValueIn_, IndexIn_ > > matrix)
Definition DelayedCast.hpp:205
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:251
std::unique_ptr< OracularDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const Options &opt) const
Definition DelayedCast.hpp:275
double prefer_rows_proportion() const
Definition DelayedCast.hpp:228
IndexOut_ nrow() const
Definition DelayedCast.hpp:208
std::unique_ptr< OracularSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, IndexOut_ block_start, IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:295
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, IndexOut_ block_start, IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:263
std::unique_ptr< OracularSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:299
bool is_sparse() const
Definition DelayedCast.hpp:216
bool uses_oracle(bool row) const
Definition DelayedCast.hpp:232
IndexOut_ ncol() const
Definition DelayedCast.hpp:212
double is_sparse_proportion() const
Definition DelayedCast.hpp:220
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, const Options &opt) const
Definition DelayedCast.hpp:243
bool prefer_rows() const
Definition DelayedCast.hpp:224
std::unique_ptr< OracularSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const Options &opt) const
Definition DelayedCast.hpp:291
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:267
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::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
typename std::conditional< oracle_, OracularSparseExtractor< Value_, Index_ >, MyopicSparseExtractor< Value_, Index_ > >::type SparseExtractor
Definition Extractor.hpp:284
std::shared_ptr< Matrix< ValueOut_, IndexOut_ > > make_DelayedCast(std::shared_ptr< const Matrix< ValueIn_, IndexIn_ > > p)
Definition DelayedCast.hpp:316
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