13#include "sleipnir/autodiff/expression.hpp"
14#include "sleipnir/autodiff/expression_type.hpp"
16namespace slp::detail {
20template <
typename Scalar>
23 using AbsExpression::NonLeafExpression::NonLeafExpression;
26 static constexpr std::string_view
NAME =
"abs";
33 template <
typename Value>
34 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
36 if constexpr (std::same_as<Value, Scalar>) {
39 }
else if (x >
Scalar(0)) {
54template <
typename Scalar>
55ExpressionPtr<Scalar> abs(
const ExpressionPtr<Scalar>& x) {
56 return fold_or_make<AbsExpression<Scalar>>(x);
62template <
typename Scalar>
65 using AcosExpression::NonLeafExpression::NonLeafExpression;
68 static constexpr std::string_view
NAME =
"acos";
75 template <
typename Value>
76 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
79 g[0] = lit<Value>(
Scalar(-1)) / sqrt(lit<Value>(
Scalar(1)) - x * x);
87template <
typename Scalar>
88ExpressionPtr<Scalar> acos(
const ExpressionPtr<Scalar>& x) {
89 return fold_or_make<AcosExpression<Scalar>>(x);
95template <
typename Scalar>
98 using AsinExpression::NonLeafExpression::NonLeafExpression;
101 static constexpr std::string_view
NAME =
"asin";
108 template <
typename Value>
109 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
112 g[0] = lit<Value>(
Scalar(1)) / sqrt(lit<Value>(
Scalar(1)) - x * x);
120template <
typename Scalar>
121ExpressionPtr<Scalar> asin(
const ExpressionPtr<Scalar>& x) {
122 return fold_or_make<AsinExpression<Scalar>>(x);
128template <
typename Scalar>
131 using AtanExpression::NonLeafExpression::NonLeafExpression;
134 static constexpr std::string_view
NAME =
"atan";
141 template <
typename Value>
142 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
144 g[0] = lit<Value>(
Scalar(1)) / (lit<Value>(
Scalar(1)) + x * x);
152template <
typename Scalar>
153ExpressionPtr<Scalar> atan(
const ExpressionPtr<Scalar>& x) {
154 return fold_or_make<AtanExpression<Scalar>>(x);
160template <
typename Scalar>
163 using Atan2Expression::NonLeafExpression::NonLeafExpression;
166 static constexpr std::string_view
NAME =
"atan2";
173 template <
typename Value>
174 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
175 const Value& y,
const Value& x) {
176 Value d = y * y + x * x;
187template <
typename Scalar>
188ExpressionPtr<Scalar> atan2(
const ExpressionPtr<Scalar>& y,
189 const ExpressionPtr<Scalar>& x) {
190 return fold_or_make<Atan2Expression<Scalar>>(y, x);
196template <
typename Scalar>
199 using CbrtExpression::NonLeafExpression::NonLeafExpression;
202 static constexpr std::string_view
NAME =
"cbrt";
209 template <
typename Value>
210 static void eval_grad(ArgArray<Value>& g,
const Value&
val,
211 [[maybe_unused]]
const Value& x) {
220template <
typename Scalar>
221ExpressionPtr<Scalar> cbrt(
const ExpressionPtr<Scalar>& x) {
222 return fold_or_make<CbrtExpression<Scalar>>(x);
228template <
typename Scalar>
231 using CosExpression::NonLeafExpression::NonLeafExpression;
234 static constexpr std::string_view
NAME =
"cos";
241 template <
typename Value>
242 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
253template <
typename Scalar>
254ExpressionPtr<Scalar> cos(
const ExpressionPtr<Scalar>& x) {
255 return fold_or_make<CosExpression<Scalar>>(x);
261template <
typename Scalar>
264 using CoshExpression::NonLeafExpression::NonLeafExpression;
267 static constexpr std::string_view
NAME =
"cosh";
274 template <
typename Value>
275 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
286template <
typename Scalar>
287ExpressionPtr<Scalar> cosh(
const ExpressionPtr<Scalar>& x) {
288 return fold_or_make<CoshExpression<Scalar>>(x);
294template <
typename Scalar>
297 using ErfExpression::NonLeafExpression::NonLeafExpression;
300 static constexpr std::string_view
NAME =
"erf";
307 template <
typename Value>
308 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
311 g[0] = lit<Value>(
Scalar(2.0 * std::numbers::inv_sqrtpi)) * exp(-x * x);
319template <
typename Scalar>
320ExpressionPtr<Scalar> erf(
const ExpressionPtr<Scalar>& x) {
321 return fold_or_make<ErfExpression<Scalar>>(x);
327template <
typename Scalar>
330 using ExpExpression::NonLeafExpression::NonLeafExpression;
333 static constexpr std::string_view
NAME =
"exp";
340 template <
typename Value>
341 static void eval_grad(ArgArray<Value>& g,
const Value&
val,
342 [[maybe_unused]]
const Value& x) {
351template <
typename Scalar>
352ExpressionPtr<Scalar> exp(
const ExpressionPtr<Scalar>& x) {
353 return fold_or_make<ExpExpression<Scalar>>(x);
356template <
typename Scalar>
357ExpressionPtr<Scalar> hypot(
const ExpressionPtr<Scalar>& x,
358 const ExpressionPtr<Scalar>& y);
363template <
typename Scalar>
366 using Hypot2Expression::NonLeafExpression::NonLeafExpression;
369 static constexpr std::string_view
NAME =
"hypot";
376 template <
typename Value>
377 static void eval_grad(ArgArray<Value>& g,
const Value&
val,
const Value& x,
389template <
typename Scalar>
390ExpressionPtr<Scalar> hypot(
const ExpressionPtr<Scalar>& x,
391 const ExpressionPtr<Scalar>& y) {
393 if (x->is_constant(Scalar(0))) {
395 }
else if (y->is_constant(Scalar(0))) {
399 return fold_or_make<Hypot2Expression<Scalar>>(x, y);
402template <
typename Scalar>
403ExpressionPtr<Scalar> hypot(
const ExpressionPtr<Scalar>& x,
404 const ExpressionPtr<Scalar>& y,
405 const ExpressionPtr<Scalar>& z);
410template <
typename Scalar>
413 using Hypot3Expression::NonLeafExpression::NonLeafExpression;
416 static constexpr std::string_view
NAME =
"hypot";
420 return hypot(x, y, z);
423 template <
typename Value>
424 static void eval_grad(ArgArray<Value>& g,
const Value&
val,
const Value& x,
425 const Value& y,
const Value& z) {
438template <
typename Scalar>
439ExpressionPtr<Scalar> hypot(
const ExpressionPtr<Scalar>& x,
440 const ExpressionPtr<Scalar>& y,
441 const ExpressionPtr<Scalar>& z) {
443 if (x->is_constant(Scalar(0))) {
445 }
else if (y->is_constant(Scalar(0))) {
447 }
else if (z->is_constant(Scalar(0))) {
451 return fold_or_make<Hypot3Expression<Scalar>>(x, y, z);
459template <
typename Scalar>
463 static constexpr std::string_view
NAME =
"if-else";
479 std::move(t), std::move(f)},
483 return cond(a, b) ? t : f;
486 template <
typename Value>
487 void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
488 const Value& a,
const Value& b,
489 [[maybe_unused]]
const Value& t,
490 [[maybe_unused]]
const Value& f)
const {
492 if constexpr (std::same_as<Value, Scalar>) {
497 auto zero = constant_ptr(
Scalar(0));
498 auto one = constant_ptr(
Scalar(1));
499 g[2] = if_else(
cond, a, b, one, zero);
500 g[3] = if_else(
cond, a, b, zero, one);
513template <
typename Scalar>
514ExpressionPtr<Scalar> if_else(
515 std::type_identity_t<
bool (*)(Scalar a, Scalar b)> cond,
516 const ExpressionPtr<Scalar>& a,
const ExpressionPtr<Scalar>& b,
517 const ExpressionPtr<Scalar>& t,
const ExpressionPtr<Scalar>& f) {
518 using enum ExpressionType;
524 }
else if (t->type() == CONSTANT && f->type() == CONSTANT &&
531 if (a->type() == CONSTANT && b->type() == CONSTANT) {
532 return cond(a->val, b->val) ? t : f;
535 return make_expression_ptr<IfElseExpression<Scalar>>(cond, a, b, t, f);
541template <
typename Scalar>
544 using LogExpression::NonLeafExpression::NonLeafExpression;
547 static constexpr std::string_view
NAME =
"log";
554 template <
typename Value>
555 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
557 g[0] = lit<Value>(
Scalar(1)) / x;
565template <
typename Scalar>
566ExpressionPtr<Scalar> log(
const ExpressionPtr<Scalar>& x) {
567 return fold_or_make<LogExpression<Scalar>>(x);
573template <
typename Scalar>
576 using Log10Expression::NonLeafExpression::NonLeafExpression;
579 static constexpr std::string_view
NAME =
"log10";
586 template <
typename Value>
587 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
589 g[0] = lit<Value>(
Scalar(1)) / (lit<Value>(
Scalar(std::numbers::ln10)) * x);
597template <
typename Scalar>
598ExpressionPtr<Scalar> log10(
const ExpressionPtr<Scalar>& x) {
599 return fold_or_make<Log10Expression<Scalar>>(x);
607template <
typename Scalar>
610 using MaxExpression::NonLeafExpression::NonLeafExpression;
613 static constexpr std::string_view
NAME =
"max";
620 template <
typename Value>
621 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
622 const Value& a,
const Value& b) {
623 if constexpr (std::same_as<Value, Scalar>) {
628 auto zero = constant_ptr(
Scalar(0));
629 auto one = constant_ptr(
Scalar(1));
631 g[0] = if_else(cond, a, b, one, zero);
632 g[1] = if_else(cond, a, b, zero, one);
642template <
typename Scalar>
643ExpressionPtr<Scalar> max(
const ExpressionPtr<Scalar>& a,
644 const ExpressionPtr<Scalar>& b) {
645 return fold_or_make<MaxExpression<Scalar>>(a, b);
653template <
typename Scalar>
656 using MinExpression::NonLeafExpression::NonLeafExpression;
659 static constexpr std::string_view
NAME =
"min";
666 template <
typename Value>
667 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
668 const Value& a,
const Value& b) {
669 if constexpr (std::same_as<Value, Scalar>) {
674 auto zero = constant_ptr(
Scalar(0));
675 auto one = constant_ptr(
Scalar(1));
677 g[0] = if_else(cond, a, b, one, zero);
678 g[1] = if_else(cond, a, b, zero, one);
688template <
typename Scalar>
689ExpressionPtr<Scalar> min(
const ExpressionPtr<Scalar>& a,
690 const ExpressionPtr<Scalar>& b) {
691 return fold_or_make<MinExpression<Scalar>>(a, b);
694template <
typename Scalar>
695ExpressionPtr<Scalar> pow(
const ExpressionPtr<Scalar>& base,
696 const ExpressionPtr<Scalar>& power);
698template <
typename Scalar>
699ExpressionPtr<Scalar> sqrt(
const ExpressionPtr<Scalar>& x);
705template <
typename Scalar, ExpressionType T>
708 using PowExpression::NonLeafExpression::NonLeafExpression;
711 static constexpr std::string_view
NAME =
"pow";
715 return pow(base, power);
718 template <
typename Value>
719 static void eval_grad(ArgArray<Value>& g,
const Value&
val,
const Value& base,
720 const Value& power) {
724 g[0] = pow(base, power - lit<Value>(
Scalar(1))) * power;
725 g[1] =
val * log(base);
734template <
typename Scalar>
735ExpressionPtr<Scalar> pow(
const ExpressionPtr<Scalar>& base,
736 const ExpressionPtr<Scalar>& power) {
737 using enum ExpressionType;
741 if (base->is_constant(Scalar(0))) {
744 }
else if (base->is_constant(Scalar(1))) {
748 if (power->is_constant(Scalar(0))) {
749 return constant_ptr(Scalar(1));
750 }
else if (power->is_constant(Scalar(1))) {
756 if (base->type() == CONSTANT && power->type() == CONSTANT) {
757 return constant_ptr(pow(base->val, power->val));
760 if (power->is_constant(Scalar(2))) {
761 auto type = base->type() == LINEAR ? QUADRATIC : NONLINEAR;
762 return make_typed_expression_ptr<MultExpression, Scalar>(type, base, base);
763 }
else if (power->is_constant(Scalar(0.5))) {
767 return make_expression_ptr<PowExpression<Scalar, NONLINEAR>>(base, power);
773template <
typename Scalar>
776 using SignExpression::NonLeafExpression::NonLeafExpression;
779 static constexpr std::string_view
NAME =
"sign";
784 }
else if (x ==
Scalar(0)) {
796template <
typename Scalar>
797ExpressionPtr<Scalar> sign(
const ExpressionPtr<Scalar>& x) {
798 return fold_or_make<SignExpression<Scalar>>(x);
804template <
typename Scalar>
807 using SinExpression::NonLeafExpression::NonLeafExpression;
810 static constexpr std::string_view
NAME =
"sin";
817 template <
typename Value>
818 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
829template <
typename Scalar>
830ExpressionPtr<Scalar> sin(
const ExpressionPtr<Scalar>& x) {
831 return fold_or_make<SinExpression<Scalar>>(x);
837template <
typename Scalar>
840 using SinhExpression::NonLeafExpression::NonLeafExpression;
843 static constexpr std::string_view
NAME =
"sinh";
850 template <
typename Value>
851 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
862template <
typename Scalar>
863ExpressionPtr<Scalar> sinh(
const ExpressionPtr<Scalar>& x) {
864 return fold_or_make<SinhExpression<Scalar>>(x);
870template <
typename Scalar>
873 using SqrtExpression::NonLeafExpression::NonLeafExpression;
876 static constexpr std::string_view
NAME =
"sqrt";
883 template <
typename Value>
884 static void eval_grad(ArgArray<Value>& g,
const Value&
val,
885 [[maybe_unused]]
const Value& x) {
894template <
typename Scalar>
895ExpressionPtr<Scalar> sqrt(
const ExpressionPtr<Scalar>& x) {
896 return fold_or_make<SqrtExpression<Scalar>>(x);
902template <
typename Scalar>
905 using TanExpression::NonLeafExpression::NonLeafExpression;
908 static constexpr std::string_view
NAME =
"tan";
915 template <
typename Value>
916 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
921 g[0] = lit<Value>(
Scalar(1)) / (c * c);
929template <
typename Scalar>
930ExpressionPtr<Scalar> tan(
const ExpressionPtr<Scalar>& x) {
931 return fold_or_make<TanExpression<Scalar>>(x);
937template <
typename Scalar>
940 using TanhExpression::NonLeafExpression::NonLeafExpression;
943 static constexpr std::string_view
NAME =
"tanh";
950 template <
typename Value>
951 static void eval_grad(ArgArray<Value>& g, [[maybe_unused]]
const Value&
val,
956 g[0] = lit<Value>(
Scalar(1)) / (c * c);
964template <
typename Scalar>
965ExpressionPtr<Scalar> tanh(
const ExpressionPtr<Scalar>& x) {
966 return fold_or_make<TanhExpression<Scalar>>(x);
Definition intrusive_shared_ptr.hpp:27
Definition expression_functions.hpp:22
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:26
Definition expression_functions.hpp:64
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:68
Definition expression_functions.hpp:97
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:101
Definition expression_functions.hpp:162
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:166
Definition expression_functions.hpp:130
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:134
Definition expression_functions.hpp:198
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:202
Definition expression_functions.hpp:230
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:234
Definition expression_functions.hpp:263
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:267
Definition expression_functions.hpp:296
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:300
Definition expression_functions.hpp:329
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:333
Scalar val
The value of the expression node.
Definition expression.hpp:138
Scalar Scalar
Scalar type alias.
Definition expression.hpp:135
Definition expression_functions.hpp:365
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:369
Definition expression_functions.hpp:412
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:416
Definition expression_functions.hpp:461
constexpr IfElseExpression(bool(*cond)(Scalar a, Scalar b), ExpressionPtr< Scalar > a, ExpressionPtr< Scalar > b, ExpressionPtr< Scalar > t, ExpressionPtr< Scalar > f)
Definition expression_functions.hpp:475
bool(* cond)(Scalar a, Scalar b)
Condition evaluated on a and b.
Definition expression_functions.hpp:466
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:463
Definition expression_functions.hpp:575
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:579
Definition expression_functions.hpp:543
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:547
Definition expression_functions.hpp:609
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:613
Definition expression_functions.hpp:655
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:659
Definition expression.hpp:405
Definition expression_functions.hpp:707
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:711
Definition expression_functions.hpp:775
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:779
Definition expression_functions.hpp:806
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:810
Definition expression_functions.hpp:839
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:843
Definition expression_functions.hpp:872
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:876
Definition expression_functions.hpp:904
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:908
Definition expression_functions.hpp:939
static constexpr std::string_view NAME
The expression's name.
Definition expression_functions.hpp:943