1#ifndef TATAMI_DELAYED_UNARY_ISOMETRIC_OPERATION_H
2#define TATAMI_DELAYED_UNARY_ISOMETRIC_OPERATION_H
7#include "../depends_utils.hpp"
26namespace DelayedUnaryIsometricOperation_internal {
38template<
bool oracle_,
typename OutputValue_,
typename InputValue_,
typename Index_,
class Operation_>
39class DenseBasicFull final :
public DenseExtractor<oracle_, OutputValue_, Index_> {
42 const Matrix<InputValue_, Index_>& matrix,
43 const Operation_& operation,
45 MaybeOracle<oracle_, Index_> oracle,
47 my_operation(operation),
49 my_oracle(oracle, my_operation, row),
50 my_extent(row ? matrix.ncol() : matrix.nrow()),
51 my_ext(
new_extractor<false, oracle_>(matrix, row, std::move(oracle), opt))
53 if constexpr(!same_value) {
54 my_holding_buffer.resize(my_extent);
59 const Operation_& my_operation;
62 DelayedIsometricOperation_internal::MaybeOracleDepends<oracle_, Operation_, Index_> my_oracle;
65 std::unique_ptr<DenseExtractor<oracle_, InputValue_, Index_> > my_ext;
67 static constexpr bool same_value = std::is_same<OutputValue_, InputValue_>::value;
68 typename std::conditional<!same_value, std::vector<InputValue_>,
bool>::type my_holding_buffer;
71 const OutputValue_* fetch(Index_ i, OutputValue_* buffer) {
72 if constexpr(same_value) {
73 auto ptr = my_ext->fetch(i, buffer);
74 copy_n(ptr, my_extent, buffer);
75 my_operation.dense(my_row, my_oracle.get(i),
static_cast<Index_
>(0), my_extent, buffer, buffer);
77 auto ptr = my_ext->fetch(i, my_holding_buffer.data());
78 my_operation.dense(my_row, my_oracle.get(i),
static_cast<Index_
>(0), my_extent, ptr, buffer);
84template<
bool oracle_,
typename OutputValue_,
typename InputValue_,
typename Index_,
class Operation_>
85class DenseBasicBlock final :
public DenseExtractor<oracle_, OutputValue_, Index_> {
88 const Matrix<InputValue_, Index_>& matrix,
89 const Operation_& operation,
91 MaybeOracle<oracle_, Index_> oracle,
95 my_operation(operation),
97 my_oracle(oracle, my_operation, row),
98 my_block_start(block_start),
99 my_block_length(block_length),
100 my_ext(
new_extractor<false, oracle_>(matrix, row, std::move(oracle), block_start, block_length, opt))
102 if constexpr(!same_value) {
103 my_holding_buffer.resize(my_block_length);
108 const Operation_& my_operation;
111 DelayedIsometricOperation_internal::MaybeOracleDepends<oracle_, Operation_, Index_> my_oracle;
112 Index_ my_block_start, my_block_length;
114 std::unique_ptr<DenseExtractor<oracle_, InputValue_, Index_> > my_ext;
116 static constexpr bool same_value = std::is_same<OutputValue_, InputValue_>::value;
117 typename std::conditional<!same_value, std::vector<InputValue_>,
bool>::type my_holding_buffer;
120 const OutputValue_* fetch(Index_ i, OutputValue_* buffer) {
121 if constexpr(same_value) {
122 auto ptr = my_ext->fetch(i, buffer);
123 copy_n(ptr, my_block_length, buffer);
124 my_operation.dense(my_row, my_oracle.get(i), my_block_start, my_block_length, buffer, buffer);
126 auto ptr = my_ext->fetch(i, my_holding_buffer.data());
127 my_operation.dense(my_row, my_oracle.get(i), my_block_start, my_block_length, ptr, buffer);
133template<
bool oracle_,
typename OutputValue_,
typename InputValue_,
typename Index_,
class Operation_>
134class DenseBasicIndex final :
public DenseExtractor<oracle_, OutputValue_, Index_> {
137 const Matrix<InputValue_, Index_>& matrix,
138 const Operation_& operation,
140 MaybeOracle<oracle_, Index_> oracle,
141 VectorPtr<Index_> indices_ptr,
142 const Options& opt) :
143 my_operation(operation),
145 my_oracle(oracle, my_operation, row),
146 my_indices_ptr(indices_ptr),
147 my_ext(
new_extractor<false, oracle_>(matrix, row, std::move(oracle), std::move(indices_ptr), opt))
149 if constexpr(!same_value) {
150 my_holding_buffer.resize(my_indices_ptr->size());
155 const Operation_& my_operation;
158 DelayedIsometricOperation_internal::MaybeOracleDepends<oracle_, Operation_, Index_> my_oracle;
159 VectorPtr<Index_> my_indices_ptr;
161 std::unique_ptr<DenseExtractor<oracle_, InputValue_, Index_> > my_ext;
163 static constexpr bool same_value = std::is_same<OutputValue_, InputValue_>::value;
164 typename std::conditional<!same_value, std::vector<InputValue_>,
bool>::type my_holding_buffer;
167 const OutputValue_* fetch(Index_ i, OutputValue_* buffer) {
168 const auto& indices = *my_indices_ptr;
169 if constexpr(same_value) {
170 auto ptr = my_ext->fetch(i, buffer);
171 copy_n(ptr, indices.size(), buffer);
172 my_operation.dense(my_row, my_oracle.get(i), indices, buffer, buffer);
174 auto ptr = my_ext->fetch(i, my_holding_buffer.data());
175 my_operation.dense(my_row, my_oracle.get(i), indices, ptr, buffer);
192template<
bool oracle_,
typename OutputValue_,
typename InputValue_,
typename Index_,
class Operation_>
193class DenseExpandedFull final :
public DenseExtractor<oracle_, OutputValue_, Index_> {
196 const Matrix<InputValue_, Index_>& matrix,
197 const Operation_& operation,
199 MaybeOracle<oracle_, Index_> oracle,
201 my_operation(operation),
203 my_oracle(oracle, my_operation, row),
204 my_extent(row ? matrix.ncol() : matrix.nrow()),
205 my_vbuffer(my_extent),
206 my_ibuffer(my_extent)
208 opt.sparse_extract_value =
true;
209 opt.sparse_extract_index =
true;
210 my_ext = new_extractor<true, oracle_>(matrix, my_row, std::move(oracle), opt);
212 if constexpr(!same_value) {
213 my_result_vbuffer.resize(my_extent);
218 const Operation_& my_operation;
221 DelayedIsometricOperation_internal::MaybeOracleDepends<oracle_, Operation_, Index_> my_oracle;
224 std::vector<InputValue_> my_vbuffer;
225 std::vector<Index_> my_ibuffer;
226 std::unique_ptr<SparseExtractor<oracle_, InputValue_, Index_> > my_ext;
228 static constexpr bool same_value = std::is_same<OutputValue_, InputValue_>::value;
229 typename std::conditional<!same_value, std::vector<OutputValue_>,
bool>::type my_result_vbuffer;
232 const OutputValue_* fetch(Index_ i, OutputValue_* buffer) {
233 auto vbuffer = my_vbuffer.data();
234 auto range = my_ext->fetch(i, vbuffer, my_ibuffer.data());
236 i = my_oracle.get(i);
237 if constexpr(same_value) {
238 copy_n(range.value, range.number, vbuffer);
239 my_operation.sparse(my_row, i, range.number, vbuffer, range.index, vbuffer);
241 my_operation.sparse(my_row, i, range.number, range.value, range.index, my_result_vbuffer.data());
245 if (range.number < my_extent) {
246 std::fill_n(buffer, my_extent, my_operation.fill(my_row, i));
249 if constexpr(same_value) {
250 for (Index_ i = 0; i < range.number; ++i) {
251 buffer[range.index[i]] = vbuffer[i];
254 for (Index_ i = 0; i < range.number; ++i) {
255 buffer[range.index[i]] = my_result_vbuffer[i];
263template<
bool oracle_,
typename OutputValue_,
typename InputValue_,
typename Index_,
class Operation_>
264class DenseExpandedBlock final :
public DenseExtractor<oracle_, OutputValue_, Index_> {
267 const Matrix<InputValue_, Index_>& matrix,
268 const Operation_& operation,
270 MaybeOracle<oracle_, Index_> oracle,
274 my_operation(operation),
276 my_oracle(oracle, my_operation, row),
277 my_block_start(block_start),
278 my_block_length(block_length),
279 my_vbuffer(block_length),
280 my_ibuffer(block_length)
282 opt.sparse_extract_value =
true;
283 opt.sparse_extract_index =
true;
284 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), block_start, block_length, opt);
286 if constexpr(!same_value) {
287 my_result_vbuffer.resize(my_block_length);
292 const Operation_& my_operation;
295 DelayedIsometricOperation_internal::MaybeOracleDepends<oracle_, Operation_, Index_> my_oracle;
296 Index_ my_block_start, my_block_length;
298 std::vector<InputValue_> my_vbuffer;
299 std::vector<Index_> my_ibuffer;
300 std::unique_ptr<SparseExtractor<oracle_, InputValue_, Index_> > my_ext;
302 static constexpr bool same_value = std::is_same<OutputValue_, InputValue_>::value;
303 typename std::conditional<!same_value, std::vector<OutputValue_>,
bool>::type my_result_vbuffer;
306 const OutputValue_* fetch(Index_ i, OutputValue_* buffer) {
307 auto vbuffer = my_vbuffer.data();
308 auto range = my_ext->fetch(i, vbuffer, my_ibuffer.data());
310 i = my_oracle.get(i);
311 if constexpr(same_value) {
312 copy_n(range.value, range.number, vbuffer);
313 my_operation.sparse(my_row, i, range.number, vbuffer, range.index, vbuffer);
315 my_operation.sparse(my_row, i, range.number, range.value, range.index, my_result_vbuffer.data());
319 if (range.number < my_block_length) {
320 std::fill_n(buffer, my_block_length, my_operation.fill(my_row, i));
323 if constexpr(same_value) {
324 for (Index_ i = 0; i < range.number; ++i) {
325 buffer[range.index[i] - my_block_start] = vbuffer[i];
328 for (Index_ i = 0; i < range.number; ++i) {
329 buffer[range.index[i] - my_block_start] = my_result_vbuffer[i];
337template<
bool oracle_,
typename OutputValue_,
typename InputValue_,
typename Index_,
class Operation_>
338class DenseExpandedIndex final :
public DenseExtractor<oracle_, OutputValue_, Index_> {
341 const Matrix<InputValue_, Index_>& matrix,
342 const Operation_& operation,
344 MaybeOracle<oracle_, Index_> oracle,
345 VectorPtr<Index_> indices_ptr,
347 my_operation(operation),
349 my_oracle(oracle, my_operation, row)
351 opt.sparse_extract_value =
true;
352 opt.sparse_extract_index =
true;
354 const auto& indices = *indices_ptr;
355 my_extent = indices.size();
356 my_vbuffer.resize(my_extent);
357 my_ibuffer.resize(my_extent);
363 my_remapping_offset = indices.front();
364 my_remapping.resize(indices.back() - my_remapping_offset + 1);
365 for (Index_ i = 0; i < my_extent; ++i) {
366 my_remapping[indices[i] - my_remapping_offset] = i;
370 my_ext = new_extractor<true, oracle_>(matrix, my_row, std::move(oracle), std::move(indices_ptr), opt);
372 if constexpr(!same_value) {
373 my_result_vbuffer.resize(my_extent);
378 const Operation_& my_operation;
381 DelayedIsometricOperation_internal::MaybeOracleDepends<oracle_, Operation_, Index_> my_oracle;
384 std::vector<InputValue_> my_vbuffer;
385 std::vector<Index_> my_ibuffer;
387 std::vector<Index_> my_remapping;
388 Index_ my_remapping_offset = 0;
389 std::unique_ptr<SparseExtractor<oracle_, InputValue_, Index_> > my_ext;
391 static constexpr bool same_value = std::is_same<OutputValue_, InputValue_>::value;
392 typename std::conditional<!same_value, std::vector<OutputValue_>,
bool>::type my_result_vbuffer;
395 const OutputValue_* fetch(Index_ i, OutputValue_* buffer) {
396 auto vbuffer = my_vbuffer.data();
397 auto range = my_ext->fetch(i, vbuffer, my_ibuffer.data());
399 i = my_oracle.get(i);
400 if constexpr(same_value) {
401 copy_n(range.value, range.number, vbuffer);
402 my_operation.sparse(my_row, i, range.number, vbuffer, range.index, vbuffer);
404 my_operation.sparse(my_row, i, range.number, range.value, range.index, my_result_vbuffer.data());
408 if (range.number < my_extent) {
409 std::fill_n(buffer, my_extent, my_operation.fill(my_row, i));
412 if constexpr(same_value) {
413 for (Index_ i = 0; i < range.number; ++i) {
414 buffer[my_remapping[range.index[i] - my_remapping_offset]] = vbuffer[i];
417 for (Index_ i = 0; i < range.number; ++i) {
418 buffer[my_remapping[range.index[i] - my_remapping_offset]] = my_result_vbuffer[i];
433template<
bool oracle_,
typename OutputValue_,
typename InputValue_,
typename Index_,
class Operation_>
434class SparseSimple final :
public SparseExtractor<oracle_, OutputValue_, Index_> {
437 const Matrix<InputValue_, Index_>& matrix,
438 const Operation_& operation,
440 MaybeOracle<oracle_, Index_> oracle,
441 const Options& opt) :
442 my_operation(operation),
444 my_oracle(oracle, my_operation, row),
445 my_ext(
new_extractor<true, oracle_>(matrix, row, std::move(oracle), opt))
447 initialize(opt, row ? matrix.ncol() : matrix.nrow());
451 const Matrix<InputValue_, Index_>& matrix,
452 const Operation_& operation,
454 MaybeOracle<oracle_, Index_> oracle,
457 const Options& opt) :
458 my_operation(operation),
460 my_oracle(oracle, my_operation, row),
461 my_ext(
new_extractor<true, oracle_>(matrix, row, std::move(oracle), block_start, block_length, opt))
463 initialize(opt, block_length);
467 const Matrix<InputValue_, Index_>& matrix,
468 const Operation_& operation,
470 MaybeOracle<oracle_, Index_> oracle,
471 VectorPtr<Index_> indices_ptr,
472 const Options& opt) :
473 my_operation(operation),
475 my_oracle(oracle, my_operation, row)
477 initialize(opt, indices_ptr->size());
480 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), std::move(indices_ptr), opt);
484 const Operation_& my_operation;
487 DelayedIsometricOperation_internal::MaybeOracleDepends<oracle_, Operation_, Index_> my_oracle;
489 std::unique_ptr<SparseExtractor<oracle_, InputValue_, Index_> > my_ext;
491 static constexpr bool same_value = std::is_same<OutputValue_, InputValue_>::value;
492 typename std::conditional<!same_value, std::vector<InputValue_>,
bool>::type my_holding_vbuffer;
494 void initialize(
const Options& opt,
size_t extent) {
495 if constexpr(!same_value) {
496 if (opt.sparse_extract_value) {
497 my_holding_vbuffer.resize(extent);
503 SparseRange<OutputValue_, Index_> fetch(Index_ i, OutputValue_* value_buffer, Index_* index_buffer) {
504 if constexpr(same_value) {
505 auto raw = my_ext->fetch(i, value_buffer, index_buffer);
507 copy_n(raw.value, raw.number, value_buffer);
508 my_operation.sparse(my_row, my_oracle.get(i), raw.number, value_buffer, raw.index, value_buffer);
509 raw.value = value_buffer;
513 auto raw = my_ext->fetch(i, my_holding_vbuffer.data(), index_buffer);
515 SparseRange<OutputValue_, Index_> output(raw.number);
516 output.index = raw.index;
518 my_operation.sparse(my_row, my_oracle.get(i), raw.number, raw.value, raw.index, value_buffer);
519 output.value = value_buffer;
534template<
bool oracle_,
typename OutputValue_,
typename InputValue_,
typename Index_,
class Operation_>
535class SparseNeedsIndices final :
public SparseExtractor<oracle_, OutputValue_, Index_> {
538 const Matrix<InputValue_, Index_>& matrix,
539 const Operation_& operation,
541 MaybeOracle<oracle_, Index_> oracle,
543 my_operation(operation),
545 my_oracle(oracle, my_operation, row)
547 initialize(opt, row ? matrix.ncol() : matrix.nrow());
548 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), opt);
552 const Matrix<InputValue_, Index_>& matrix,
553 const Operation_& operation,
555 MaybeOracle<oracle_, Index_> oracle,
559 my_operation(operation),
561 my_oracle(oracle, my_operation, row)
563 initialize(opt, block_length);
564 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), block_start, block_length, opt);
568 const Matrix<InputValue_, Index_>& matrix,
569 const Operation_& operation,
571 MaybeOracle<oracle_, Index_> oracle,
572 VectorPtr<Index_> indices_ptr,
574 my_operation(operation),
576 my_oracle(oracle, my_operation, row)
578 initialize(opt, indices_ptr->size());
579 my_ext = new_extractor<true, oracle_>(matrix, row, std::move(oracle), std::move(indices_ptr), opt);
583 void initialize(Options& opt,
size_t extent) {
584 my_report_value = opt.sparse_extract_value;
585 my_report_index = opt.sparse_extract_index;
589 if (my_report_value) {
590 opt.sparse_extract_index =
true;
595 if (!my_report_index) {
596 my_ibuffer.resize(extent);
600 if constexpr(!same_value) {
601 if (my_report_value) {
602 my_holding_vbuffer.resize(extent);
608 const Operation_& my_operation;
611 DelayedIsometricOperation_internal::MaybeOracleDepends<oracle_, Operation_, Index_> my_oracle;
613 bool my_report_value, my_report_index;
614 std::vector<Index_> my_ibuffer;
616 std::unique_ptr<SparseExtractor<oracle_, InputValue_, Index_> > my_ext;
618 static constexpr bool same_value = std::is_same<OutputValue_, InputValue_>::value;
619 typename std::conditional<!same_value, std::vector<InputValue_>,
bool>::type my_holding_vbuffer;
622 SparseRange<OutputValue_, Index_> fetch(Index_ i, OutputValue_* value_buffer, Index_* index_buffer) {
623 auto iptr = my_report_index ? index_buffer : my_ibuffer.data();
625 if constexpr(same_value) {
626 auto raw = my_ext->fetch(i, value_buffer, iptr);
627 if (my_report_value) {
628 copy_n(raw.value, raw.number, value_buffer);
629 my_operation.sparse(my_row, my_oracle.get(i), raw.number, value_buffer, raw.index, value_buffer);
630 raw.value = value_buffer;
632 if (!my_report_index) {
638 auto raw = my_ext->fetch(i, my_holding_vbuffer.data(), iptr);
639 SparseRange<OutputValue_, Index_> output(raw.number, NULL, (my_report_index ? raw.index : NULL));
640 if (my_report_value) {
641 my_operation.sparse(my_row, my_oracle.get(i), raw.number, raw.value, raw.index, value_buffer);
642 output.value = value_buffer;
668template<
typename OutputValue_,
typename InputValue_,
typename Index_,
class Operation_ = DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> >
677 std::shared_ptr<const Operation_> operation
679 my_matrix(std::move(matrix)),
680 my_operation(std::move(operation))
682 auto expected_rows = my_operation->nrow();
683 if (expected_rows.has_value() && *expected_rows != my_matrix->nrow()) {
684 throw std::runtime_error(
"number of rows in 'matrix' is not consistent with those expected by 'operation'");
686 auto expected_cols = my_operation->ncol();
687 if (expected_cols.has_value() && *expected_cols != my_matrix->ncol()) {
688 throw std::runtime_error(
"number of columns in 'matrix' is not consistent with those expected by 'operation'");
693 std::shared_ptr<const Matrix<InputValue_, Index_> > my_matrix;
694 std::shared_ptr<const Operation_> my_operation;
698 return my_matrix->nrow();
702 return my_matrix->ncol();
706 if (my_operation->is_sparse()) {
707 return my_matrix->is_sparse();
713 if (my_operation->is_sparse()) {
714 return my_matrix->is_sparse_proportion();
720 return my_matrix->prefer_rows();
724 return my_matrix->prefer_rows_proportion();
728 return my_matrix->uses_oracle(row);
739 template<
bool oracle_>
741 return std::make_unique<DelayedUnaryIsometricOperation_internal::DenseBasicFull<oracle_, OutputValue_, InputValue_, Index_, Operation_> >(
750 template<
bool oracle_>
751 std::unique_ptr<DenseExtractor<oracle_, OutputValue_, Index_> > dense_basic_internal(
bool row,
MaybeOracle<oracle_, Index_> oracle, Index_ block_start, Index_ block_length,
const Options& opt)
const {
752 return std::make_unique<DelayedUnaryIsometricOperation_internal::DenseBasicBlock<oracle_, OutputValue_, InputValue_, Index_, Operation_> >(
763 template<
bool oracle_>
765 return std::make_unique<DelayedUnaryIsometricOperation_internal::DenseBasicIndex<oracle_, OutputValue_, InputValue_, Index_, Operation_> >(
770 std::move(indices_ptr),
775 template<
bool oracle_>
776 std::unique_ptr<DenseExtractor<oracle_, OutputValue_, Index_> > dense_expanded_internal(
bool row,
MaybeOracle<oracle_, Index_> oracle,
const Options& opt)
const {
777 return std::make_unique<DelayedUnaryIsometricOperation_internal::DenseExpandedFull<oracle_, OutputValue_, InputValue_, Index_, Operation_> >(
786 template<
bool oracle_>
787 std::unique_ptr<DenseExtractor<oracle_, OutputValue_, Index_> > dense_expanded_internal(
bool row,
MaybeOracle<oracle_, Index_> oracle, Index_ block_start, Index_ block_length,
const Options& opt)
const {
788 return std::make_unique<DelayedUnaryIsometricOperation_internal::DenseExpandedBlock<oracle_, OutputValue_, InputValue_, Index_, Operation_> >(
799 template<
bool oracle_>
801 return std::make_unique<DelayedUnaryIsometricOperation_internal::DenseExpandedIndex<oracle_, OutputValue_, InputValue_, Index_, Operation_> >(
806 std::move(indices_ptr),
811 template<
bool oracle_,
typename ... Args_>
812 std::unique_ptr<DenseExtractor<oracle_, OutputValue_, Index_> > dense_internal(
bool row, Args_&& ... args)
const {
813 if (my_matrix->is_sparse()) {
814 if (DelayedIsometricOperation_internal::can_dense_expand(*my_operation, row)) {
815 return dense_expanded_internal<oracle_>(row, std::forward<Args_>(args)...);
818 return dense_basic_internal<oracle_>(row, std::forward<Args_>(args)...);
822 std::unique_ptr<MyopicDenseExtractor<OutputValue_, Index_> >
dense(
bool row,
const Options& opt)
const {
823 return dense_internal<false>(row,
false, opt);
826 std::unique_ptr<MyopicDenseExtractor<OutputValue_, Index_> >
dense(
bool row, Index_ block_start, Index_ block_length,
const Options& opt)
const {
827 return dense_internal<false>(row,
false, block_start, block_length, opt);
831 return dense_internal<false>(row,
false, std::move(indices_ptr), opt);
838 template<
bool oracle_,
typename ... Args_>
840 return std::make_unique<FullSparsifiedWrapper<oracle_, OutputValue_, Index_> >(
841 dense_internal<oracle_>(row, std::move(oracle), opt),
842 (row ? my_matrix->ncol() : my_matrix->nrow()),
847 template<
bool oracle_,
typename ... Args_>
848 std::unique_ptr<SparseExtractor<oracle_, OutputValue_, Index_> > sparse_to_dense_internal(
bool row,
MaybeOracle<oracle_, Index_> oracle, Index_ block_start, Index_ block_length,
const Options& opt)
const {
849 return std::make_unique<BlockSparsifiedWrapper<oracle_, OutputValue_, Index_> >(
850 dense_internal<oracle_>(row, std::move(oracle), block_start, block_length, opt),
857 template<
bool oracle_,
typename ... Args_>
859 return std::make_unique<IndexSparsifiedWrapper<oracle_, OutputValue_, Index_> >(
860 dense_internal<oracle_>(row, std::move(oracle), indices_ptr, opt),
866 template<
bool oracle_,
typename ... Args_>
867 std::unique_ptr<SparseExtractor<oracle_, OutputValue_, Index_> > sparse_internal(
bool row,
MaybeOracle<oracle_, Index_> oracle, Args_&& ... args)
const {
868 if (my_operation->is_sparse() && my_matrix->is_sparse()) {
869 if (DelayedIsometricOperation_internal::needs_sparse_indices(*my_operation, row)) {
870 return std::make_unique<DelayedUnaryIsometricOperation_internal::SparseNeedsIndices<oracle_, OutputValue_, InputValue_, Index_, Operation_> >(
875 std::forward<Args_>(args)...
879 return std::make_unique<DelayedUnaryIsometricOperation_internal::SparseSimple<oracle_, OutputValue_, InputValue_, Index_, Operation_> >(
884 std::forward<Args_>(args)...
888 return sparse_to_dense_internal<oracle_>(row, std::move(oracle), std::forward<Args_>(args)...);
892 std::unique_ptr<MyopicSparseExtractor<OutputValue_, Index_> >
sparse(
bool row,
const Options& opt)
const {
893 return sparse_internal<false>(row,
false, opt);
896 std::unique_ptr<MyopicSparseExtractor<OutputValue_, Index_> >
sparse(
bool row, Index_ block_start, Index_ block_length,
const Options& opt)
const {
897 return sparse_internal<false>(row,
false, block_start, block_length, opt);
901 return sparse_internal<false>(row,
false, std::move(indices_ptr), opt);
908 std::unique_ptr<OracularDenseExtractor<OutputValue_, Index_> >
dense(
bool row, std::shared_ptr<
const Oracle<Index_> > oracle,
const Options& opt)
const {
909 return dense_internal<true>(row, std::move(oracle), opt);
912 std::unique_ptr<OracularDenseExtractor<OutputValue_, Index_> >
dense(
bool row, std::shared_ptr<
const Oracle<Index_> > oracle, Index_ block_start, Index_ block_length,
const Options& opt)
const {
913 return dense_internal<true>(row, std::move(oracle), block_start, block_length, opt);
917 return dense_internal<true>(row, std::move(oracle), std::move(indices_ptr), opt);
924 std::unique_ptr<OracularSparseExtractor<OutputValue_, Index_> >
sparse(
bool row, std::shared_ptr<
const Oracle<Index_> > oracle,
const Options& opt)
const {
925 return sparse_internal<true>(row, std::move(oracle), opt);
928 std::unique_ptr<OracularSparseExtractor<OutputValue_, Index_> >
sparse(
bool row, std::shared_ptr<
const Oracle<Index_> > oracle, Index_ block_start, Index_ block_length,
const Options& opt)
const {
929 return sparse_internal<true>(row, std::move(oracle), block_start, block_length, opt);
933 return sparse_internal<true>(row, std::move(oracle), std::move(indices_ptr), opt);
941template<
typename OutputValue_ =
double,
typename InputValue_,
typename Index_,
class Operation_>
942std::shared_ptr<Matrix<OutputValue_, Index_> > make_DelayedUnaryIsometricOperation(std::shared_ptr<
const Matrix<InputValue_, Index_> > matrix, std::shared_ptr<const Operation_> operation) {
943 return std::shared_ptr<Matrix<OutputValue_, Index_> >(
new DelayedUnaryIsometricOperation<OutputValue_, InputValue_, Index_, Operation_>(std::move(matrix), std::move(operation)));
946template<
typename OutputValue_ =
double,
typename InputValue_,
typename Index_,
class Operation_>
947std::shared_ptr<Matrix<OutputValue_, Index_> > make_DelayedUnaryIsometricOperation(std::shared_ptr<Matrix<InputValue_, Index_> > matrix, std::shared_ptr<Operation_> operation) {
948 return std::shared_ptr<Matrix<OutputValue_, Index_> >(
new DelayedUnaryIsometricOperation<OutputValue_, InputValue_, Index_, Operation_>(std::move(matrix), std::move(operation)));
951template<
typename ... Args_>
952auto make_DelayedIsometricOperation(Args_&&... args) {
953 return make_DelayedUnaryIsometricOperation(std::forward<Args_>(args)...);
956template<
typename OutputValue_,
typename Index_,
class Operation_>
957using DelayedIsometricOperation = DelayedUnaryIsometricOperation<OutputValue_, Index_, Operation_, OutputValue_>;
Virtual class for a matrix of some numeric type.
Delayed isometric operation on a single matrix.
Definition DelayedUnaryIsometricOperation.hpp:669
std::unique_ptr< OracularDenseExtractor< OutputValue_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:908
std::unique_ptr< OracularSparseExtractor< OutputValue_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:928
std::unique_ptr< OracularDenseExtractor< OutputValue_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:916
Index_ nrow() const
Definition DelayedUnaryIsometricOperation.hpp:697
std::unique_ptr< MyopicSparseExtractor< OutputValue_, Index_ > > sparse(bool row, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:896
std::unique_ptr< MyopicSparseExtractor< OutputValue_, Index_ > > sparse(bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:900
double prefer_rows_proportion() const
Definition DelayedUnaryIsometricOperation.hpp:723
Index_ ncol() const
Definition DelayedUnaryIsometricOperation.hpp:701
std::unique_ptr< MyopicDenseExtractor< OutputValue_, Index_ > > dense(bool row, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:826
std::unique_ptr< MyopicSparseExtractor< OutputValue_, Index_ > > sparse(bool row, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:892
DelayedUnaryIsometricOperation(std::shared_ptr< const Matrix< InputValue_, Index_ > > matrix, std::shared_ptr< const Operation_ > operation)
Definition DelayedUnaryIsometricOperation.hpp:675
std::unique_ptr< MyopicDenseExtractor< OutputValue_, Index_ > > dense(bool row, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:822
std::unique_ptr< OracularSparseExtractor< OutputValue_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:924
std::unique_ptr< MyopicDenseExtractor< OutputValue_, Index_ > > dense(bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:830
std::unique_ptr< OracularDenseExtractor< OutputValue_, Index_ > > dense(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, Index_ block_start, Index_ block_length, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:912
bool prefer_rows() const
Definition DelayedUnaryIsometricOperation.hpp:719
bool is_sparse() const
Definition DelayedUnaryIsometricOperation.hpp:705
double is_sparse_proportion() const
Definition DelayedUnaryIsometricOperation.hpp:712
std::unique_ptr< OracularSparseExtractor< OutputValue_, Index_ > > sparse(bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedUnaryIsometricOperation.hpp:932
bool uses_oracle(bool row) const
Definition DelayedUnaryIsometricOperation.hpp:727
Virtual class for a matrix.
Definition Matrix.hpp:59
Predict future access requests on the target dimension.
Definition Oracle.hpp:21
Copy data from one buffer to another.
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_, std::shared_ptr< const Oracle< Index_ > >, bool >::type MaybeOracle
Definition new_extractor.hpp:20
typename std::conditional< oracle_, OracularDenseExtractor< Value_, Index_ >, MyopicDenseExtractor< Value_, Index_ > >::type DenseExtractor
Definition Extractor.hpp:273
Value_ * copy_n(const Value_ *input, Size_ n, Value_ *output)
Definition copy.hpp:25
auto new_extractor(const Matrix< Value_, Index_ > &matrix, bool row, MaybeOracle< oracle_, Index_ > oracle, Args_ &&... args)
Definition new_extractor.hpp:42
Options for accessing data from a Matrix instance.
Definition Options.hpp:30
Interface for tatami::DelayedUnaryIsometricOperation helpers.