1#ifndef TATAMI_ISOMETRIC_UNARY_SUBSTITUTE_HELPERS_H
2#define TATAMI_ISOMETRIC_UNARY_SUBSTITUTE_HELPERS_H
22template<CompareOperation op_,
typename InputValue_,
typename Scalar_,
typename OutputValue_>
23bool delayed_substitute_is_sparse(Scalar_ compared, OutputValue_ substitute) {
24 return !delayed_compare<op_, InputValue_>(0, compared) || substitute == 0;
27template<CompareOperation op_,
typename InputValue_,
typename Scalar_,
typename OutputValue_>
28OutputValue_ delayed_substitute_run(InputValue_ val, Scalar_ compared, OutputValue_ substitute) {
29 if (delayed_compare<op_>(val, compared)) {
36template<CompareOperation op_,
typename InputValue_,
typename Index_,
typename Scalar_,
typename OutputValue_>
37void delayed_substitute_run_simple(
const InputValue_* input, Index_ length, Scalar_ compared, OutputValue_* output, OutputValue_ substitute) {
38 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
41 for (Index_ i = 0; i < length; ++i) {
42 output[i] = delayed_substitute_run<op_>(input[i], compared, substitute);
61template<CompareOperation op_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
70 my_sparse = delayed_substitute_is_sparse<op_, InputValue_>(my_compared, my_substitute);
75 OutputValue_ my_substitute;
79 std::optional<Index_>
nrow()
const {
83 std::optional<Index_>
ncol()
const {
105 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
106 delayed_substitute_run_simple<op_>(input, length, my_compared, output, my_substitute);
109 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
110 delayed_substitute_run_simple<op_>(input,
static_cast<Index_
>(indices.size()), my_compared, output, my_substitute);
118 void sparse(
bool, Index_, Index_ number,
const InputValue_* input_value,
const Index_*, OutputValue_* output_value)
const {
119 delayed_substitute_run_simple<op_>(input_value, number, my_compared, output_value, my_substitute);
122 OutputValue_
fill(
bool, Index_)
const {
126 return my_substitute;
139template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
150template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
161template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
172template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
183template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
194template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
205template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
212template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
213std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteEqualScalar(Scalar_ compared, OutputValue_ substitute) {
214 return std::make_shared<DelayedUnaryIsometricSubstituteEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
217template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
218std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteGreaterThanScalar(Scalar_ compared, OutputValue_ substitute) {
219 return std::make_shared<DelayedUnaryIsometricSubstituteGreaterThanScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
222template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
223std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteLessThanScalar(Scalar_ compared, OutputValue_ substitute) {
224 return std::make_shared<DelayedUnaryIsometricSubstituteLessThanScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
227template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
228std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteGreaterThanOrEqualScalar(Scalar_ compared, OutputValue_ substitute) {
229 return std::make_shared<DelayedUnaryIsometricSubstituteGreaterThanOrEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
232template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
233std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteLessThanOrEqualScalar(Scalar_ compared, OutputValue_ substitute) {
234 return std::make_shared<DelayedUnaryIsometricSubstituteLessThanOrEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
237template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
238std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteNotEqualScalar(Scalar_ compared, OutputValue_ substitute) {
239 return std::make_shared<DelayedUnaryIsometricSubstituteNotEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
261template<CompareOperation op_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
275 my_compared(std::move(compared)),
276 my_substitute(std::move(substitute)),
279 auto ncompared = my_compared.size();
281 throw std::runtime_error(
"'compared' and 'substitute' should have the same length");
283 for (
decltype(ncompared) i = 0; i < ncompared; ++i) {
284 if (!delayed_substitute_is_sparse<op_, InputValue_>(my_compared[i], my_substitute[i])) {
292 ComparedVector_ my_compared;
293 SubstituteVector_ my_substitute;
295 bool my_sparse =
true;
298 std::optional<Index_>
nrow()
const {
300 return my_compared.size();
306 std::optional<Index_>
ncol()
const {
310 return my_compared.size();
332 void dense(
bool row, Index_ idx, Index_ start, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
333 if (row == my_by_row) {
334 delayed_substitute_run_simple<op_>(input, length, my_compared[idx], output, my_substitute[idx]);
336 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
339 for (Index_ i = 0; i < length; ++i) {
340 Index_ is = i + start;
341 output[i] = delayed_substitute_run<op_>(input[i], my_compared[is], my_substitute[is]);
346 void dense(
bool row, Index_ idx,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
347 if (row == my_by_row) {
348 delayed_substitute_run_simple<op_>(input,
static_cast<Index_
>(indices.size()), my_compared[idx], output, my_substitute[idx]);
350 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
353 Index_ length = indices.size();
354 for (Index_ i = 0; i < length; ++i) {
355 auto ii = indices[i];
356 output[i] = delayed_substitute_run<op_>(input[i], my_compared[ii], my_substitute[ii]);
366 void sparse(
bool row, Index_ idx, Index_ number,
const InputValue_* input_value,
const Index_* indices, OutputValue_* output_value)
const {
367 if (row == my_by_row) {
368 delayed_substitute_run_simple<op_>(input_value, number, my_compared[idx], output_value, my_substitute[idx]);
370 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
371 input_value = output_value;
373 for (Index_ i = 0; i < number; ++i) {
374 auto ii = indices[i];
375 output_value[i] = delayed_substitute_run<op_>(input_value[i], my_compared[ii], my_substitute[ii]);
380 OutputValue_
fill(
bool row, Index_ idx)
const {
381 if (row == my_by_row) {
382 auto sub = my_substitute[idx];
383 if (!delayed_compare<op_, InputValue_>(0, my_compared[idx])) {
405template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
417template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
429template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
441template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
453template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
465template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
477template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
484template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
485std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteEqualVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
486 return std::make_shared<DelayedUnaryIsometricSubstituteEqualVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
489template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
490std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteGreaterThanVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
491 return std::make_shared<DelayedUnaryIsometricSubstituteGreaterThanVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
494template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
495std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteLessThanVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
496 return std::make_shared<DelayedUnaryIsometricSubstituteLessThanVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
499template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
500std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteGreaterThanOrEqualVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
501 return std::make_shared<DelayedUnaryIsometricSubstituteGreaterThanOrEqualVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
504template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
505std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricLessSubstituteThanOrEqualVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
506 return std::make_shared<DelayedUnaryIsometricSubstituteLessThanOrEqualVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
509template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
510std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteNotEqualVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
511 return std::make_shared<DelayedUnaryIsometricSubstituteNotEqualVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
520template<SpecialCompareOperation op_,
bool pass_,
typename InputValue_,
typename OutputValue_>
521bool delayed_special_substitute_is_sparse(OutputValue_ substitute) {
522 return !delayed_special_compare<op_, pass_, InputValue_>(0) || substitute == 0;
525template<SpecialCompareOperation op_,
bool pass_,
typename InputValue_,
typename OutputValue_>
526OutputValue_ delayed_special_substitute_run(InputValue_ val, OutputValue_ substitute) {
527 if (delayed_special_compare<op_, pass_>(val)) {
534template<SpecialCompareOperation op_,
bool pass_,
typename InputValue_,
typename Index_,
typename OutputValue_>
535void delayed_special_substitute_run_simple(
const InputValue_* input, Index_ length, OutputValue_ substitute, OutputValue_* output) {
536 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
539 for (Index_ i = 0; i < length; ++i) {
540 output[i] = delayed_special_substitute_run<op_, pass_>(input[i], substitute);
560template<SpecialCompareOperation op_,
bool pass_,
typename OutputValue_,
typename InputValue_,
typename Index_>
567 my_sparse = delayed_special_substitute_is_sparse<op_, pass_, InputValue_>(my_substitute);
571 OutputValue_ my_substitute;
575 std::optional<Index_>
nrow()
const {
579 std::optional<Index_>
ncol()
const {
601 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
602 delayed_special_substitute_run_simple<op_, pass_>(input, length, my_substitute, output);
605 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
606 delayed_special_substitute_run_simple<op_, pass_>(input,
static_cast<Index_
>(indices.size()), my_substitute, output);
614 void sparse(
bool, Index_, Index_ number,
const InputValue_* input_value,
const Index_*, OutputValue_* output_value)
const {
615 delayed_special_substitute_run_simple<op_, pass_>(input_value, number, my_substitute, output_value);
618 OutputValue_
fill(
bool, Index_)
const {
622 return my_substitute;
635template<
bool pass_,
typename OutputValue_,
typename InputValue_,
typename Index_>
646template<
bool pass_,
typename OutputValue_,
typename InputValue_,
typename Index_>
657template<
bool pass_,
typename OutputValue_,
typename InputValue_,
typename Index_>
664template<
bool pass_ = true,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int>
665std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteIsnan(OutputValue_ substitute) {
666 return std::make_shared<DelayedUnaryIsometricSubstituteIsnanHelper<pass_, OutputValue_, InputValue_, Index_> >(substitute);
669template<
bool pass_ = true,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int>
670std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteIsinf(OutputValue_ substitute) {
671 return std::make_shared<DelayedUnaryIsometricSubstituteIsinfHelper<pass_, OutputValue_, InputValue_, Index_> >(substitute);
674template<
bool pass_ = true,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int>
675std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteIsfinite(OutputValue_ substitute) {
676 return std::make_shared<DelayedUnaryIsometricSubstituteIsfiniteHelper<pass_, OutputValue_, InputValue_, Index_> >(substitute);
Helper operation interface for DelayedUnaryIsometricOperation.
Definition helper_interface.hpp:27
Delayed special value substitution.
Definition substitute_helpers.hpp:561
std::optional< Index_ > ncol() const
Definition substitute_helpers.hpp:579
void dense(bool, Index_, Index_, Index_ length, const InputValue_ *input, OutputValue_ *output) const
Definition substitute_helpers.hpp:601
bool zero_depends_on_column() const
Definition substitute_helpers.hpp:588
bool zero_depends_on_row() const
Definition substitute_helpers.hpp:584
DelayedUnaryIsometricSpecialSubstituteHelper(OutputValue_ substitute)
Definition substitute_helpers.hpp:566
bool non_zero_depends_on_column() const
Definition substitute_helpers.hpp:596
std::optional< Index_ > nrow() const
Definition substitute_helpers.hpp:575
void sparse(bool, Index_, Index_ number, const InputValue_ *input_value, const Index_ *, OutputValue_ *output_value) const
Definition substitute_helpers.hpp:614
bool is_sparse() const
Definition substitute_helpers.hpp:610
void dense(bool, Index_, const std::vector< Index_ > &indices, const InputValue_ *input, OutputValue_ *output) const
Definition substitute_helpers.hpp:605
bool non_zero_depends_on_row() const
Definition substitute_helpers.hpp:592
OutputValue_ fill(bool, Index_) const
Definition substitute_helpers.hpp:618
Helper for delayed scalar substitution.
Definition substitute_helpers.hpp:62
bool non_zero_depends_on_column() const
Definition substitute_helpers.hpp:100
bool is_sparse() const
Definition substitute_helpers.hpp:114
DelayedUnaryIsometricSubstituteScalarHelper(Scalar_ compared, OutputValue_ substitute)
Definition substitute_helpers.hpp:69
std::optional< Index_ > nrow() const
Definition substitute_helpers.hpp:79
void sparse(bool, Index_, Index_ number, const InputValue_ *input_value, const Index_ *, OutputValue_ *output_value) const
Definition substitute_helpers.hpp:118
void dense(bool, Index_, const std::vector< Index_ > &indices, const InputValue_ *input, OutputValue_ *output) const
Definition substitute_helpers.hpp:109
OutputValue_ fill(bool, Index_) const
Definition substitute_helpers.hpp:122
bool non_zero_depends_on_row() const
Definition substitute_helpers.hpp:96
bool zero_depends_on_column() const
Definition substitute_helpers.hpp:92
void dense(bool, Index_, Index_, Index_ length, const InputValue_ *input, OutputValue_ *output) const
Definition substitute_helpers.hpp:105
std::optional< Index_ > ncol() const
Definition substitute_helpers.hpp:83
bool zero_depends_on_row() const
Definition substitute_helpers.hpp:88
Delayed vector comparisons.
Definition substitute_helpers.hpp:262
std::optional< Index_ > nrow() const
Definition substitute_helpers.hpp:298
bool is_sparse() const
Definition substitute_helpers.hpp:362
bool zero_depends_on_row() const
Definition substitute_helpers.hpp:315
DelayedUnaryIsometricSubstituteVectorHelper(ComparedVector_ compared, SubstituteVector_ substitute, bool by_row)
Definition substitute_helpers.hpp:274
void dense(bool row, Index_ idx, const std::vector< Index_ > &indices, const InputValue_ *input, OutputValue_ *output) const
Definition substitute_helpers.hpp:346
std::optional< Index_ > ncol() const
Definition substitute_helpers.hpp:306
void dense(bool row, Index_ idx, Index_ start, Index_ length, const InputValue_ *input, OutputValue_ *output) const
Definition substitute_helpers.hpp:332
OutputValue_ fill(bool row, Index_ idx) const
Definition substitute_helpers.hpp:380
void sparse(bool row, Index_ idx, Index_ number, const InputValue_ *input_value, const Index_ *indices, OutputValue_ *output_value) const
Definition substitute_helpers.hpp:366
bool non_zero_depends_on_row() const
Definition substitute_helpers.hpp:323
bool zero_depends_on_column() const
Definition substitute_helpers.hpp:319
bool non_zero_depends_on_column() const
Definition substitute_helpers.hpp:327
Utilities for delayed comparison operations.
Sign-aware integer comparisons.
Flexible representations for matrix data.
Definition Extractor.hpp:15
bool safe_non_negative_equal(Left_ l, Right_ r)
Definition integer_comparisons.hpp:23
Interface for tatami::DelayedUnaryIsometricOperation helpers.