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"
7
8#include <limits>
9#include <vector>
10
17namespace tatami {
18
29template<ArithmeticOperation op_, typename OutputValue_, typename InputValue_, typename Index_>
30class DelayedBinaryIsometricArithmeticHelper final : public DelayedBinaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> {
31public:
32 bool zero_depends_on_row() const { return false; }
33 bool zero_depends_on_column() const { return false; }
34 bool non_zero_depends_on_row() const { return false; }
35 bool non_zero_depends_on_column() const { return false; }
36
37public:
38 void dense(
39 const bool,
40 const Index_,
41 const Index_,
42 const Index_ length,
43 const InputValue_* const left_buffer,
44 const InputValue_* const right_buffer,
45 OutputValue_* const output_buffer)
46 const {
47 for (Index_ i = 0; i < length; ++i) {
48 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
49 auto& val = output_buffer[i];
50 val = delayed_arithmetic<op_, true>(val, right_buffer[i]);
51 } else {
52 output_buffer[i] = delayed_arithmetic<op_, true>(left_buffer[i], right_buffer[i]);
53 }
54 }
55 }
56
57 void dense(
58 const bool,
59 const Index_,
60 const std::vector<Index_>& indices,
61 const InputValue_* const left_buffer,
62 const InputValue_* const right_buffer,
63 OutputValue_* const output_buffer)
64 const {
65 const Index_ length = indices.size();
66 for (Index_ i = 0; i < length; ++i) {
67 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
68 auto& val = output_buffer[i];
69 val = delayed_arithmetic<op_, true>(val, right_buffer[i]);
70 } else {
71 output_buffer[i] = delayed_arithmetic<op_, true>(left_buffer[i], right_buffer[i]);
72 }
73 }
74 }
75
76 Index_ sparse(
77 const bool,
78 const Index_,
81 OutputValue_* const value_buffer,
82 Index_* const index_buffer,
83 const bool needs_value,
84 const bool needs_index)
85 const {
86 // Technically, MULTIPLY could skip processing if either is a zero.
87 // However, this is not correct if the other value is an NaN/Inf, as
88 // the product would be a NaN, not a zero; so we have to err on the
89 // side of caution of attemping the operation.
90 constexpr bool must_have_both = (op_ == ArithmeticOperation::MULTIPLY &&
91 !std::numeric_limits<InputValue_>::has_quiet_NaN &&
92 !std::numeric_limits<InputValue_>::has_infinity);
93
94 return delayed_binary_isometric_sparse_operation<must_have_both>(
95 left,
96 right,
97 value_buffer,
98 index_buffer,
99 needs_value,
100 needs_index,
101 [](InputValue_ l, InputValue_ r) -> auto {
102 return delayed_arithmetic<op_, true>(l, r);
103 }
104 );
105 }
106
107public:
108 OutputValue_ fill(const bool, const Index_) const {
109 if constexpr(has_unsafe_divide_by_zero<op_, true, InputValue_, InputValue_>()) {
110 throw std::runtime_error("division by zero is not supported");
111 return 0;
112 } else {
113 return delayed_arithmetic<op_, true, InputValue_, InputValue_>(0, 0);
114 }
115 }
116
117 bool is_sparse() const {
118 return (
119 op_ == ArithmeticOperation::ADD ||
120 op_ == ArithmeticOperation::SUBTRACT ||
121 op_ == ArithmeticOperation::MULTIPLY
122 );
123 }
124
125public:
126 std::optional<Index_> nrow() const {
127 return std::nullopt;
128 }
129
130 std::optional<Index_> ncol() const {
131 return std::nullopt;
132 }
133};
134
142template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
144
152template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
154
162template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
164
172template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
174
182template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
184
192template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
194
202template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
204
208// Provided for back-compatibility only.
209template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
210std::shared_ptr<DelayedBinaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedBinaryIsometricAdd() {
211 return std::make_shared<DelayedBinaryIsometricAddHelper<OutputValue_, InputValue_, Index_> >();
212}
213
214template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
215std::shared_ptr<DelayedBinaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedBinaryIsometricSubtract() {
216 return std::make_shared<DelayedBinaryIsometricSubtractHelper<OutputValue_, InputValue_, Index_> >();
217}
218
219template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
220std::shared_ptr<DelayedBinaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedBinaryIsometricMultiply() {
221 return std::make_shared<DelayedBinaryIsometricMultiplyHelper<OutputValue_, InputValue_, Index_> >();
222}
223
224template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
225std::shared_ptr<DelayedBinaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedBinaryIsometricDivide() {
226 return std::make_shared<DelayedBinaryIsometricDivideHelper<OutputValue_, InputValue_, Index_> >();
227}
228
229template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
230std::shared_ptr<DelayedBinaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedBinaryIsometricPower() {
231 return std::make_shared<DelayedBinaryIsometricPowerHelper<OutputValue_, InputValue_, Index_> >();
232}
233
234template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
235std::shared_ptr<DelayedBinaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedBinaryIsometricModulo() {
236 return std::make_shared<DelayedBinaryIsometricModuloHelper<OutputValue_, InputValue_, Index_> >();
237}
238
239template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
240std::shared_ptr<DelayedBinaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedBinaryIsometricIntegerDivide() {
241 return std::make_shared<DelayedBinaryIsometricIntegerDivideHelper<OutputValue_, InputValue_, Index_> >();
242}
247}
248
249#endif
Utilities for delayed arithmetic operations.
Interface for tatami::DelayedBinaryIsometricOperation helpers.
Helper for delayed binary isometric arithmetic.
Definition arithmetic_helpers.hpp:30
bool zero_depends_on_column() const
Definition arithmetic_helpers.hpp:33
std::optional< Index_ > nrow() const
Definition arithmetic_helpers.hpp:126
bool zero_depends_on_row() const
Definition arithmetic_helpers.hpp:32
bool non_zero_depends_on_row() const
Definition arithmetic_helpers.hpp:34
void dense(const bool, const Index_, const std::vector< Index_ > &indices, const InputValue_ *const left_buffer, const InputValue_ *const right_buffer, OutputValue_ *const output_buffer) const
Definition arithmetic_helpers.hpp:57
Index_ sparse(const bool, const Index_, const SparseRange< InputValue_, Index_ > &left, const SparseRange< InputValue_, Index_ > &right, OutputValue_ *const value_buffer, Index_ *const index_buffer, const bool needs_value, const bool needs_index) const
Definition arithmetic_helpers.hpp:76
bool is_sparse() const
Definition arithmetic_helpers.hpp:117
void dense(const bool, const Index_, const Index_, const Index_ length, const InputValue_ *const left_buffer, const InputValue_ *const right_buffer, OutputValue_ *const output_buffer) const
Definition arithmetic_helpers.hpp:38
bool non_zero_depends_on_column() const
Definition arithmetic_helpers.hpp:35
OutputValue_ fill(const bool, const Index_) const
Definition arithmetic_helpers.hpp:108
std::optional< Index_ > ncol() const
Definition arithmetic_helpers.hpp:130
Helper operation interface for DelayedBinaryIsometricOperation.
Definition helper_interface.hpp:26
Flexible representations for matrix data.
Definition Extractor.hpp:15
A range of a sparse vector.
Definition SparseRange.hpp:32