Sleipnir C++ API
Loading...
Searching...
No Matches
Expression.hpp
Go to the documentation of this file.
1// Copyright (c) Sleipnir contributors
2
3#pragma once
4
5#include <stdint.h>
6
7#include <array>
8#include <cmath>
9#include <memory>
10#include <numbers>
11#include <utility>
12
17
19
20// The global pool allocator uses a thread-local static pool resource, which
21// isn't guaranteed to be initialized properly across DLL boundaries on Windows
22#ifdef _WIN32
23inline constexpr bool kUsePoolAllocator = false;
24#else
25inline constexpr bool kUsePoolAllocator = true;
26#endif
27
28struct Expression;
29
30inline constexpr void IntrusiveSharedPtrIncRefCount(Expression* expr);
31inline constexpr void IntrusiveSharedPtrDecRefCount(Expression* expr);
32
37
45template <typename T, typename... Args>
46static ExpressionPtr MakeExpressionPtr(Args&&... args) {
47 if constexpr (kUsePoolAllocator) {
49 std::forward<Args>(args)...);
50 } else {
51 return MakeIntrusiveShared<T>(std::forward<Args>(args)...);
52 }
53}
54
55template <ExpressionType Type>
56struct BinaryMinusExpression;
57
58template <ExpressionType Type>
59struct BinaryPlusExpression;
60
61struct ConstExpression;
62
63template <ExpressionType Type>
64struct DivExpression;
65
66template <ExpressionType Type>
67struct MultExpression;
68
69template <ExpressionType Type>
70struct UnaryMinusExpression;
71
75struct Expression {
77 double value = 0.0;
78
80 double adjoint = 0.0;
81
85
89
93
96
98 std::array<ExpressionPtr, 2> args{nullptr, nullptr};
99
103 constexpr Expression() = default;
104
110 explicit constexpr Expression(double value) : value{value} {}
111
117 explicit constexpr Expression(ExpressionPtr lhs)
118 : args{std::move(lhs), nullptr} {}
119
127 : args{std::move(lhs), std::move(rhs)} {}
128
129 virtual ~Expression() = default;
130
136 constexpr bool IsConstant(double constant) const {
138 }
139
147 const ExpressionPtr& rhs) {
148 using enum ExpressionType;
149
150 // Prune expression
151 if (lhs->IsConstant(0.0)) {
152 // Return zero
153 return lhs;
154 } else if (rhs->IsConstant(0.0)) {
155 // Return zero
156 return rhs;
157 } else if (lhs->IsConstant(1.0)) {
158 return rhs;
159 } else if (rhs->IsConstant(1.0)) {
160 return lhs;
161 }
162
163 // Evaluate constant
164 if (lhs->Type() == kConstant && rhs->Type() == kConstant) {
165 return MakeExpressionPtr<ConstExpression>(lhs->value * rhs->value);
166 }
167
168 // Evaluate expression type
169 if (lhs->Type() == kConstant) {
170 if (rhs->Type() == kLinear) {
172 } else if (rhs->Type() == kQuadratic) {
174 } else {
176 }
177 } else if (rhs->Type() == kConstant) {
178 if (lhs->Type() == kLinear) {
180 } else if (lhs->Type() == kQuadratic) {
182 } else {
184 }
185 } else if (lhs->Type() == kLinear && rhs->Type() == kLinear) {
187 } else {
189 }
190 }
191
199 const ExpressionPtr& rhs) {
200 using enum ExpressionType;
201
202 // Prune expression
203 if (lhs->IsConstant(0.0)) {
204 // Return zero
205 return lhs;
206 } else if (rhs->IsConstant(1.0)) {
207 return lhs;
208 }
209
210 // Evaluate constant
211 if (lhs->Type() == kConstant && rhs->Type() == kConstant) {
212 return MakeExpressionPtr<ConstExpression>(lhs->value / rhs->value);
213 }
214
215 // Evaluate expression type
216 if (rhs->Type() == kConstant) {
217 if (lhs->Type() == kLinear) {
219 } else if (lhs->Type() == kQuadratic) {
221 } else {
223 }
224 } else {
226 }
227 }
228
236 const ExpressionPtr& rhs) {
237 using enum ExpressionType;
238
239 // Prune expression
240 if (lhs == nullptr || lhs->IsConstant(0.0)) {
241 return rhs;
242 } else if (rhs == nullptr || rhs->IsConstant(0.0)) {
243 return lhs;
244 }
245
246 // Evaluate constant
247 if (lhs->Type() == kConstant && rhs->Type() == kConstant) {
248 return MakeExpressionPtr<ConstExpression>(lhs->value + rhs->value);
249 }
250
251 // Use max of lhs and rhs expression types
252 if (lhs->Type() < rhs->Type()) {
253 if (rhs->Type() == kLinear) {
255 } else if (rhs->Type() == kQuadratic) {
257 } else {
259 }
260 } else {
261 if (lhs->Type() == kLinear) {
263 } else if (lhs->Type() == kQuadratic) {
265 } else {
267 }
268 }
269 }
270
278 const ExpressionPtr& rhs) {
279 using enum ExpressionType;
280
281 // Prune expression
282 if (lhs->IsConstant(0.0)) {
283 if (rhs->IsConstant(0.0)) {
284 // Return zero
285 return rhs;
286 } else {
287 return -rhs;
288 }
289 } else if (rhs->IsConstant(0.0)) {
290 return lhs;
291 }
292
293 // Evaluate constant
294 if (lhs->Type() == kConstant && rhs->Type() == kConstant) {
295 return MakeExpressionPtr<ConstExpression>(lhs->value - rhs->value);
296 }
297
298 // Use max of lhs and rhs expression types
299 if (lhs->Type() < rhs->Type()) {
300 if (rhs->Type() == kLinear) {
302 } else if (rhs->Type() == kQuadratic) {
304 } else {
306 }
307 } else {
308 if (lhs->Type() == kLinear) {
310 } else if (lhs->Type() == kQuadratic) {
312 } else {
314 }
315 }
316 }
317
324 using enum ExpressionType;
325
326 // Prune expression
327 if (lhs->IsConstant(0.0)) {
328 // Return zero
329 return lhs;
330 }
331
332 // Evaluate constant
333 if (lhs->Type() == kConstant) {
335 }
336
337 if (lhs->Type() == kLinear) {
339 } else if (lhs->Type() == kQuadratic) {
341 } else {
343 }
344 }
345
351 friend ExpressionPtr operator+(const ExpressionPtr& lhs) { return lhs; }
352
361 virtual double Value([[maybe_unused]] double lhs,
362 [[maybe_unused]] double rhs) const = 0;
363
368 virtual ExpressionType Type() const = 0;
369
377 virtual double GradientValueLhs([[maybe_unused]] double lhs,
378 [[maybe_unused]] double rhs,
379 [[maybe_unused]] double parentAdjoint) const {
380 return 0.0;
381 }
382
390 virtual double GradientValueRhs([[maybe_unused]] double lhs,
391 [[maybe_unused]] double rhs,
392 [[maybe_unused]] double parentAdjoint) const {
393 return 0.0;
394 }
395
409
423};
424
425template <ExpressionType T>
434 : Expression{std::move(lhs), std::move(rhs)} {
435 value = args[0]->value - args[1]->value;
436 }
437
438 double Value(double lhs, double rhs) const override { return lhs - rhs; }
439
440 ExpressionType Type() const override { return T; }
441
442 double GradientValueLhs(double, double, double parentAdjoint) const override {
443 return parentAdjoint;
444 }
445
446 double GradientValueRhs(double, double, double parentAdjoint) const override {
447 return -parentAdjoint;
448 }
449
451 const ExpressionPtr& parentAdjoint) const override {
452 return parentAdjoint;
453 }
454
456 const ExpressionPtr& parentAdjoint) const override {
457 return -parentAdjoint;
458 }
459};
460
461template <ExpressionType T>
470 : Expression{std::move(lhs), std::move(rhs)} {
471 value = args[0]->value + args[1]->value;
472 }
473
474 double Value(double lhs, double rhs) const override { return lhs + rhs; }
475
476 ExpressionType Type() const override { return T; }
477
478 double GradientValueLhs(double, double, double parentAdjoint) const override {
479 return parentAdjoint;
480 }
481
482 double GradientValueRhs(double, double, double parentAdjoint) const override {
483 return parentAdjoint;
484 }
485
487 const ExpressionPtr& parentAdjoint) const override {
488 return parentAdjoint;
489 }
490
492 const ExpressionPtr& parentAdjoint) const override {
493 return parentAdjoint;
494 }
495};
496
501 constexpr ConstExpression() = default;
502
508 explicit constexpr ConstExpression(double value) : Expression{value} {}
509
510 double Value(double, double) const override { return value; }
511
512 ExpressionType Type() const override { return ExpressionType::kConstant; }
513};
514
519 constexpr DecisionVariableExpression() = default;
520
526 explicit constexpr DecisionVariableExpression(double value)
527 : Expression{value} {}
528
529 double Value(double, double) const override { return value; }
530
531 ExpressionType Type() const override { return ExpressionType::kLinear; }
532};
533
534template <ExpressionType T>
543 : Expression{std::move(lhs), std::move(rhs)} {
544 value = args[0]->value / args[1]->value;
545 }
546
547 double Value(double lhs, double rhs) const override { return lhs / rhs; }
548
549 ExpressionType Type() const override { return T; }
550
551 double GradientValueLhs(double, double rhs,
552 double parentAdjoint) const override {
553 return parentAdjoint / rhs;
554 };
555
556 double GradientValueRhs(double lhs, double rhs,
557 double parentAdjoint) const override {
558 return parentAdjoint * -lhs / (rhs * rhs);
559 }
560
562 const ExpressionPtr& parentAdjoint) const override {
563 return parentAdjoint / rhs;
564 }
565
567 const ExpressionPtr& parentAdjoint) const override {
568 return parentAdjoint * -lhs / (rhs * rhs);
569 }
570};
571
572template <ExpressionType T>
581 : Expression{std::move(lhs), std::move(rhs)} {
582 value = args[0]->value * args[1]->value;
583 }
584
585 double Value(double lhs, double rhs) const override { return lhs * rhs; }
586
587 ExpressionType Type() const override { return T; }
588
589 double GradientValueLhs([[maybe_unused]] double lhs, double rhs,
590 double parentAdjoint) const override {
591 return parentAdjoint * rhs;
592 }
593
594 double GradientValueRhs(double lhs, [[maybe_unused]] double rhs,
595 double parentAdjoint) const override {
596 return parentAdjoint * lhs;
597 }
598
600 const ExpressionPtr& rhs,
601 const ExpressionPtr& parentAdjoint) const override {
602 return parentAdjoint * rhs;
603 }
604
606 [[maybe_unused]] const ExpressionPtr& rhs,
607 const ExpressionPtr& parentAdjoint) const override {
608 return parentAdjoint * lhs;
609 }
610};
611
612template <ExpressionType T>
620 : Expression{std::move(lhs)} {
621 value = -args[0]->value;
622 }
623
624 double Value(double lhs, double) const override { return -lhs; }
625
626 ExpressionType Type() const override { return T; }
627
628 double GradientValueLhs(double, double, double parentAdjoint) const override {
629 return -parentAdjoint;
630 }
631
633 const ExpressionPtr& parentAdjoint) const override {
634 return -parentAdjoint;
635 }
636};
637
638inline ExpressionPtr exp(const ExpressionPtr& x);
639inline ExpressionPtr sin(const ExpressionPtr& x);
640inline ExpressionPtr sinh(const ExpressionPtr& x);
641inline ExpressionPtr sqrt(const ExpressionPtr& x);
642
648inline constexpr void IntrusiveSharedPtrIncRefCount(Expression* expr) {
649 ++expr->refCount;
650}
651
657inline constexpr void IntrusiveSharedPtrDecRefCount(Expression* expr) {
658 // If a deeply nested tree is being deallocated all at once, calling the
659 // Expression destructor when expr's refcount reaches zero can cause a stack
660 // overflow. Instead, we iterate over its children to decrement their
661 // refcounts and deallocate them.
663 stack.emplace_back(expr);
664
665 while (!stack.empty()) {
666 auto elem = stack.back();
667 stack.pop_back();
668
669 // Decrement the current node's refcount. If it reaches zero, deallocate the
670 // node and enqueue its children so their refcounts are decremented too.
671 if (--elem->refCount == 0) {
672 if (elem->adjointExpr != nullptr) {
673 stack.emplace_back(elem->adjointExpr.Get());
674 }
675 for (auto& arg : elem->args) {
676 if (arg != nullptr) {
677 stack.emplace_back(arg.Get());
678 }
679 }
680
681 // Not calling the destructor here is safe because it only decrements
682 // refcounts, which was already done above.
683 if constexpr (kUsePoolAllocator) {
685 std::allocator_traits<decltype(alloc)>::deallocate(alloc, elem,
686 sizeof(Expression));
687 }
688 }
689 }
690}
691
698 explicit constexpr AbsExpression(ExpressionPtr lhs)
699 : Expression{std::move(lhs)} {
700 value = args[0]->value < 0 ? -args[0]->value : args[0]->value;
701 }
702
703 double Value(double x, double) const override { return std::abs(x); }
704
705 ExpressionType Type() const override { return ExpressionType::kNonlinear; }
706
707 double GradientValueLhs(double x, double,
708 double parentAdjoint) const override {
709 if (x < 0.0) {
710 return -parentAdjoint;
711 } else if (x > 0.0) {
712 return parentAdjoint;
713 } else {
714 return 0.0;
715 }
716 }
717
719 const ExpressionPtr& parentAdjoint) const override {
720 if (x->value < 0.0) {
721 return -parentAdjoint;
722 } else if (x->value > 0.0) {
723 return parentAdjoint;
724 } else {
725 // Return zero
727 }
728 }
729};
730
737 using enum ExpressionType;
738
739 // Prune expression
740 if (x->IsConstant(0.0)) {
741 // Return zero
742 return x;
743 }
744
745 // Evaluate constant
746 if (x->Type() == kConstant) {
747 return MakeExpressionPtr<ConstExpression>(std::abs(x->value));
748 }
749
751}
752
760 value = std::acos(args[0]->value);
761 }
762
763 double Value(double x, double) const override { return std::acos(x); }
764
765 ExpressionType Type() const override { return ExpressionType::kNonlinear; }
766
767 double GradientValueLhs(double x, double,
768 double parentAdjoint) const override {
769 return -parentAdjoint / std::sqrt(1.0 - x * x);
770 }
771
773 const ExpressionPtr& parentAdjoint) const override {
774 return -parentAdjoint /
776 x * x);
777 }
778};
779
786 using enum ExpressionType;
787
788 // Prune expression
789 if (x->IsConstant(0.0)) {
790 return MakeExpressionPtr<ConstExpression>(std::numbers::pi / 2.0);
791 }
792
793 // Evaluate constant
794 if (x->Type() == kConstant) {
795 return MakeExpressionPtr<ConstExpression>(std::acos(x->value));
796 }
797
799}
800
808 value = std::asin(args[0]->value);
809 }
810
811 double Value(double x, double) const override { return std::asin(x); }
812
813 ExpressionType Type() const override { return ExpressionType::kNonlinear; }
814
815 double GradientValueLhs(double x, double,
816 double parentAdjoint) const override {
817 return parentAdjoint / std::sqrt(1.0 - x * x);
818 }
819
825};
826
833 using enum ExpressionType;
834
835 // Prune expression
836 if (x->IsConstant(0.0)) {
837 // Return zero
838 return x;
839 }
840
841 // Evaluate constant
842 if (x->Type() == kConstant) {
843 return MakeExpressionPtr<ConstExpression>(std::asin(x->value));
844 }
845
847}
848
856 value = std::atan(args[0]->value);
857 }
858
859 double Value(double x, double) const override { return std::atan(x); }
860
861 ExpressionType Type() const override { return ExpressionType::kNonlinear; }
862
863 double GradientValueLhs(double x, double,
864 double parentAdjoint) const override {
865 return parentAdjoint / (1.0 + x * x);
866 }
867
869 const ExpressionPtr& parentAdjoint) const override {
871 }
872};
873
880 using enum ExpressionType;
881
882 // Prune expression
883 if (x->IsConstant(0.0)) {
884 // Return zero
885 return x;
886 }
887
888 // Evaluate constant
889 if (x->Type() == kConstant) {
890 return MakeExpressionPtr<ConstExpression>(std::atan(x->value));
891 }
892
894}
895
904 : Expression{std::move(lhs), std::move(rhs)} {
905 value = std::atan2(args[0]->value, args[1]->value);
906 }
907
908 double Value(double y, double x) const override { return std::atan2(y, x); }
909
910 ExpressionType Type() const override { return ExpressionType::kNonlinear; }
911
912 double GradientValueLhs(double y, double x,
913 double parentAdjoint) const override {
914 return parentAdjoint * x / (y * y + x * x);
915 }
916
917 double GradientValueRhs(double y, double x,
918 double parentAdjoint) const override {
919 return parentAdjoint * -y / (y * y + x * x);
920 }
921
923 const ExpressionPtr& parentAdjoint) const override {
924 return parentAdjoint * x / (y * y + x * x);
925 }
926
928 const ExpressionPtr& parentAdjoint) const override {
929 return parentAdjoint * -y / (y * y + x * x);
930 }
931};
932
940 using enum ExpressionType;
941
942 // Prune expression
943 if (y->IsConstant(0.0)) {
944 // Return zero
945 return y;
946 } else if (x->IsConstant(0.0)) {
947 return MakeExpressionPtr<ConstExpression>(std::numbers::pi / 2.0);
948 }
949
950 // Evaluate constant
951 if (y->Type() == kConstant && x->Type() == kConstant) {
952 return MakeExpressionPtr<ConstExpression>(std::atan2(y->value, x->value));
953 }
954
956}
957
965 value = std::cos(args[0]->value);
966 }
967
968 double Value(double x, double) const override { return std::cos(x); }
969
970 ExpressionType Type() const override { return ExpressionType::kNonlinear; }
971
972 double GradientValueLhs(double x, double,
973 double parentAdjoint) const override {
974 return -parentAdjoint * std::sin(x);
975 }
976
978 const ExpressionPtr& parentAdjoint) const override {
980 }
981};
982
989 using enum ExpressionType;
990
991 // Prune expression
992 if (x->IsConstant(0.0)) {
994 }
995
996 // Evaluate constant
997 if (x->Type() == kConstant) {
998 return MakeExpressionPtr<ConstExpression>(std::cos(x->value));
999 }
1000
1002}
1003
1011 value = std::cosh(args[0]->value);
1012 }
1013
1014 double Value(double x, double) const override { return std::cosh(x); }
1015
1017
1018 double GradientValueLhs(double x, double,
1019 double parentAdjoint) const override {
1020 return parentAdjoint * std::sinh(x);
1021 }
1022
1024 const ExpressionPtr& parentAdjoint) const override {
1026 }
1027};
1028
1035 using enum ExpressionType;
1036
1037 // Prune expression
1038 if (x->IsConstant(0.0)) {
1040 }
1041
1042 // Evaluate constant
1043 if (x->Type() == kConstant) {
1044 return MakeExpressionPtr<ConstExpression>(std::cosh(x->value));
1045 }
1046
1048}
1049
1057 value = std::erf(args[0]->value);
1058 }
1059
1060 double Value(double x, double) const override { return std::erf(x); }
1061
1063
1064 double GradientValueLhs(double x, double,
1065 double parentAdjoint) const override {
1066 return parentAdjoint * 2.0 * std::numbers::inv_sqrtpi * std::exp(-x * x);
1067 }
1068
1070 const ExpressionPtr& parentAdjoint) const override {
1071 return parentAdjoint *
1072 MakeExpressionPtr<ConstExpression>(2.0 * std::numbers::inv_sqrtpi) *
1073 sleipnir::detail::exp(-x * x);
1074 }
1075};
1076
1083 using enum ExpressionType;
1084
1085 // Prune expression
1086 if (x->IsConstant(0.0)) {
1087 // Return zero
1088 return x;
1089 }
1090
1091 // Evaluate constant
1092 if (x->Type() == kConstant) {
1093 return MakeExpressionPtr<ConstExpression>(std::erf(x->value));
1094 }
1095
1097}
1098
1106 value = std::exp(args[0]->value);
1107 }
1108
1109 double Value(double x, double) const override { return std::exp(x); }
1110
1112
1113 double GradientValueLhs(double x, double,
1114 double parentAdjoint) const override {
1115 return parentAdjoint * std::exp(x);
1116 }
1117
1119 const ExpressionPtr& parentAdjoint) const override {
1121 }
1122};
1123
1130 using enum ExpressionType;
1131
1132 // Prune expression
1133 if (x->IsConstant(0.0)) {
1135 }
1136
1137 // Evaluate constant
1138 if (x->Type() == kConstant) {
1139 return MakeExpressionPtr<ConstExpression>(std::exp(x->value));
1140 }
1141
1143}
1144
1145inline ExpressionPtr hypot(const ExpressionPtr& x, const ExpressionPtr& y);
1146
1155 : Expression{std::move(lhs), std::move(rhs)} {
1156 value = std::hypot(args[0]->value, args[1]->value);
1157 }
1158
1159 double Value(double x, double y) const override { return std::hypot(x, y); }
1160
1162
1163 double GradientValueLhs(double x, double y,
1164 double parentAdjoint) const override {
1165 return parentAdjoint * x / std::hypot(x, y);
1166 }
1167
1168 double GradientValueRhs(double x, double y,
1169 double parentAdjoint) const override {
1170 return parentAdjoint * y / std::hypot(x, y);
1171 }
1172
1174 const ExpressionPtr& parentAdjoint) const override {
1175 return parentAdjoint * x / sleipnir::detail::hypot(x, y);
1176 }
1177
1179 const ExpressionPtr& parentAdjoint) const override {
1181 }
1182};
1183
1191 using enum ExpressionType;
1192
1193 // Prune expression
1194 if (x->IsConstant(0.0)) {
1195 return y;
1196 } else if (y->IsConstant(0.0)) {
1197 return x;
1198 }
1199
1200 // Evaluate constant
1201 if (x->Type() == kConstant && y->Type() == kConstant) {
1202 return MakeExpressionPtr<ConstExpression>(std::hypot(x->value, y->value));
1203 }
1204
1206}
1207
1215 value = std::log(args[0]->value);
1216 }
1217
1218 double Value(double x, double) const override { return std::log(x); }
1219
1221
1222 double GradientValueLhs(double x, double,
1223 double parentAdjoint) const override {
1224 return parentAdjoint / x;
1225 }
1226
1228 const ExpressionPtr& parentAdjoint) const override {
1229 return parentAdjoint / x;
1230 }
1231};
1232
1239 using enum ExpressionType;
1240
1241 // Prune expression
1242 if (x->IsConstant(0.0)) {
1243 // Return zero
1244 return x;
1245 }
1246
1247 // Evaluate constant
1248 if (x->Type() == kConstant) {
1249 return MakeExpressionPtr<ConstExpression>(std::log(x->value));
1250 }
1251
1253}
1254
1262 value = std::log10(args[0]->value);
1263 }
1264
1265 double Value(double x, double) const override { return std::log10(x); }
1266
1268
1269 double GradientValueLhs(double x, double,
1270 double parentAdjoint) const override {
1271 return parentAdjoint / (std::numbers::ln10 * x);
1272 }
1273
1275 const ExpressionPtr& parentAdjoint) const override {
1276 return parentAdjoint /
1277 (MakeExpressionPtr<ConstExpression>(std::numbers::ln10) * x);
1278 }
1279};
1280
1287 using enum ExpressionType;
1288
1289 // Prune expression
1290 if (x->IsConstant(0.0)) {
1291 // Return zero
1292 return x;
1293 }
1294
1295 // Evaluate constant
1296 if (x->Type() == kConstant) {
1297 return MakeExpressionPtr<ConstExpression>(std::log10(x->value));
1298 }
1299
1301}
1302
1303inline ExpressionPtr pow(const ExpressionPtr& base, const ExpressionPtr& power);
1304
1305template <ExpressionType T>
1314 : Expression{std::move(lhs), std::move(rhs)} {
1315 value = std::pow(args[0]->value, args[1]->value);
1316 }
1317
1318 double Value(double base, double power) const override {
1319 return std::pow(base, power);
1320 }
1321
1322 ExpressionType Type() const override { return T; }
1323
1324 double GradientValueLhs(double base, double power,
1325 double parentAdjoint) const override {
1326 return parentAdjoint * std::pow(base, power - 1) * power;
1327 }
1328
1329 double GradientValueRhs(double base, double power,
1330 double parentAdjoint) const override {
1331 // Since x * std::log(x) -> 0 as x -> 0
1332 if (base == 0.0) {
1333 return 0.0;
1334 } else {
1335 return parentAdjoint * std::pow(base, power - 1) * base * std::log(base);
1336 }
1337 }
1338
1340 const ExpressionPtr& power,
1341 const ExpressionPtr& parentAdjoint) const override {
1342 return parentAdjoint *
1345 power;
1346 }
1347
1349 const ExpressionPtr& power,
1350 const ExpressionPtr& parentAdjoint) const override {
1351 // Since x * std::log(x) -> 0 as x -> 0
1352 if (base->value == 0.0) {
1353 // Return zero
1354 return base;
1355 } else {
1356 return parentAdjoint *
1359 base * sleipnir::detail::log(base);
1360 }
1361 }
1362};
1363
1371 const ExpressionPtr& power) {
1372 using enum ExpressionType;
1373
1374 // Prune expression
1375 if (base->IsConstant(0.0)) {
1376 // Return zero
1377 return base;
1378 } else if (base->IsConstant(1.0)) {
1379 return base;
1380 }
1381 if (power->IsConstant(0.0)) {
1383 } else if (power->IsConstant(1.0)) {
1384 return base;
1385 }
1386
1387 // Evaluate constant
1388 if (base->Type() == kConstant && power->Type() == kConstant) {
1390 std::pow(base->value, power->value));
1391 }
1392
1393 if (base->Type() == kLinear && power->IsConstant(2.0)) {
1395 } else {
1397 }
1398}
1399
1407 : Expression{std::move(lhs)} {
1408 if (args[0]->value < 0.0) {
1409 value = -1.0;
1410 } else if (args[0]->value == 0.0) {
1411 value = 0.0;
1412 } else {
1413 value = 1.0;
1414 }
1415 }
1416
1417 double Value(double x, double) const override {
1418 if (x < 0.0) {
1419 return -1.0;
1420 } else if (x == 0.0) {
1421 return 0.0;
1422 } else {
1423 return 1.0;
1424 }
1425 }
1426
1428
1429 double GradientValueLhs(double, double, double) const override { return 0.0; }
1430
1432 const ExpressionPtr&) const override {
1433 // Return zero
1435 }
1436};
1437
1444 using enum ExpressionType;
1445
1446 // Evaluate constant
1447 if (x->Type() == kConstant) {
1448 if (x->value < 0.0) {
1450 } else if (x->value == 0.0) {
1451 // Return zero
1452 return x;
1453 } else {
1455 }
1456 }
1457
1459}
1460
1468 value = std::sin(args[0]->value);
1469 }
1470
1471 double Value(double x, double) const override { return std::sin(x); }
1472
1474
1475 double GradientValueLhs(double x, double,
1476 double parentAdjoint) const override {
1477 return parentAdjoint * std::cos(x);
1478 }
1479
1481 const ExpressionPtr& parentAdjoint) const override {
1483 }
1484};
1485
1492 using enum ExpressionType;
1493
1494 // Prune expression
1495 if (x->IsConstant(0.0)) {
1496 // Return zero
1497 return x;
1498 }
1499
1500 // Evaluate constant
1501 if (x->Type() == kConstant) {
1502 return MakeExpressionPtr<ConstExpression>(std::sin(x->value));
1503 }
1504
1506}
1507
1515 value = std::sinh(args[0]->value);
1516 }
1517
1518 double Value(double x, double) const override { return std::sinh(x); }
1519
1521
1522 double GradientValueLhs(double x, double,
1523 double parentAdjoint) const override {
1524 return parentAdjoint * std::cosh(x);
1525 }
1526
1528 const ExpressionPtr& parentAdjoint) const override {
1530 }
1531};
1532
1539 using enum ExpressionType;
1540
1541 // Prune expression
1542 if (x->IsConstant(0.0)) {
1543 // Return zero
1544 return x;
1545 }
1546
1547 // Evaluate constant
1548 if (x->Type() == kConstant) {
1549 return MakeExpressionPtr<ConstExpression>(std::sinh(x->value));
1550 }
1551
1553}
1554
1562 value = std::sqrt(args[0]->value);
1563 }
1564
1565 double Value(double x, double) const override { return std::sqrt(x); }
1566
1568
1569 double GradientValueLhs(double x, double,
1570 double parentAdjoint) const override {
1571 return parentAdjoint / (2.0 * std::sqrt(x));
1572 }
1573
1579};
1580
1587 using enum ExpressionType;
1588
1589 // Evaluate constant
1590 if (x->Type() == kConstant) {
1591 if (x->value == 0.0) {
1592 // Return zero
1593 return x;
1594 } else if (x->value == 1.0) {
1595 return x;
1596 } else {
1597 return MakeExpressionPtr<ConstExpression>(std::sqrt(x->value));
1598 }
1599 }
1600
1602}
1603
1611 value = std::tan(args[0]->value);
1612 }
1613
1614 double Value(double x, double) const override { return std::tan(x); }
1615
1617
1618 double GradientValueLhs(double x, double,
1619 double parentAdjoint) const override {
1620 return parentAdjoint / (std::cos(x) * std::cos(x));
1621 }
1622
1624 const ExpressionPtr& parentAdjoint) const override {
1625 return parentAdjoint /
1627 }
1628};
1629
1636 using enum ExpressionType;
1637
1638 // Prune expression
1639 if (x->IsConstant(0.0)) {
1640 // Return zero
1641 return x;
1642 }
1643
1644 // Evaluate constant
1645 if (x->Type() == kConstant) {
1646 return MakeExpressionPtr<ConstExpression>(std::tan(x->value));
1647 }
1648
1650}
1651
1659 value = std::tanh(args[0]->value);
1660 }
1661
1662 double Value(double x, double) const override { return std::tanh(x); }
1663
1665
1666 double GradientValueLhs(double x, double,
1667 double parentAdjoint) const override {
1668 return parentAdjoint / (std::cosh(x) * std::cosh(x));
1669 }
1670
1672 const ExpressionPtr& parentAdjoint) const override {
1673 return parentAdjoint /
1675 }
1676};
1677
1684 using enum ExpressionType;
1685
1686 // Prune expression
1687 if (x->IsConstant(0.0)) {
1688 // Return zero
1689 return x;
1690 }
1691
1692 // Evaluate constant
1693 if (x->Type() == kConstant) {
1694 return MakeExpressionPtr<ConstExpression>(std::tanh(x->value));
1695 }
1696
1698}
1699
1700} // namespace sleipnir::detail
Definition small_vector.hpp:3616
::value &&MoveInsertable constexpr reference emplace_back(Args &&... args)
Definition small_vector.hpp:4071
Definition Expression.hpp:18
ExpressionPtr abs(const ExpressionPtr &x)
Definition Expression.hpp:736
ExpressionPtr log(const ExpressionPtr &x)
Definition Expression.hpp:1238
constexpr void IntrusiveSharedPtrIncRefCount(Expression *expr)
Definition Expression.hpp:648
static ExpressionPtr MakeExpressionPtr(Args &&... args)
Definition Expression.hpp:46
ExpressionPtr exp(const ExpressionPtr &x)
Definition Expression.hpp:1129
ExpressionPtr tanh(const ExpressionPtr &x)
Definition Expression.hpp:1683
IntrusiveSharedPtr< Expression > ExpressionPtr
Definition Expression.hpp:36
ExpressionPtr atan(const ExpressionPtr &x)
Definition Expression.hpp:879
ExpressionPtr sinh(const ExpressionPtr &x)
Definition Expression.hpp:1538
ExpressionPtr log10(const ExpressionPtr &x)
Definition Expression.hpp:1286
ExpressionPtr pow(const ExpressionPtr &base, const ExpressionPtr &power)
Definition Expression.hpp:1370
ExpressionPtr sign(const ExpressionPtr &x)
Definition Expression.hpp:1443
ExpressionPtr atan2(const ExpressionPtr &y, const ExpressionPtr &x)
Definition Expression.hpp:939
ExpressionPtr asin(const ExpressionPtr &x)
Definition Expression.hpp:832
ExpressionPtr erf(const ExpressionPtr &x)
Definition Expression.hpp:1082
constexpr void IntrusiveSharedPtrDecRefCount(Expression *expr)
Definition Expression.hpp:657
constexpr bool kUsePoolAllocator
Definition Expression.hpp:25
ExpressionPtr sin(const ExpressionPtr &x)
Definition Expression.hpp:1491
ExpressionPtr tan(const ExpressionPtr &x)
Definition Expression.hpp:1635
ExpressionPtr acos(const ExpressionPtr &x)
Definition Expression.hpp:785
ExpressionPtr cosh(const ExpressionPtr &x)
Definition Expression.hpp:1034
ExpressionPtr cos(const ExpressionPtr &x)
Definition Expression.hpp:988
ExpressionPtr sqrt(const ExpressionPtr &x)
Definition Expression.hpp:1586
ExpressionPtr hypot(const ExpressionPtr &x, const ExpressionPtr &y)
Definition Expression.hpp:1190
IntrusiveSharedPtr< T > AllocateIntrusiveShared(Alloc alloc, Args &&... args)
Definition IntrusiveSharedPtr.hpp:275
ExpressionType
Definition ExpressionType.hpp:14
@ kConstant
The expression is a constant.
@ kLinear
The expression is composed of linear and lower-order operators.
@ kNonlinear
The expression is composed of nonlinear and lower-order operators.
@ kQuadratic
The expression is composed of quadratic and lower-order operators.
Definition Expression.hpp:692
constexpr AbsExpression(ExpressionPtr lhs)
Definition Expression.hpp:698
ExpressionType Type() const override
Definition Expression.hpp:705
double Value(double x, double) const override
Definition Expression.hpp:703
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:718
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:707
Definition Expression.hpp:753
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:772
AcosExpression(ExpressionPtr lhs)
Definition Expression.hpp:759
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:767
ExpressionType Type() const override
Definition Expression.hpp:765
double Value(double x, double) const override
Definition Expression.hpp:763
Definition Expression.hpp:801
ExpressionType Type() const override
Definition Expression.hpp:813
AsinExpression(ExpressionPtr lhs)
Definition Expression.hpp:807
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:820
double Value(double x, double) const override
Definition Expression.hpp:811
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:815
Definition Expression.hpp:896
ExpressionType Type() const override
Definition Expression.hpp:910
double GradientValueRhs(double y, double x, double parentAdjoint) const override
Definition Expression.hpp:917
Atan2Expression(ExpressionPtr lhs, ExpressionPtr rhs)
Definition Expression.hpp:903
ExpressionPtr GradientRhs(const ExpressionPtr &y, const ExpressionPtr &x, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:927
ExpressionPtr GradientLhs(const ExpressionPtr &y, const ExpressionPtr &x, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:922
double GradientValueLhs(double y, double x, double parentAdjoint) const override
Definition Expression.hpp:912
double Value(double y, double x) const override
Definition Expression.hpp:908
Definition Expression.hpp:849
ExpressionType Type() const override
Definition Expression.hpp:861
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:868
AtanExpression(ExpressionPtr lhs)
Definition Expression.hpp:855
double Value(double x, double) const override
Definition Expression.hpp:859
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:863
Definition Expression.hpp:426
ExpressionPtr GradientLhs(const ExpressionPtr &, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:450
ExpressionType Type() const override
Definition Expression.hpp:440
ExpressionPtr GradientRhs(const ExpressionPtr &, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:455
double GradientValueRhs(double, double, double parentAdjoint) const override
Definition Expression.hpp:446
constexpr BinaryMinusExpression(ExpressionPtr lhs, ExpressionPtr rhs)
Definition Expression.hpp:433
double GradientValueLhs(double, double, double parentAdjoint) const override
Definition Expression.hpp:442
double Value(double lhs, double rhs) const override
Definition Expression.hpp:438
Definition Expression.hpp:462
double GradientValueLhs(double, double, double parentAdjoint) const override
Definition Expression.hpp:478
ExpressionType Type() const override
Definition Expression.hpp:476
ExpressionPtr GradientLhs(const ExpressionPtr &, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:486
double Value(double lhs, double rhs) const override
Definition Expression.hpp:474
double GradientValueRhs(double, double, double parentAdjoint) const override
Definition Expression.hpp:482
constexpr BinaryPlusExpression(ExpressionPtr lhs, ExpressionPtr rhs)
Definition Expression.hpp:469
ExpressionPtr GradientRhs(const ExpressionPtr &, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:491
Definition Expression.hpp:497
constexpr ConstExpression()=default
constexpr ConstExpression(double value)
Definition Expression.hpp:508
double Value(double, double) const override
Definition Expression.hpp:510
ExpressionType Type() const override
Definition Expression.hpp:512
Definition Expression.hpp:958
CosExpression(ExpressionPtr lhs)
Definition Expression.hpp:964
double Value(double x, double) const override
Definition Expression.hpp:968
ExpressionType Type() const override
Definition Expression.hpp:970
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:977
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:972
Definition Expression.hpp:1004
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1018
ExpressionType Type() const override
Definition Expression.hpp:1016
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1023
CoshExpression(ExpressionPtr lhs)
Definition Expression.hpp:1010
double Value(double x, double) const override
Definition Expression.hpp:1014
constexpr DecisionVariableExpression(double value)
Definition Expression.hpp:526
double Value(double, double) const override
Definition Expression.hpp:529
ExpressionType Type() const override
Definition Expression.hpp:531
Definition Expression.hpp:535
ExpressionPtr GradientRhs(const ExpressionPtr &lhs, const ExpressionPtr &rhs, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:566
ExpressionType Type() const override
Definition Expression.hpp:549
double GradientValueLhs(double, double rhs, double parentAdjoint) const override
Definition Expression.hpp:551
ExpressionPtr GradientLhs(const ExpressionPtr &, const ExpressionPtr &rhs, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:561
double GradientValueRhs(double lhs, double rhs, double parentAdjoint) const override
Definition Expression.hpp:556
double Value(double lhs, double rhs) const override
Definition Expression.hpp:547
constexpr DivExpression(ExpressionPtr lhs, ExpressionPtr rhs)
Definition Expression.hpp:542
Definition Expression.hpp:1050
ErfExpression(ExpressionPtr lhs)
Definition Expression.hpp:1056
double Value(double x, double) const override
Definition Expression.hpp:1060
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1069
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1064
ExpressionType Type() const override
Definition Expression.hpp:1062
Definition Expression.hpp:1099
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1118
ExpExpression(ExpressionPtr lhs)
Definition Expression.hpp:1105
double Value(double x, double) const override
Definition Expression.hpp:1109
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1113
ExpressionType Type() const override
Definition Expression.hpp:1111
Definition Expression.hpp:75
virtual ExpressionType Type() const =0
double adjoint
The adjoint of the expression node used during autodiff.
Definition Expression.hpp:80
constexpr Expression(double value)
Definition Expression.hpp:110
virtual ExpressionPtr GradientRhs(const ExpressionPtr &lhs, const ExpressionPtr &rhs, const ExpressionPtr &parentAdjoint) const
Definition Expression.hpp:417
uint32_t duplications
Definition Expression.hpp:84
std::array< ExpressionPtr, 2 > args
Expression arguments.
Definition Expression.hpp:98
constexpr Expression()=default
constexpr Expression(ExpressionPtr lhs)
Definition Expression.hpp:117
virtual double GradientValueLhs(double lhs, double rhs, double parentAdjoint) const
Definition Expression.hpp:377
friend ExpressionPtr operator+(const ExpressionPtr &lhs)
Definition Expression.hpp:351
constexpr bool IsConstant(double constant) const
Definition Expression.hpp:136
friend ExpressionPtr operator*(const ExpressionPtr &lhs, const ExpressionPtr &rhs)
Definition Expression.hpp:146
virtual double GradientValueRhs(double lhs, double rhs, double parentAdjoint) const
Definition Expression.hpp:390
friend ExpressionPtr operator-(const ExpressionPtr &lhs)
Definition Expression.hpp:323
friend ExpressionPtr operator-(const ExpressionPtr &lhs, const ExpressionPtr &rhs)
Definition Expression.hpp:277
friend ExpressionPtr operator/(const ExpressionPtr &lhs, const ExpressionPtr &rhs)
Definition Expression.hpp:198
virtual ~Expression()=default
virtual double Value(double lhs, double rhs) const =0
ExpressionPtr adjointExpr
Definition Expression.hpp:92
uint32_t refCount
Reference count for intrusive shared pointer.
Definition Expression.hpp:95
virtual ExpressionPtr GradientLhs(const ExpressionPtr &lhs, const ExpressionPtr &rhs, const ExpressionPtr &parentAdjoint) const
Definition Expression.hpp:403
constexpr Expression(ExpressionPtr lhs, ExpressionPtr rhs)
Definition Expression.hpp:126
double value
The value of the expression node.
Definition Expression.hpp:77
friend ExpressionPtr operator+(const ExpressionPtr &lhs, const ExpressionPtr &rhs)
Definition Expression.hpp:235
int32_t row
Definition Expression.hpp:88
Definition Expression.hpp:1147
ExpressionPtr GradientRhs(const ExpressionPtr &x, const ExpressionPtr &y, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1178
HypotExpression(ExpressionPtr lhs, ExpressionPtr rhs)
Definition Expression.hpp:1154
double GradientValueRhs(double x, double y, double parentAdjoint) const override
Definition Expression.hpp:1168
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &y, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1173
double GradientValueLhs(double x, double y, double parentAdjoint) const override
Definition Expression.hpp:1163
double Value(double x, double y) const override
Definition Expression.hpp:1159
ExpressionType Type() const override
Definition Expression.hpp:1161
Definition Expression.hpp:1255
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1269
Log10Expression(ExpressionPtr lhs)
Definition Expression.hpp:1261
ExpressionType Type() const override
Definition Expression.hpp:1267
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1274
double Value(double x, double) const override
Definition Expression.hpp:1265
Definition Expression.hpp:1208
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1222
ExpressionType Type() const override
Definition Expression.hpp:1220
LogExpression(ExpressionPtr lhs)
Definition Expression.hpp:1214
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1227
double Value(double x, double) const override
Definition Expression.hpp:1218
Definition Expression.hpp:573
double GradientValueLhs(double lhs, double rhs, double parentAdjoint) const override
Definition Expression.hpp:589
double GradientValueRhs(double lhs, double rhs, double parentAdjoint) const override
Definition Expression.hpp:594
ExpressionPtr GradientRhs(const ExpressionPtr &lhs, const ExpressionPtr &rhs, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:605
ExpressionType Type() const override
Definition Expression.hpp:587
ExpressionPtr GradientLhs(const ExpressionPtr &lhs, const ExpressionPtr &rhs, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:599
double Value(double lhs, double rhs) const override
Definition Expression.hpp:585
constexpr MultExpression(ExpressionPtr lhs, ExpressionPtr rhs)
Definition Expression.hpp:580
Definition Expression.hpp:1306
double GradientValueLhs(double base, double power, double parentAdjoint) const override
Definition Expression.hpp:1324
double Value(double base, double power) const override
Definition Expression.hpp:1318
ExpressionType Type() const override
Definition Expression.hpp:1322
ExpressionPtr GradientLhs(const ExpressionPtr &base, const ExpressionPtr &power, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1339
ExpressionPtr GradientRhs(const ExpressionPtr &base, const ExpressionPtr &power, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1348
PowExpression(ExpressionPtr lhs, ExpressionPtr rhs)
Definition Expression.hpp:1313
double GradientValueRhs(double base, double power, double parentAdjoint) const override
Definition Expression.hpp:1329
Definition Expression.hpp:1400
ExpressionType Type() const override
Definition Expression.hpp:1427
ExpressionPtr GradientLhs(const ExpressionPtr &, const ExpressionPtr &, const ExpressionPtr &) const override
Definition Expression.hpp:1431
double Value(double x, double) const override
Definition Expression.hpp:1417
constexpr SignExpression(ExpressionPtr lhs)
Definition Expression.hpp:1406
double GradientValueLhs(double, double, double) const override
Definition Expression.hpp:1429
Definition Expression.hpp:1461
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1480
double Value(double x, double) const override
Definition Expression.hpp:1471
SinExpression(ExpressionPtr lhs)
Definition Expression.hpp:1467
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1475
ExpressionType Type() const override
Definition Expression.hpp:1473
Definition Expression.hpp:1508
SinhExpression(ExpressionPtr lhs)
Definition Expression.hpp:1514
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1522
double Value(double x, double) const override
Definition Expression.hpp:1518
ExpressionType Type() const override
Definition Expression.hpp:1520
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1527
Definition Expression.hpp:1555
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1574
ExpressionType Type() const override
Definition Expression.hpp:1567
double Value(double x, double) const override
Definition Expression.hpp:1565
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1569
SqrtExpression(ExpressionPtr lhs)
Definition Expression.hpp:1561
Definition Expression.hpp:1604
ExpressionType Type() const override
Definition Expression.hpp:1616
TanExpression(ExpressionPtr lhs)
Definition Expression.hpp:1610
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1623
double Value(double x, double) const override
Definition Expression.hpp:1614
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1618
Definition Expression.hpp:1652
TanhExpression(ExpressionPtr lhs)
Definition Expression.hpp:1658
ExpressionType Type() const override
Definition Expression.hpp:1664
ExpressionPtr GradientLhs(const ExpressionPtr &x, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:1671
double Value(double x, double) const override
Definition Expression.hpp:1662
double GradientValueLhs(double x, double, double parentAdjoint) const override
Definition Expression.hpp:1666
Definition Expression.hpp:613
ExpressionPtr GradientLhs(const ExpressionPtr &, const ExpressionPtr &, const ExpressionPtr &parentAdjoint) const override
Definition Expression.hpp:632
constexpr UnaryMinusExpression(ExpressionPtr lhs)
Definition Expression.hpp:619
ExpressionType Type() const override
Definition Expression.hpp:626
double Value(double lhs, double) const override
Definition Expression.hpp:624
double GradientValueLhs(double, double, double parentAdjoint) const override
Definition Expression.hpp:628