tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
arithmetic_helpers.hpp
Go to the documentation of this file.
1#ifndef TATAMI_ISOMETRIC_BINARY_ARITHMETIC_HELPERS_H
2#define TATAMI_ISOMETRIC_BINARY_ARITHMETIC_HELPERS_H
3
5#include "utils.hpp"
6#include <limits>
7#include <vector>
8
15namespace tatami {
16
24template<ArithmeticOperation op_>
26public:
30 static constexpr bool known_sparse = (op_ == ArithmeticOperation::ADD ||
31 op_ == ArithmeticOperation::SUBTRACT ||
32 op_ == ArithmeticOperation::MULTIPLY);
33
34 static constexpr bool is_basic = false;
39public:
43 template<typename Index_, typename InputValue_, typename OutputValue_>
44 void dense(bool, Index_, Index_, Index_ length, const InputValue_* left_buffer, const InputValue_* right_buffer, OutputValue_* output_buffer) const {
45 for (Index_ i = 0; i < length; ++i) {
46 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
47 auto& val = output_buffer[i];
48 val = delayed_arithmetic<op_, true>(val, right_buffer[i]);
49 } else {
50 output_buffer[i] = delayed_arithmetic<op_, true>(left_buffer[i], right_buffer[i]);
51 }
52 }
53 }
54
55 template<typename Index_, typename InputValue_, typename OutputValue_>
56 void dense(bool, Index_, const std::vector<Index_>& indices, const InputValue_* left_buffer, const InputValue_* right_buffer, OutputValue_* output_buffer) const {
57 Index_ length = indices.size();
58 for (Index_ i = 0; i < length; ++i) {
59 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
60 auto& val = output_buffer[i];
61 val = delayed_arithmetic<op_, true>(val, right_buffer[i]);
62 } else {
63 output_buffer[i] = delayed_arithmetic<op_, true>(left_buffer[i], right_buffer[i]);
64 }
65 }
66 }
67
68 template<typename Index_, typename InputValue_, typename OutputValue_>
69 Index_ sparse(bool, Index_, const SparseRange<InputValue_, Index_>& left, const SparseRange<InputValue_, Index_>& right, OutputValue_* value_buffer, Index_* index_buffer, bool needs_value, bool needs_index) const {
70 // Technically, MULTIPLY could skip processing if either is a zero.
71 // However, this is not correct if the other value is an NaN/Inf, as
72 // the product would be a NaN, not a zero; so we have to err on the
73 // side of caution of attemping the operation.
74 constexpr bool must_have_both = (op_ == ArithmeticOperation::MULTIPLY &&
75 !std::numeric_limits<InputValue_>::has_quiet_NaN &&
76 !std::numeric_limits<InputValue_>::has_infinity);
77
78 return delayed_binary_isometric_sparse_operation<must_have_both>(
79 left,
80 right,
81 value_buffer,
82 index_buffer,
83 needs_value,
84 needs_index,
85 [](InputValue_ l, InputValue_ r) -> auto {
86 return delayed_arithmetic<op_, true>(l, r);
87 }
88 );
89 }
90
91 template<typename OutputValue_, typename InputValue_, typename Index_>
92 OutputValue_ fill(bool, Index_) const {
93 if constexpr(has_unsafe_divide_by_zero<op_, true, InputValue_, InputValue_>()) {
94 throw std::runtime_error("division by zero is not supported");
95 return 0;
96 } else {
97 return delayed_arithmetic<op_, true, InputValue_>(0, 0);
98 }
99 }
100
101 bool is_sparse() const {
102 return known_sparse;
103 }
107};
108
116
124
132
140
148
155
162
163}
164
165#endif
Utilities for delayed arithmetic operations.
Delayed binary isometric arithmetic.
Definition arithmetic_helpers.hpp:25
Flexible representations for matrix data.
Definition Extractor.hpp:15
DelayedBinaryIsometricArithmetic< ArithmeticOperation::MULTIPLY > make_DelayedBinaryIsometricMultiply()
Definition arithmetic_helpers.hpp:129
DelayedBinaryIsometricArithmetic< ArithmeticOperation::POWER > make_DelayedBinaryIsometricPower()
Definition arithmetic_helpers.hpp:145
DelayedBinaryIsometricArithmetic< ArithmeticOperation::MODULO > make_DelayedBinaryIsometricModulo()
Definition arithmetic_helpers.hpp:152
DelayedBinaryIsometricArithmetic< ArithmeticOperation::SUBTRACT > make_DelayedBinaryIsometricSubtract()
Definition arithmetic_helpers.hpp:121
DelayedBinaryIsometricArithmetic< ArithmeticOperation::ADD > make_DelayedBinaryIsometricAdd()
Definition arithmetic_helpers.hpp:113
DelayedBinaryIsometricArithmetic< ArithmeticOperation::DIVIDE > make_DelayedBinaryIsometricDivide()
Definition arithmetic_helpers.hpp:137
DelayedBinaryIsometricArithmetic< ArithmeticOperation::INTEGER_DIVIDE > make_DelayedBinaryIsometricIntegerDivide()
Definition arithmetic_helpers.hpp:159
A range of a sparse vector.
Definition SparseRange.hpp:32