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(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_> {
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);
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);
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);
82 void allocate(IndexIn_ n) {
83 if constexpr(!no_op) {
89 const ValueOut_* fetch(IndexOut_ i, ValueOut_* buffer) {
91 return my_ext->fetch(i, buffer);
93 auto ptr = my_ext->fetch(i, my_buffer.data());
94 std::copy_n(ptr, my_buffer.size(), buffer);
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;
105template<
bool oracle_,
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
106class Sparse final :
public SparseExtractor<oracle_, ValueOut_, IndexOut_> {
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);
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);
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);
124 void allocate(IndexIn_ n,
const Options& opt) {
125 if constexpr(!no_op_value) {
126 if (opt.sparse_extract_value) {
130 if constexpr(!no_op_index) {
131 if (opt.sparse_extract_index) {
138 SparseRange<ValueOut_, IndexOut_> fetch(IndexOut_ i, ValueOut_* value_buffer, IndexOut_* index_buffer) {
139 IndexIn_* iptr = [&]{
140 if constexpr(no_op_index) {
143 return my_ibuffer.data();
147 ValueIn_* vptr = [&]{
148 if constexpr(no_op_value) {
151 return my_vbuffer.data();
155 auto range = my_ext->fetch(i, vptr, iptr);
156 SparseRange<ValueOut_, IndexOut_> output(range.number);
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;
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;
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;
201template<
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
211 return my_matrix->nrow();
215 return my_matrix->ncol();
219 return my_matrix->is_sparse();
223 return my_matrix->is_sparse_proportion();
227 return my_matrix->prefer_rows();
231 return my_matrix->prefer_rows_proportion();
235 return my_matrix->uses_oracle(row);
239 std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > my_matrix;
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);
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);
254 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row,
false, std::move(indices_my_matrix), opt);
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);
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);
270 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row,
false, std::move(indices_my_matrix), opt);
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);
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);
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);
294 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), opt);
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);
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);
317template<
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
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)));
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
Options for accessing data from a Matrix instance.
Definition Options.hpp:30