1#ifndef TATAMI_DELAYED_CAST_HPP
2#define TATAMI_DELAYED_CAST_HPP
22namespace DelayedCast_internal {
24template<
typename IndexIn_,
typename IndexOut_>
25class CastOracle final :
public Oracle<IndexIn_> {
27 CastOracle(std::shared_ptr<
const Oracle<IndexOut_> > oracle) : my_oracle(std::move(oracle)) {}
29 IndexIn_ get(
size_t i)
const {
30 return my_oracle->get(i);
33 size_t total()
const {
34 return my_oracle->total();
38 std::shared_ptr<const Oracle<IndexOut_> > my_oracle;
41template<
bool oracle_,
typename IndexIn_,
typename IndexOut_>
42MaybeOracle<oracle_, IndexIn_> convert(MaybeOracle<oracle_, IndexOut_> oracle) {
43 if constexpr(!oracle_) {
45 }
else if constexpr(std::is_same<IndexIn_, IndexOut_>::value) {
48 return std::make_shared<CastOracle<IndexIn_, IndexOut_> >(std::move(oracle));
52template<
typename IndexIn_,
typename IndexOut_>
53VectorPtr<IndexIn_> convert(VectorPtr<IndexOut_> indices_ptr) {
54 if constexpr(std::is_same<IndexIn_, IndexOut_>::value) {
57 return std::make_shared<std::vector<IndexIn_> >(indices_ptr->begin(), indices_ptr->end());
61template<
bool oracle_,
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
62class Dense final :
public DenseExtractor<oracle_, ValueOut_, IndexOut_> {
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);
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);
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);
80 void allocate(
size_t n) {
81 if constexpr(!no_op) {
87 const ValueOut_* fetch(IndexOut_ i, ValueOut_* buffer) {
89 return my_ext->fetch(i, buffer);
91 auto ptr = my_ext->fetch(i, my_buffer.data());
92 std::copy_n(ptr, my_buffer.size(), buffer);
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;
103template<
bool oracle_,
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
104class Sparse final :
public SparseExtractor<oracle_, ValueOut_, IndexOut_> {
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);
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);
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);
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);
128 if constexpr(!no_op_index) {
129 if (opt.sparse_extract_index) {
130 my_ibuffer.resize(n);
136 SparseRange<ValueOut_, IndexOut_> fetch(IndexOut_ i, ValueOut_* value_buffer, IndexOut_* index_buffer) {
137 IndexIn_* iptr = [&]{
138 if constexpr(no_op_index) {
141 return my_ibuffer.data();
145 ValueIn_* vptr = [&]{
146 if constexpr(no_op_value) {
149 return my_vbuffer.data();
153 auto range = my_ext->fetch(i, vptr, iptr);
154 SparseRange<ValueOut_, IndexOut_> output(range.number);
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;
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;
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;
199template<
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
209 return my_matrix->nrow();
213 return my_matrix->ncol();
217 return my_matrix->is_sparse();
221 return my_matrix->is_sparse_proportion();
225 return my_matrix->prefer_rows();
229 return my_matrix->prefer_rows_proportion();
233 return my_matrix->uses_oracle(row);
237 std::shared_ptr<const Matrix<ValueIn_, IndexIn_> > my_matrix;
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);
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);
252 return std::make_unique<DelayedCast_internal::Dense<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row,
false, std::move(indices_my_matrix), opt);
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);
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);
268 return std::make_unique<DelayedCast_internal::Sparse<false, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row,
false, std::move(indices_my_matrix), opt);
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);
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);
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);
292 return std::make_unique<DelayedCast_internal::Sparse<true, ValueOut_, IndexOut_, ValueIn_, IndexIn_> >(my_matrix.get(), row, std::move(oracle), opt);
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);
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);
315template<
typename ValueOut_,
typename IndexOut_,
typename ValueIn_,
typename IndexIn_>
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)));
Virtual class for a matrix of some numeric type.
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
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
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:316
Options for accessing data from a Matrix instance.
Definition Options.hpp:30