1#ifndef TATAMI_DELAYED_CAST_HPP
2#define TATAMI_DELAYED_CAST_HPP
6#include "../utils/Index_to_container.hpp"
24namespace DelayedCast_internal {
26template<
typename IndexIn_,
typename IndexOut_>
27class CastOracle final :
public Oracle<IndexIn_> {
29 CastOracle(std::shared_ptr<
const Oracle<IndexOut_> > oracle) : my_oracle(std::move(oracle)) {}
31 IndexIn_ get(
const PredictionIndex i)
const {
32 return my_oracle->get(i);
36 return my_oracle->total();
40 std::shared_ptr<const Oracle<IndexOut_> > my_oracle;
43template<
bool oracle_,
typename IndexIn_,
typename IndexOut_>
44MaybeOracle<oracle_, IndexIn_> convert(MaybeOracle<oracle_, IndexOut_> oracle) {
45 if constexpr(!oracle_) {
47 }
else if constexpr(std::is_same<IndexIn_, IndexOut_>::value) {
50 return std::make_shared<CastOracle<IndexIn_, IndexOut_> >(std::move(oracle));
54template<
typename IndexIn_,
typename IndexOut_>
55VectorPtr<IndexIn_> convert(VectorPtr<IndexOut_> indices_ptr) {
56 if constexpr(std::is_same<IndexIn_, IndexOut_>::value) {
59 return std::make_shared<std::vector<IndexIn_> >(indices_ptr->begin(), indices_ptr->end());
63template<
bool oracle_,
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
64class Dense final :
public DenseExtractor<oracle_, ValueOut_, IndexOut_> {
67 const Matrix<ValueIn_, IndexIn_>& matrix,
68 const bool row, MaybeOracle<oracle_, IndexOut_> oracle,
71 allocate(row ? matrix.ncol() : matrix.nrow());
72 my_ext = new_extractor<false, oracle_>(matrix, row, convert<oracle_, IndexIn_, IndexOut_>(std::move(oracle)), opt);
76 const Matrix<ValueIn_, IndexIn_>& matrix,
78 MaybeOracle<oracle_, IndexOut_> oracle,
79 const IndexOut_ block_start,
80 const IndexOut_ block_length,
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);
88 const Matrix<ValueIn_, IndexIn_>& matrix,
90 MaybeOracle<oracle_, IndexOut_> oracle,
91 VectorPtr<IndexOut_> indices_ptr,
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);
99 void allocate(
const IndexIn_ n) {
100 if constexpr(!no_op) {
106 const ValueOut_* fetch(
const IndexOut_ i, ValueOut_*
const buffer) {
107 if constexpr(no_op) {
108 return my_ext->fetch(i, buffer);
110 const auto ptr = my_ext->fetch(i, my_buffer.data());
111 std::copy_n(ptr, my_buffer.size(), buffer);
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;
122template<
bool oracle_,
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
123class Sparse final :
public SparseExtractor<oracle_, ValueOut_, IndexOut_> {
126 const Matrix<ValueIn_, IndexIn_>& matrix,
128 MaybeOracle<oracle_, IndexOut_> oracle,
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);
136 const Matrix<ValueIn_, IndexIn_>& matrix,
138 MaybeOracle<oracle_, IndexOut_> oracle,
139 const IndexOut_ block_start,
140 const IndexOut_ block_length,
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);
148 const Matrix<ValueIn_, IndexIn_>& matrix,
150 MaybeOracle<oracle_, IndexOut_> oracle,
151 VectorPtr<IndexOut_> indices_ptr,
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);
159 void allocate(
const IndexIn_ n,
const Options& opt) {
160 if constexpr(!no_op_value) {
161 if (opt.sparse_extract_value) {
165 if constexpr(!no_op_index) {
166 if (opt.sparse_extract_index) {
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) {
178 return my_ibuffer.data();
182 ValueIn_*
const vptr = [&]{
183 if constexpr(no_op_value) {
186 return my_vbuffer.data();
190 const auto range = my_ext->fetch(i, vptr, iptr);
191 SparseRange<ValueOut_, IndexOut_> output(range.number);
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;
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;
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;
236template<
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
246 return my_matrix->nrow();
250 return my_matrix->ncol();
254 return my_matrix->is_sparse();
258 return my_matrix->is_sparse_proportion();
262 return my_matrix->prefer_rows();
266 return my_matrix->prefer_rows_proportion();
270 return my_matrix->uses_oracle(row);
274 std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > my_matrix;
280 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> >
dense(
284 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row,
false, opt);
287 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> >
dense(
289 const IndexOut_ block_start,
290 const IndexOut_ block_length,
293 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row,
false, block_start, block_length, opt);
296 std::unique_ptr<MyopicDenseExtractor<ValueOut_, IndexOut_> >
dense(
301 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row,
false, std::move(indices_my_matrix), opt);
308 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> >
sparse(
312 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row,
false, opt);
315 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> >
sparse(
317 const IndexOut_ block_start,
318 const IndexOut_ block_length,
321 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row,
false, block_start, block_length, opt);
324 std::unique_ptr<MyopicSparseExtractor<ValueOut_, IndexOut_> >
sparse(
329 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row,
false, std::move(indices_my_matrix), opt);
336 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> >
dense(
341 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), opt);
344 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> >
dense(
347 const IndexOut_ block_start,
348 const IndexOut_ block_length,
351 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), block_start, block_length, opt);
354 std::unique_ptr<OracularDenseExtractor<ValueOut_, IndexOut_> >
dense(
360 return std::make_unique<DelayedCast_internal::Dense<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), std::move(indices_my_matrix), opt);
367 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> >
sparse(
372 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), opt);
375 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> >
sparse(
378 const IndexOut_ block_start,
379 const IndexOut_ block_length,
382 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), block_start, block_length, opt);
385 std::unique_ptr<OracularSparseExtractor<ValueOut_, IndexOut_> >
sparse(
391 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(*my_matrix, row, std::move(oracle), std::move(indices_my_matrix), opt);
406template<
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
414template<
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
415std::shared_ptr<Matrix<ValueOut_, IndexOut_> >
make_DelayedCast(std::shared_ptr<Matrix<ValueIn_, IndexIn_> > p) {
416 return std::shared_ptr<Matrix<ValueOut_, IndexOut_> >(
new DelayedCast<ValueOut_, IndexOut_, ValueIn_, IndexIn_>(std::move(p)));
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:375
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(const bool row, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:324
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:287
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:385
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:354
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(const bool row, const Options &opt) const
Definition DelayedCast.hpp:280
double prefer_rows_proportion() const
Definition DelayedCast.hpp:265
IndexOut_ nrow() const
Definition DelayedCast.hpp:245
std::unique_ptr< OracularSparseExtractor< ValueOut_, IndexOut_ > > sparse(const bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const Options &opt) const
Definition DelayedCast.hpp:367
std::unique_ptr< OracularDenseExtractor< ValueOut_, IndexOut_ > > dense(const bool row, std::shared_ptr< const Oracle< IndexOut_ > > oracle, const Options &opt) const
Definition DelayedCast.hpp:336
std::unique_ptr< MyopicDenseExtractor< ValueOut_, IndexOut_ > > dense(const bool row, VectorPtr< IndexOut_ > indices_my_matrix, const Options &opt) const
Definition DelayedCast.hpp:296
bool uses_oracle(const bool row) const
Definition DelayedCast.hpp:269
bool is_sparse() const
Definition DelayedCast.hpp:253
IndexOut_ ncol() const
Definition DelayedCast.hpp:249
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:344
double is_sparse_proportion() const
Definition DelayedCast.hpp:257
bool prefer_rows() const
Definition DelayedCast.hpp:261
std::unique_ptr< MyopicSparseExtractor< ValueOut_, IndexOut_ > > sparse(const bool row, const Options &opt) const
Definition DelayedCast.hpp:308
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:315
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:92
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:407
std::size_t PredictionIndex
Definition Oracle.hpp:18
Options for accessing data from a Matrix instance.
Definition Options.hpp:30