tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
substitute_helpers.hpp
Go to the documentation of this file.
1#ifndef TATAMI_ISOMETRIC_UNARY_SUBSTITUTE_HELPERS_H
2#define TATAMI_ISOMETRIC_UNARY_SUBSTITUTE_HELPERS_H
3
5#include <vector>
6#include <limits>
7
14namespace tatami {
15
19template<CompareOperation op_, typename Value_>
20bool delayed_substitute_is_sparse(Value_ compared, Value_ substitute) {
21 return !delayed_compare<op_, Value_>(0, compared) || substitute == 0;
22}
23
24template<CompareOperation op_, typename Value_>
25void delayed_substitute_run(Value_& val, Value_ compared, Value_ substitute) {
26 if (delayed_compare<op_, Value_>(val, compared)) {
27 val = substitute;
28 }
29}
30
31template<CompareOperation op_, typename Value_, typename Index_>
32void delayed_substitute_run_simple(Value_* buffer, Index_ length, Value_ compared, Value_ substitute) {
33 for (Index_ i = 0; i < length; ++i) {
34 delayed_substitute_run<op_, Value_>(buffer[i], compared, substitute);
35 }
36}
52template<CompareOperation op_, typename Value_>
54public:
60 DelayedUnaryIsometricSubstituteScalar(Value_ compared, Value_ substitute) : my_compared(compared), my_substitute(substitute) {
61 my_sparse = delayed_substitute_is_sparse<op_, Value_>(my_compared, my_substitute);
62 }
63
64private:
65 Value_ my_compared, my_substitute;
66 bool my_sparse;
67
68public:
72 static constexpr bool is_basic = false;
73
74 bool is_sparse() const {
75 return my_sparse;
76 }
81public:
85 template<typename Index_>
86 void dense(bool, Index_, Index_, Index_ length, const Value_*, Value_* output) const {
87 delayed_substitute_run_simple<op_, Value_>(output, length, my_compared, my_substitute);
88 }
89
90 template<typename Index_>
91 void dense(bool, Index_, const std::vector<Index_>& indices, const Value_*, Value_* output) const {
92 delayed_substitute_run_simple<op_, Value_>(output, static_cast<Index_>(indices.size()), my_compared, my_substitute);
93 }
94
95 template<typename Index_>
96 void sparse(bool, Index_, Index_ number, const Value_*, const Index_*, Value_* output_value) const {
97 delayed_substitute_run_simple<op_, Value_>(output_value, number, my_compared, my_substitute);
98 }
99
100 template<typename, typename, typename Index_>
101 Value_ fill(bool, Index_) const {
102 if (my_sparse) {
103 return 0;
104 } else {
105 return my_substitute;
106 }
107 }
111};
112
124template<CompareOperation op_, typename Value_, typename Vector_>
126public:
137 DelayedUnaryIsometricSubstituteVector(Vector_ compared, Vector_ substitute, bool by_row) :
138 my_compared(std::move(compared)), my_substitute(std::move(substitute)), my_by_row(by_row)
139 {
140 for (size_t i = 0, end = my_compared.size(); i < end; ++i) {
141 if (!delayed_substitute_is_sparse<op_, Value_>(my_compared[i], my_substitute[i])) {
142 my_sparse = false;
143 break;
144 }
145 }
146 }
147
148private:
149 Vector_ my_compared, my_substitute;
150 bool my_by_row;
151 bool my_sparse = true;
152
153public:
157 static constexpr bool is_basic = false;
158
159 bool zero_depends_on_row() const {
160 return my_by_row;
161 }
162
163 bool zero_depends_on_column() const {
164 return !my_by_row;
165 }
166
167 bool non_zero_depends_on_row() const {
168 return my_by_row;
169 }
170
171 bool non_zero_depends_on_column() const {
172 return !my_by_row;
173 }
174
175 bool is_sparse() const {
176 return my_sparse;
177 }
182public:
186 template<typename Index_>
187 void dense(bool row, Index_ idx, Index_ start, Index_ length, const Value_*, Value_* output) const {
188 if (row == my_by_row) {
189 delayed_substitute_run_simple<op_, Value_>(output, length, my_compared[idx], my_substitute[idx]);
190 } else {
191 for (Index_ i = 0; i < length; ++i) {
192 Index_ is = i + start;
193 delayed_substitute_run<op_, Value_>(output[i], my_compared[is], my_substitute[is]);
194 }
195 }
196 }
197
198 template<typename Index_>
199 void dense(bool row, Index_ idx, const std::vector<Index_>& indices, const Value_*, Value_* output) const {
200 if (row == my_by_row) {
201 delayed_substitute_run_simple<op_, Value_>(output, static_cast<Index_>(indices.size()), my_compared[idx], my_substitute[idx]);
202 } else {
203 Index_ length = indices.size();
204 for (Index_ i = 0; i < length; ++i) {
205 auto ii = indices[i];
206 delayed_substitute_run<op_, Value_>(output[i], my_compared[ii], my_substitute[ii]);
207 }
208 }
209 }
210
211 template<typename Index_>
212 void sparse(bool row, Index_ idx, Index_ number, const Value_*, const Index_* indices, Value_* output_value) const {
213 if (row == my_by_row) {
214 delayed_substitute_run_simple<op_, Value_>(output_value, number, my_compared[idx], my_substitute[idx]);
215 } else {
216 for (Index_ i = 0; i < number; ++i) {
217 auto ii = indices[i];
218 delayed_substitute_run<op_, Value_>(output_value[i], my_compared[ii], my_substitute[ii]);
219 }
220 }
221 }
222
223 template<typename, typename, typename Index_>
224 Value_ fill(bool row, Index_ idx) const {
225 if (row == my_by_row) {
226 auto sub = my_substitute[idx];
227 if (!delayed_compare<op_, Value_>(0, my_compared[idx])) {
228 return 0;
229 } else {
230 return sub;
231 }
232 } else {
233 // We should only get to this point if it's sparse, otherwise no
234 // single fill value would work across the length of my_compared.
235 return 0;
236 }
237 }
241};
242
250template<typename Value_ = double>
251DelayedUnaryIsometricSubstituteScalar<CompareOperation::EQUAL, Value_>
252 make_DelayedUnaryIsometricSubstituteEqualScalar(Value_ compared, Value_ substitute)
253{
254 return DelayedUnaryIsometricSubstituteScalar<CompareOperation::EQUAL, Value_>(std::move(compared), std::move(substitute));
255}
256
264template<typename Value_ = double>
265DelayedUnaryIsometricSubstituteScalar<CompareOperation::GREATER_THAN, Value_>
267{
268 return DelayedUnaryIsometricSubstituteScalar<CompareOperation::GREATER_THAN, Value_>(std::move(compared), std::move(substitute));
269}
270
278template<typename Value_ = double>
279DelayedUnaryIsometricSubstituteScalar<CompareOperation::LESS_THAN, Value_>
280 make_DelayedUnaryIsometricSubstituteLessThanScalar(Value_ compared, Value_ substitute)
281{
282 return DelayedUnaryIsometricSubstituteScalar<CompareOperation::LESS_THAN, Value_>(std::move(compared), std::move(substitute));
283}
284
292template<typename Value_ = double>
293DelayedUnaryIsometricSubstituteScalar<CompareOperation::GREATER_THAN_OR_EQUAL, Value_>
295{
297}
298
306template<typename Value_ = double>
307DelayedUnaryIsometricSubstituteScalar<CompareOperation::LESS_THAN_OR_EQUAL, Value_>
309{
310 return DelayedUnaryIsometricSubstituteScalar<CompareOperation::LESS_THAN_OR_EQUAL, Value_>(std::move(compared), std::move(substitute));
311}
312
320template<typename Value_ = double>
321DelayedUnaryIsometricSubstituteScalar<CompareOperation::NOT_EQUAL, Value_>
322 make_DelayedUnaryIsometricSubstituteNotEqualScalar(Value_ compared, Value_ substitute)
323{
324 return DelayedUnaryIsometricSubstituteScalar<CompareOperation::NOT_EQUAL, Value_>(std::move(compared), std::move(substitute));
325}
326
336template<typename Value_ = double, typename Vector_ = std::vector<Value_> >
337DelayedUnaryIsometricSubstituteVector<CompareOperation::EQUAL, Value_, Vector_>
338 make_DelayedUnaryIsometricSubstituteEqualVector(Vector_ compared, Vector_ substitute, bool by_row)
339{
340 return DelayedUnaryIsometricSubstituteVector<CompareOperation::EQUAL, Value_, Vector_>(std::move(compared), std::move(substitute), by_row);
341}
342
352template<typename Value_ = double, typename Vector_ = std::vector<Value_> >
353DelayedUnaryIsometricSubstituteVector<CompareOperation::GREATER_THAN, Value_, Vector_>
354 make_DelayedUnaryIsometricSubstituteGreaterThanVector(Vector_ compared, Vector_ substitute, bool by_row)
355{
356 return DelayedUnaryIsometricSubstituteVector<CompareOperation::GREATER_THAN, Value_, Vector_>(std::move(compared), std::move(substitute), by_row);
357}
358
368template<typename Value_ = double, typename Vector_ = std::vector<Value_> >
369DelayedUnaryIsometricSubstituteVector<CompareOperation::LESS_THAN, Value_, Vector_>
370 make_DelayedUnaryIsometricSubstituteLessThanVector(Vector_ compared, Vector_ substitute, bool by_row)
371{
372 return DelayedUnaryIsometricSubstituteVector<CompareOperation::LESS_THAN, Value_, Vector_>(std::move(compared), std::move(substitute), by_row);
373}
374
384template<typename Value_ = double, typename Vector_ = std::vector<Value_> >
385DelayedUnaryIsometricSubstituteVector<CompareOperation::GREATER_THAN_OR_EQUAL, Value_, Vector_>
386 make_DelayedUnaryIsometricSubstituteGreaterThanOrEqualVector(Vector_ compared, Vector_ substitute, bool by_row)
387{
388 return DelayedUnaryIsometricSubstituteVector<CompareOperation::GREATER_THAN_OR_EQUAL, Value_, Vector_>(std::move(compared), std::move(substitute), by_row);
389}
390
400template<typename Value_ = double, typename Vector_ = std::vector<Value_> >
401DelayedUnaryIsometricSubstituteVector<CompareOperation::LESS_THAN_OR_EQUAL, Value_, Vector_>
402 make_DelayedUnaryIsometricSubstituteLessThanOrEqualVector(Vector_ compared, Vector_ substitute, bool by_row)
403{
404 return DelayedUnaryIsometricSubstituteVector<CompareOperation::LESS_THAN_OR_EQUAL, Value_, Vector_>(std::move(compared), std::move(substitute), by_row);
405}
406
416template<typename Value_ = double, typename Vector_ = std::vector<Value_> >
417DelayedUnaryIsometricSubstituteVector<CompareOperation::NOT_EQUAL, Value_, Vector_>
418 make_DelayedUnaryIsometricSubstituteNotEqualVector(Vector_ compared, Vector_ substitute, bool by_row)
419{
420 return DelayedUnaryIsometricSubstituteVector<CompareOperation::NOT_EQUAL, Value_, Vector_>(std::move(compared), std::move(substitute), by_row);
421}
422
426template<SpecialCompareOperation op_, bool pass_, typename Value_>
427bool delayed_special_substitute_is_sparse(Value_ substitute) {
428 return !delayed_special_compare<op_, pass_, Value_>(0) || substitute == 0;
429}
430
431template<SpecialCompareOperation op_, bool pass_, typename Value_>
432void delayed_special_substitute_run(Value_& val, Value_ substitute) {
433 if (delayed_special_compare<op_, pass_, Value_>(val)) {
434 val = substitute;
435 }
436}
437
438template<SpecialCompareOperation op_, bool pass_, typename Value_, typename Index_>
439void delayed_special_substitute_run_simple(Value_* buffer, Index_ length, Value_ substitute) {
440 for (Index_ i = 0; i < length; ++i) {
441 delayed_special_substitute_run<op_, pass_, Value_>(buffer[i], substitute);
442 }
443}
459template<SpecialCompareOperation op_, bool pass_, typename Value_>
461public:
465 DelayedUnaryIsometricSpecialSubstitute(Value_ substitute) : my_substitute(substitute) {
466 my_sparse = delayed_special_substitute_is_sparse<op_, pass_, Value_>(my_substitute);
467 }
468
469private:
470 Value_ my_substitute;
471 bool my_sparse;
472
473public:
477 static constexpr bool is_basic = false;
478
479 bool is_sparse() const {
480 return my_sparse;
481 }
486public:
490 template<typename Index_>
491 void dense(bool, Index_, Index_, Index_ length, const Value_*, Value_* output) const {
492 delayed_special_substitute_run_simple<op_, pass_, Value_>(output, length, my_substitute);
493 }
494
495 template<typename Index_>
496 void dense(bool, Index_, const std::vector<Index_>& indices, const Value_*, Value_* output) const {
497 delayed_special_substitute_run_simple<op_, pass_, Value_>(output, static_cast<Index_>(indices.size()), my_substitute);
498 }
499
500 template<typename Index_>
501 void sparse(bool, Index_, Index_ number, const Value_*, const Index_*, Value_* output_value) const {
502 delayed_special_substitute_run_simple<op_, pass_, Value_>(output_value, number, my_substitute);
503 }
504
505 template<typename, typename, typename Index_>
506 Value_ fill(bool, Index_) const {
507 if (my_sparse) {
508 return 0;
509 } else {
510 return my_substitute;
511 }
512 }
516};
517
525template<bool pass_ = true, typename Value_ = double>
529
537template<bool pass_ = true, typename Value_ = double>
541
549template<bool pass_ = true, typename Value_ = double>
553
554}
555
556#endif
Delayed special value substitution.
Definition substitute_helpers.hpp:460
DelayedUnaryIsometricSpecialSubstitute(Value_ substitute)
Definition substitute_helpers.hpp:465
Delayed scalar substitution.
Definition substitute_helpers.hpp:53
DelayedUnaryIsometricSubstituteScalar(Value_ compared, Value_ substitute)
Definition substitute_helpers.hpp:60
Delayed vector comparisons.
Definition substitute_helpers.hpp:125
DelayedUnaryIsometricSubstituteVector(Vector_ compared, Vector_ substitute, bool by_row)
Definition substitute_helpers.hpp:137
Utilities for delayed comparison operations.
Flexible representations for matrix data.
Definition Extractor.hpp:15
DelayedUnaryIsometricSubstituteScalar< CompareOperation::LESS_THAN, Value_ > make_DelayedUnaryIsometricSubstituteLessThanScalar(Value_ compared, Value_ substitute)
Definition substitute_helpers.hpp:280
DelayedUnaryIsometricSubstituteVector< CompareOperation::LESS_THAN, Value_, Vector_ > make_DelayedUnaryIsometricSubstituteLessThanVector(Vector_ compared, Vector_ substitute, bool by_row)
Definition substitute_helpers.hpp:370
DelayedUnaryIsometricSubstituteVector< CompareOperation::LESS_THAN_OR_EQUAL, Value_, Vector_ > make_DelayedUnaryIsometricSubstituteLessThanOrEqualVector(Vector_ compared, Vector_ substitute, bool by_row)
Definition substitute_helpers.hpp:402
DelayedUnaryIsometricSubstituteScalar< CompareOperation::EQUAL, Value_ > make_DelayedUnaryIsometricSubstituteEqualScalar(Value_ compared, Value_ substitute)
Definition substitute_helpers.hpp:252
DelayedUnaryIsometricSubstituteScalar< CompareOperation::GREATER_THAN, Value_ > make_DelayedUnaryIsometricSubstituteGreaterThanScalar(Value_ compared, Value_ substitute)
Definition substitute_helpers.hpp:266
DelayedUnaryIsometricSpecialSubstitute< SpecialCompareOperation::ISNAN, pass_, Value_ > make_DelayedUnaryIsometricSubstituteIsnan(Value_ substitute)
Definition substitute_helpers.hpp:526
DelayedUnaryIsometricSubstituteScalar< CompareOperation::NOT_EQUAL, Value_ > make_DelayedUnaryIsometricSubstituteNotEqualScalar(Value_ compared, Value_ substitute)
Definition substitute_helpers.hpp:322
DelayedUnaryIsometricSubstituteVector< CompareOperation::GREATER_THAN, Value_, Vector_ > make_DelayedUnaryIsometricSubstituteGreaterThanVector(Vector_ compared, Vector_ substitute, bool by_row)
Definition substitute_helpers.hpp:354
DelayedUnaryIsometricSpecialSubstitute< SpecialCompareOperation::ISFINITE, pass_, Value_ > make_DelayedUnaryIsometricSubstituteIsfinite(Value_ substitute)
Definition substitute_helpers.hpp:550
DelayedUnaryIsometricSubstituteVector< CompareOperation::EQUAL, Value_, Vector_ > make_DelayedUnaryIsometricSubstituteEqualVector(Vector_ compared, Vector_ substitute, bool by_row)
Definition substitute_helpers.hpp:338
DelayedUnaryIsometricSpecialSubstitute< SpecialCompareOperation::ISINF, pass_, Value_ > make_DelayedUnaryIsometricSubstituteIsinf(Value_ substitute)
Definition substitute_helpers.hpp:538
DelayedUnaryIsometricSubstituteScalar< CompareOperation::LESS_THAN_OR_EQUAL, Value_ > make_DelayedUnaryIsometricSubstituteLessThanOrEqualScalar(Value_ compared, Value_ substitute)
Definition substitute_helpers.hpp:308
DelayedUnaryIsometricSubstituteScalar< CompareOperation::GREATER_THAN_OR_EQUAL, Value_ > make_DelayedUnaryIsometricSubstituteGreaterThanOrEqualScalar(Value_ compared, Value_ substitute)
Definition substitute_helpers.hpp:294
DelayedUnaryIsometricSubstituteVector< CompareOperation::NOT_EQUAL, Value_, Vector_ > make_DelayedUnaryIsometricSubstituteNotEqualVector(Vector_ compared, Vector_ substitute, bool by_row)
Definition substitute_helpers.hpp:418
DelayedUnaryIsometricSubstituteVector< CompareOperation::GREATER_THAN_OR_EQUAL, Value_, Vector_ > make_DelayedUnaryIsometricSubstituteGreaterThanOrEqualVector(Vector_ compared, Vector_ substitute, bool by_row)
Definition substitute_helpers.hpp:386