tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
compare_helpers.hpp
Go to the documentation of this file.
1#ifndef TATAMI_ISOMETRIC_UNARY_COMPARE_HELPERS_H
2#define TATAMI_ISOMETRIC_UNARY_COMPARE_HELPERS_H
3
6#include <vector>
7#include <type_traits>
8
15namespace tatami {
16
20template<CompareOperation op_, typename InputValue_, typename Index_, typename Scalar_, typename OutputValue_>
21void delayed_compare_run_simple(const InputValue_* input, Index_ length, Scalar_ scalar, OutputValue_* output) {
22 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
23 input = output; // basically an assertion to the compiler to enable optimizations.
24 }
25 for (Index_ i = 0; i < length; ++i) {
26 output[i] = delayed_compare<op_>(input[i], scalar);
27 }
28}
29
30template<CompareOperation op_, typename InputValue_, typename Scalar_>
31bool delayed_compare_actual_sparse(Scalar_ scalar) {
32 return !delayed_compare<op_, InputValue_>(0, scalar);
33}
50template<CompareOperation op_, typename OutputValue_, typename InputValue_, typename Index_, typename Scalar_>
51class DelayedUnaryIsometricCompareScalarHelper final : public DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> {
52public:
57 DelayedUnaryIsometricCompareScalarHelper(Scalar_ scalar) : my_scalar(scalar) {
58 my_sparse = delayed_compare_actual_sparse<op_, InputValue_>(my_scalar);
59 }
60
61private:
62 Scalar_ my_scalar;
63 bool my_sparse;
64
65public:
66 std::optional<Index_> nrow() const {
67 return std::nullopt;
68 }
69
70 std::optional<Index_> ncol() const {
71 return std::nullopt;
72 }
73
74public:
75 bool zero_depends_on_row() const {
76 return false;
77 }
78
80 return false;
81 }
82
84 return false;
85 }
86
88 return false;
89 }
90
91public:
92 void dense(bool, Index_, Index_, Index_ length, const InputValue_* input, OutputValue_* output) const {
93 delayed_compare_run_simple<op_>(input, length, my_scalar, output);
94 }
95
96 void dense(bool, Index_, const std::vector<Index_>& indices, const InputValue_* input, OutputValue_* output) const {
97 delayed_compare_run_simple<op_>(input, static_cast<Index_>(indices.size()), my_scalar, output);
98 }
99
100public:
101 bool is_sparse() const {
102 return my_sparse;
103 }
104
105 void sparse(bool, Index_, Index_ number, const InputValue_* input_value, const Index_*, OutputValue_* output_value) const {
106 delayed_compare_run_simple<op_>(input_value, number, my_scalar, output_value);
107 }
108
109 OutputValue_ fill(bool, Index_) const {
110 return delayed_compare<op_, InputValue_>(0, my_scalar);
111 }
112};
113
122template<typename OutputValue_, typename InputValue_, typename Index_, typename Scalar_>
124
133template<typename OutputValue_, typename InputValue_, typename Index_, typename Scalar_>
135
144template<typename OutputValue_, typename InputValue_, typename Index_, typename Scalar_>
146
155template<typename OutputValue_, typename InputValue_, typename Index_, typename Scalar_>
157
166template<typename OutputValue_, typename InputValue_, typename Index_, typename Scalar_>
168
177template<typename OutputValue_, typename InputValue_, typename Index_, typename Scalar_>
179
183// Back-compatibility only.
184template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Scalar_>
185std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricEqualScalar(Scalar_ scalar) {
186 return std::make_shared<DelayedUnaryIsometricEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
187}
188
189template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Scalar_>
190std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricGreaterThanScalar(Scalar_ scalar) {
191 return std::make_shared<DelayedUnaryIsometricGreaterThanScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
192}
193
194template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Scalar_>
195std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricLessThanScalar(Scalar_ scalar) {
196 return std::make_shared<DelayedUnaryIsometricLessThanScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
197}
198
199template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Scalar_>
200std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricGreaterThanOrEqualScalar(Scalar_ scalar) {
201 return std::make_shared<DelayedUnaryIsometricGreaterThanOrEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
202}
203
204template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Scalar_>
205std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricLessThanOrEqualScalar(Scalar_ scalar) {
206 return std::make_shared<DelayedUnaryIsometricLessThanOrEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
207}
208
209template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Scalar_>
210std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricNotEqualScalar(Scalar_ scalar) {
211 return std::make_shared<DelayedUnaryIsometricNotEqualScalarHelper<OutputValue_, InputValue_, Index_, Scalar_> >(std::move(scalar));
212}
229template<CompareOperation op_, typename OutputValue_, typename InputValue_, typename Index_, typename Vector_>
230class DelayedUnaryIsometricCompareVectorHelper final : public DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> {
231public:
240 DelayedUnaryIsometricCompareVectorHelper(Vector_ vector, bool by_row) :
241 my_vector(std::move(vector)),
242 my_by_row(by_row)
243 {
244 for (auto x : my_vector) {
245 if (!delayed_compare_actual_sparse<op_, InputValue_>(x)) {
246 my_sparse = false;
247 break;
248 }
249 }
250 }
251
252private:
253 Vector_ my_vector;
254 bool my_by_row;
255 bool my_sparse = true;
256
257public:
258 std::optional<Index_> nrow() const {
259 if (my_by_row) {
260 return my_vector.size();
261 } else {
262 return std::nullopt;
263 }
264 }
265
266 std::optional<Index_> ncol() const {
267 if (my_by_row) {
268 return std::nullopt;
269 } else {
270 return my_vector.size();
271 }
272 }
273
274public:
275 bool zero_depends_on_row() const {
276 return my_by_row;
277 }
278
280 return !my_by_row;
281 }
282
284 return my_by_row;
285 }
286
288 return !my_by_row;
289 }
290
291public:
292 void dense(bool row, Index_ idx, Index_ start, Index_ length, const InputValue_* input, OutputValue_* output) const {
293 if (row == my_by_row) {
294 delayed_compare_run_simple<op_, InputValue_>(input, length, my_vector[idx], output);
295 } else {
296 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
297 input = output; // basically an assertion to the compiler to enable optimizations.
298 }
299 for (Index_ i = 0; i < length; ++i) {
300 output[i] = delayed_compare<op_, InputValue_>(input[i], my_vector[i + start]);
301 }
302 }
303 }
304
305 void dense(bool row, Index_ idx, const std::vector<Index_>& indices, const InputValue_* input, OutputValue_* output) const {
306 if (row == my_by_row) {
307 delayed_compare_run_simple<op_, InputValue_>(input, static_cast<Index_>(indices.size()), my_vector[idx], output);
308 } else {
309 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
310 input = output; // basically an assertion to the compiler to enable optimizations.
311 }
312 Index_ length = indices.size();
313 for (Index_ i = 0; i < length; ++i) {
314 output[i] = delayed_compare<op_, InputValue_>(input[i], my_vector[indices[i]]);
315 }
316 }
317 }
318
319public:
320 bool is_sparse() const {
321 return my_sparse;
322 }
323
324 void sparse(bool row, Index_ idx, Index_ number, const InputValue_* input_value, const Index_* indices, OutputValue_* output_value) const {
325 if (row == my_by_row) {
326 delayed_compare_run_simple<op_, InputValue_>(input_value, number, my_vector[idx], output_value);
327 } else {
328 if constexpr(std::is_same<InputValue_, OutputValue_>::value) {
329 input_value = output_value; // basically an assertion to the compiler to enable optimizations.
330 }
331 for (Index_ i = 0; i < number; ++i) {
332 output_value[i] = delayed_compare<op_, InputValue_>(input_value[i], my_vector[indices[i]]);
333 }
334 }
335 }
336
337 OutputValue_ fill(bool row, Index_ idx) const {
338 if (row == my_by_row) {
339 return delayed_compare<op_, InputValue_>(0, my_vector[idx]);
340 } else {
341 // We should only get to this point if it's sparse, otherwise no
342 // single fill value would work across the length of my_vector.
343 return 0;
344 }
345 }
346};
347
356template<typename OutputValue_, typename InputValue_, typename Index_, typename Vector_>
358
367template<typename OutputValue_, typename InputValue_, typename Index_, typename Vector_>
369
378template<typename OutputValue_, typename InputValue_, typename Index_, typename Vector_>
380
389template<typename OutputValue_, typename InputValue_, typename Index_, typename Vector_>
391
400template<typename OutputValue_, typename InputValue_, typename Index_, typename Vector_>
402
411template<typename OutputValue_, typename InputValue_, typename Index_, typename Vector_>
413
417// Back-compatibility only.
418template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Vector_>
419std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricEqualVector(Vector_ vector, bool by_row) {
420 return std::make_shared<DelayedUnaryIsometricEqualVectorHelper<OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
421}
422
423template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Vector_>
424std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricGreaterThanVector(Vector_ vector, bool by_row) {
425 return std::make_shared<DelayedUnaryIsometricGreaterThanVectorHelper<OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
426}
427
428template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Vector_>
429std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricLessThanVector(Vector_ vector, bool by_row) {
430 return std::make_shared<DelayedUnaryIsometricLessThanVectorHelper<OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
431}
432
433template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Vector_>
434std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricGreaterThanOrEqualVector(Vector_ vector, bool by_row) {
435 return std::make_shared<DelayedUnaryIsometricGreaterThanOrEqualVectorHelper<OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
436}
437
438template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Vector_>
439std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricLessThanOrEqualVector(Vector_ vector, bool by_row) {
440 return std::make_shared<DelayedUnaryIsometricLessThanOrEqualVectorHelper<OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
441}
442
443template<typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int, typename Vector_>
444std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricNotEqualVector(Vector_ vector, bool by_row) {
445 return std::make_shared<DelayedUnaryIsometricNotEqualVectorHelper<OutputValue_, InputValue_, Index_, Vector_> >(std::move(vector), by_row);
446}
454template<SpecialCompareOperation op_, bool pass_, typename InputValue_, typename Index_, typename OutputValue_>
455void delayed_special_compare_run_simple(const InputValue_* input, Index_ length, OutputValue_* output) {
456 for (Index_ i = 0; i < length; ++i) {
457 output[i] = delayed_special_compare<op_, pass_, InputValue_>(input[i]);
458 }
459}
460
461template<SpecialCompareOperation op_, bool pass_, typename InputValue_>
462bool delayed_special_compare_actual_sparse() {
463 return !delayed_special_compare<op_, pass_, InputValue_>(0);
464}
481template<SpecialCompareOperation op_, bool pass_, typename OutputValue_, typename InputValue_, typename Index_>
482class DelayedUnaryIsometricSpecialCompareHelper final : public DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> {
483public:
488 my_sparse = !delayed_special_compare<op_, pass_, InputValue_>(0);
489 }
490
491private:
492 bool my_sparse;
493
494public:
495 std::optional<Index_> nrow() const {
496 return std::nullopt;
497 }
498
499 std::optional<Index_> ncol() const {
500 return std::nullopt;
501 }
502
503public:
504 bool zero_depends_on_row() const {
505 return false;
506 }
507
509 return false;
510 }
511
513 return false;
514 }
515
517 return false;
518 }
519
520public:
521 void dense(bool, Index_, Index_, Index_ length, const InputValue_* input, OutputValue_* output) const {
522 delayed_special_compare_run_simple<op_, pass_>(input, length, output);
523 }
524
525 void dense(bool, Index_, const std::vector<Index_>& indices, const InputValue_* input, OutputValue_* output) const {
526 delayed_special_compare_run_simple<op_, pass_>(input, static_cast<Index_>(indices.size()), output);
527 }
528
529public:
530 bool is_sparse() const {
531 return my_sparse;
532 }
533
534 void sparse(bool, Index_, Index_ number, const InputValue_* input_value, const Index_*, OutputValue_* output_value) const {
535 delayed_special_compare_run_simple<op_, pass_>(input_value, number, output_value);
536 }
537
538 OutputValue_ fill(bool, Index_) const {
539 return !my_sparse;
540 }
541};
542
551template<bool pass_, typename OutputValue_, typename InputValue_, typename Index_>
553
562template<bool pass_, typename OutputValue_, typename InputValue_, typename Index_>
564
573template<bool pass_, typename OutputValue_, typename InputValue_, typename Index_>
575
579// Back-compatibility only.
580template<bool pass_ = true, typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
581std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricIsnan() {
582 return std::make_shared<DelayedUnaryIsometricIsnanHelper<pass_, OutputValue_, InputValue_, Index_> >();
583}
584
585template<bool pass_ = true, typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
586std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricIsinf() {
587 return std::make_shared<DelayedUnaryIsometricIsinfHelper<pass_, OutputValue_, InputValue_, Index_> >();
588}
589
590template<bool pass_ = true, typename OutputValue_ = double, typename InputValue_ = double, typename Index_ = int>
591std::shared_ptr<DelayedUnaryIsometricOperationHelper<OutputValue_, InputValue_, Index_> > make_DelayedUnaryIsometricIsfinite() {
592 return std::make_shared<DelayedUnaryIsometricIsfiniteHelper<pass_, OutputValue_, InputValue_, Index_> >();
593}
598}
599
600#endif
Helper for delayed scalar comparisons.
Definition compare_helpers.hpp:51
bool zero_depends_on_row() const
Definition compare_helpers.hpp:75
void dense(bool, Index_, Index_, Index_ length, const InputValue_ *input, OutputValue_ *output) const
Definition compare_helpers.hpp:92
void sparse(bool, Index_, Index_ number, const InputValue_ *input_value, const Index_ *, OutputValue_ *output_value) const
Definition compare_helpers.hpp:105
DelayedUnaryIsometricCompareScalarHelper(Scalar_ scalar)
Definition compare_helpers.hpp:57
std::optional< Index_ > ncol() const
Definition compare_helpers.hpp:70
bool zero_depends_on_column() const
Definition compare_helpers.hpp:79
void dense(bool, Index_, const std::vector< Index_ > &indices, const InputValue_ *input, OutputValue_ *output) const
Definition compare_helpers.hpp:96
bool is_sparse() const
Definition compare_helpers.hpp:101
bool non_zero_depends_on_row() const
Definition compare_helpers.hpp:83
std::optional< Index_ > nrow() const
Definition compare_helpers.hpp:66
OutputValue_ fill(bool, Index_) const
Definition compare_helpers.hpp:109
bool non_zero_depends_on_column() const
Definition compare_helpers.hpp:87
Helper for delayed vector comparisons.
Definition compare_helpers.hpp:230
bool zero_depends_on_column() const
Definition compare_helpers.hpp:279
bool is_sparse() const
Definition compare_helpers.hpp:320
std::optional< Index_ > nrow() const
Definition compare_helpers.hpp:258
void sparse(bool row, Index_ idx, Index_ number, const InputValue_ *input_value, const Index_ *indices, OutputValue_ *output_value) const
Definition compare_helpers.hpp:324
bool non_zero_depends_on_column() const
Definition compare_helpers.hpp:287
bool zero_depends_on_row() const
Definition compare_helpers.hpp:275
void dense(bool row, Index_ idx, Index_ start, Index_ length, const InputValue_ *input, OutputValue_ *output) const
Definition compare_helpers.hpp:292
void dense(bool row, Index_ idx, const std::vector< Index_ > &indices, const InputValue_ *input, OutputValue_ *output) const
Definition compare_helpers.hpp:305
OutputValue_ fill(bool row, Index_ idx) const
Definition compare_helpers.hpp:337
bool non_zero_depends_on_row() const
Definition compare_helpers.hpp:283
std::optional< Index_ > ncol() const
Definition compare_helpers.hpp:266
DelayedUnaryIsometricCompareVectorHelper(Vector_ vector, bool by_row)
Definition compare_helpers.hpp:240
Helper operation interface for DelayedUnaryIsometricOperation.
Definition helper_interface.hpp:27
Delayed special value comparison.
Definition compare_helpers.hpp:482
std::optional< Index_ > ncol() const
Definition compare_helpers.hpp:499
bool non_zero_depends_on_column() const
Definition compare_helpers.hpp:516
bool is_sparse() const
Definition compare_helpers.hpp:530
void dense(bool, Index_, const std::vector< Index_ > &indices, const InputValue_ *input, OutputValue_ *output) const
Definition compare_helpers.hpp:525
bool zero_depends_on_row() const
Definition compare_helpers.hpp:504
bool zero_depends_on_column() const
Definition compare_helpers.hpp:508
bool non_zero_depends_on_row() const
Definition compare_helpers.hpp:512
void dense(bool, Index_, Index_, Index_ length, const InputValue_ *input, OutputValue_ *output) const
Definition compare_helpers.hpp:521
DelayedUnaryIsometricSpecialCompareHelper()
Definition compare_helpers.hpp:487
void sparse(bool, Index_, Index_ number, const InputValue_ *input_value, const Index_ *, OutputValue_ *output_value) const
Definition compare_helpers.hpp:534
OutputValue_ fill(bool, Index_) const
Definition compare_helpers.hpp:538
std::optional< Index_ > nrow() const
Definition compare_helpers.hpp:495
Utilities for delayed comparison operations.
Flexible representations for matrix data.
Definition Extractor.hpp:15
Interface for tatami::DelayedUnaryIsometricOperation helpers.