1#ifndef TATAMI_ISOMETRIC_UNARY_ARITHMETIC_HELPERS_H
2#define TATAMI_ISOMETRIC_UNARY_ARITHMETIC_HELPERS_H
21template<ArithmeticOperation op_,
bool right_,
typename InputValue_,
typename Index_,
typename Scalar_,
typename OutputValue_>
22void delayed_arithmetic_run_simple(
const InputValue_* input, Index_ length, Scalar_ scalar, OutputValue_* output) {
23 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
26 for (Index_ i = 0; i < length; ++i) {
27 output[i] = delayed_arithmetic<op_, right_>(input[i], scalar);
33template<
bool check_only_, ArithmeticOperation op_,
bool right_,
typename OutputValue_,
typename InputValue_,
typename Scalar_>
34auto delayed_arithmetic_zeroish(Scalar_ scalar) {
35 if constexpr(has_unsafe_divide_by_zero<op_, right_, InputValue_, Scalar_>()) {
36 if constexpr(right_) {
38 OutputValue_ val = delayed_arithmetic<op_, right_, InputValue_, Scalar_>(0, scalar);
39 if constexpr(check_only_) {
47 if constexpr(check_only_) {
50 throw std::runtime_error(
"division by zero is not supported");
55 OutputValue_ val = delayed_arithmetic<op_, right_, InputValue_, Scalar_>(0, scalar);
56 if constexpr(check_only_) {
64template<ArithmeticOperation op_,
bool right_,
typename OutputValue_,
typename InputValue_,
typename Scalar_>
65bool delayed_arithmetic_actual_sparse(Scalar_ scalar) {
66 return delayed_arithmetic_zeroish<true, op_, right_, OutputValue_, InputValue_, Scalar_>(scalar);
69template<ArithmeticOperation op_,
bool right_,
typename OutputValue_,
typename InputValue_,
typename Scalar_>
70OutputValue_ delayed_arithmetic_zero(Scalar_ scalar) {
71 return delayed_arithmetic_zeroish<false, op_, right_, OutputValue_, InputValue_, Scalar_>(scalar);
92template<ArithmeticOperation op_,
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
99 my_sparse = delayed_arithmetic_actual_sparse<op_, right_, OutputValue_, InputValue_>(my_scalar);
107 std::optional<Index_>
nrow()
const {
111 std::optional<Index_>
ncol()
const {
133 void dense(
bool, Index_, Index_, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
134 delayed_arithmetic_run_simple<op_, right_>(input, length, my_scalar, output);
137 void dense(
bool, Index_,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
138 delayed_arithmetic_run_simple<op_, right_>(input,
static_cast<Index_
>(indices.size()), my_scalar, output);
146 void sparse(
bool, Index_, Index_ number,
const InputValue_* input_value,
const Index_*, OutputValue_* output_value)
const {
147 delayed_arithmetic_run_simple<op_, right_>(input_value, number, my_scalar, output_value);
150 OutputValue_
fill(
bool, Index_)
const {
155 return delayed_arithmetic_zero<op_, right_, OutputValue_, InputValue_>(my_scalar);
167template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
179template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
190template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
202template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
214template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
226template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
238template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Scalar_>
245template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
246std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricAddScalar(Scalar_ scalar) {
247 return std::make_shared<DelayedUnaryIsometricAddScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
250template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
251std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubtractScalar(Scalar_ scalar) {
252 return std::make_shared<DelayedUnaryIsometricSubtractScalarHelper<right_, OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
255template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
256std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricMultiplyScalar(Scalar_ scalar) {
257 return std::make_shared<DelayedUnaryIsometricMultiplyScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
260template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
261std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricDivideScalar(Scalar_ scalar) {
262 return std::make_shared<DelayedUnaryIsometricDivideScalarHelper<right_, OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
265template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
266std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricModuloScalar(Scalar_ scalar) {
267 return std::make_shared<DelayedUnaryIsometricModuloScalarHelper<right_, OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
270template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
271std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricPowerScalar(Scalar_ scalar) {
272 return std::make_shared<DelayedUnaryIsometricPowerScalarHelper<right_, OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
275template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Scalar_>
276std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricIntegerDivideScalar(Scalar_ scalar) {
277 return std::make_shared<DelayedUnaryIsometricIntegerDivideScalarHelper<right_, OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
299template<ArithmeticOperation op_,
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Vector_>
310 for (
auto x : my_vector) {
311 if (!delayed_arithmetic_actual_sparse<op_, right_, OutputValue_, InputValue_>(x)) {
321 bool my_sparse =
true;
324 std::optional<Index_>
nrow()
const {
326 return my_vector.size();
332 std::optional<Index_>
ncol()
const {
336 return my_vector.size();
358 void dense(
bool row, Index_ idx, Index_ start, Index_ length,
const InputValue_* input, OutputValue_* output)
const {
359 if (row == my_by_row) {
360 delayed_arithmetic_run_simple<op_, right_>(input, length, my_vector[idx], output);
362 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
365 for (Index_ i = 0; i < length; ++i) {
366 output[i] = delayed_arithmetic<op_, right_>(input[i], my_vector[i + start]);
371 void dense(
bool row, Index_ idx,
const std::vector<Index_>& indices,
const InputValue_* input, OutputValue_* output)
const {
372 if (row == my_by_row) {
373 delayed_arithmetic_run_simple<op_, right_>(input,
static_cast<Index_
>(indices.size()), my_vector[idx], output);
375 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
378 Index_ length = indices.size();
379 for (Index_ i = 0; i < length; ++i) {
380 output[i] = delayed_arithmetic<op_, right_>(input[i], my_vector[indices[i]]);
390 void sparse(
bool row, Index_ idx, Index_ number,
const InputValue_* input_value,
const Index_* index, OutputValue_* output_value)
const {
391 if (row == my_by_row) {
392 delayed_arithmetic_run_simple<op_, right_>(input_value, number, my_vector[idx], output_value);
394 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
395 input_value = output_value;
397 for (Index_ i = 0; i < number; ++i) {
398 output_value[i] = delayed_arithmetic<op_, right_>(input_value[i], my_vector[index[i]]);
403 OutputValue_
fill(
bool row, Index_ idx)
const {
404 if (row == my_by_row) {
405 return delayed_arithmetic_zero<op_, right_, OutputValue_, InputValue_>(my_vector[idx]);
422template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Vector_>
434template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Vector_>
445template<
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Vector_>
457template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Vector_>
469template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Vector_>
481template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Vector_>
493template<
bool right_,
typename OutputValue_,
typename InputValue_,
typename Index_,
typename Vector_>
500template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Vector_>
501std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricAddVector(Vector_ vector,
bool by_row) {
502 return std::make_shared<DelayedUnaryIsometricAddVectorHelper<OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
505template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Vector_>
506std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricSubtractVector(Vector_ vector,
bool by_row) {
507 return std::make_shared<DelayedUnaryIsometricSubtractVectorHelper<right_, OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
510template<
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Vector_>
511std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricMultiplyVector(Vector_ vector,
bool by_row) {
512 return std::make_shared<DelayedUnaryIsometricMultiplyVectorHelper<OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
515template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Vector_>
516std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricDivideVector(Vector_ vector,
bool by_row) {
517 return std::make_shared<DelayedUnaryIsometricDivideVectorHelper<right_, OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
520template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Vector_>
521std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricModuloVector(Vector_ vector,
bool by_row) {
522 return std::make_shared<DelayedUnaryIsometricModuloVectorHelper<right_, OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
525template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Vector_>
526std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricPowerVector(Vector_ vector,
bool by_row) {
527 return std::make_shared<DelayedUnaryIsometricPowerVectorHelper<right_, OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
530template<
bool right_,
typename OutputValue_ =
double,
typename InputValue_ =
double,
typename Index_ =
int,
typename Vector_>
531std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricIntegerDivideVector(Vector_ vector,
bool by_row) {
532 return std::make_shared<DelayedUnaryIsometricIntegerDivideVectorHelper<right_, OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
Utilities for delayed arithmetic operations.
Helper for delayed unary isometric scalar arithmetic.
Definition arithmetic_helpers.hpp:93
bool zero_depends_on_row() const
Definition arithmetic_helpers.hpp:116
void sparse(bool, Index_, Index_ number, const InputValue_ *input_value, const Index_ *, OutputValue_ *output_value) const
Definition arithmetic_helpers.hpp:146
OutputValue_ fill(bool, Index_) const
Definition arithmetic_helpers.hpp:150
bool non_zero_depends_on_row() const
Definition arithmetic_helpers.hpp:124
DelayedUnaryIsometricArithmeticScalarHelper(Scalar_ scalar)
Definition arithmetic_helpers.hpp:98
std::optional< Index_ > nrow() const
Definition arithmetic_helpers.hpp:107
bool is_sparse() const
Definition arithmetic_helpers.hpp:142
void dense(bool, Index_, const std::vector< Index_ > &indices, const InputValue_ *input, OutputValue_ *output) const
Definition arithmetic_helpers.hpp:137
void dense(bool, Index_, Index_, Index_ length, const InputValue_ *input, OutputValue_ *output) const
Definition arithmetic_helpers.hpp:133
bool zero_depends_on_column() const
Definition arithmetic_helpers.hpp:120
std::optional< Index_ > ncol() const
Definition arithmetic_helpers.hpp:111
bool non_zero_depends_on_column() const
Definition arithmetic_helpers.hpp:128
Helper for delayed unary isometric vector arithmetic.
Definition arithmetic_helpers.hpp:300
void dense(bool row, Index_ idx, const std::vector< Index_ > &indices, const InputValue_ *input, OutputValue_ *output) const
Definition arithmetic_helpers.hpp:371
bool is_sparse() const
Definition arithmetic_helpers.hpp:386
void dense(bool row, Index_ idx, Index_ start, Index_ length, const InputValue_ *input, OutputValue_ *output) const
Definition arithmetic_helpers.hpp:358
bool non_zero_depends_on_column() const
Definition arithmetic_helpers.hpp:353
std::optional< Index_ > nrow() const
Definition arithmetic_helpers.hpp:324
void sparse(bool row, Index_ idx, Index_ number, const InputValue_ *input_value, const Index_ *index, OutputValue_ *output_value) const
Definition arithmetic_helpers.hpp:390
bool non_zero_depends_on_row() const
Definition arithmetic_helpers.hpp:349
DelayedUnaryIsometricArithmeticVectorHelper(Vector_ vector, bool by_row)
Definition arithmetic_helpers.hpp:309
bool zero_depends_on_column() const
Definition arithmetic_helpers.hpp:345
std::optional< Index_ > ncol() const
Definition arithmetic_helpers.hpp:332
OutputValue_ fill(bool row, Index_ idx) const
Definition arithmetic_helpers.hpp:403
bool zero_depends_on_row() const
Definition arithmetic_helpers.hpp:341
Helper operation interface for DelayedUnaryIsometricOperation.
Definition helper_interface.hpp:27
Flexible representations for matrix data.
Definition Extractor.hpp:15
Interface for tatami::DelayedUnaryIsometricOperation helpers.