1#ifndef TATAMI_ISOMETRIC_UNARY_SUBSTITUTE_HELPERS_H
2#define TATAMI_ISOMETRIC_UNARY_SUBSTITUTE_HELPERS_H
5#include "../../utils/Index_to_container.hpp"
22template<CompareOperation op_,
typename InputValue_,
typename Scalar_,
typename OutputValue_>
23bool delayed_substitute_is_sparse(
const Scalar_ compared,
const 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(
const InputValue_ val,
const Scalar_ compared,
const 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,
const Index_ length,
const Scalar_ compared, OutputValue_*
const output,
const 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_compared(compared),
71 my_substitute(substitute)
73 my_sparse = delayed_substitute_is_sparse<op_, InputValue_>(my_compared, my_substitute);
78 OutputValue_ my_substitute;
82 std::optional<Index_>
nrow()
const {
86 std::optional<Index_>
ncol()
const {
108 void dense(
const bool,
const Index_,
const Index_,
const Index_ length,
const InputValue_*
const input, OutputValue_*
const output)
const {
109 delayed_substitute_run_simple<op_>(input, length, my_compared, output, my_substitute);
112 void dense(
const bool,
const Index_,
const std::vector<Index_>& indices,
const InputValue_*
const input, OutputValue_*
const output)
const {
113 delayed_substitute_run_simple<op_>(input,
static_cast<Index_
>(indices.size()), my_compared, output, my_substitute);
121 void sparse(
const bool,
const Index_,
const Index_ number,
const InputValue_*
const input_value,
const Index_*
const, OutputValue_*
const output_value)
const {
122 delayed_substitute_run_simple<op_>(input_value, number, my_compared, output_value, my_substitute);
125 OutputValue_
fill(
const bool,
const Index_)
const {
129 return my_substitute;
142template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
153template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
164template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
175template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
186template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
197template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
208template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
215template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
216std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteEqualScalar(Scalar_ compared, OutputValue_ substitute) {
217 return std::make_shared<DelayedUnaryIsometricSubstituteEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
220template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
221std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteGreaterThanScalar(Scalar_ compared, OutputValue_ substitute) {
222 return std::make_shared<DelayedUnaryIsometricSubstituteGreaterThanScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
225template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
226std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteLessThanScalar(Scalar_ compared, OutputValue_ substitute) {
227 return std::make_shared<DelayedUnaryIsometricSubstituteLessThanScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
230template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
231std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteGreaterThanOrEqualScalar(Scalar_ compared, OutputValue_ substitute) {
232 return std::make_shared<DelayedUnaryIsometricSubstituteGreaterThanOrEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
235template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
236std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteLessThanOrEqualScalar(Scalar_ compared, OutputValue_ substitute) {
237 return std::make_shared<DelayedUnaryIsometricSubstituteLessThanOrEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
240template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
241std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteNotEqualScalar(Scalar_ compared, OutputValue_ substitute) {
242 return std::make_shared<DelayedUnaryIsometricSubstituteNotEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(compared, substitute);
264template<CompareOperation op_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
278 my_compared(std::move(compared)),
279 my_substitute(std::move(substitute)),
282 const auto ncompared = my_compared.size();
283 if (!safe_non_negative_equal(ncompared, my_substitute.size())) {
284 throw std::runtime_error(
"'compared' and 'substitute' should have the same length");
286 for (I<
decltype(ncompared)> i = 0; i < ncompared; ++i) {
287 if (!delayed_substitute_is_sparse<op_, InputValue_>(my_compared[i], my_substitute[i])) {
295 ComparedVector_ my_compared;
296 SubstituteVector_ my_substitute;
298 bool my_sparse =
true;
301 std::optional<Index_>
nrow()
const {
303 return my_compared.size();
309 std::optional<Index_>
ncol()
const {
313 return my_compared.size();
335 void dense(
const bool row,
const Index_ idx,
const Index_ start,
const Index_ length,
const InputValue_* input, OutputValue_*
const output)
const {
336 if (row == my_by_row) {
337 delayed_substitute_run_simple<op_>(input, length, my_compared[idx], output, my_substitute[idx]);
339 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
342 for (Index_ i = 0; i < length; ++i) {
343 const Index_ is = i + start;
344 output[i] = delayed_substitute_run<op_>(input[i], my_compared[is], my_substitute[is]);
349 void dense(
const bool row,
const Index_ idx,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_*
const output)
const {
350 if (row == my_by_row) {
351 delayed_substitute_run_simple<op_>(input,
static_cast<Index_
>(indices.size()), my_compared[idx], output, my_substitute[idx]);
353 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
356 const Index_ length = indices.size();
357 for (Index_ i = 0; i < length; ++i) {
358 const auto ii = indices[i];
359 output[i] = delayed_substitute_run<op_>(input[i], my_compared[ii], my_substitute[ii]);
369 void sparse(
bool row, Index_ idx, Index_ number,
const InputValue_* input_value,
const Index_* indices, OutputValue_* output_value)
const {
370 if (row == my_by_row) {
371 delayed_substitute_run_simple<op_>(input_value, number, my_compared[idx], output_value, my_substitute[idx]);
373 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
374 input_value = output_value;
376 for (Index_ i = 0; i < number; ++i) {
377 const auto ii = indices[i];
378 output_value[i] = delayed_substitute_run<op_>(input_value[i], my_compared[ii], my_substitute[ii]);
383 OutputValue_
fill(
bool row, Index_ idx)
const {
384 if (row == my_by_row) {
385 const auto sub = my_substitute[idx];
386 if (!delayed_compare<op_, InputValue_>(0, my_compared[idx])) {
408template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
420template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
432template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
444template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
456template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
468template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
480template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename ComparedVector_,
typename SubstituteVector_>
487template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
488std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteEqualVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
489 return std::make_shared<DelayedUnaryIsometricSubstituteEqualVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
492template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
493std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteGreaterThanVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
494 return std::make_shared<DelayedUnaryIsometricSubstituteGreaterThanVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
497template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
498std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteLessThanVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
499 return std::make_shared<DelayedUnaryIsometricSubstituteLessThanVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
502template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
503std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteGreaterThanOrEqualVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
504 return std::make_shared<DelayedUnaryIsometricSubstituteGreaterThanOrEqualVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
507template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
508std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricLessSubstituteThanOrEqualVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
509 return std::make_shared<DelayedUnaryIsometricSubstituteLessThanOrEqualVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
512template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename ComparedVector_,
typename SubstituteVector_>
513std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteNotEqualVector(ComparedVector_ compared, SubstituteVector_ substitute,
bool by_row) {
514 return std::make_shared<DelayedUnaryIsometricSubstituteNotEqualVectorHelper<OutputValue_, InputValue_, Index_, ComparedVector_, SubstituteVector_> >(std::move(compared), std::move(substitute), by_row);
523template<SpecialCompareOperation op_,
bool pass_,
typename InputValue_,
typename OutputValue_>
524bool delayed_special_substitute_is_sparse(
const OutputValue_ substitute) {
525 return !delayed_special_compare<op_, pass_, InputValue_>(0) || substitute == 0;
528template<SpecialCompareOperation op_,
bool pass_,
typename InputValue_,
typename OutputValue_>
529OutputValue_ delayed_special_substitute_run(
const InputValue_ val,
const OutputValue_ substitute) {
530 if (delayed_special_compare<op_, pass_>(val)) {
537template<SpecialCompareOperation op_,
bool pass_,
typename InputValue_,
typename Index_,
typename OutputValue_>
538void delayed_special_substitute_run_simple(
const InputValue_* input,
const Index_ length,
const OutputValue_ substitute, OutputValue_*
const output) {
539 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
542 for (Index_ i = 0; i < length; ++i) {
543 output[i] = delayed_special_substitute_run<op_, pass_>(input[i], substitute);
563template<SpecialCompareOperation op_,
bool pass_,
typename OutputValue_,
typename InputValue_,
typename Index_>
570 my_sparse = delayed_special_substitute_is_sparse<op_, pass_, InputValue_>(my_substitute);
574 OutputValue_ my_substitute;
578 std::optional<Index_>
nrow()
const {
582 std::optional<Index_>
ncol()
const {
604 void dense(
const bool,
const Index_,
const Index_,
const Index_ length,
const InputValue_*
const input, OutputValue_*
const output)
const {
605 delayed_special_substitute_run_simple<op_, pass_>(input, length, my_substitute, output);
608 void dense(
const bool,
const Index_,
const std::vector<Index_>& indices,
const InputValue_*
const input, OutputValue_*
const output)
const {
609 delayed_special_substitute_run_simple<op_, pass_>(input,
static_cast<Index_
>(indices.size()), my_substitute, output);
617 void sparse(
const bool,
const Index_,
const Index_ number,
const InputValue_*
const input_value,
const Index_*
const, OutputValue_*
const output_value)
const {
618 delayed_special_substitute_run_simple<op_, pass_>(input_value, number, my_substitute, output_value);
621 OutputValue_
fill(
const bool,
const Index_)
const {
625 return my_substitute;
638template<
bool pass_,
typename OutputValue_,
typename InputValue_,
typename Index_>
649template<
bool pass_,
typename OutputValue_,
typename InputValue_,
typename Index_>
660template<
bool pass_,
typename OutputValue_,
typename InputValue_,
typename Index_>
667template<
bool pass_ = true,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int>
668std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteIsnan(OutputValue_ substitute) {
669 return std::make_shared<DelayedUnaryIsometricSubstituteIsnanHelper<pass_, OutputValue_, InputValue_, Index_> >(substitute);
672template<
bool pass_ = true,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int>
673std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteIsinf(OutputValue_ substitute) {
674 return std::make_shared<DelayedUnaryIsometricSubstituteIsinfHelper<pass_, OutputValue_, InputValue_, Index_> >(substitute);
677template<
bool pass_ = true,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int>
678std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubstituteIsfinite(OutputValue_ substitute) {
679 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:564
void dense(const bool, const Index_, const Index_, const Index_ length, const InputValue_ *const input, OutputValue_ *const output) const
Definition substitute_helpers.hpp:604
std::optional< Index_ > ncol() const
Definition substitute_helpers.hpp:582
bool zero_depends_on_column() const
Definition substitute_helpers.hpp:591
void sparse(const bool, const Index_, const Index_ number, const InputValue_ *const input_value, const Index_ *const, OutputValue_ *const output_value) const
Definition substitute_helpers.hpp:617
bool zero_depends_on_row() const
Definition substitute_helpers.hpp:587
OutputValue_ fill(const bool, const Index_) const
Definition substitute_helpers.hpp:621
DelayedUnaryIsometricSpecialSubstituteHelper(const OutputValue_ substitute)
Definition substitute_helpers.hpp:569
bool non_zero_depends_on_column() const
Definition substitute_helpers.hpp:599
std::optional< Index_ > nrow() const
Definition substitute_helpers.hpp:578
bool is_sparse() const
Definition substitute_helpers.hpp:613
void dense(const bool, const Index_, const std::vector< Index_ > &indices, const InputValue_ *const input, OutputValue_ *const output) const
Definition substitute_helpers.hpp:608
bool non_zero_depends_on_row() const
Definition substitute_helpers.hpp:595
Helper for delayed scalar substitution.
Definition substitute_helpers.hpp:62
bool non_zero_depends_on_column() const
Definition substitute_helpers.hpp:103
bool is_sparse() const
Definition substitute_helpers.hpp:117
DelayedUnaryIsometricSubstituteScalarHelper(const Scalar_ compared, const OutputValue_ substitute)
Definition substitute_helpers.hpp:69
OutputValue_ fill(const bool, const Index_) const
Definition substitute_helpers.hpp:125
std::optional< Index_ > nrow() const
Definition substitute_helpers.hpp:82
void dense(const bool, const Index_, const Index_, const Index_ length, const InputValue_ *const input, OutputValue_ *const output) const
Definition substitute_helpers.hpp:108
bool non_zero_depends_on_row() const
Definition substitute_helpers.hpp:99
bool zero_depends_on_column() const
Definition substitute_helpers.hpp:95
void dense(const bool, const Index_, const std::vector< Index_ > &indices, const InputValue_ *const input, OutputValue_ *const output) const
Definition substitute_helpers.hpp:112
std::optional< Index_ > ncol() const
Definition substitute_helpers.hpp:86
void sparse(const bool, const Index_, const Index_ number, const InputValue_ *const input_value, const Index_ *const, OutputValue_ *const output_value) const
Definition substitute_helpers.hpp:121
bool zero_depends_on_row() const
Definition substitute_helpers.hpp:91
Delayed vector comparisons.
Definition substitute_helpers.hpp:265
std::optional< Index_ > nrow() const
Definition substitute_helpers.hpp:301
bool is_sparse() const
Definition substitute_helpers.hpp:365
bool zero_depends_on_row() const
Definition substitute_helpers.hpp:318
DelayedUnaryIsometricSubstituteVectorHelper(ComparedVector_ compared, SubstituteVector_ substitute, const bool by_row)
Definition substitute_helpers.hpp:277
std::optional< Index_ > ncol() const
Definition substitute_helpers.hpp:309
void dense(const bool row, const Index_ idx, const Index_ start, const Index_ length, const InputValue_ *input, OutputValue_ *const output) const
Definition substitute_helpers.hpp:335
void dense(const bool row, const Index_ idx, const std::vector< Index_ > &indices, const InputValue_ *input, OutputValue_ *const output) const
Definition substitute_helpers.hpp:349
OutputValue_ fill(bool row, Index_ idx) const
Definition substitute_helpers.hpp:383
void sparse(bool row, Index_ idx, Index_ number, const InputValue_ *input_value, const Index_ *indices, OutputValue_ *output_value) const
Definition substitute_helpers.hpp:369
bool non_zero_depends_on_row() const
Definition substitute_helpers.hpp:326
bool zero_depends_on_column() const
Definition substitute_helpers.hpp:322
bool non_zero_depends_on_column() const
Definition substitute_helpers.hpp:330
Utilities for delayed comparison operations.
Flexible representations for matrix data.
Definition Extractor.hpp:15
Interface for tatami::DelayedUnaryIsometricOperation helpers.