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"
6#include "../utils/Index_to_container.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(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(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, const Options& opt) {
67 allocate(row ? matrix->ncol() : matrix->nrow());
68 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), opt);
69 }
70
71 Dense(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) {
72 allocate(block_length);
73 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), block_start, block_length, opt);
74 }
75
76 Dense(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, VectorPtr<IndexOut_> indices_ptr, const Options& opt) {
77 allocate(indices_ptr->size());
78 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), convert<IndexIn_>(std::move(indices_ptr)), opt);
79 }
80
81private:
82 void allocate(IndexIn_ n) {
83 if constexpr(!no_op) {
85 }
86 }
87
88public:
89 const ValueOut_* fetch(IndexOut_ i, ValueOut_* buffer) {
90 if constexpr(no_op) {
91 return my_ext->fetch(i, buffer);
92 } else {
93 auto ptr = my_ext->fetch(i, my_buffer.data());
94 std::copy_n(ptr, my_buffer.size(), buffer);
95 return buffer;
96 }
97 }
98
99private:
100 std::unique_ptr<DenseExtractor<oracle_, ValueIn_, IndexIn_> > my_ext;
101 static constexpr bool no_op = std::is_same<ValueOut_, ValueIn_>::value;
102 typename std::conditional<no_op, bool, std::vector<ValueIn_> >::type my_buffer;
103};
104
105template<bool oracle_, typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
106class Sparse final : public SparseExtractor<oracle_, ValueOut_, IndexOut_> {
107public:
108 Sparse(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, const Options& opt) {
109 allocate(row ? matrix->ncol() : matrix->nrow(), opt);
110 my_ext = new_extractor<true, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), opt);
111 }
112
113 Sparse(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) {
114 allocate(block_length, opt);
115 my_ext = new_extractor<true, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), block_start, block_length, opt);
116 }
117
118 Sparse(const Matrix<ValueIn_, IndexIn_>* matrix, bool row, MaybeOracle<oracle_, IndexOut_> oracle, VectorPtr<IndexOut_> indices_ptr, const Options& opt) {
119 allocate(indices_ptr->size(), opt);
120 my_ext = new_extractor<true, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), convert<IndexIn_>(std::move(indices_ptr)), opt);
121 }
122
123private:
124 void allocate(IndexIn_ n, const Options& opt) {
125 if constexpr(!no_op_value) {
126 if (opt.sparse_extract_value) {
127 resize_container_to_Index_size(my_vbuffer, n);
128 }
129 }
130 if constexpr(!no_op_index) {
131 if (opt.sparse_extract_index) {
132 resize_container_to_Index_size(my_ibuffer, n);
133 }
134 }
135 }
136
137public:
138 SparseRange<ValueOut_, IndexOut_> fetch(IndexOut_ i, ValueOut_* value_buffer, IndexOut_* index_buffer) {
139 IndexIn_* iptr = [&]{
140 if constexpr(no_op_index) {
141 return index_buffer;
142 } else {
143 return my_ibuffer.data();
144 }
145 }();
146
147 ValueIn_* vptr = [&]{
148 if constexpr(no_op_value) {
149 return value_buffer;
150 } else {
151 return my_vbuffer.data();
152 }
153 }();
154
155 auto range = my_ext->fetch(i, vptr, iptr);
156 SparseRange<ValueOut_, IndexOut_> output(range.number);
157
158 if constexpr(no_op_index) {
159 output.index = range.index;
160 } else if (range.index != NULL) {
161 std::copy_n(range.index, range.number, index_buffer);
162 output.index = index_buffer;
163 }
164
165 if constexpr(no_op_value) {
166 output.value = range.value;
167 } else if (range.value != NULL) {
168 std::copy_n(range.value, range.number, value_buffer);
169 output.value = value_buffer;
170 }
171
172 return output;
173 }
174
175private:
176 std::unique_ptr<SparseExtractor<oracle_, ValueIn_, IndexIn_> > my_ext;
177 static constexpr bool no_op_value = std::is_same<ValueOut_, ValueIn_>::value;
178 typename std::conditional<no_op_value, bool, std::vector<ValueIn_> >::type my_vbuffer;
179 static constexpr bool no_op_index = std::is_same<IndexOut_, IndexIn_>::value;
180 typename std::conditional<no_op_index, bool, std::vector<IndexIn_> >::type my_ibuffer;
181};
182
183}
201template<typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
202class DelayedCast final : public Matrix<ValueOut_, IndexOut_> {
203public:
207 DelayedCast(std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > matrix) : my_matrix(std::move(matrix)) {}
208
209public:
210 IndexOut_ nrow() const {
211 return my_matrix->nrow();
212 }
213
214 IndexOut_ ncol() const {
215 return my_matrix->ncol();
216 }
217
218 bool is_sparse() const {
219 return my_matrix->is_sparse();
220 }
221
222 double is_sparse_proportion() const {
223 return my_matrix->is_sparse_proportion();
224 }
225
226 bool prefer_rows() const {
227 return my_matrix->prefer_rows();
228 }
229
230 double prefer_rows_proportion() const {
231 return my_matrix->prefer_rows_proportion();
232 }
233
234 bool uses_oracle(bool row) const {
235 return my_matrix->uses_oracle(row);
236 }
237
238private:
239 std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > my_matrix;
240
241 /********************
242 *** Myopic dense ***
243 ********************/
244public:
245 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, const Options& opt) const {
246 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, opt);
247 }
248
249 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) const {
250 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, block_start, block_length, opt);
251 }
252
253 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, VectorPtr<IndexOut_> indices_my_matrix, const Options& opt) const {
254 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, std::move(indices_my_matrix), opt);
255 }
256
257 /*********************
258 *** Myopic sparse ***
259 *********************/
260public:
261 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, const Options& opt) const {
262 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, opt);
263 }
264
265 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, IndexOut_ block_start, IndexOut_ block_length, const Options& opt) const {
266 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, block_start, block_length, opt);
267 }
268
269 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, VectorPtr<IndexOut_> indices_my_matrix, const Options& opt) const {
270 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, false, std::move(indices_my_matrix), opt);
271 }
272
273 /**********************
274 *** Oracular dense ***
275 **********************/
276public:
277 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> > dense(bool row, std::shared_ptr<const Oracle<IndexOut_> > oracle, const Options& opt) const {
278 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), opt);
279 }
280
281 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 {
282 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), block_start, block_length, opt);
283 }
284
285 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 {
286 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);
287 }
288
289 /***********************
290 *** Oracular sparse ***
291 ***********************/
292public:
293 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> > sparse(bool row, std::shared_ptr<const Oracle<IndexOut_> > oracle, const Options& opt) const {
294 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), opt);
295 }
296
297 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 {
298 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), block_start, block_length, opt);
299 }
300
301 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 {
302 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);
303 }
304};
305
317template<typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
318std::shared_ptr<Matrix<ValueOut_, IndexOut_> > make_DelayedCast(std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > p) {
319 return std::shared_ptr<Matrix<ValueOut_, IndexOut_> >(new DelayedCast<ValueOut_, IndexOut_, ValueIn_, IndexIn_>(std::move(p)));
320}
321
325template<typename ValueOut_, typename IndexOut_, typename ValueIn_, typename IndexIn_>
326std::shared_ptr<Matrix<ValueOut_, IndexOut_> > make_DelayedCast(std::shared_ptr<Matrix<ValueIn_, IndexIn_> > p) {
327 return std::shared_ptr<Matrix<ValueOut_, IndexOut_> >(new DelayedCast<ValueOut_, IndexOut_, ValueIn_, IndexIn_>(std::move(p)));
328}
333}
334
335#endif
Virtual class for a matrix of some numeric type.
Recast a Matrix to a different interface type.
Definition DelayedCast.hpp:202
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:281
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, IndexOut_ block_start, IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:249
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:285
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, const Options &opt) const
Definition DelayedCast.hpp:261
DelayedCast(std::shared_ptr< const Matrix< ValueIn_, IndexIn_ > > matrix)
Definition DelayedCast.hpp:207
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:253
std::unique_ptr< OracularDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const Options &opt) const
Definition DelayedCast.hpp:277
double prefer_rows_proportion() const
Definition DelayedCast.hpp:230
IndexOut_ nrow() const
Definition DelayedCast.hpp:210
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:297
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, IndexOut_ block_start, IndexOut_ block_length, const Options &opt) const
Definition DelayedCast.hpp:265
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:301
bool is_sparse() const
Definition DelayedCast.hpp:218
bool uses_oracle(bool row) const
Definition DelayedCast.hpp:234
IndexOut_ ncol() const
Definition DelayedCast.hpp:214
double is_sparse_proportion() const
Definition DelayedCast.hpp:222
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(bool row, const Options &opt) const
Definition DelayedCast.hpp:245
bool prefer_rows() const
Definition DelayedCast.hpp:226
std::unique_ptr< OracularSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const Options &opt) const
Definition DelayedCast.hpp:293
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(bool row, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:269
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, Index_ x)
Definition Index_to_container.hpp:86
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:318
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