Graph Framework
Loading...
Searching...
No Matches
logical.hpp
Go to the documentation of this file.
1//------------------------------------------------------------------------------
6//------------------------------------------------------------------------------
7#ifndef logical_h
8#define logical_h
9
10#include "node.hpp"
11
13namespace graph {
15 template<jit::float_scalar T, bool SAFE_MATH=false>
19
21 template<jit::float_scalar T, bool SAFE_MATH=false>
25
26//******************************************************************************
27// IsInf node.
28//******************************************************************************
29//------------------------------------------------------------------------------
34//------------------------------------------------------------------------------
35 template<std::floating_point T, bool SAFE_MATH=false>
36 class isinf_node final : public no_derivative<T, SAFE_MATH, straight_node<T, SAFE_MATH>> {
37 private:
38//------------------------------------------------------------------------------
43//------------------------------------------------------------------------------
44 static std::string to_string(leaf_node<T, SAFE_MATH> *arg) {
45 return "isinf" +
46 jit::format_to_string(reinterpret_cast<size_t> (arg));
47 }
48
49 public:
50//------------------------------------------------------------------------------
54//------------------------------------------------------------------------------
59
60//------------------------------------------------------------------------------
66//------------------------------------------------------------------------------
68 backend::buffer<T> arg = this->arg->evaluate();
69 arg.isinf();
70 return arg;
71 }
72
73//------------------------------------------------------------------------------
77//------------------------------------------------------------------------------
79// Constant reductions.
80 auto arg = constant_cast(this->arg);
81
82 if (arg.get()) {
83 return constant<T, SAFE_MATH> (this->evaluate());
84 }
85
86 return this->shared_from_this();
87 }
88
89//------------------------------------------------------------------------------
96//------------------------------------------------------------------------------
98 compile(std::ostringstream &stream,
99 jit::register_map &registers,
101 const jit::register_usage &usage) {
102 if (registers.find(this) == registers.end()) {
103 auto arg = this->arg->compile(stream, registers,
105
106 registers[this] = jit::to_string('l', this);
107 stream << " const bool ";
108 stream << registers[this] << " = isinf("
109 << registers[arg.get()] << ")";
110 this->endline(stream, usage);
111 }
112
113 return this->shared_from_this();
114 }
115
116//------------------------------------------------------------------------------
118//------------------------------------------------------------------------------
119 virtual void to_latex() const {
120 std::cout << "isinf\\left(";
121 this->arg->to_latex();
122 std::cout << "\\right)";
123 }
124
125//------------------------------------------------------------------------------
131//------------------------------------------------------------------------------
132 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
133 jit::register_map &registers) {
134 if (registers.find(this) == registers.end()) {
135 const std::string name = jit::to_string('r', this);
136 registers[this] = name;
137 stream << " " << name
138 << " [label = \"!\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
139
140 auto arg = this->arg->to_vizgraph(stream, registers);
141 stream << " " << name << " -- " << registers[arg.get()] << ";" << std::endl;
142 }
143
144 return this->shared_from_this();
145 }
146 };
147
148//------------------------------------------------------------------------------
155//------------------------------------------------------------------------------
156 template<std::floating_point T, bool SAFE_MATH=false>
158 auto temp = std::make_shared<isinf_node<T, SAFE_MATH>> (arg)->reduce();
159// Test for hash collisions.
160 for (size_t i = temp->get_hash();
162 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
165 return temp;
166 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
168 }
169 }
170#if defined(__clang__) || defined(__GNUC__)
172#else
173 assert(false && "Should never reach.");
174#endif
175 }
176
178 template<std::floating_point T, bool SAFE_MATH=false>
179 using shared_isinf = std::shared_ptr<isinf_node<T, SAFE_MATH>>;
180
181//------------------------------------------------------------------------------
189//------------------------------------------------------------------------------
190 template<std::floating_point T, bool SAFE_MATH=false>
192 return std::dynamic_pointer_cast<isinf_node<T, SAFE_MATH>> (x);
193 }
194
195//******************************************************************************
196// IsNaN node.
197//******************************************************************************
198//------------------------------------------------------------------------------
203//------------------------------------------------------------------------------
204 template<std::floating_point T, bool SAFE_MATH=false>
205 class isnan_node final : public no_derivative<T, SAFE_MATH, straight_node<T, SAFE_MATH>> {
206 private:
207//------------------------------------------------------------------------------
212//------------------------------------------------------------------------------
213 static std::string to_string(leaf_node<T, SAFE_MATH> *arg) {
214 return "isnan" +
215 jit::format_to_string(reinterpret_cast<size_t> (arg));
216 }
217
218 public:
219//------------------------------------------------------------------------------
223//------------------------------------------------------------------------------
226 straight_node<T, SAFE_MATH>> (arg,
227 isnan_node::to_string(arg.get())) {}
228
229//------------------------------------------------------------------------------
235//------------------------------------------------------------------------------
237 backend::buffer<T> arg = this->arg->evaluate();
238 arg.isnan();
239 return arg;
240 }
241
242//------------------------------------------------------------------------------
246//------------------------------------------------------------------------------
248// Constant reductions.
249 auto arg = constant_cast(this->arg);
250
251 if (arg.get()) {
252 return constant<T, SAFE_MATH> (this->evaluate());
253 }
254
255 return this->shared_from_this();
256 }
257
258//------------------------------------------------------------------------------
265//------------------------------------------------------------------------------
267 compile(std::ostringstream &stream,
268 jit::register_map &registers,
270 const jit::register_usage &usage) {
271 if (registers.find(this) == registers.end()) {
272 auto arg = this->arg->compile(stream, registers,
274
275 registers[this] = jit::to_string('l', this);
276 stream << " const bool ";
277 stream << registers[this] << " = isnan("
278 << registers[arg.get()] << ")";
279 this->endline(stream, usage);
280 }
281
282 return this->shared_from_this();
283 }
284
285//------------------------------------------------------------------------------
287//------------------------------------------------------------------------------
288 virtual void to_latex() const {
289 std::cout << "isnan\\left(";
290 this->arg->to_latex();
291 std::cout << "\\right)";
292 }
293
294//------------------------------------------------------------------------------
300//------------------------------------------------------------------------------
301 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
302 jit::register_map &registers) {
303 if (registers.find(this) == registers.end()) {
304 const std::string name = jit::to_string('r', this);
305 registers[this] = name;
306 stream << " " << name
307 << " [label = \"!\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
308
309 auto arg = this->arg->to_vizgraph(stream, registers);
310 stream << " " << name << " -- " << registers[arg.get()] << ";" << std::endl;
311 }
312
313 return this->shared_from_this();
314 }
315 };
316
317//------------------------------------------------------------------------------
324//------------------------------------------------------------------------------
325 template<std::floating_point T, bool SAFE_MATH=false>
327 auto temp = std::make_shared<isnan_node<T, SAFE_MATH>> (arg)->reduce();
328// Test for hash collisions.
329 for (size_t i = temp->get_hash();
331 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
334 return temp;
335 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
337 }
338 }
339#if defined(__clang__) || defined(__GNUC__)
341#else
342 assert(false && "Should never reach.");
343#endif
344 }
345
347 template<std::floating_point T, bool SAFE_MATH=false>
348 using shared_isnan = std::shared_ptr<isnan_node<T, SAFE_MATH>>;
349
350//------------------------------------------------------------------------------
358//------------------------------------------------------------------------------
359 template<std::floating_point T, bool SAFE_MATH=false>
361 return std::dynamic_pointer_cast<isnan_node<T, SAFE_MATH>> (x);
362 }
363
364//******************************************************************************
365// Not node.
366//******************************************************************************
367//------------------------------------------------------------------------------
374//------------------------------------------------------------------------------
375 template<jit::float_scalar T, bool SAFE_MATH=false>
376 class not_node final : public no_derivative<T, SAFE_MATH, straight_node<T, SAFE_MATH>> {
377 private:
378//------------------------------------------------------------------------------
383//------------------------------------------------------------------------------
384 static std::string to_string(leaf_node<T, SAFE_MATH> *arg) {
385 return "!" + jit::format_to_string(reinterpret_cast<size_t> (arg));
386 }
387
388 public:
389//------------------------------------------------------------------------------
393//------------------------------------------------------------------------------
396 straight_node<T, SAFE_MATH>> (arg,
397 not_node::to_string(arg.get())) {}
398
399//------------------------------------------------------------------------------
405//------------------------------------------------------------------------------
407 backend::buffer<T> arg = this->arg->evaluate();
408 return !arg;
409 }
410
411//------------------------------------------------------------------------------
415//------------------------------------------------------------------------------
417// Constant reductions.
418 auto arg = constant_cast(this->arg);
419
420 if (arg.get()) {
421 return constant<T, SAFE_MATH> (this->evaluate());
422 }
423
424// !(a == b) -> a != b
425 auto equalc = equal_cast(this->arg);
426 if (equalc.get()) {
427 return equalc->get_left() != equalc->get_right();
428 }
429
430// !(a != b) -> a == b
431 auto nequalc = not_equal_cast(this->arg);
432 if (nequalc.get()) {
433 return nequalc->get_left() == nequalc->get_right();
434 }
435
436 if constexpr (!jit::complex_scalar<T>) {
437// !(a < b) -> a >= b
438 auto ltc = less_than_cast(this->arg);
439 if (ltc.get()) {
440 return ltc->get_left() >= ltc->get_right();
441 }
442
443// !(a <= b) -> a > b
444 auto lec = less_than_equal_cast(this->arg);
445 if (lec.get()) {
446 return lec->get_left() > lec->get_right();
447 }
448
449// !(a > b) -> a <= b
450 auto gtc = greater_than_cast(this->arg);
451 if (gtc.get()) {
452 return gtc->get_left() <= gtc->get_right();
453 }
454
455// !(a >= b) -> a < b
456 auto gec = greater_than_equal_cast(this->arg);
457 if (gec.get()) {
458 return gec->get_left() < gec->get_right();
459 }
460 }
461
462// !!a -> a
463 auto n = not_cast(this->arg);
464 if (n.get()) {
465 return n->get_arg();
466 }
467
468 return this->shared_from_this();
469 }
470
471//------------------------------------------------------------------------------
478//------------------------------------------------------------------------------
480 compile(std::ostringstream &stream,
481 jit::register_map &registers,
483 const jit::register_usage &usage) {
484 if (registers.find(this) == registers.end()) {
485 auto arg = this->arg->compile(stream, registers,
487
488 registers[this] = jit::to_string('l', this);
489 stream << " const bool "
490 << registers[this] << " = !";
491 if constexpr (jit::complex_scalar<T>) {
492 stream << "real(";
493 }
494 stream << registers[arg.get()];
495 if constexpr (jit::complex_scalar<T>) {
496 stream << ")";
497 }
498 this->endline(stream, usage);
499 }
500
501 return this->shared_from_this();
502 }
503
504//------------------------------------------------------------------------------
506//------------------------------------------------------------------------------
507 virtual void to_latex() const {
508 bool arg_brackets = add_cast(this->arg).get() ||
509 subtract_cast(this->arg).get();
510 std::cout << "\neg";
511 if (arg_brackets) {
512 std::cout << "\\left(";
513 }
514 this->arg->to_latex();
515 if (arg_brackets) {
516 std::cout << "\\right)";
517 }
518 }
519
520//------------------------------------------------------------------------------
526//------------------------------------------------------------------------------
527 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
528 jit::register_map &registers) {
529 if (registers.find(this) == registers.end()) {
530 const std::string name = jit::to_string('r', this);
531 registers[this] = name;
532 stream << " " << name
533 << " [label = \"!\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
534
535 auto arg = this->arg->to_vizgraph(stream, registers);
536 stream << " " << name << " -- " << registers[arg.get()] << ";" << std::endl;
537 }
538
539 return this->shared_from_this();
540 }
541 };
542
543//------------------------------------------------------------------------------
550//------------------------------------------------------------------------------
551 template<jit::float_scalar T, bool SAFE_MATH=false>
553 auto temp = std::make_shared<not_node<T, SAFE_MATH>> (arg)->reduce();
554// Test for hash collisions.
555 for (size_t i = temp->get_hash();
557 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
560 return temp;
561 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
563 }
564 }
565#if defined(__clang__) || defined(__GNUC__)
567#else
568 assert(false && "Should never reach.");
569#endif
570 }
571
572//------------------------------------------------------------------------------
582//------------------------------------------------------------------------------
583 template<jit::float_scalar T, bool SAFE_MATH=false>
587
589 template<jit::float_scalar T, bool SAFE_MATH=false>
590 using shared_not = std::shared_ptr<not_node<T, SAFE_MATH>>;
591
592//------------------------------------------------------------------------------
600//------------------------------------------------------------------------------
601 template<jit::float_scalar T, bool SAFE_MATH=false>
603 return std::dynamic_pointer_cast<not_node<T, SAFE_MATH>> (x);
604 }
605
606//******************************************************************************
607// Equal node.
608//******************************************************************************
609//------------------------------------------------------------------------------
616//------------------------------------------------------------------------------
617 template<jit::float_scalar T, bool SAFE_MATH=false>
618 class equal_node final : public no_derivative<T, SAFE_MATH, branch_node<T, SAFE_MATH>> {
619 private:
620//------------------------------------------------------------------------------
626//------------------------------------------------------------------------------
627 static std::string to_string(leaf_node<T, SAFE_MATH> *l,
629 return jit::format_to_string(reinterpret_cast<size_t> (l)) + "==" +
630 jit::format_to_string(reinterpret_cast<size_t> (r));
631 }
632
633 public:
634//------------------------------------------------------------------------------
639//------------------------------------------------------------------------------
646
647//------------------------------------------------------------------------------
653//------------------------------------------------------------------------------
655 backend::buffer<T> l_result = this->left->evaluate();
656 backend::buffer<T> r_result = this->right->evaluate();
657 return l_result == r_result;
658 }
659
660//------------------------------------------------------------------------------
664//------------------------------------------------------------------------------
666// Constant reductions.
667 auto l = constant_cast(this->left);
668 auto r = constant_cast(this->right);
669
670 if (l.get() && r.get()) {
671 return constant<T, SAFE_MATH> (this->evaluate());
672 }
673
674 return this->shared_from_this();
675 }
676
677//------------------------------------------------------------------------------
684//------------------------------------------------------------------------------
686 compile(std::ostringstream &stream,
687 jit::register_map &registers,
689 const jit::register_usage &usage) {
690 if (registers.find(this) == registers.end()) {
691 auto l = this->left->compile(stream, registers,
693 auto r = this->right->compile(stream, registers,
695
696 registers[this] = jit::to_string('l', this);
697 stream << " const bool ";
698 stream << registers[this] << " = "
699 << registers[l.get()] << "=="
700 << registers[r.get()];
701 this->endline(stream, usage);
702 }
703
704 return this->shared_from_this();
705 }
706
707//------------------------------------------------------------------------------
712//------------------------------------------------------------------------------
714 if (this == x.get()) {
715 return true;
716 }
717
718 auto x_cast = equal_cast(x);
719 if (x_cast.get()) {
720// equal is commutative.
721 if ((this->left->is_match(x_cast->get_left()) &&
722 this->right->is_match(x_cast->get_right())) ||
723 (this->right->is_match(x_cast->get_left()) &&
724 this->left->is_match(x_cast->get_right()))) {
725 return true;
726 }
727 }
728
729 return false;
730 }
731
732//------------------------------------------------------------------------------
734//------------------------------------------------------------------------------
735 virtual void to_latex() const {
736 bool l_brackets = add_cast(this->left).get() ||
737 subtract_cast(this->left).get();
738 bool r_brackets = add_cast(this->right).get() ||
739 subtract_cast(this->right).get();
740 if (l_brackets) {
741 std::cout << "\\left(";
742 }
743 this->left->to_latex();
744 if (l_brackets) {
745 std::cout << "\\right)";
746 }
747 std::cout << "=";
748 if (r_brackets) {
749 std::cout << "\\left(";
750 }
751 this->right->to_latex();
752 if (r_brackets) {
753 std::cout << "\\right)";
754 }
755 }
756
757//------------------------------------------------------------------------------
763//------------------------------------------------------------------------------
764 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
765 jit::register_map &registers) {
766 if (registers.find(this) == registers.end()) {
767 const std::string name = jit::to_string('r', this);
768 registers[this] = name;
769 stream << " " << name
770 << " [label = \"==\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
771
772 auto l = this->left->to_vizgraph(stream, registers);
773 stream << " " << name << " -- " << registers[l.get()] << ";" << std::endl;
774 auto r = this->right->to_vizgraph(stream, registers);
775 stream << " " << name << " -- " << registers[r.get()] << ";" << std::endl;
776 }
777
778 return this->shared_from_this();
779 }
780 };
781
782//------------------------------------------------------------------------------
790//------------------------------------------------------------------------------
791 template<jit::float_scalar T, bool SAFE_MATH=false>
794 auto temp = std::make_shared<equal_node<T, SAFE_MATH>> (l, r)->reduce();
795// Test for hash collisions.
796 for (size_t i = temp->get_hash();
798 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
801 return temp;
802 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
804 }
805 }
806#if defined(__clang__) || defined(__GNUC__)
808#else
809 assert(false && "Should never reach.");
810#endif
811 }
812
813//------------------------------------------------------------------------------
824//------------------------------------------------------------------------------
825 template<jit::float_scalar T, bool SAFE_MATH=false>
830
831//------------------------------------------------------------------------------
843//------------------------------------------------------------------------------
844 template<jit::float_scalar T, jit::float_scalar L, bool SAFE_MATH=false>
849
850//------------------------------------------------------------------------------
862//------------------------------------------------------------------------------
863 template<jit::float_scalar T, jit::float_scalar R, bool SAFE_MATH=false>
868
870 template<jit::float_scalar T, bool SAFE_MATH=false>
871 using shared_equal = std::shared_ptr<equal_node<T, SAFE_MATH>>;
872
873//------------------------------------------------------------------------------
881//------------------------------------------------------------------------------
882 template<jit::float_scalar T, bool SAFE_MATH=false>
884 return std::dynamic_pointer_cast<equal_node<T, SAFE_MATH>> (x);
885 }
886
887//******************************************************************************
888// Not equal node.
889//******************************************************************************
890//------------------------------------------------------------------------------
897//------------------------------------------------------------------------------
898 template<jit::float_scalar T, bool SAFE_MATH=false>
899 class not_equal_node final : public no_derivative<T, SAFE_MATH, branch_node<T, SAFE_MATH>> {
900 private:
901//------------------------------------------------------------------------------
907//------------------------------------------------------------------------------
908 static std::string to_string(leaf_node<T, SAFE_MATH> *l,
910 return jit::format_to_string(reinterpret_cast<size_t> (l)) + "!=" +
911 jit::format_to_string(reinterpret_cast<size_t> (r));
912 }
913
914 public:
915//------------------------------------------------------------------------------
920//------------------------------------------------------------------------------
927
928//------------------------------------------------------------------------------
934//------------------------------------------------------------------------------
936 backend::buffer<T> l_result = this->left->evaluate();
937 backend::buffer<T> r_result = this->right->evaluate();
938 return l_result != r_result;
939 }
940
941//------------------------------------------------------------------------------
945//------------------------------------------------------------------------------
947// Constant reductions.
948 auto l = constant_cast(this->left);
949 auto r = constant_cast(this->right);
950
951 if (l.get() && r.get()) {
952 return constant<T, SAFE_MATH> (this->evaluate());
953 }
954
955 return this->shared_from_this();
956 }
957
958//------------------------------------------------------------------------------
965//------------------------------------------------------------------------------
967 compile(std::ostringstream &stream,
968 jit::register_map &registers,
970 const jit::register_usage &usage) {
971 if (registers.find(this) == registers.end()) {
972 auto l = this->left->compile(stream, registers,
974 auto r = this->right->compile(stream, registers,
976
977 registers[this] = jit::to_string('l', this);
978 stream << " const bool ";
979 stream << registers[this] << " = "
980 << registers[l.get()] << "!="
981 << registers[r.get()];
982 this->endline(stream, usage);
983 }
984
985 return this->shared_from_this();
986 }
987
988//------------------------------------------------------------------------------
993//------------------------------------------------------------------------------
995 if (this == x.get()) {
996 return true;
997 }
998
999 auto x_cast = not_equal_cast(x);
1000 if (x_cast.get()) {
1001// equal is commutative.
1002 if ((this->left->is_match(x_cast->get_left()) &&
1003 this->right->is_match(x_cast->get_right())) ||
1004 (this->right->is_match(x_cast->get_left()) &&
1005 this->left->is_match(x_cast->get_right()))) {
1006 return true;
1007 }
1008 }
1009
1010 return false;
1011 }
1012
1013//------------------------------------------------------------------------------
1015//------------------------------------------------------------------------------
1016 virtual void to_latex() const {
1017 bool l_brackets = add_cast(this->left).get() ||
1018 subtract_cast(this->left).get();
1019 bool r_brackets = add_cast(this->right).get() ||
1020 subtract_cast(this->right).get();
1021 if (l_brackets) {
1022 std::cout << "\\left(";
1023 }
1024 this->left->to_latex();
1025 if (l_brackets) {
1026 std::cout << "\\right)";
1027 }
1028 std::cout << "\\ne";
1029 if (r_brackets) {
1030 std::cout << "\\left(";
1031 }
1032 this->right->to_latex();
1033 if (r_brackets) {
1034 std::cout << "\\right)";
1035 }
1036 }
1037
1038//------------------------------------------------------------------------------
1044//------------------------------------------------------------------------------
1045 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
1046 jit::register_map &registers) {
1047 if (registers.find(this) == registers.end()) {
1048 const std::string name = jit::to_string('r', this);
1049 registers[this] = name;
1050 stream << " " << name
1051 << " [label = \"!=\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
1052
1053 auto l = this->left->to_vizgraph(stream, registers);
1054 stream << " " << name << " -- " << registers[l.get()] << ";" << std::endl;
1055 auto r = this->right->to_vizgraph(stream, registers);
1056 stream << " " << name << " -- " << registers[r.get()] << ";" << std::endl;
1057 }
1058
1059 return this->shared_from_this();
1060 }
1061 };
1062
1063//------------------------------------------------------------------------------
1071//------------------------------------------------------------------------------
1072 template<jit::float_scalar T, bool SAFE_MATH=false>
1075 auto temp = std::make_shared<not_equal_node<T, SAFE_MATH>> (l, r)->reduce();
1076// Test for hash collisions.
1077 for (size_t i = temp->get_hash();
1079 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
1080 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
1082 return temp;
1083 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
1084 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
1085 }
1086 }
1087#if defined(__clang__) || defined(__GNUC__)
1089#else
1090 assert(false && "Should never reach.");
1091#endif
1092 }
1093
1094//------------------------------------------------------------------------------
1105//------------------------------------------------------------------------------
1106 template<jit::float_scalar T, bool SAFE_MATH=false>
1111
1112//------------------------------------------------------------------------------
1124//------------------------------------------------------------------------------
1125 template<jit::float_scalar T, jit::float_scalar L, bool SAFE_MATH=false>
1130
1131//------------------------------------------------------------------------------
1143//------------------------------------------------------------------------------
1144 template<jit::float_scalar T, jit::float_scalar R, bool SAFE_MATH=false>
1149
1151 template<jit::float_scalar T, bool SAFE_MATH=false>
1152 using shared_not_equal = std::shared_ptr<not_equal_node<T, SAFE_MATH>>;
1153
1154//------------------------------------------------------------------------------
1162//------------------------------------------------------------------------------
1163 template<jit::float_scalar T, bool SAFE_MATH=false>
1165 return std::dynamic_pointer_cast<not_equal_node<T, SAFE_MATH>> (x);
1166 }
1167
1168//******************************************************************************
1169// Greater than node.
1170//******************************************************************************
1171//------------------------------------------------------------------------------
1178//------------------------------------------------------------------------------
1179 template<std::floating_point T, bool SAFE_MATH=false>
1180 class greater_than_node final : public no_derivative<T, SAFE_MATH, branch_node<T, SAFE_MATH>> {
1181 private:
1182//------------------------------------------------------------------------------
1188//------------------------------------------------------------------------------
1189 static std::string to_string(leaf_node<T, SAFE_MATH> *l,
1191 return jit::format_to_string(reinterpret_cast<size_t> (l)) + ">" +
1192 jit::format_to_string(reinterpret_cast<size_t> (r));
1193 }
1194
1195 public:
1196//------------------------------------------------------------------------------
1201//------------------------------------------------------------------------------
1208
1209//------------------------------------------------------------------------------
1215//------------------------------------------------------------------------------
1217 backend::buffer<T> l_result = this->left->evaluate();
1218 backend::buffer<T> r_result = this->right->evaluate();
1219 return l_result > r_result;
1220 }
1221
1222//------------------------------------------------------------------------------
1226//------------------------------------------------------------------------------
1228// Constant reductions.
1229 auto l = constant_cast(this->left);
1230 auto r = constant_cast(this->right);
1231
1232 if (l.get() && r.get()) {
1233 return constant<T, SAFE_MATH> (this->evaluate());
1234 }
1235
1236 return this->shared_from_this();
1237 }
1238
1239//------------------------------------------------------------------------------
1246//------------------------------------------------------------------------------
1248 compile(std::ostringstream &stream,
1249 jit::register_map &registers,
1251 const jit::register_usage &usage) {
1252 if (registers.find(this) == registers.end()) {
1253 auto l = this->left->compile(stream, registers,
1254 thread_mem, usage);
1255 auto r = this->right->compile(stream, registers,
1256 thread_mem, usage);
1257
1258 registers[this] = jit::to_string('l', this);
1259 stream << " const bool ";
1260 stream << registers[this] << " = "
1261 << registers[l.get()] << ">"
1262 << registers[r.get()];
1263 this->endline(stream, usage);
1264 }
1265
1266 return this->shared_from_this();
1267 }
1268
1269//------------------------------------------------------------------------------
1271//------------------------------------------------------------------------------
1272 virtual void to_latex() const {
1273 bool l_brackets = add_cast(this->left).get() ||
1274 subtract_cast(this->left).get();
1275 bool r_brackets = add_cast(this->right).get() ||
1276 subtract_cast(this->right).get();
1277 if (l_brackets) {
1278 std::cout << "\\left(";
1279 }
1280 this->left->to_latex();
1281 if (l_brackets) {
1282 std::cout << "\\right)";
1283 }
1284 std::cout << ">";
1285 if (r_brackets) {
1286 std::cout << "\\left(";
1287 }
1288 this->right->to_latex();
1289 if (r_brackets) {
1290 std::cout << "\\right)";
1291 }
1292 }
1293
1294//------------------------------------------------------------------------------
1300//------------------------------------------------------------------------------
1301 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
1302 jit::register_map &registers) {
1303 if (registers.find(this) == registers.end()) {
1304 const std::string name = jit::to_string('r', this);
1305 registers[this] = name;
1306 stream << " " << name
1307 << " [label = \">\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
1308
1309 auto l = this->left->to_vizgraph(stream, registers);
1310 stream << " " << name << " -- " << registers[l.get()] << ";" << std::endl;
1311 auto r = this->right->to_vizgraph(stream, registers);
1312 stream << " " << name << " -- " << registers[r.get()] << ";" << std::endl;
1313 }
1314
1315 return this->shared_from_this();
1316 }
1317 };
1318
1319//------------------------------------------------------------------------------
1327//------------------------------------------------------------------------------
1328 template<std::floating_point T, bool SAFE_MATH=false>
1331 auto temp = std::make_shared<greater_than_node<T, SAFE_MATH>> (l, r)->reduce();
1332// Test for hash collisions.
1333 for (size_t i = temp->get_hash();
1335 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
1336 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
1338 return temp;
1339 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
1340 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
1341 }
1342 }
1343#if defined(__clang__) || defined(__GNUC__)
1345#else
1346 assert(false && "Should never reach.");
1347#endif
1348 }
1349
1350//------------------------------------------------------------------------------
1361//------------------------------------------------------------------------------
1362 template<std::floating_point T, bool SAFE_MATH=false>
1367
1368//------------------------------------------------------------------------------
1380//------------------------------------------------------------------------------
1381 template<std::floating_point T, std::floating_point L, bool SAFE_MATH=false>
1386
1387//------------------------------------------------------------------------------
1399//------------------------------------------------------------------------------
1400 template<std::floating_point T, std::floating_point R, bool SAFE_MATH=false>
1405
1407 template<std::floating_point T, bool SAFE_MATH=false>
1408 using shared_greater_than = std::shared_ptr<greater_than_node<T, SAFE_MATH>>;
1409
1410//------------------------------------------------------------------------------
1418//------------------------------------------------------------------------------
1419 template<std::floating_point T, bool SAFE_MATH=false>
1421 return std::dynamic_pointer_cast<greater_than_node<T, SAFE_MATH>> (x);
1422 }
1423
1424//******************************************************************************
1425// Less than node.
1426//******************************************************************************
1427//------------------------------------------------------------------------------
1434//------------------------------------------------------------------------------
1435 template<std::floating_point T, bool SAFE_MATH=false>
1436 class less_than_node final : public no_derivative<T, SAFE_MATH, branch_node<T, SAFE_MATH>> {
1437 private:
1438//------------------------------------------------------------------------------
1444//------------------------------------------------------------------------------
1445 static std::string to_string(leaf_node<T, SAFE_MATH> *l,
1447 return jit::format_to_string(reinterpret_cast<size_t> (l)) + "<" +
1448 jit::format_to_string(reinterpret_cast<size_t> (r));
1449 }
1450
1451 public:
1452//------------------------------------------------------------------------------
1457//------------------------------------------------------------------------------
1464
1465//------------------------------------------------------------------------------
1471//------------------------------------------------------------------------------
1473 backend::buffer<T> l_result = this->left->evaluate();
1474 backend::buffer<T> r_result = this->right->evaluate();
1475 return l_result < r_result;
1476 }
1477
1478//------------------------------------------------------------------------------
1482//------------------------------------------------------------------------------
1484// Constant reductions.
1485 auto l = constant_cast(this->left);
1486 auto r = constant_cast(this->right);
1487
1488 if (l.get() && r.get()) {
1489 return constant<T, SAFE_MATH> (this->evaluate());
1490 }
1491
1492 return this->shared_from_this();
1493 }
1494
1495//------------------------------------------------------------------------------
1502//------------------------------------------------------------------------------
1504 compile(std::ostringstream &stream,
1505 jit::register_map &registers,
1507 const jit::register_usage &usage) {
1508 if (registers.find(this) == registers.end()) {
1509 auto l = this->left->compile(stream, registers,
1510 thread_mem, usage);
1511 auto r = this->right->compile(stream, registers,
1512 thread_mem, usage);
1513
1514 registers[this] = jit::to_string('l', this);
1515 stream << " const bool ";
1516 stream << registers[this] << " = "
1517 << registers[l.get()] << "<"
1518 << registers[r.get()];
1519 this->endline(stream, usage);
1520 }
1521
1522 return this->shared_from_this();
1523 }
1524
1525//------------------------------------------------------------------------------
1527//------------------------------------------------------------------------------
1528 virtual void to_latex() const {
1529 bool l_brackets = add_cast(this->left).get() ||
1530 subtract_cast(this->left).get();
1531 bool r_brackets = add_cast(this->right).get() ||
1532 subtract_cast(this->right).get();
1533 if (l_brackets) {
1534 std::cout << "\\left(";
1535 }
1536 this->left->to_latex();
1537 if (l_brackets) {
1538 std::cout << "\\right)";
1539 }
1540 std::cout << "<";
1541 if (r_brackets) {
1542 std::cout << "\\left(";
1543 }
1544 this->right->to_latex();
1545 if (r_brackets) {
1546 std::cout << "\\right)";
1547 }
1548 }
1549
1550//------------------------------------------------------------------------------
1556//------------------------------------------------------------------------------
1557 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
1558 jit::register_map &registers) {
1559 if (registers.find(this) == registers.end()) {
1560 const std::string name = jit::to_string('r', this);
1561 registers[this] = name;
1562 stream << " " << name
1563 << " [label = \"<\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
1564
1565 auto l = this->left->to_vizgraph(stream, registers);
1566 stream << " " << name << " -- " << registers[l.get()] << ";" << std::endl;
1567 auto r = this->right->to_vizgraph(stream, registers);
1568 stream << " " << name << " -- " << registers[r.get()] << ";" << std::endl;
1569 }
1570
1571 return this->shared_from_this();
1572 }
1573 };
1574
1575//------------------------------------------------------------------------------
1583//------------------------------------------------------------------------------
1584 template<std::floating_point T, bool SAFE_MATH=false>
1587 auto temp = std::make_shared<less_than_node<T, SAFE_MATH>> (l, r)->reduce();
1588// Test for hash collisions.
1589 for (size_t i = temp->get_hash();
1591 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
1592 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
1594 return temp;
1595 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
1596 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
1597 }
1598 }
1599#if defined(__clang__) || defined(__GNUC__)
1601#else
1602 assert(false && "Should never reach.");
1603#endif
1604 }
1605
1606//------------------------------------------------------------------------------
1617//------------------------------------------------------------------------------
1618 template<std::floating_point T, bool SAFE_MATH=false>
1621 return less_than<T, SAFE_MATH> (l, r);
1622 }
1623
1624//------------------------------------------------------------------------------
1636//------------------------------------------------------------------------------
1637 template<std::floating_point T, std::floating_point L, bool SAFE_MATH=false>
1640 return less_than<T, SAFE_MATH> (constant<T, SAFE_MATH> (static_cast<T> (l)), r);
1641 }
1642
1643//------------------------------------------------------------------------------
1655//------------------------------------------------------------------------------
1656 template<std::floating_point T, std::floating_point R, bool SAFE_MATH=false>
1658 const R r) {
1659 return less_than<T, SAFE_MATH> (l, constant<T, SAFE_MATH> (static_cast<T> (r)));
1660 }
1661
1663 template<std::floating_point T, bool SAFE_MATH=false>
1664 using shared_less_than = std::shared_ptr<less_than_node<T, SAFE_MATH>>;
1665
1666//------------------------------------------------------------------------------
1674//------------------------------------------------------------------------------
1675 template<std::floating_point T, bool SAFE_MATH=false>
1677 return std::dynamic_pointer_cast<less_than_node<T, SAFE_MATH>> (x);
1678 }
1679
1680//******************************************************************************
1681// Greater than equal node.
1682//******************************************************************************
1683//------------------------------------------------------------------------------
1690//------------------------------------------------------------------------------
1691 template<std::floating_point T, bool SAFE_MATH=false>
1692 class greater_than_equal_node final : public no_derivative<T, SAFE_MATH, branch_node<T, SAFE_MATH>> {
1693 private:
1694//------------------------------------------------------------------------------
1700//------------------------------------------------------------------------------
1701 static std::string to_string(leaf_node<T, SAFE_MATH> *l,
1703 return jit::format_to_string(reinterpret_cast<size_t> (l)) + ">=" +
1704 jit::format_to_string(reinterpret_cast<size_t> (r));
1705 }
1706
1707 public:
1708//------------------------------------------------------------------------------
1713//------------------------------------------------------------------------------
1720
1721//------------------------------------------------------------------------------
1727//------------------------------------------------------------------------------
1729 backend::buffer<T> l_result = this->left->evaluate();
1730 backend::buffer<T> r_result = this->right->evaluate();
1731 return l_result >= r_result;
1732 }
1733
1734//------------------------------------------------------------------------------
1738//------------------------------------------------------------------------------
1740// Constant reductions.
1741 auto l = constant_cast(this->left);
1742 auto r = constant_cast(this->right);
1743
1744 if (l.get() && r.get()) {
1745 return constant<T, SAFE_MATH> (this->evaluate());
1746 }
1747
1748 return this->shared_from_this();
1749 }
1750
1751//------------------------------------------------------------------------------
1758//------------------------------------------------------------------------------
1760 compile(std::ostringstream &stream,
1761 jit::register_map &registers,
1763 const jit::register_usage &usage) {
1764 if (registers.find(this) == registers.end()) {
1765 auto l = this->left->compile(stream, registers,
1766 thread_mem, usage);
1767 auto r = this->right->compile(stream, registers,
1768 thread_mem, usage);
1769
1770 registers[this] = jit::to_string('l', this);
1771 stream << " const bool ";
1772 stream << registers[this] << " = "
1773 << registers[l.get()] << ">="
1774 << registers[r.get()];
1775 this->endline(stream, usage);
1776 }
1777
1778 return this->shared_from_this();
1779 }
1780
1781//------------------------------------------------------------------------------
1783//------------------------------------------------------------------------------
1784 virtual void to_latex() const {
1785 bool l_brackets = add_cast(this->left).get() ||
1786 subtract_cast(this->left).get();
1787 bool r_brackets = add_cast(this->right).get() ||
1788 subtract_cast(this->right).get();
1789 if (l_brackets) {
1790 std::cout << "\\left(";
1791 }
1792 this->left->to_latex();
1793 if (l_brackets) {
1794 std::cout << "\\right)";
1795 }
1796 std::cout << "\\ge";
1797 if (r_brackets) {
1798 std::cout << "\\left(";
1799 }
1800 this->right->to_latex();
1801 if (r_brackets) {
1802 std::cout << "\\right)";
1803 }
1804 }
1805
1806//------------------------------------------------------------------------------
1812//------------------------------------------------------------------------------
1813 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
1814 jit::register_map &registers) {
1815 if (registers.find(this) == registers.end()) {
1816 const std::string name = jit::to_string('r', this);
1817 registers[this] = name;
1818 stream << " " << name
1819 << " [label = \">=\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
1820
1821 auto l = this->left->to_vizgraph(stream, registers);
1822 stream << " " << name << " -- " << registers[l.get()] << ";" << std::endl;
1823 auto r = this->right->to_vizgraph(stream, registers);
1824 stream << " " << name << " -- " << registers[r.get()] << ";" << std::endl;
1825 }
1826
1827 return this->shared_from_this();
1828 }
1829 };
1830
1831//------------------------------------------------------------------------------
1839//------------------------------------------------------------------------------
1840 template<std::floating_point T, bool SAFE_MATH=false>
1843 auto temp = std::make_shared<greater_than_equal_node<T, SAFE_MATH>> (l, r)->reduce();
1844// Test for hash collisions.
1845 for (size_t i = temp->get_hash();
1847 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
1848 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
1850 return temp;
1851 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
1852 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
1853 }
1854 }
1855#if defined(__clang__) || defined(__GNUC__)
1857#else
1858 assert(false && "Should never reach.");
1859#endif
1860 }
1861
1862//------------------------------------------------------------------------------
1873//------------------------------------------------------------------------------
1874 template<std::floating_point T, bool SAFE_MATH=false>
1879
1880//------------------------------------------------------------------------------
1892//------------------------------------------------------------------------------
1893 template<std::floating_point T, std::floating_point L, bool SAFE_MATH=false>
1898
1899//------------------------------------------------------------------------------
1911//------------------------------------------------------------------------------
1912 template<std::floating_point T, std::floating_point R, bool SAFE_MATH=false>
1917
1919 template<std::floating_point T, bool SAFE_MATH=false>
1920 using shared_greater_than_equal = std::shared_ptr<greater_than_equal_node<T, SAFE_MATH>>;
1921
1922//------------------------------------------------------------------------------
1930//------------------------------------------------------------------------------
1931 template<std::floating_point T, bool SAFE_MATH=false>
1933 return std::dynamic_pointer_cast<greater_than_equal_node<T, SAFE_MATH>> (x);
1934 }
1935
1936//******************************************************************************
1937// Less than equal node.
1938//******************************************************************************
1939//------------------------------------------------------------------------------
1946//------------------------------------------------------------------------------
1947 template<std::floating_point T, bool SAFE_MATH=false>
1948 class less_than_equal_node final : public no_derivative<T, SAFE_MATH, branch_node<T, SAFE_MATH>> {
1949 private:
1950//------------------------------------------------------------------------------
1956//------------------------------------------------------------------------------
1957 static std::string to_string(leaf_node<T, SAFE_MATH> *l,
1959 return jit::format_to_string(reinterpret_cast<size_t> (l)) + "<=" +
1960 jit::format_to_string(reinterpret_cast<size_t> (r));
1961 }
1962
1963 public:
1964//------------------------------------------------------------------------------
1969//------------------------------------------------------------------------------
1976
1977//------------------------------------------------------------------------------
1983//------------------------------------------------------------------------------
1985 backend::buffer<T> l_result = this->left->evaluate();
1986 backend::buffer<T> r_result = this->right->evaluate();
1987 return l_result <= r_result;
1988 }
1989
1990//------------------------------------------------------------------------------
1994//------------------------------------------------------------------------------
1996// Constant reductions.
1997 auto l = constant_cast(this->left);
1998 auto r = constant_cast(this->right);
1999
2000 if (l.get() && r.get()) {
2001 return constant<T, SAFE_MATH> (this->evaluate());
2002 }
2003
2004 return this->shared_from_this();
2005 }
2006
2007//------------------------------------------------------------------------------
2014//------------------------------------------------------------------------------
2016 compile(std::ostringstream &stream,
2017 jit::register_map &registers,
2019 const jit::register_usage &usage) {
2020 if (registers.find(this) == registers.end()) {
2021 auto l = this->left->compile(stream, registers,
2022 thread_mem, usage);
2023 auto r = this->right->compile(stream, registers,
2024 thread_mem, usage);
2025
2026 registers[this] = jit::to_string('l', this);
2027 stream << " const bool ";
2028 stream << registers[this] << " = "
2029 << registers[l.get()] << "<="
2030 << registers[r.get()];
2031 this->endline(stream, usage);
2032 }
2033
2034 return this->shared_from_this();
2035 }
2036
2037//------------------------------------------------------------------------------
2039//------------------------------------------------------------------------------
2040 virtual void to_latex() const {
2041 bool l_brackets = add_cast(this->left).get() ||
2042 subtract_cast(this->left).get();
2043 bool r_brackets = add_cast(this->right).get() ||
2044 subtract_cast(this->right).get();
2045 if (l_brackets) {
2046 std::cout << "\\left(";
2047 }
2048 this->left->to_latex();
2049 if (l_brackets) {
2050 std::cout << "\\right)";
2051 }
2052 std::cout << "\\le";
2053 if (r_brackets) {
2054 std::cout << "\\left(";
2055 }
2056 this->right->to_latex();
2057 if (r_brackets) {
2058 std::cout << "\\right)";
2059 }
2060 }
2061
2062//------------------------------------------------------------------------------
2068//------------------------------------------------------------------------------
2069 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
2070 jit::register_map &registers) {
2071 if (registers.find(this) == registers.end()) {
2072 const std::string name = jit::to_string('r', this);
2073 registers[this] = name;
2074 stream << " " << name
2075 << " [label = \"<=\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
2076
2077 auto l = this->left->to_vizgraph(stream, registers);
2078 stream << " " << name << " -- " << registers[l.get()] << ";" << std::endl;
2079 auto r = this->right->to_vizgraph(stream, registers);
2080 stream << " " << name << " -- " << registers[r.get()] << ";" << std::endl;
2081 }
2082
2083 return this->shared_from_this();
2084 }
2085 };
2086
2087//------------------------------------------------------------------------------
2095//------------------------------------------------------------------------------
2096 template<std::floating_point T, bool SAFE_MATH=false>
2099 auto temp = std::make_shared<less_than_equal_node<T, SAFE_MATH>> (l, r)->reduce();
2100// Test for hash collisions.
2101 for (size_t i = temp->get_hash();
2103 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
2104 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
2106 return temp;
2107 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
2108 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
2109 }
2110 }
2111#if defined(__clang__) || defined(__GNUC__)
2113#else
2114 assert(false && "Should never reach.");
2115#endif
2116 }
2117
2118//------------------------------------------------------------------------------
2129//------------------------------------------------------------------------------
2130 template<std::floating_point T, bool SAFE_MATH=false>
2133 return less_than_equal<T, SAFE_MATH> (l, r);
2134 }
2135
2136//------------------------------------------------------------------------------
2148//------------------------------------------------------------------------------
2149 template<std::floating_point T, std::floating_point L, bool SAFE_MATH=false>
2152 return less_than_equal<T, SAFE_MATH> (constant<T, SAFE_MATH> (static_cast<T> (l)), r);
2153 }
2154
2155//------------------------------------------------------------------------------
2167//------------------------------------------------------------------------------
2168 template<std::floating_point T, std::floating_point R, bool SAFE_MATH=false>
2170 const R r) {
2171 return less_than_equal<T, SAFE_MATH> (l, constant<T, SAFE_MATH> (static_cast<T> (r)));
2172 }
2173
2175 template<std::floating_point T, bool SAFE_MATH=false>
2176 using shared_less_than_equal = std::shared_ptr<less_than_equal_node<T, SAFE_MATH>>;
2177
2178//------------------------------------------------------------------------------
2186//------------------------------------------------------------------------------
2187 template<std::floating_point T, bool SAFE_MATH=false>
2189 return std::dynamic_pointer_cast<less_than_equal_node<T, SAFE_MATH>> (x);
2190 }
2191
2192//******************************************************************************
2193// And node.
2194//******************************************************************************
2195//------------------------------------------------------------------------------
2202//------------------------------------------------------------------------------
2203 template<std::floating_point T, bool SAFE_MATH=false>
2204 class and_node final : public no_derivative<T, SAFE_MATH, branch_node<T, SAFE_MATH>> {
2205 private:
2206//------------------------------------------------------------------------------
2212//------------------------------------------------------------------------------
2213 static std::string to_string(leaf_node<T, SAFE_MATH> *l,
2215 return jit::format_to_string(reinterpret_cast<size_t> (l)) + "&&" +
2216 jit::format_to_string(reinterpret_cast<size_t> (r));
2217 }
2218
2219 public:
2220//------------------------------------------------------------------------------
2225//------------------------------------------------------------------------------
2231
2232//------------------------------------------------------------------------------
2238//------------------------------------------------------------------------------
2240 backend::buffer<T> l_result = this->left->evaluate();
2241 backend::buffer<T> r_result = this->right->evaluate();
2242 return l_result && r_result;
2243 }
2244
2245//------------------------------------------------------------------------------
2249//------------------------------------------------------------------------------
2251// Constant reductions.
2252 auto l = constant_cast(this->left);
2253 auto r = constant_cast(this->right);
2254
2255 if (l.get() && r.get()) {
2256 return constant<T, SAFE_MATH> (this->evaluate());
2257 }
2258
2259 return this->shared_from_this();
2260 }
2261
2262//------------------------------------------------------------------------------
2269//------------------------------------------------------------------------------
2271 compile(std::ostringstream &stream,
2272 jit::register_map &registers,
2274 const jit::register_usage &usage) {
2275 if (registers.find(this) == registers.end()) {
2276 auto l = this->left->compile(stream, registers,
2277 thread_mem, usage);
2278 auto r = this->right->compile(stream, registers,
2279 thread_mem, usage);
2280
2281 registers[this] = jit::to_string('l', this);
2282 stream << " const bool ";
2283 stream << registers[this] << " = "
2284 << registers[l.get()] << "&&"
2285 << registers[r.get()];
2286 this->endline(stream, usage);
2287 }
2288
2289 return this->shared_from_this();
2290 }
2291
2292//------------------------------------------------------------------------------
2297//------------------------------------------------------------------------------
2299 if (this == x.get()) {
2300 return true;
2301 }
2302
2303 auto x_cast = and_cast(x);
2304 if (x_cast.get()) {
2305// and is commutative.
2306 if ((this->left->is_match(x_cast->get_left()) &&
2307 this->right->is_match(x_cast->get_right())) ||
2308 (this->right->is_match(x_cast->get_left()) &&
2309 this->left->is_match(x_cast->get_right()))) {
2310 return true;
2311 }
2312 }
2313
2314 return false;
2315 }
2316
2317//------------------------------------------------------------------------------
2319//------------------------------------------------------------------------------
2320 virtual void to_latex() const {
2321 bool l_brackets = add_cast(this->left).get() ||
2322 subtract_cast(this->left).get();
2323 bool r_brackets = add_cast(this->right).get() ||
2324 subtract_cast(this->right).get();
2325 if (l_brackets) {
2326 std::cout << "\\left(";
2327 }
2328 this->left->to_latex();
2329 if (l_brackets) {
2330 std::cout << "\\right)";
2331 }
2332 std::cout << "\\land";
2333 if (r_brackets) {
2334 std::cout << "\\left(";
2335 }
2336 this->right->to_latex();
2337 if (r_brackets) {
2338 std::cout << "\\right)";
2339 }
2340 }
2341
2342//------------------------------------------------------------------------------
2348//------------------------------------------------------------------------------
2349 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
2350 jit::register_map &registers) {
2351 if (registers.find(this) == registers.end()) {
2352 const std::string name = jit::to_string('r', this);
2353 registers[this] = name;
2354 stream << " " << name
2355 << " [label = \"&&\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
2356
2357 auto l = this->left->to_vizgraph(stream, registers);
2358 stream << " " << name << " -- " << registers[l.get()] << ";" << std::endl;
2359 auto r = this->right->to_vizgraph(stream, registers);
2360 stream << " " << name << " -- " << registers[r.get()] << ";" << std::endl;
2361 }
2362
2363 return this->shared_from_this();
2364 }
2365 };
2366
2367//------------------------------------------------------------------------------
2375//------------------------------------------------------------------------------
2376 template<std::floating_point T, bool SAFE_MATH=false>
2379 auto temp = std::make_shared<and_node<T, SAFE_MATH>> (l, r)->reduce();
2380// Test for hash collisions.
2381 for (size_t i = temp->get_hash();
2383 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
2384 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
2386 return temp;
2387 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
2388 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
2389 }
2390 }
2391#if defined(__clang__) || defined(__GNUC__)
2393#else
2394 assert(false && "Should never reach.");
2395#endif
2396 }
2397
2398//------------------------------------------------------------------------------
2409//------------------------------------------------------------------------------
2410 template<std::floating_point T, bool SAFE_MATH=false>
2415
2416//------------------------------------------------------------------------------
2427//------------------------------------------------------------------------------
2428 template<std::floating_point T, bool SAFE_MATH=false>
2431 return and_<T, SAFE_MATH> (constant<T, SAFE_MATH> (static_cast<T> (l)), r);
2432 }
2433
2434//------------------------------------------------------------------------------
2445//------------------------------------------------------------------------------
2446 template<std::floating_point T, bool SAFE_MATH=false>
2448 const bool r) {
2449 return and_<T, SAFE_MATH> (l, constant<T, SAFE_MATH> (static_cast<T> (r)));
2450 }
2451
2453 template<std::floating_point T, bool SAFE_MATH=false>
2454 using shared_and = std::shared_ptr<and_node<T, SAFE_MATH>>;
2455
2456//------------------------------------------------------------------------------
2464//------------------------------------------------------------------------------
2465 template<std::floating_point T, bool SAFE_MATH=false>
2467 return std::dynamic_pointer_cast<and_node<T, SAFE_MATH>> (x);
2468 }
2469
2470//******************************************************************************
2471// Or node.
2472//******************************************************************************
2473//------------------------------------------------------------------------------
2480//------------------------------------------------------------------------------
2481 template<std::floating_point T, bool SAFE_MATH=false>
2482 class or_node final : public no_derivative<T, SAFE_MATH, branch_node<T, SAFE_MATH>> {
2483 private:
2484//------------------------------------------------------------------------------
2490//------------------------------------------------------------------------------
2491 static std::string to_string(leaf_node<T, SAFE_MATH> *l,
2493 return jit::format_to_string(reinterpret_cast<size_t> (l)) + "||" +
2494 jit::format_to_string(reinterpret_cast<size_t> (r));
2495 }
2496
2497 public:
2498//------------------------------------------------------------------------------
2503//------------------------------------------------------------------------------
2509
2510//------------------------------------------------------------------------------
2516//------------------------------------------------------------------------------
2518 backend::buffer<T> l_result = this->left->evaluate();
2519 backend::buffer<T> r_result = this->right->evaluate();
2520 return l_result || r_result;
2521 }
2522
2523//------------------------------------------------------------------------------
2527//------------------------------------------------------------------------------
2529// Constant reductions.
2530 auto l = constant_cast(this->left);
2531 auto r = constant_cast(this->right);
2532
2533 if (l.get() && r.get()) {
2534 return constant<T, SAFE_MATH> (this->evaluate());
2535 }
2536
2537 return this->shared_from_this();
2538 }
2539
2540//------------------------------------------------------------------------------
2547//------------------------------------------------------------------------------
2549 compile(std::ostringstream &stream,
2550 jit::register_map &registers,
2552 const jit::register_usage &usage) {
2553 if (registers.find(this) == registers.end()) {
2554 auto l = this->left->compile(stream, registers,
2555 thread_mem, usage);
2556 auto r = this->right->compile(stream, registers,
2557 thread_mem, usage);
2558
2559 registers[this] = jit::to_string('l', this);
2560 stream << " const bool ";
2561 stream << registers[this] << " = "
2562 << registers[l.get()] << "||"
2563 << registers[r.get()];
2564 this->endline(stream, usage);
2565 }
2566
2567 return this->shared_from_this();
2568 }
2569
2570//------------------------------------------------------------------------------
2575//------------------------------------------------------------------------------
2577 if (this == x.get()) {
2578 return true;
2579 }
2580
2581 auto x_cast = or_cast(x);
2582 if (x_cast.get()) {
2583// or is commutative.
2584 if ((this->left->is_match(x_cast->get_left()) &&
2585 this->right->is_match(x_cast->get_right())) ||
2586 (this->right->is_match(x_cast->get_left()) &&
2587 this->left->is_match(x_cast->get_right()))) {
2588 return true;
2589 }
2590 }
2591
2592 return false;
2593 }
2594
2595//------------------------------------------------------------------------------
2597//------------------------------------------------------------------------------
2598 virtual void to_latex() const {
2599 bool l_brackets = add_cast(this->left).get() ||
2600 subtract_cast(this->left).get();
2601 bool r_brackets = add_cast(this->right).get() ||
2602 subtract_cast(this->right).get();
2603 if (l_brackets) {
2604 std::cout << "\\left(";
2605 }
2606 this->left->to_latex();
2607 if (l_brackets) {
2608 std::cout << "\\right)";
2609 }
2610 std::cout << "\\lor";
2611 if (r_brackets) {
2612 std::cout << "\\left(";
2613 }
2614 this->right->to_latex();
2615 if (r_brackets) {
2616 std::cout << "\\right)";
2617 }
2618 }
2619
2620//------------------------------------------------------------------------------
2626//------------------------------------------------------------------------------
2627 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
2628 jit::register_map &registers) {
2629 if (registers.find(this) == registers.end()) {
2630 const std::string name = jit::to_string('r', this);
2631 registers[this] = name;
2632 stream << " " << name
2633 << " [label = \"||\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
2634
2635 auto l = this->left->to_vizgraph(stream, registers);
2636 stream << " " << name << " -- " << registers[l.get()] << ";" << std::endl;
2637 auto r = this->right->to_vizgraph(stream, registers);
2638 stream << " " << name << " -- " << registers[r.get()] << ";" << std::endl;
2639 }
2640
2641 return this->shared_from_this();
2642 }
2643 };
2644
2645//------------------------------------------------------------------------------
2653//------------------------------------------------------------------------------
2654 template<std::floating_point T, bool SAFE_MATH=false>
2657 auto temp = std::make_shared<or_node<T, SAFE_MATH>> (l, r)->reduce();
2658// Test for hash collisions.
2659 for (size_t i = temp->get_hash();
2661 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
2662 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
2664 return temp;
2665 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
2666 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
2667 }
2668 }
2669#if defined(__clang__) || defined(__GNUC__)
2671#else
2672 assert(false && "Should never reach.");
2673#endif
2674 }
2675
2676//------------------------------------------------------------------------------
2687//------------------------------------------------------------------------------
2688 template<std::floating_point T, bool SAFE_MATH=false>
2693
2694//------------------------------------------------------------------------------
2705//------------------------------------------------------------------------------
2706 template<std::floating_point T, bool SAFE_MATH=false>
2709 return or_<T, SAFE_MATH> (constant<T, SAFE_MATH> (static_cast<T> (l)), r);
2710 }
2711
2712//------------------------------------------------------------------------------
2723//------------------------------------------------------------------------------
2724 template<std::floating_point T, bool SAFE_MATH=false>
2726 const bool r) {
2727 return or_<T, SAFE_MATH> (l, constant<T, SAFE_MATH> (static_cast<T> (r)));
2728 }
2729
2731 template<std::floating_point T, bool SAFE_MATH=false>
2732 using shared_or = std::shared_ptr<or_node<T, SAFE_MATH>>;
2733
2734//------------------------------------------------------------------------------
2742//------------------------------------------------------------------------------
2743 template<std::floating_point T, bool SAFE_MATH=false>
2745 return std::dynamic_pointer_cast<or_node<T, SAFE_MATH>> (x);
2746 }
2747
2748//******************************************************************************
2749// If node.
2750//******************************************************************************
2751//------------------------------------------------------------------------------
2758//------------------------------------------------------------------------------
2759 template<jit::float_scalar T, bool SAFE_MATH=false>
2760 class if_node final : public triple_node<T, SAFE_MATH> {
2761 private:
2762//------------------------------------------------------------------------------
2769//------------------------------------------------------------------------------
2770 static std::string to_string(leaf_node<T, SAFE_MATH> *c,
2773 return "if" +
2774 jit::format_to_string(reinterpret_cast<size_t> (c)) +
2775 jit::format_to_string(reinterpret_cast<size_t> (t)) +
2776 jit::format_to_string(reinterpret_cast<size_t> (f));
2777 }
2778
2779 public:
2780//------------------------------------------------------------------------------
2786//------------------------------------------------------------------------------
2790 triple_node<T, SAFE_MATH> (c, t, f,
2791 if_node::to_string(c.get(),
2792 t.get(),
2793 f.get())) {}
2794
2795//------------------------------------------------------------------------------
2801//------------------------------------------------------------------------------
2803 backend::buffer<T> c_result = this->left->evaluate();
2804 backend::buffer<T> t_result = this->middle->evaluate();
2805 backend::buffer<T> f_result = this->right->evaluate();
2806 return c_result.if_(t_result, f_result);
2807 }
2808
2809//------------------------------------------------------------------------------
2813//------------------------------------------------------------------------------
2815// Constant reductions.
2816 auto c = constant_cast(this->left);
2817 auto t = constant_cast(this->middle);
2818 auto f = constant_cast(this->right);
2819
2820 if (c.get() && t.get() && f.get()) {
2821 return constant<T, SAFE_MATH> (this->evaluate());
2822 }
2823
2824// If(c, a, a) -> a
2825 if (this->middle->is_match(this->right)) {
2826 return this->middle;
2827 }
2828
2829// If(!a, b, c) -> If(a, c, b)
2830 auto n = not_cast(this->left);
2831 if (n.get()) {
2832 return if_(n->get_arg(), this->right, this->middle);
2833 }
2834
2835 return this->shared_from_this();
2836 }
2837
2838//------------------------------------------------------------------------------
2845//------------------------------------------------------------------------------
2848 if (this->is_match(x)) {
2849 return one<T, SAFE_MATH> ();
2850 }
2851
2852 const size_t hash = reinterpret_cast<size_t> (x.get());
2853 if (this->df_cache.find(hash) == this->df_cache.end()) {
2854 this->df_cache[hash] = if_<T, SAFE_MATH> (this->left,
2855 this->middle->df(x),
2856 this->right->df(x));
2857 }
2858 return this->df_cache[hash];
2859 }
2860
2861//------------------------------------------------------------------------------
2868//------------------------------------------------------------------------------
2870 compile(std::ostringstream &stream,
2871 jit::register_map &registers,
2873 const jit::register_usage &usage) {
2874 if (registers.find(this) == registers.end()) {
2875 auto c = this->left->compile(stream, registers,
2876 thread_mem, usage);
2877 registers[this] = jit::to_string('r', this);
2878 auto t = this->middle->compile(stream, registers,
2879 thread_mem, usage);
2880 auto f = this->right->compile(stream, registers,
2881 thread_mem, usage);
2882 stream << " const ";
2883 jit::add_type<T> (stream);
2884 stream << " " << registers[this] << " = "
2885 << registers[c.get()] << " ? "
2886 << registers[t.get()] << " : "
2887 << registers[f.get()];
2888 this->endline(stream, usage);
2889 }
2890
2891 return this->shared_from_this();
2892 }
2893
2894//------------------------------------------------------------------------------
2896//------------------------------------------------------------------------------
2897 virtual void to_latex() const {
2898 std::cout << "if\\left(";
2899 this->left->to_latex();
2900 std::cout << ",";
2901 this->middle->to_latex();
2902 std::cout << ",";
2903 this->right->to_latex();
2904 std::cout << "\\right)";
2905 }
2906
2907//------------------------------------------------------------------------------
2911//------------------------------------------------------------------------------
2913 if (this->has_pseudo()) {
2914 return if_<T, SAFE_MATH> (this->left,
2915 this->middle->remove_pseudo(),
2916 this->right->remove_pseudo());
2917 }
2918 return this->shared_from_this();
2919 }
2920
2921//------------------------------------------------------------------------------
2927//------------------------------------------------------------------------------
2928 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
2929 jit::register_map &registers) {
2930 if (registers.find(this) == registers.end()) {
2931 const std::string name = jit::to_string('r', this);
2932 registers[this] = name;
2933 stream << " " << name
2934 << " [label = \"if\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
2935
2936 auto c = this->left->to_vizgraph(stream, registers);
2937 stream << " " << name << " -- " << registers[c.get()] << ";" << std::endl;
2938 auto t = this->middle->to_vizgraph(stream, registers);
2939 stream << " " << name << " -- " << registers[t.get()] << ";" << std::endl;
2940 auto f = this->right->to_vizgraph(stream, registers);
2941 stream << " " << name << " -- " << registers[f.get()] << ";" << std::endl;
2942 }
2943
2944 return this->shared_from_this();
2945 }
2946 };
2947
2948//------------------------------------------------------------------------------
2961//------------------------------------------------------------------------------
2962 template<jit::float_scalar T, bool SAFE_MATH=false>
2966 auto temp = std::make_shared<if_node<T, SAFE_MATH>> (c, t, f)->reduce();
2967// Test for hash collisions.
2968 for (size_t i = temp->get_hash();
2970 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
2971 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
2973 return temp;
2974 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
2975 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
2976 }
2977 }
2978#if defined(__clang__) || defined(__GNUC__)
2980#else
2981 assert(false && "Should never reach.");
2982#endif
2983 }
2984
2986 template<jit::float_scalar T, bool SAFE_MATH=false>
2987 using shared_if = std::shared_ptr<if_node<T, SAFE_MATH>>;
2988
2989//------------------------------------------------------------------------------
2997//------------------------------------------------------------------------------
2998 template<jit::float_scalar T, bool SAFE_MATH=false>
3000 return std::dynamic_pointer_cast<if_node<T, SAFE_MATH>> (x);
3001 }
3002
3003//******************************************************************************
3004// Min node.
3005//******************************************************************************
3006//------------------------------------------------------------------------------
3013//------------------------------------------------------------------------------
3014 template<std::floating_point T, bool SAFE_MATH=false>
3015 class min_node final : public branch_node<T, SAFE_MATH> {
3016 private:
3017//------------------------------------------------------------------------------
3023//------------------------------------------------------------------------------
3024 static std::string to_string(leaf_node<T, SAFE_MATH> *l,
3026 return "min" +
3027 jit::format_to_string(reinterpret_cast<size_t> (l)) +
3028 jit::format_to_string(reinterpret_cast<size_t> (r));
3029 }
3030
3031 public:
3032//------------------------------------------------------------------------------
3037//------------------------------------------------------------------------------
3040 branch_node<T, SAFE_MATH> (l, r,
3041 min_node::to_string(l.get(),
3042 r.get())) {}
3043
3044//------------------------------------------------------------------------------
3050//------------------------------------------------------------------------------
3052 backend::buffer<T> l_result = this->left->evaluate();
3053 backend::buffer<T> r_result = this->right->evaluate();
3054 return backend::min(l_result, r_result);
3055 }
3056
3057//------------------------------------------------------------------------------
3061//------------------------------------------------------------------------------
3063// Constant reductions.
3064 auto lc = constant_cast(this->left);
3065 auto rc = constant_cast(this->right);
3066
3067 if (lc.get() && rc.get()) {
3068 return constant<T, SAFE_MATH> (this->evaluate());
3069 }
3070
3071 auto pl1 = piecewise_1D_cast(this->left);
3072 auto pr1 = piecewise_1D_cast(this->right);
3073 if (pl1.get() && (rc.get() || pl1->is_arg_match(this->right))) {
3074 return piecewise_1D(this->evaluate(), pl1->get_arg());
3075 } else if (pr1.get() && (lc.get() || pr1->is_arg_match(this->left))) {
3076 return piecewise_1D(this->evaluate(), pr1->get_arg());
3077 }
3078
3079 auto pl2 = piecewise_2D_cast(this->left);
3080 auto pr2 = piecewise_2D_cast(this->right);
3081 if (pl2.get() && (rc.get() || pl2->is_arg_match(this->right))) {
3082 return piecewise_2D(this->evaluate(),
3083 pl2->get_num_columns(),
3084 pl2->get_left(),
3085 pl2->get_right());
3086 } else if (pr2.get() && (lc.get() || pr2->is_arg_match(this->left))) {
3087 return piecewise_2D(this->evaluate(),
3088 pr2->get_num_columns(),
3089 pr2->get_left(),
3090 pr2->get_right());
3091 }
3092
3093// Combine 2D and 1D piecewise constants if a row or column matches.
3094 if (pr2.get() && pr2->is_row_match(this->left)) {
3095 backend::buffer<T> result = pl1->evaluate();
3096 result.min_row(pr2->evaluate());
3097 return piecewise_2D(result,
3098 pr2->get_num_columns(),
3099 pr2->get_left(),
3100 pr2->get_right());
3101 } else if (pr2.get() && pr2->is_col_match(this->left)) {
3102 backend::buffer<T> result = pl1->evaluate();
3103 result.min_col(pr2->evaluate());
3104 return piecewise_2D(result,
3105 pr2->get_num_columns(),
3106 pr2->get_left(),
3107 pr2->get_right());
3108 } else if (pl2.get() && pl2->is_row_match(this->right)) {
3109 backend::buffer<T> result = pl2->evaluate();
3110 result.min_row(pr1->evaluate());
3111 return piecewise_2D(result,
3112 pl2->get_num_columns(),
3113 pl2->get_left(),
3114 pl2->get_right());
3115 } else if (pl2.get() && pl2->is_col_match(this->right)) {
3116 backend::buffer<T> result = pl2->evaluate();
3117 result.min_col(pr1->evaluate());
3118 return piecewise_2D(result,
3119 pl2->get_num_columns(),
3120 pl2->get_left(),
3121 pl2->get_right());
3122 }
3123
3124 return this->shared_from_this();
3125 }
3126
3127//------------------------------------------------------------------------------
3134//------------------------------------------------------------------------------
3137 if (this->is_match(x)) {
3138 return one<T, SAFE_MATH> ();
3139 }
3140
3141 const size_t hash = reinterpret_cast<size_t> (x.get());
3142 if (this->df_cache.find(hash) == this->df_cache.end()) {
3143 this->df_cache[hash] = min<T, SAFE_MATH> (this->left->df(x),
3144 this->right->df(x));
3145 }
3146 return this->df_cache[hash];
3147 }
3148
3149//------------------------------------------------------------------------------
3156//------------------------------------------------------------------------------
3158 compile(std::ostringstream &stream,
3159 jit::register_map &registers,
3161 const jit::register_usage &usage) {
3162 if (registers.find(this) == registers.end()) {
3163 auto l = this->left->compile(stream, registers,
3164 thread_mem, usage);
3165 auto r = this->left->compile(stream, registers,
3166 thread_mem, usage);
3167 registers[this] = jit::to_string('r', this);
3168
3169 stream << " const ";
3170 jit::add_type<T> (stream);
3171 stream << " " << registers[this] << " = min("
3172 << registers[l.get()] << ", "
3173 << registers[r.get()] << ")";
3174 this->endline(stream, usage);
3175 }
3176
3177 return this->shared_from_this();
3178 }
3179
3180//------------------------------------------------------------------------------
3185//------------------------------------------------------------------------------
3187 if (this == x.get()) {
3188 return true;
3189 }
3190
3191 auto x_cast = min_cast(x);
3192 if (x_cast.get()) {
3193// Min is commutative.
3194 return (this->left->is_match(x_cast->get_left()) &&
3195 this->right->is_match(x_cast->get_right())) ||
3196 (this->right->is_match(x_cast->get_left()) &&
3197 this->left->is_match(x_cast->get_right()));
3198 }
3199
3200 return false;
3201 }
3202
3203//------------------------------------------------------------------------------
3205//------------------------------------------------------------------------------
3206 virtual void to_latex() const {
3207 std::cout << "min\\left(";
3208 this->left->to_latex();
3209 std::cout << ",";
3210 this->right->to_latex();
3211 std::cout << "\\right)";
3212 }
3213
3214//------------------------------------------------------------------------------
3218//------------------------------------------------------------------------------
3220 if (this->has_pseudo()) {
3221 return min<T, SAFE_MATH> (this->left->remove_pseudo(),
3222 this->right->remove_pseudo());
3223 }
3224 return this->shared_from_this();
3225 }
3226
3227//------------------------------------------------------------------------------
3233//------------------------------------------------------------------------------
3234 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
3235 jit::register_map &registers) {
3236 if (registers.find(this) == registers.end()) {
3237 const std::string name = jit::to_string('r', this);
3238 registers[this] = name;
3239 stream << " " << name
3240 << " [label = \"min\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
3241
3242 auto l = this->left->to_vizgraph(stream, registers);
3243 stream << " " << name << " -- " << registers[l.get()] << ";" << std::endl;
3244 auto r = this->right->to_vizgraph(stream, registers);
3245 stream << " " << name << " -- " << registers[r.get()] << ";" << std::endl;
3246 }
3247
3248 return this->shared_from_this();
3249 }
3250 };
3251
3252//------------------------------------------------------------------------------
3264//------------------------------------------------------------------------------
3265 template<std::floating_point T, bool SAFE_MATH=false>
3268 auto temp = std::make_shared<min_node<T, SAFE_MATH>> (l, r)->reduce();
3269// Test for hash collisions.
3270 for (size_t i = temp->get_hash();
3272 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
3273 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
3275 return temp;
3276 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
3277 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
3278 }
3279 }
3280#if defined(__clang__) || defined(__GNUC__)
3282#else
3283 assert(false && "Should never reach.");
3284#endif
3285 }
3286
3287//------------------------------------------------------------------------------
3297//------------------------------------------------------------------------------
3298 template<std::floating_point T, jit::float_scalar L, bool SAFE_MATH=false>
3301 return min(constant<T, SAFE_MATH> (static_cast<T> (l)), r);
3302 }
3303
3304//------------------------------------------------------------------------------
3314//------------------------------------------------------------------------------
3315 template<std::floating_point T, jit::float_scalar R, bool SAFE_MATH=false>
3317 const R r) {
3318 return min(l, constant<T, SAFE_MATH> (static_cast<T> (r)));
3319 }
3320
3322 template<std::floating_point T, bool SAFE_MATH=false>
3323 using shared_min = std::shared_ptr<min_node<T, SAFE_MATH>>;
3324
3325//------------------------------------------------------------------------------
3333//------------------------------------------------------------------------------
3334 template<jit::float_scalar T, bool SAFE_MATH=false>
3336 return std::dynamic_pointer_cast<min_node<T, SAFE_MATH>> (x);
3337 }
3338}
3339
3340#endif /* logical_h */
Class representing a generic buffer.
Definition backend.hpp:29
void isinf()
isinf query.
Definition backend.hpp:960
void min_row(const buffer< T > &x)
Min row operation.
Definition backend.hpp:517
buffer< T > if_(const buffer< T > &t, const buffer< T > &f)
Apply condition.
Definition backend.hpp:892
void min_col(const buffer< T > &x)
Min col operation.
Definition backend.hpp:561
void isnan()
isnan query.
Definition backend.hpp:967
A and node.
Definition logical.hpp:2204
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce and node.
Definition logical.hpp:2250
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:2271
and_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Construct an and node.
Definition logical.hpp:2226
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:2320
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:2349
virtual backend::buffer< T > evaluate()
Evaluate the results of less than equal.
Definition logical.hpp:2239
virtual bool is_match(shared_leaf< T, SAFE_MATH > x)
Query if the nodes match.
Definition logical.hpp:2298
Class representing a branch node.
Definition node.hpp:1337
shared_leaf< T, SAFE_MATH > right
Right branch of the tree.
Definition node.hpp:1342
shared_leaf< T, SAFE_MATH > left
Left branch of the tree.
Definition node.hpp:1340
An equal node.
Definition logical.hpp:618
equal_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Construct an equal node.
Definition logical.hpp:640
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce an equal node.
Definition logical.hpp:665
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:686
virtual bool is_match(shared_leaf< T, SAFE_MATH > x)
Query if the nodes match.
Definition logical.hpp:713
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:764
virtual backend::buffer< T > evaluate()
Evaluate the results of equal.
Definition logical.hpp:654
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:735
A greater than equal node.
Definition logical.hpp:1692
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:1813
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce greater than equal node.
Definition logical.hpp:1739
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:1784
virtual backend::buffer< T > evaluate()
Evaluate the results of greater than equal.
Definition logical.hpp:1728
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:1760
greater_than_equal_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Construct a greater than equal node.
Definition logical.hpp:1714
A greater than node.
Definition logical.hpp:1180
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce greater than node.
Definition logical.hpp:1227
virtual backend::buffer< T > evaluate()
Evaluate the results of greater than.
Definition logical.hpp:1216
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:1301
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:1272
greater_than_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Construct a greater than node.
Definition logical.hpp:1202
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:1248
An If conditional node.
Definition logical.hpp:2760
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:2928
if_node(shared_leaf< T, SAFE_MATH > c, shared_leaf< T, SAFE_MATH > t, shared_leaf< T, SAFE_MATH > f)
Construct an equal node.
Definition logical.hpp:2787
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce an if node.
Definition logical.hpp:2814
virtual shared_leaf< T, SAFE_MATH > remove_pseudo()
Remove pseudo variable nodes.
Definition logical.hpp:2912
virtual backend::buffer< T > evaluate()
Evaluate the results of if.
Definition logical.hpp:2802
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:2870
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:2897
virtual shared_leaf< T, SAFE_MATH > df(shared_leaf< T, SAFE_MATH > x)
Transform node to derivative.
Definition logical.hpp:2847
isinf node.
Definition logical.hpp:36
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:119
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:98
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce an isinf node.
Definition logical.hpp:78
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:132
isinf_node(shared_leaf< T, SAFE_MATH > arg)
Construct an isinf node.
Definition logical.hpp:55
virtual backend::buffer< T > evaluate()
Evaluate the results of isinf.
Definition logical.hpp:67
isnan node.
Definition logical.hpp:205
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:288
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce an isnan node.
Definition logical.hpp:247
virtual backend::buffer< T > evaluate()
Evaluate the results of isnan.
Definition logical.hpp:236
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:267
isnan_node(shared_leaf< T, SAFE_MATH > arg)
Construct an isnan node.
Definition logical.hpp:224
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:301
Class representing a node leaf.
Definition node.hpp:371
virtual bool is_match(std::shared_ptr< leaf_node< T, SAFE_MATH > > x)
Query if the nodes match.
Definition node.hpp:483
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)=0
Compile the node.
virtual void to_latex() const
Convert the node to latex.
Definition node.hpp:530
virtual void endline(std::ostringstream &stream, const jit::register_usage &usage, const char end=';') const
End a line in the kernel source.
Definition node.hpp:653
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > to_vizgraph(std::stringstream &stream, jit::register_map &registers)=0
Convert the node to vizgraph.
virtual bool has_pseudo() const
Query if the node contains pseudo variables.
Definition node.hpp:633
const size_t hash
Hash for node.
Definition node.hpp:374
std::unordered_map< size_t, std::shared_ptr< leaf_node< T, SAFE_MATH > > > df_cache
Cache derivative terms.
Definition node.hpp:378
A less than equal node.
Definition logical.hpp:1948
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:2016
virtual backend::buffer< T > evaluate()
Evaluate the results of less than equal.
Definition logical.hpp:1984
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce less than equal node.
Definition logical.hpp:1995
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:2069
less_than_equal_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Construct a less than equal node.
Definition logical.hpp:1970
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:2040
A less than node.
Definition logical.hpp:1436
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce less than node.
Definition logical.hpp:1483
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:1504
virtual backend::buffer< T > evaluate()
Evaluate the results of less than.
Definition logical.hpp:1472
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:1557
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:1528
less_than_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Construct a less than node.
Definition logical.hpp:1458
A Min node.
Definition logical.hpp:3015
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:3158
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce a min node.
Definition logical.hpp:3062
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:3234
virtual bool is_match(shared_leaf< T, SAFE_MATH > x)
Query if the nodes match.
Definition logical.hpp:3186
min_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Construct an equal node.
Definition logical.hpp:3038
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:3206
virtual shared_leaf< T, SAFE_MATH > df(shared_leaf< T, SAFE_MATH > x)
Transform node to derivative.
Definition logical.hpp:3136
virtual backend::buffer< T > evaluate()
Evaluate the results of if.
Definition logical.hpp:3051
virtual shared_leaf< T, SAFE_MATH > remove_pseudo()
Remove pseudo variable nodes.
Definition logical.hpp:3219
Nodes without derivatives.
Definition node.hpp:1713
A not equal node.
Definition logical.hpp:899
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:967
virtual backend::buffer< T > evaluate()
Evaluate the results of not equal.
Definition logical.hpp:935
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:1045
virtual bool is_match(shared_leaf< T, SAFE_MATH > x)
Query if the nodes match.
Definition logical.hpp:994
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce an not equal node.
Definition logical.hpp:946
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:1016
not_equal_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Construct an not equal node.
Definition logical.hpp:921
Not node.
Definition logical.hpp:376
not_node(shared_leaf< T, SAFE_MATH > arg)
Construct an not node.
Definition logical.hpp:394
virtual backend::buffer< T > evaluate()
Evaluate the results of not.
Definition logical.hpp:406
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:507
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:480
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:527
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce a not node.
Definition logical.hpp:416
A or node.
Definition logical.hpp:2482
virtual shared_leaf< T, SAFE_MATH > reduce()
Reduce or node.
Definition logical.hpp:2528
virtual bool is_match(shared_leaf< T, SAFE_MATH > x)
Query if the nodes match.
Definition logical.hpp:2576
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition logical.hpp:2549
or_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Construct a or node.
Definition logical.hpp:2504
virtual backend::buffer< T > evaluate()
Evaluate the results of less than equal.
Definition logical.hpp:2517
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition logical.hpp:2627
virtual void to_latex() const
Convert the node to latex.
Definition logical.hpp:2598
Class representing a straight node.
Definition node.hpp:1219
Class representing a triple branch node.
Definition node.hpp:1467
shared_leaf< T, SAFE_MATH > middle
Middle branch of the tree.
Definition node.hpp:1470
Complex scalar concept.
Definition register.hpp:25
subroutine assert(test, message)
Assert check.
Definition f_binding_test.f90:38
buffer< T > min(buffer< T > &a, buffer< T > &b)
Min operation.
Definition backend.hpp:1052
Name space for graph nodes.
Definition arithmetic.hpp:13
shared_piecewise_2D< T, SAFE_MATH > piecewise_2D_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a piecewise 2D node.
Definition piecewise.hpp:1508
shared_leaf< T, SAFE_MATH > less_than(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build less than node from two leaves.
Definition logical.hpp:1585
std::shared_ptr< min_node< T, SAFE_MATH > > shared_min
Convenience type alias for shared min nodes.
Definition logical.hpp:3323
shared_leaf< T, SAFE_MATH > operator!(shared_leaf< T, SAFE_MATH > arg)
Build not node from two leaves.
Definition logical.hpp:584
shared_not< T, SAFE_MATH > not_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a not node.
Definition logical.hpp:602
shared_leaf< T, SAFE_MATH > and_(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build and node from two leaves.
Definition logical.hpp:2377
std::shared_ptr< not_node< T, SAFE_MATH > > shared_not
Convenience type alias for shared not nodes.
Definition logical.hpp:590
std::shared_ptr< and_node< T, SAFE_MATH > > shared_and
Convenience type alias for shared and nodes.
Definition logical.hpp:2454
shared_not_equal< T, SAFE_MATH > not_equal_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a equal node.
Definition logical.hpp:1164
shared_leaf< T, SAFE_MATH > operator>(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build greater than node from two leaves.
Definition logical.hpp:1363
shared_leaf< T, SAFE_MATH > isnan(shared_leaf< T, SAFE_MATH > arg)
Build isnan node from the argument leaves.
Definition logical.hpp:326
shared_subtract< T, SAFE_MATH > subtract_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a subtract node.
Definition arithmetic.hpp:1710
std::shared_ptr< greater_than_node< T, SAFE_MATH > > shared_greater_than
Convenience type alias for shared greater than nodes.
Definition logical.hpp:1408
constexpr shared_leaf< T, SAFE_MATH > zero()
Forward declare for zero.
Definition node.hpp:1154
shared_equal< T, SAFE_MATH > equal_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a equal node.
Definition logical.hpp:883
shared_leaf< T, SAFE_MATH > not_(shared_leaf< T, SAFE_MATH > arg)
Build not node from the argument leaves.
Definition logical.hpp:552
shared_greater_than< T, SAFE_MATH > greater_than_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a greater than node.
Definition logical.hpp:1420
shared_leaf< T, SAFE_MATH > not_equal(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build note equal node from two leaves.
Definition logical.hpp:1073
shared_and< T, SAFE_MATH > and_cast(shared_leaf< T, SAFE_MATH > x)
Cast to an and node.
Definition logical.hpp:2466
shared_add< T, SAFE_MATH > add_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a add node.
Definition arithmetic.hpp:855
shared_leaf< T, SAFE_MATH > greater_than(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build greater than node from two leaves.
Definition logical.hpp:1329
shared_leaf< T, SAFE_MATH > less_than_equal(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build less than equal node from two leaves.
Definition logical.hpp:2097
shared_leaf< T, SAFE_MATH > operator<(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build less than node from two leaves.
Definition logical.hpp:1619
shared_piecewise_1D< T, SAFE_MATH > piecewise_1D_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a piecewise 1D node.
Definition piecewise.hpp:849
shared_leaf< T, SAFE_MATH > or_(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build or node from two leaves.
Definition logical.hpp:2655
shared_leaf< T, SAFE_MATH > operator!=(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build not equal node from two leaves.
Definition logical.hpp:1107
shared_leaf< T, SAFE_MATH > operator>=(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build greater than equal node from two leaves.
Definition logical.hpp:1875
std::shared_ptr< isnan_node< T, SAFE_MATH > > shared_isnan
Convenience type alias for shared isnan nodes.
Definition logical.hpp:348
std::shared_ptr< isinf_node< T, SAFE_MATH > > shared_isinf
Convenience type alias for shared isinf nodes.
Definition logical.hpp:179
shared_isnan< T, SAFE_MATH > isnan_cast(shared_leaf< T, SAFE_MATH > x)
Cast to an isnan node.
Definition logical.hpp:360
shared_constant< T, SAFE_MATH > constant_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a constant node.
Definition node.hpp:1202
shared_less_than_equal< T, SAFE_MATH > less_than_equal_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a less than equal node.
Definition logical.hpp:2188
std::shared_ptr< less_than_equal_node< T, SAFE_MATH > > shared_less_than_equal
Convenience type alias for shared less than equal nodes.
Definition logical.hpp:2176
std::shared_ptr< greater_than_equal_node< T, SAFE_MATH > > shared_greater_than_equal
Convenience type alias for shared greater than equal nodes.
Definition logical.hpp:1920
constexpr T i
Convenience type for imaginary constant.
Definition node.hpp:1186
shared_min< T, SAFE_MATH > min_cast(shared_leaf< T, SAFE_MATH > x)
Cast to an min node.
Definition logical.hpp:3335
shared_leaf< T, SAFE_MATH > operator||(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build or node from two leaves.
Definition logical.hpp:2689
std::shared_ptr< less_than_node< T, SAFE_MATH > > shared_less_than
Convenience type alias for shared less than nodes.
Definition logical.hpp:1664
shared_isinf< T, SAFE_MATH > isinf_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a isinf node.
Definition logical.hpp:191
shared_leaf< T, SAFE_MATH > if_(shared_leaf< T, SAFE_MATH > c, shared_leaf< T, SAFE_MATH > t, shared_leaf< T, SAFE_MATH > f)
Build an if node from a condition and two leaves.
Definition logical.hpp:2963
std::shared_ptr< equal_node< T, SAFE_MATH > > shared_equal
Convenience type alias for shared equal nodes.
Definition logical.hpp:871
std::shared_ptr< or_node< T, SAFE_MATH > > shared_or
Convenience type alias for shared or nodes.
Definition logical.hpp:2732
shared_leaf< T, SAFE_MATH > min(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build a max node from a condition and two leaves.
Definition logical.hpp:3266
shared_leaf< T, SAFE_MATH > equal(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build equal node from two leaves.
Definition logical.hpp:792
std::shared_ptr< leaf_node< T, SAFE_MATH > > shared_leaf
Convenience type alias for shared leaf nodes.
Definition node.hpp:691
shared_leaf< T, SAFE_MATH > operator==(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build equal node from two leaves.
Definition logical.hpp:826
shared_less_than< T, SAFE_MATH > less_than_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a less than node.
Definition logical.hpp:1676
shared_leaf< T, SAFE_MATH > isinf(shared_leaf< T, SAFE_MATH > arg)
Build not node from the argument leaves.
Definition logical.hpp:157
constexpr shared_leaf< T, SAFE_MATH > true_constant()
Convenience type for true constant.
Definition logical.hpp:16
constexpr shared_leaf< T, SAFE_MATH > false_constant()
Convenience type for false constant.
Definition logical.hpp:22
std::shared_ptr< not_equal_node< T, SAFE_MATH > > shared_not_equal
Convenience type alias for shared not equal nodes.
Definition logical.hpp:1152
shared_leaf< T, SAFE_MATH > operator<=(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build less than equal node from two leaves.
Definition logical.hpp:2131
shared_leaf< T, SAFE_MATH > operator&&(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build and node from two leaves.
Definition logical.hpp:2411
shared_if< T, SAFE_MATH > if_cast(shared_leaf< T, SAFE_MATH > x)
Cast to an if node.
Definition logical.hpp:2999
shared_or< T, SAFE_MATH > or_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a or node.
Definition logical.hpp:2744
shared_greater_than_equal< T, SAFE_MATH > greater_than_equal_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a greater than equal node.
Definition logical.hpp:1932
shared_leaf< T, SAFE_MATH > greater_than_equal(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r)
Build greater than equal node from two leaves.
Definition logical.hpp:1841
std::shared_ptr< if_node< T, SAFE_MATH > > shared_if
Convenience type alias for shared add nodes.
Definition logical.hpp:2987
std::string format_to_string(const T value)
Convert a value to a string while avoiding locale.
Definition register.hpp:213
std::unordered_map< void *, size_t > register_usage
Type alias for counting register usage.
Definition register.hpp:261
std::unordered_map< void *, std::string > register_map
Type alias for mapping node pointers to register names.
Definition register.hpp:259
std::string to_string(const char prefix, const NODE *pointer)
Convert a graph::leaf_node pointer to a string.
Definition register.hpp:247
Base nodes of graph computation framework.
void piecewise_1D()
Tests for 1D piecewise nodes.
Definition piecewise_test.cpp:82
void piecewise_2D()
Tests for 2D piecewise nodes.
Definition piecewise_test.cpp:321