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"
7
8#include <memory>
9#include <type_traits>
10#include <algorithm>
11#include <cstddef>
12
19namespace tatami {
20
24namespace DelayedCast_internal {
25
26template<typename IndexIn_, typename IndexOut_>
27class CastOracle final : public Oracle<IndexIn_> {
28public:
29 CastOracle(std::shared_ptr<const Oracle<IndexOut_> > oracle) : my_oracle(std::move(oracle)) {}
30
31 IndexIn_ get(const PredictionIndex i) const {
32 return my_oracle->get(i);
33 }
34
35 PredictionIndex total() const {
36 return my_oracle->total();
37 }
38
39private:
40 std::shared_ptr<const Oracle<IndexOut_> > my_oracle;
41};
42
43template<bool oracle_, typename IndexIn_, typename IndexOut_>
44MaybeOracle<oracle_, IndexIn_> convert(MaybeOracle<oracle_, IndexOut_> oracle) {
45 if constexpr(!oracle_) {
46 return false;
47 } else if constexpr(std::is_same<IndexIn_, IndexOut_>::value) {
48 return oracle;
49 } else {
50 return std::make_shared<CastOracle<IndexIn_, IndexOut_> >(std::move(oracle));
51 }
52}
53
54template<typename IndexIn_, typename IndexOut_>
55VectorPtr<IndexIn_> convert(VectorPtr<IndexOut_> indices_ptr) {
56 if constexpr(std::is_same<IndexIn_, IndexOut_>::value) {
57 return indices_ptr;
58 } else {
59 return std::make_shared<std::vector<IndexIn_> >(indices_ptr->begin(), indices_ptr->end());
60 }
61}
62
63template<bool oracle_, typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
64class Dense final : public DenseExtractor<oracle_, ValueOut_, IndexOut_> {
65public:
66 Dense(
67 const Matrix<ValueIn_, IndexIn_>& matrix,
68 const bool row, MaybeOracle<oracle_, IndexOut_> oracle,
69 const Options& opt
70 ) {
71 allocate(row ? matrix.ncol() : matrix.nrow());
72 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), opt);
73 }
74
75 Dense(
76 const Matrix<ValueIn_, IndexIn_>& matrix,
77 const bool row,
78 MaybeOracle<oracle_, IndexOut_> oracle,
79 const IndexOut_ block_start,
80 const IndexOut_ block_length,
81 const Options& opt
82 ) {
83 allocate(block_length);
84 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), block_start, block_length, opt);
85 }
86
87 Dense(
88 const Matrix<ValueIn_, IndexIn_>& matrix,
89 const bool row,
90 MaybeOracle<oracle_, IndexOut_> oracle,
91 VectorPtr<IndexOut_> indices_ptr,
92 const Options& opt
93 ) {
94 allocate(indices_ptr->size());
95 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), convert<IndexIn_>(std::move(indices_ptr)), opt);
96 }
97
98private:
99 void allocate(const IndexIn_ n) {
100 if constexpr(!no_op) {
101 resize_container_to_Index_size(my_buffer, n);
102 }
103 }
104
105public:
106 const ValueOut_* fetch(const IndexOut_ i, ValueOut_* const buffer) {
107 if constexpr(no_op) {
108 return my_ext->fetch(i, buffer);
109 } else {
110 const auto ptr = my_ext->fetch(i, my_buffer.data());
111 std::copy_n(ptr, my_buffer.size(), buffer);
112 return buffer;
113 }
114 }
115
116private:
117 std::unique_ptr<DenseExtractor<oracle_, ValueIn_, IndexIn_> > my_ext;
118 static constexpr bool no_op = std::is_same<ValueOut_, ValueIn_>::value;
119 typename std::conditional<no_op, bool, std::vector<ValueIn_> >::type my_buffer;
120};
121
122template<bool oracle_, typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
123class Sparse final : public SparseExtractor<oracle_, ValueOut_, IndexOut_> {
124public:
125 Sparse(
126 const Matrix<ValueIn_, IndexIn_>& matrix,
127 const bool row,
128 MaybeOracle<oracle_, IndexOut_> oracle,
129 const Options& opt
130 ) {
131 allocate(row ? matrix.ncol() : matrix.nrow(), opt);
132 my_ext = new_extractor<true, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), opt);
133 }
134
135 Sparse(
136 const Matrix<ValueIn_, IndexIn_>& matrix,
137 const bool row,
138 MaybeOracle<oracle_, IndexOut_> oracle,
139 const IndexOut_ block_start,
140 const IndexOut_ block_length,
141 const Options& opt
142 ) {
143 allocate(block_length, opt);
144 my_ext = new_extractor<true, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), block_start, block_length, opt);
145 }
146
147 Sparse(
148 const Matrix<ValueIn_, IndexIn_>& matrix,
149 const bool row,
150 MaybeOracle<oracle_, IndexOut_> oracle,
151 VectorPtr<IndexOut_> indices_ptr,
152 const Options& opt
153 ) {
154 allocate(indices_ptr->size(), opt);
155 my_ext = new_extractor<true, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), convert<IndexIn_>(std::move(indices_ptr)), opt);
156 }
157
158private:
159 void allocate(const IndexIn_ n, const Options& opt) {
160 if constexpr(!no_op_value) {
161 if (opt.sparse_extract_value) {
162 resize_container_to_Index_size(my_vbuffer, n);
163 }
164 }
165 if constexpr(!no_op_index) {
166 if (opt.sparse_extract_index) {
167 resize_container_to_Index_size(my_ibuffer, n);
168 }
169 }
170 }
171
172public:
173 SparseRange<ValueOut_, IndexOut_> fetch(const IndexOut_ i, ValueOut_* const value_buffer, IndexOut_* const index_buffer) {
174 IndexIn_* const iptr = [&]{
175 if constexpr(no_op_index) {
176 return index_buffer;
177 } else {
178 return my_ibuffer.data();
179 }
180 }();
181
182 ValueIn_* const vptr = [&]{
183 if constexpr(no_op_value) {
184 return value_buffer;
185 } else {
186 return my_vbuffer.data();
187 }
188 }();
189
190 const auto range = my_ext->fetch(i, vptr, iptr);
191 SparseRange<ValueOut_, IndexOut_> output(range.number);
192
193 if constexpr(no_op_index) {
194 output.index = range.index;
195 } else if (range.index != NULL) {
196 std::copy_n(range.index, range.number, index_buffer);
197 output.index = index_buffer;
198 }
199
200 if constexpr(no_op_value) {
201 output.value = range.value;
202 } else if (range.value != NULL) {
203 std::copy_n(range.value, range.number, value_buffer);
204 output.value = value_buffer;
205 }
206
207 return output;
208 }
209
210private:
211 std::unique_ptr<SparseExtractor<oracle_, ValueIn_, IndexIn_> > my_ext;
212 static constexpr bool no_op_value = std::is_same<ValueOut_, ValueIn_>::value;
213 typename std::conditional<no_op_value, bool, std::vector<ValueIn_> >::type my_vbuffer;
214 static constexpr bool no_op_index = std::is_same<IndexOut_, IndexIn_>::value;
215 typename std::conditional<no_op_index, bool, std::vector<IndexIn_> >::type my_ibuffer;
216};
217
218}
236template<typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
237class DelayedCast final : public Matrix<ValueOut_, IndexOut_> {
238public:
242 DelayedCast(std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > matrix) :
243 my_matrix(std::move(matrix)),
244 my_nrow(sanisizer::cast<IndexOut_>(attest_for_Index(my_matrix->nrow()))),
245 my_ncol(sanisizer::cast<IndexOut_>(attest_for_Index(my_matrix->ncol())))
246 {}
247
248public:
249 IndexOut_ nrow() const {
250 return my_nrow;
251 }
252
253 IndexOut_ ncol() const {
254 return my_ncol;
255 }
256
257 bool is_sparse() const {
258 return my_matrix->is_sparse();
259 }
260
261 double is_sparse_proportion() const {
262 return my_matrix->is_sparse_proportion();
263 }
264
265 bool prefer_rows() const {
266 return my_matrix->prefer_rows();
267 }
268
269 double prefer_rows_proportion() const {
270 return my_matrix->prefer_rows_proportion();
271 }
272
273 bool uses_oracle(const bool row) const {
274 return my_matrix->uses_oracle(row);
275 }
276
277private:
278 std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > my_matrix;
279 IndexOut_ my_nrow, my_ncol;
280
281 /********************
282 *** Myopic dense ***
283 ********************/
284public:
285 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> > dense(
286 const bool row,
287 const Options& opt
288 ) const {
289 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, false, opt);
290 }
291
292 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> > dense(
293 const bool row,
294 const IndexOut_ block_start,
295 const IndexOut_ block_length,
296 const Options& opt
297 ) const {
298 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, false, block_start, block_length, opt);
299 }
300
301 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> > dense(
302 const bool row,
303 VectorPtr<IndexOut_> indices_my_matrix,
304 const Options& opt
305 ) const {
306 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, false, std::move(indices_my_matrix), opt);
307 }
308
309 /*********************
310 *** Myopic sparse ***
311 *********************/
312public:
313 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> > sparse(
314 const bool row,
315 const Options& opt
316 ) const {
317 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, false, opt);
318 }
319
320 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> > sparse(
321 const bool row,
322 const IndexOut_ block_start,
323 const IndexOut_ block_length,
324 const Options& opt
325 ) const {
326 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, false, block_start, block_length, opt);
327 }
328
329 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> > sparse(
330 const bool row,
331 VectorPtr<IndexOut_> indices_my_matrix,
332 const Options& opt
333 ) const {
334 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, false, std::move(indices_my_matrix), opt);
335 }
336
337 /**********************
338 *** Oracular dense ***
339 **********************/
340public:
341 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> > dense(
342 const bool row,
343 std::shared_ptr<const Oracle<IndexOut_> > oracle,
344 const Options& opt
345 ) const {
346 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), opt);
347 }
348
349 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> > dense(
350 const bool row,
351 std::shared_ptr<const Oracle<IndexOut_> > oracle,
352 const IndexOut_ block_start,
353 const IndexOut_ block_length,
354 const Options& opt
355 ) const {
356 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), block_start, block_length, opt);
357 }
358
359 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> > dense(
360 const bool row,
361 std::shared_ptr<const Oracle<IndexOut_> > oracle,
362 VectorPtr<IndexOut_> indices_my_matrix,
363 const Options& opt
364 ) const {
365 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), std::move(indices_my_matrix), opt);
366 }
367
368 /***********************
369 *** Oracular sparse ***
370 ***********************/
371public:
372 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> > sparse(
373 const bool row,
374 std::shared_ptr<const Oracle<IndexOut_> > oracle,
375 const Options& opt
376 ) const {
377 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), opt);
378 }
379
380 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> > sparse(
381 const bool row,
382 std::shared_ptr<const Oracle<IndexOut_> > oracle,
383 const IndexOut_ block_start,
384 const IndexOut_ block_length,
385 const Options& opt
386 ) const {
387 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), block_start, block_length, opt);
388 }
389
390 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> > sparse(
391 const bool row,
392 std::shared_ptr<const Oracle<IndexOut_> > oracle,
393 VectorPtr<IndexOut_> indices_my_matrix,
394 const Options& opt
395 ) const {
396 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), std::move(indices_my_matrix), opt);
397 }
398};
399
411template<typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
412std::shared_ptr<Matrix<ValueOut_, IndexOut_> > make_DelayedCast(std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > p) {
413 return std::shared_ptr<Matrix<ValueOut_, IndexOut_> >(new DelayedCast<ValueOut_, IndexOut_, ValueIn_, IndexIn_>(std::move(p)));
414}
415
419template<typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
420std::shared_ptr<Matrix<ValueOut_, IndexOut_> > make_DelayedCast(std::shared_ptr<Matrix<ValueIn_, IndexIn_> > p) {
421 return std::shared_ptr<Matrix<ValueOut_, IndexOut_> >(new DelayedCast<ValueOut_, IndexOut_, ValueIn_, IndexIn_>(std::move(p)));
422}
427}
428
429#endif
Convert index type to container size.
Virtual class for a matrix of some numeric type.
Recast a Matrix to a different interface type.
Definition DelayedCast.hpp:237
std::unique_ptr< OracularSparseExtractor< ValueOut_, IndexOut_ > > sparse(const bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const IndexOut_ block_start, const IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:380
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(const bool row, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:329
DelayedCast(std::shared_ptr< const Matrix< ValueIn_, IndexIn_ > > matrix)
Definition DelayedCast.hpp:242
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(const bool row, const IndexOut_ block_start, const IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:292
std::unique_ptr< OracularSparseExtractor< ValueOut_, IndexOut_ > > sparse(const bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:390
std::unique_ptr< OracularDenseExtractor< ValueOut_, IndexOut_ > > dense(const bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:359
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(const bool row, const Options &opt) const
Definition DelayedCast.hpp:285
double prefer_rows_proportion() const
Definition DelayedCast.hpp:269
IndexOut_ nrow() const
Definition DelayedCast.hpp:249
std::unique_ptr< OracularSparseExtractor< ValueOut_, IndexOut_ > > sparse(const bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const Options &opt) const
Definition DelayedCast.hpp:372
std::unique_ptr< OracularDenseExtractor< ValueOut_, IndexOut_ > > dense(const bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const Options &opt) const
Definition DelayedCast.hpp:341
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(const bool row, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:301
bool uses_oracle(const bool row) const
Definition DelayedCast.hpp:273
bool is_sparse() const
Definition DelayedCast.hpp:257
IndexOut_ ncol() const
Definition DelayedCast.hpp:253
std::unique_ptr< OracularDenseExtractor< ValueOut_, IndexOut_ > > dense(const bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const IndexOut_ block_start, const IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:349
double is_sparse_proportion() const
Definition DelayedCast.hpp:261
bool prefer_rows() const
Definition DelayedCast.hpp:265
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(const bool row, const Options &opt) const
Definition DelayedCast.hpp:313
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(const bool row, const IndexOut_ block_start, const IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:320
Virtual class for a matrix.
Definition Matrix.hpp:59
Predict future access requests on the target dimension.
Definition Oracle.hpp:29
Flexible representations for matrix data.
Definition Extractor.hpp:15
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
void resize_container_to_Index_size(Container_ &container, const Index_ x, Args_ &&... args)
Definition Index_to_container.hpp:99
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
std::shared_ptr< Matrix< ValueOut_, IndexOut_ > > make_DelayedCast(std::shared_ptr< const Matrix< ValueIn_, IndexIn_ > > p)
Definition DelayedCast.hpp:412
std::size_t PredictionIndex
Definition Oracle.hpp:18
Templated construction of a new extractor.
Options for accessing data from a Matrix instance.
Definition Options.hpp:30