52 #ifndef SACADO_ELRCACHEFAD_OPS_HPP
53 #define SACADO_ELRCACHEFAD_OPS_HPP
62 namespace ELRCacheFad {
68 template <
typename ExprT>
71 template <
typename ExprT>
80 static const int num_args = ExprT::num_args;
82 static const bool is_linear =
true;
85 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
88 int size()
const {
return expr.size(); }
92 bool isActive()
const {
return expr.template isActive<Arg>(); }
110 expr.computePartials(bar, partials);
115 expr.getTangents(i, dots); }
119 return expr.template getTangent<Arg>(i);
124 return expr.isLinear();
129 return expr.hasFastAccess();
139 return expr.fastAccessDx(i);
144 return expr.getDx(j);
152 template <
typename T>
165 template <
typename ExprT>
168 template <
typename ExprT>
177 static const int num_args = ExprT::num_args;
179 static const bool is_linear =
true;
182 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
185 int size()
const {
return expr.size(); }
189 bool isActive()
const {
return expr.template isActive<Arg>(); }
207 expr.computePartials(-bar, partials);
212 expr.getTangents(i, dots); }
217 return expr.template getTangent<Arg>(i);
222 return expr.isLinear();
227 return expr.hasFastAccess();
237 return -expr.fastAccessDx(i);
242 return expr.getDx(j);
250 template <
typename T>
264 template <
typename ExprT>
267 template <
typename ExprT>
276 static const int num_args = ExprT::num_args;
278 static const bool is_linear =
false;
281 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
284 int size()
const {
return expr.size(); }
288 bool isActive()
const {
return expr.template isActive<Arg>(); }
309 expr.computePartials(bar, partials);
311 expr.computePartials(-bar, partials);
316 expr.getTangents(i, dots); }
321 return expr.template getTangent<Arg>(i);
331 return expr.hasFastAccess();
336 if (v_pos)
return expr.dx(i);
337 else return -expr.dx(i);
342 if (v_pos)
return expr.fastAccessDx(i);
343 else return -expr.fastAccessDx(i);
348 return expr.getDx(j);
358 template <
typename T>
372 template <
typename ExprT>
375 template <
typename ExprT>
384 static const int num_args = ExprT::num_args;
386 static const bool is_linear =
false;
389 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
392 int size()
const {
return expr.size(); }
396 bool isActive()
const {
return expr.template isActive<Arg>(); }
417 expr.computePartials(bar, partials);
419 expr.computePartials(-bar, partials);
424 expr.getTangents(i, dots); }
429 return expr.template getTangent<Arg>(i);
439 return expr.hasFastAccess();
444 if (v_pos)
return expr.dx(i);
445 else return -expr.dx(i);
450 if (v_pos)
return expr.fastAccessDx(i);
451 else return -expr.fastAccessDx(i);
456 return expr.getDx(j);
466 template <
typename T>
479 #define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE) \
481 namespace ELRCacheFad { \
483 template <typename ExprT> \
486 template <typename ExprT> \
487 class Expr< OP<ExprT> > { \
490 typedef typename ExprT::value_type value_type; \
491 typedef typename ExprT::scalar_type scalar_type; \
493 typedef typename ExprT::base_expr_type base_expr_type; \
495 static const int num_args = ExprT::num_args; \
497 static const bool is_linear = false; \
499 KOKKOS_INLINE_FUNCTION \
500 explicit Expr(const ExprT& expr_) : expr(expr_) {} \
502 KOKKOS_INLINE_FUNCTION \
503 int size() const { return expr.size(); } \
506 KOKKOS_INLINE_FUNCTION \
507 bool isActive() const { return expr.template isActive<Arg>(); } \
509 KOKKOS_INLINE_FUNCTION \
510 bool updateValue() const { return expr.updateValue(); } \
512 KOKKOS_INLINE_FUNCTION \
513 void cache() const { \
519 KOKKOS_INLINE_FUNCTION \
520 value_type val() const { \
524 KOKKOS_INLINE_FUNCTION \
525 void computePartials(const value_type& bar, \
526 value_type partials[]) const { \
527 expr.computePartials(bar*a, partials); \
530 KOKKOS_INLINE_FUNCTION \
531 void getTangents(int i, value_type dots[]) const { \
532 expr.getTangents(i, dots); } \
535 KOKKOS_INLINE_FUNCTION \
536 value_type getTangent(int i) const { \
537 return expr.template getTangent<Arg>(i); \
540 KOKKOS_INLINE_FUNCTION \
541 bool isLinear() const { \
545 KOKKOS_INLINE_FUNCTION \
546 bool hasFastAccess() const { \
547 return expr.hasFastAccess(); \
550 KOKKOS_INLINE_FUNCTION \
551 const value_type dx(int i) const { \
552 return expr.dx(i)*a; \
555 KOKKOS_INLINE_FUNCTION \
556 const value_type fastAccessDx(int i) const { \
557 return expr.fastAccessDx(i)*a; \
560 KOKKOS_INLINE_FUNCTION \
561 const value_type* getDx(int j) const { \
562 return expr.getDx(j); \
568 mutable value_type v; \
569 mutable value_type a; \
572 template <typename T> \
573 KOKKOS_INLINE_FUNCTION \
574 Expr< OP< Expr<T> > > \
575 OPNAME (const Expr<T>& expr) \
577 typedef OP< Expr<T> > expr_t; \
579 return Expr<expr_t>(expr); \
590 a=scalar_type(1.0)/v,
594 a = scalar_type(1.0)/(std::log(scalar_type(10.0))*v),
598 a = scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)),
602 a = (v == value_type(0.0) ? value_type(0.0) : value_type(scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)))),
614 a = scalar_type(1.0)+std::tan(v)*std::tan(v),
618 a = scalar_type(-1.0)/std::sqrt(scalar_type(1.0)-v*v),
622 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)-v*v),
626 a = scalar_type(1.0)/(scalar_type(1.0)+v*v),
638 a = scalar_type(1.0)-std::tanh(v)*std::tanh(v),
642 a = scalar_type(1.0)/std::sqrt((v-scalar_type(1.0))*(v+scalar_type(1.0))),
646 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)+v*v),
650 a = scalar_type(1.0)/(scalar_type(1.0)-v*v),
652 #ifdef HAVE_SACADO_CXX11
655 a = scalar_type(1.0)/(scalar_type(3.0)*
std::cbrt(v*v)),
659 #undef FAD_UNARYOP_MACRO
665 namespace ELRCacheFad {
671 template <
typename ExprT1,
typename ExprT2>
674 template <
typename ExprT1,
typename ExprT2>
675 class Expr< AdditionOp<ExprT1,ExprT2> > {
679 typedef typename ExprT1::value_type value_type_1;
680 typedef typename ExprT2::value_type value_type_2;
682 value_type_2>::type value_type;
683 typedef typename ExprT1::scalar_type scalar_type_1;
684 typedef typename ExprT2::scalar_type scalar_type_2;
686 scalar_type_2>::type scalar_type;
688 typedef typename ExprT1::base_expr_type base_expr_type_1;
689 typedef typename ExprT2::base_expr_type base_expr_type_2;
691 base_expr_type_2>::type base_expr_type;
693 static const int num_args1 = ExprT1::num_args;
694 static const int num_args2 = ExprT2::num_args;
695 static const int num_args = num_args1 + num_args2;
697 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
700 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
701 expr1(expr1_), expr2(expr2_) {}
705 int sz1 = expr1.size(), sz2 = expr2.size();
706 return sz1 > sz2 ? sz1 : sz2;
711 bool isActive()
const {
713 return expr1.template isActive<Arg>();
715 return expr2.template isActive<Arg-num_args1>();
719 bool updateValue()
const {
720 return expr1.updateValue() && expr2.updateValue();
730 value_type
val()
const {
731 return expr1.val()+expr2.val();
735 void computePartials(
const value_type&
bar,
736 value_type partials[])
const {
738 expr1.computePartials(bar, partials);
740 expr2.computePartials(bar, partials+num_args1);
744 void getTangents(
int i, value_type dots[])
const {
745 expr1.getTangents(i, dots);
746 expr2.getTangents(i, dots+num_args1);
751 value_type getTangent(
int i)
const {
753 return expr1.template getTangent<Arg>(i);
755 return expr2.template getTangent<Arg-num_args1>(i);
759 bool isLinear()
const {
760 return expr1.isLinear() && expr2.isLinear();
764 bool hasFastAccess()
const {
765 return expr1.hasFastAccess() && expr2.hasFastAccess();
769 const value_type
dx(
int i)
const {
770 return expr1.dx(i) + expr2.dx(i);
775 return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
779 const value_type* getDx(
int j)
const {
781 return expr1.getDx(j);
783 return expr2.getDx(j-num_args1);
793 template <
typename ExprT1,
typename T2>
794 class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
798 typedef ConstExpr<T2> ExprT2;
799 typedef typename ExprT1::value_type value_type_1;
800 typedef typename ExprT2::value_type value_type_2;
802 value_type_2>::type value_type;
803 typedef typename ExprT1::scalar_type scalar_type_1;
804 typedef typename ExprT2::scalar_type scalar_type_2;
806 scalar_type_2>::type scalar_type;
808 typedef typename ExprT1::base_expr_type base_expr_type_1;
809 typedef typename ExprT2::base_expr_type base_expr_type_2;
811 base_expr_type_2>::type base_expr_type;
813 static const int num_args = ExprT1::num_args;
815 static const bool is_linear = ExprT1::is_linear;
818 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
819 expr1(expr1_), expr2(expr2_) {}
828 bool isActive()
const {
829 return expr1.template isActive<Arg>();
833 bool updateValue()
const {
834 return expr1.updateValue();
843 value_type
val()
const {
844 return expr1.val() + expr2.val();
848 void computePartials(
const value_type&
bar,
849 value_type partials[])
const {
850 expr1.computePartials(bar, partials);
854 void getTangents(
int i, value_type dots[])
const {
855 expr1.getTangents(i, dots);
860 value_type getTangent(
int i)
const {
861 return expr1.template getTangent<Arg>(i);
865 bool isLinear()
const {
866 return expr1.isLinear();
870 bool hasFastAccess()
const {
871 return expr1.hasFastAccess();
875 const value_type
dx(
int i)
const {
881 return expr1.fastAccessDx(i);
885 const value_type* getDx(
int j)
const {
886 return expr1.getDx(j);
896 template <
typename T1,
typename ExprT2>
897 class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
901 typedef ConstExpr<T1> ExprT1;
902 typedef typename ExprT1::value_type value_type_1;
903 typedef typename ExprT2::value_type value_type_2;
905 value_type_2>::type value_type;
906 typedef typename ExprT1::scalar_type scalar_type_1;
907 typedef typename ExprT2::scalar_type scalar_type_2;
909 scalar_type_2>::type scalar_type;
911 typedef typename ExprT1::base_expr_type base_expr_type_1;
912 typedef typename ExprT2::base_expr_type base_expr_type_2;
914 base_expr_type_2>::type base_expr_type;
916 static const int num_args = ExprT2::num_args;
918 static const bool is_linear = ExprT2::is_linear;
921 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
922 expr1(expr1_), expr2(expr2_) {}
931 bool isActive()
const {
932 return expr2.template isActive<Arg>();
936 bool updateValue()
const {
937 return expr2.updateValue();
946 value_type
val()
const {
947 return expr1.val() + expr2.val();
951 void computePartials(
const value_type&
bar,
952 value_type partials[])
const {
953 expr2.computePartials(bar, partials);
957 void getTangents(
int i, value_type dots[])
const {
958 expr2.getTangents(i, dots);
963 value_type getTangent(
int i)
const {
964 return expr2.template getTangent<Arg>(i);
968 bool isLinear()
const {
969 return expr2.isLinear();
973 bool hasFastAccess()
const {
974 return expr2.hasFastAccess();
978 const value_type
dx(
int i)
const {
984 return expr2.fastAccessDx(i);
988 const value_type* getDx(
int j)
const {
989 return expr2.getDx(j);
1003 template <
typename ExprT1,
typename ExprT2>
1006 template <
typename ExprT1,
typename ExprT2>
1007 class Expr< SubtractionOp<ExprT1,ExprT2> > {
1011 typedef typename ExprT1::value_type value_type_1;
1012 typedef typename ExprT2::value_type value_type_2;
1014 value_type_2>::type value_type;
1015 typedef typename ExprT1::scalar_type scalar_type_1;
1016 typedef typename ExprT2::scalar_type scalar_type_2;
1018 scalar_type_2>::type scalar_type;
1020 typedef typename ExprT1::base_expr_type base_expr_type_1;
1021 typedef typename ExprT2::base_expr_type base_expr_type_2;
1023 base_expr_type_2>::type base_expr_type;
1025 static const int num_args1 = ExprT1::num_args;
1026 static const int num_args2 = ExprT2::num_args;
1027 static const int num_args = num_args1 + num_args2;
1029 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
1032 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1033 expr1(expr1_), expr2(expr2_) {}
1037 int sz1 = expr1.size(), sz2 = expr2.size();
1038 return sz1 > sz2 ? sz1 : sz2;
1043 bool isActive()
const {
1044 if (Arg < num_args1)
1045 return expr1.template isActive<Arg>();
1047 return expr2.template isActive<Arg-num_args1>();
1051 bool updateValue()
const {
1052 return expr1.updateValue() && expr2.updateValue();
1056 void cache()
const {
1062 value_type
val()
const {
1063 return expr1.val()-expr2.val();
1067 void computePartials(
const value_type&
bar,
1068 value_type partials[])
const {
1070 expr1.computePartials(bar, partials);
1072 expr2.computePartials(-bar, partials+num_args1);
1076 void getTangents(
int i, value_type dots[])
const {
1077 expr1.getTangents(i, dots);
1078 expr2.getTangents(i, dots+num_args1);
1083 value_type getTangent(
int i)
const {
1084 if (Arg < num_args1)
1085 return expr1.template getTangent<Arg>(i);
1087 return expr2.template getTangent<Arg-num_args1>(i);
1091 bool isLinear()
const {
1092 return expr1.isLinear() && expr2.isLinear();
1096 bool hasFastAccess()
const {
1097 return expr1.hasFastAccess() && expr2.hasFastAccess();
1101 const value_type
dx(
int i)
const {
1102 return expr1.dx(i) - expr2.dx(i);
1107 return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
1111 const value_type* getDx(
int j)
const {
1113 return expr1.getDx(j);
1115 return expr2.getDx(j-num_args1);
1120 const ExprT1& expr1;
1121 const ExprT2& expr2;
1125 template <
typename ExprT1,
typename T2>
1126 class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
1130 typedef ConstExpr<T2> ExprT2;
1131 typedef typename ExprT1::value_type value_type_1;
1132 typedef typename ExprT2::value_type value_type_2;
1134 value_type_2>::type value_type;
1135 typedef typename ExprT1::scalar_type scalar_type_1;
1136 typedef typename ExprT2::scalar_type scalar_type_2;
1138 scalar_type_2>::type scalar_type;
1140 typedef typename ExprT1::base_expr_type base_expr_type_1;
1141 typedef typename ExprT2::base_expr_type base_expr_type_2;
1143 base_expr_type_2>::type base_expr_type;
1145 static const int num_args = ExprT1::num_args;
1147 static const bool is_linear = ExprT1::is_linear;
1150 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1151 expr1(expr1_), expr2(expr2_) {}
1155 return expr1.size();
1160 bool isActive()
const {
1161 return expr1.template isActive<Arg>();
1165 bool updateValue()
const {
1166 return expr1.updateValue();
1170 void cache()
const {
1175 value_type
val()
const {
1176 return expr1.val() - expr2.val();
1180 void computePartials(
const value_type&
bar,
1181 value_type partials[])
const {
1182 expr1.computePartials(bar, partials);
1186 void getTangents(
int i, value_type dots[])
const {
1187 expr1.getTangents(i, dots);
1192 value_type getTangent(
int i)
const {
1193 return expr1.template getTangent<Arg>(i);
1197 bool isLinear()
const {
1198 return expr1.isLinear();
1202 bool hasFastAccess()
const {
1203 return expr1.hasFastAccess();
1207 const value_type
dx(
int i)
const {
1213 return expr1.fastAccessDx(i);
1217 const value_type* getDx(
int j)
const {
1218 return expr1.getDx(j);
1223 const ExprT1& expr1;
1228 template <
typename T1,
typename ExprT2>
1229 class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
1233 typedef ConstExpr<T1> ExprT1;
1234 typedef typename ExprT1::value_type value_type_1;
1235 typedef typename ExprT2::value_type value_type_2;
1237 value_type_2>::type value_type;
1238 typedef typename ExprT1::scalar_type scalar_type_1;
1239 typedef typename ExprT2::scalar_type scalar_type_2;
1241 scalar_type_2>::type scalar_type;
1243 typedef typename ExprT1::base_expr_type base_expr_type_1;
1244 typedef typename ExprT2::base_expr_type base_expr_type_2;
1246 base_expr_type_2>::type base_expr_type;
1248 static const int num_args = ExprT2::num_args;
1250 static const bool is_linear = ExprT2::is_linear;
1253 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1254 expr1(expr1_), expr2(expr2_) {}
1258 return expr2.size();
1263 bool isActive()
const {
1264 return expr2.template isActive<Arg>();
1268 bool updateValue()
const {
1269 return expr2.updateValue();
1273 void cache()
const {
1278 value_type
val()
const {
1279 return expr1.val() - expr2.val();
1283 void computePartials(
const value_type&
bar,
1284 value_type partials[])
const {
1285 expr2.computePartials(-bar, partials);
1289 void getTangents(
int i, value_type dots[])
const {
1290 expr2.getTangents(i, dots);
1295 value_type getTangent(
int i)
const {
1296 return expr2.template getTangent<Arg>(i);
1300 bool isLinear()
const {
1301 return expr2.isLinear();
1305 bool hasFastAccess()
const {
1306 return expr2.hasFastAccess();
1310 const value_type
dx(
int i)
const {
1311 return -expr2.dx(i);
1316 return -expr2.fastAccessDx(i);
1320 const value_type* getDx(
int j)
const {
1321 return expr2.getDx(j);
1327 const ExprT2& expr2;
1335 template <
typename ExprT1,
typename ExprT2>
1338 template <
typename ExprT1,
typename ExprT2>
1339 class Expr< MultiplicationOp<ExprT1,ExprT2> > {
1343 typedef typename ExprT1::value_type value_type_1;
1344 typedef typename ExprT2::value_type value_type_2;
1346 value_type_2>::type value_type;
1347 typedef typename ExprT1::scalar_type scalar_type_1;
1348 typedef typename ExprT2::scalar_type scalar_type_2;
1350 scalar_type_2>::type scalar_type;
1352 typedef typename ExprT1::base_expr_type base_expr_type_1;
1353 typedef typename ExprT2::base_expr_type base_expr_type_2;
1355 base_expr_type_2>::type base_expr_type;
1357 static const int num_args1 = ExprT1::num_args;
1358 static const int num_args2 = ExprT2::num_args;
1359 static const int num_args = num_args1 + num_args2;
1361 static const bool is_linear =
false;
1364 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1365 expr1(expr1_), expr2(expr2_) {}
1369 int sz1 = expr1.size(), sz2 = expr2.size();
1370 return sz1 > sz2 ? sz1 : sz2;
1375 bool isActive()
const {
1376 if (Arg < num_args1)
1377 return expr1.template isActive<Arg>();
1379 return expr2.template isActive<Arg-num_args1>();
1383 bool updateValue()
const {
1384 return expr1.updateValue() && expr2.updateValue();
1388 void cache()
const {
1396 value_type
val()
const {
1401 void computePartials(
const value_type&
bar,
1402 value_type partials[])
const {
1404 expr1.computePartials(bar*v2, partials);
1406 expr2.computePartials(bar*v1, partials+num_args1);
1410 void getTangents(
int i, value_type dots[])
const {
1411 expr1.getTangents(i, dots);
1412 expr2.getTangents(i, dots+num_args1);
1417 value_type getTangent(
int i)
const {
1418 if (Arg < num_args1)
1419 return expr1.template getTangent<Arg>(i);
1421 return expr2.template getTangent<Arg-num_args1>(i);
1425 bool isLinear()
const {
1430 bool hasFastAccess()
const {
1431 return expr1.hasFastAccess() && expr2.hasFastAccess();
1435 const value_type
dx(
int i)
const {
1436 if (expr1.size() > 0 && expr2.size() > 0)
1437 return v1*expr2.dx(i) + expr1.dx(i)*v2;
1438 else if (expr1.size() > 0)
1439 return expr1.dx(i)*v2;
1441 return v1*expr2.dx(i);
1446 return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1450 const value_type* getDx(
int j)
const {
1452 return expr1.getDx(j);
1454 return expr2.getDx(j-num_args1);
1459 const ExprT1& expr1;
1460 const ExprT2& expr2;
1461 mutable value_type_1 v1;
1462 mutable value_type_2 v2;
1466 template <
typename ExprT1,
typename T2>
1467 class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1471 typedef ConstExpr<T2> ExprT2;
1472 typedef typename ExprT1::value_type value_type_1;
1473 typedef typename ExprT2::value_type value_type_2;
1475 value_type_2>::type value_type;
1476 typedef typename ExprT1::scalar_type scalar_type_1;
1477 typedef typename ExprT2::scalar_type scalar_type_2;
1479 scalar_type_2>::type scalar_type;
1481 typedef typename ExprT1::base_expr_type base_expr_type_1;
1482 typedef typename ExprT2::base_expr_type base_expr_type_2;
1484 base_expr_type_2>::type base_expr_type;
1486 static const int num_args = ExprT1::num_args;
1488 static const bool is_linear = ExprT1::is_linear;
1491 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1492 expr1(expr1_), expr2(expr2_) {}
1496 return expr1.size();
1501 bool isActive()
const {
1502 return expr1.template isActive<Arg>();
1506 bool updateValue()
const {
1507 return expr1.updateValue();
1511 void cache()
const {
1516 value_type
val()
const {
1517 return expr1.val()*expr2.val();
1521 void computePartials(
const value_type&
bar,
1522 value_type partials[])
const {
1523 expr1.computePartials(bar*expr2.val(), partials);
1527 void getTangents(
int i, value_type dots[])
const {
1528 expr1.getTangents(i, dots);
1533 value_type getTangent(
int i)
const {
1534 return expr1.template getTangent<Arg>(i);
1538 bool isLinear()
const {
1539 return expr1.isLinear();
1543 bool hasFastAccess()
const {
1544 return expr1.hasFastAccess();
1548 const value_type
dx(
int i)
const {
1549 return expr1.dx(i)*expr2.val();
1554 return expr1.fastAccessDx(i)*expr2.val();
1558 const value_type* getDx(
int j)
const {
1559 return expr1.getDx(j);
1564 const ExprT1& expr1;
1569 template <
typename T1,
typename ExprT2>
1570 class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1574 typedef ConstExpr<T1> ExprT1;
1575 typedef typename ExprT1::value_type value_type_1;
1576 typedef typename ExprT2::value_type value_type_2;
1578 value_type_2>::type value_type;
1579 typedef typename ExprT1::scalar_type scalar_type_1;
1580 typedef typename ExprT2::scalar_type scalar_type_2;
1582 scalar_type_2>::type scalar_type;
1584 typedef typename ExprT1::base_expr_type base_expr_type_1;
1585 typedef typename ExprT2::base_expr_type base_expr_type_2;
1587 base_expr_type_2>::type base_expr_type;
1589 static const int num_args = ExprT2::num_args;
1591 static const bool is_linear = ExprT2::is_linear;
1594 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1595 expr1(expr1_), expr2(expr2_) {}
1599 return expr2.size();
1604 bool isActive()
const {
1605 return expr2.template isActive<Arg>();
1609 bool updateValue()
const {
1610 return expr2.updateValue();
1614 void cache()
const {
1619 value_type
val()
const {
1620 return expr1.val()*expr2.val();
1624 void computePartials(
const value_type&
bar,
1625 value_type partials[])
const {
1626 expr2.computePartials(bar*expr1.val(), partials);
1630 void getTangents(
int i, value_type dots[])
const {
1631 expr2.getTangents(i, dots);
1636 value_type getTangent(
int i)
const {
1637 return expr2.template getTangent<Arg>(i);
1641 bool isLinear()
const {
1642 return expr2.isLinear();
1646 bool hasFastAccess()
const {
1647 return expr2.hasFastAccess();
1651 const value_type
dx(
int i)
const {
1652 return expr1.val()*expr2.dx(i);
1657 return expr1.val()*expr2.fastAccessDx(i);
1661 const value_type* getDx(
int j)
const {
1662 return expr2.getDx(j);
1668 const ExprT2& expr2;
1676 template <
typename ExprT1,
typename ExprT2>
1679 template <
typename ExprT1,
typename ExprT2>
1680 class Expr< DivisionOp<ExprT1,ExprT2> > {
1684 typedef typename ExprT1::value_type value_type_1;
1685 typedef typename ExprT2::value_type value_type_2;
1687 value_type_2>::type value_type;
1688 typedef typename ExprT1::scalar_type scalar_type_1;
1689 typedef typename ExprT2::scalar_type scalar_type_2;
1691 scalar_type_2>::type scalar_type;
1693 typedef typename ExprT1::base_expr_type base_expr_type_1;
1694 typedef typename ExprT2::base_expr_type base_expr_type_2;
1696 base_expr_type_2>::type base_expr_type;
1698 static const int num_args1 = ExprT1::num_args;
1699 static const int num_args2 = ExprT2::num_args;
1700 static const int num_args = num_args1 + num_args2;
1702 static const bool is_linear =
false;
1705 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1706 expr1(expr1_), expr2(expr2_) {}
1710 int sz1 = expr1.size(), sz2 = expr2.size();
1711 return sz1 > sz2 ? sz1 : sz2;
1716 bool isActive()
const {
1717 if (Arg < num_args1)
1718 return expr1.template isActive<Arg>();
1720 return expr2.template isActive<Arg-num_args1>();
1724 bool updateValue()
const {
1725 return expr1.updateValue() && expr2.updateValue();
1729 void cache()
const {
1732 const value_type_1 v1 = expr1.val();
1733 const value_type_2 v2 = expr2.val();
1734 a = scalar_type(1.0)/v2;
1740 value_type
val()
const {
1745 void computePartials(
const value_type&
bar,
1746 value_type partials[])
const {
1748 expr1.computePartials(bar*
a, partials);
1750 expr2.computePartials(bar*b, partials+num_args1);
1754 void getTangents(
int i, value_type dots[])
const {
1755 expr1.getTangents(i, dots);
1756 expr2.getTangents(i, dots+num_args1);
1761 value_type getTangent(
int i)
const {
1762 if (Arg < num_args1)
1763 return expr1.template getTangent<Arg>(i);
1765 return expr2.template getTangent<Arg-num_args1>(i);
1769 bool isLinear()
const {
1774 bool hasFastAccess()
const {
1775 return expr1.hasFastAccess() && expr2.hasFastAccess();
1779 const value_type
dx(
int i)
const {
1780 if (expr1.size() > 0 && expr2.size() > 0)
1781 return expr1.dx(i)*
a + expr2.dx(i)*b;
1782 else if (expr1.size() > 0)
1783 return expr1.dx(i)*
a;
1785 return expr1.val()*b;
1790 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
1794 const value_type* getDx(
int j)
const {
1796 return expr1.getDx(j);
1798 return expr2.getDx(j-num_args1);
1803 const ExprT1& expr1;
1804 const ExprT2& expr2;
1805 mutable value_type v;
1806 mutable value_type
a;
1807 mutable value_type b;
1811 template <
typename ExprT1,
typename T2>
1812 class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1816 typedef ConstExpr<T2> ExprT2;
1817 typedef typename ExprT1::value_type value_type_1;
1818 typedef typename ExprT2::value_type value_type_2;
1820 value_type_2>::type value_type;
1821 typedef typename ExprT1::scalar_type scalar_type_1;
1822 typedef typename ExprT2::scalar_type scalar_type_2;
1824 scalar_type_2>::type scalar_type;
1826 typedef typename ExprT1::base_expr_type base_expr_type_1;
1827 typedef typename ExprT2::base_expr_type base_expr_type_2;
1829 base_expr_type_2>::type base_expr_type;
1831 static const int num_args = ExprT1::num_args;
1833 static const bool is_linear = ExprT1::is_linear;
1836 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1837 expr1(expr1_), expr2(expr2_) {}
1841 return expr1.size();
1846 bool isActive()
const {
1847 return expr1.template isActive<Arg>();
1851 bool updateValue()
const {
1852 return expr1.updateValue();
1856 void cache()
const {
1858 const value_type_1 v1 = expr1.val();
1859 a = scalar_type(1.0)/expr2.val();
1864 value_type
val()
const {
1869 void computePartials(
const value_type&
bar,
1870 value_type partials[])
const {
1871 expr1.computePartials(bar*
a, partials);
1875 void getTangents(
int i, value_type dots[])
const {
1876 expr1.getTangents(i, dots);
1881 value_type getTangent(
int i)
const {
1882 return expr1.template getTangent<Arg>(i);
1886 bool isLinear()
const {
1887 return expr1.isLinear();
1891 bool hasFastAccess()
const {
1892 return expr1.hasFastAccess();
1896 const value_type
dx(
int i)
const {
1897 return expr1.dx(i)*
a;
1902 return expr1.fastAccessDx(i)*
a;
1906 const value_type* getDx(
int j)
const {
1907 return expr1.getDx(j);
1912 const ExprT1& expr1;
1914 mutable value_type v;
1915 mutable value_type
a;
1919 template <
typename T1,
typename ExprT2>
1920 class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1924 typedef ConstExpr<T1> ExprT1;
1925 typedef typename ExprT1::value_type value_type_1;
1926 typedef typename ExprT2::value_type value_type_2;
1928 value_type_2>::type value_type;
1929 typedef typename ExprT1::scalar_type scalar_type_1;
1930 typedef typename ExprT2::scalar_type scalar_type_2;
1932 scalar_type_2>::type scalar_type;
1934 typedef typename ExprT1::base_expr_type base_expr_type_1;
1935 typedef typename ExprT2::base_expr_type base_expr_type_2;
1937 base_expr_type_2>::type base_expr_type;
1939 static const int num_args = ExprT2::num_args;
1941 static const bool is_linear =
false;
1944 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1945 expr1(expr1_), expr2(expr2_) {}
1949 return expr2.size();
1954 bool isActive()
const {
1955 return expr2.template isActive<Arg>();
1959 bool updateValue()
const {
1960 return expr2.updateValue();
1964 void cache()
const {
1966 const value_type_2 v2 = expr2.val();
1972 value_type
val()
const {
1977 void computePartials(
const value_type&
bar,
1978 value_type partials[])
const {
1979 expr2.computePartials(bar*b, partials);
1983 void getTangents(
int i, value_type dots[])
const {
1984 expr2.getTangents(i, dots);
1989 value_type getTangent(
int i)
const {
1990 return expr2.template getTangent<Arg>(i);
1994 bool isLinear()
const {
1999 bool hasFastAccess()
const {
2000 return expr2.hasFastAccess();
2004 const value_type
dx(
int i)
const {
2005 return expr2.dx(i)*b;
2010 return expr2.fastAccessDx(i)*b;
2014 const value_type* getDx(
int j)
const {
2015 return expr2.getDx(j);
2021 const ExprT2& expr2;
2022 mutable value_type v;
2023 mutable value_type b;
2031 template <
typename ExprT1,
typename ExprT2>
2034 template <
typename ExprT1,
typename ExprT2>
2035 class Expr< Atan2Op<ExprT1,ExprT2> > {
2039 typedef typename ExprT1::value_type value_type_1;
2040 typedef typename ExprT2::value_type value_type_2;
2042 value_type_2>::type value_type;
2043 typedef typename ExprT1::scalar_type scalar_type_1;
2044 typedef typename ExprT2::scalar_type scalar_type_2;
2046 scalar_type_2>::type scalar_type;
2048 typedef typename ExprT1::base_expr_type base_expr_type_1;
2049 typedef typename ExprT2::base_expr_type base_expr_type_2;
2051 base_expr_type_2>::type base_expr_type;
2053 static const int num_args1 = ExprT1::num_args;
2054 static const int num_args2 = ExprT2::num_args;
2055 static const int num_args = num_args1 + num_args2;
2057 static const bool is_linear =
false;
2060 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2061 expr1(expr1_), expr2(expr2_) {}
2065 int sz1 = expr1.size(), sz2 = expr2.size();
2066 return sz1 > sz2 ? sz1 : sz2;
2071 bool isActive()
const {
2072 if (Arg < num_args1)
2073 return expr1.template isActive<Arg>();
2075 return expr2.template isActive<Arg-num_args1>();
2079 bool updateValue()
const {
2080 return expr1.updateValue() && expr2.updateValue();
2084 void cache()
const {
2087 const value_type_1 v1 = expr1.val();
2088 const value_type_2 v2 = expr2.val();
2089 a = scalar_type(1.0)/(v1*v1 + v2*v2);
2096 value_type
val()
const {
2101 void computePartials(
const value_type&
bar,
2102 value_type partials[])
const {
2104 expr1.computePartials(bar*
a, partials);
2106 expr2.computePartials(bar*b, partials+num_args1);
2110 void getTangents(
int i, value_type dots[])
const {
2111 expr1.getTangents(i, dots);
2112 expr2.getTangents(i, dots+num_args1);
2117 value_type getTangent(
int i)
const {
2118 if (Arg < num_args1)
2119 return expr1.template getTangent<Arg>(i);
2121 return expr2.template getTangent<Arg-num_args1>(i);
2125 bool isLinear()
const {
2130 bool hasFastAccess()
const {
2131 return expr1.hasFastAccess() && expr2.hasFastAccess();
2135 const value_type
dx(
int i)
const {
2136 if (expr1.size() > 0 && expr2.size() > 0)
2137 return expr1.dx(i)*
a + expr2.dx(i)*b;
2138 else if (expr1.size() > 0)
2139 return expr1.dx(i)*
a;
2141 return expr1.val()*b;
2146 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
2150 const value_type* getDx(
int j)
const {
2152 return expr1.getDx(j);
2154 return expr2.getDx(j-num_args1);
2159 const ExprT1& expr1;
2160 const ExprT2& expr2;
2161 mutable value_type v;
2162 mutable value_type
a;
2163 mutable value_type b;
2167 template <
typename ExprT1,
typename T2>
2168 class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
2172 typedef ConstExpr<T2> ExprT2;
2173 typedef typename ExprT1::value_type value_type_1;
2174 typedef typename ExprT2::value_type value_type_2;
2176 value_type_2>::type value_type;
2177 typedef typename ExprT1::scalar_type scalar_type_1;
2178 typedef typename ExprT2::scalar_type scalar_type_2;
2180 scalar_type_2>::type scalar_type;
2182 typedef typename ExprT1::base_expr_type base_expr_type_1;
2183 typedef typename ExprT2::base_expr_type base_expr_type_2;
2185 base_expr_type_2>::type base_expr_type;
2187 static const int num_args = ExprT1::num_args;
2189 static const bool is_linear =
false;
2192 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2193 expr1(expr1_), expr2(expr2_) {}
2197 return expr1.size();
2202 bool isActive()
const {
2203 return expr1.template isActive<Arg>();
2207 bool updateValue()
const {
2208 return expr1.updateValue();
2212 void cache()
const {
2214 const value_type_1 v1 = expr1.val();
2215 const value_type_2 v2 = expr2.val();
2216 a = v2/(v1*v1 + v2*v2);
2221 value_type
val()
const {
2226 void computePartials(
const value_type&
bar,
2227 value_type partials[])
const {
2228 expr1.computePartials(bar*
a, partials);
2232 void getTangents(
int i, value_type dots[])
const {
2233 expr1.getTangents(i, dots);
2238 value_type getTangent(
int i)
const {
2239 return expr1.template getTangent<Arg>(i);
2243 bool isLinear()
const {
2248 bool hasFastAccess()
const {
2249 return expr1.hasFastAccess();
2253 const value_type
dx(
int i)
const {
2254 return expr1.dx(i)*
a;
2259 return expr1.fastAccessDx(i)*
a;
2263 const value_type* getDx(
int j)
const {
2264 return expr1.getDx(j);
2269 const ExprT1& expr1;
2271 mutable value_type v;
2272 mutable value_type
a;
2276 template <
typename T1,
typename ExprT2>
2277 class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
2281 typedef ConstExpr<T1> ExprT1;
2282 typedef typename ExprT1::value_type value_type_1;
2283 typedef typename ExprT2::value_type value_type_2;
2285 value_type_2>::type value_type;
2286 typedef typename ExprT1::scalar_type scalar_type_1;
2287 typedef typename ExprT2::scalar_type scalar_type_2;
2289 scalar_type_2>::type scalar_type;
2291 typedef typename ExprT1::base_expr_type base_expr_type_1;
2292 typedef typename ExprT2::base_expr_type base_expr_type_2;
2294 base_expr_type_2>::type base_expr_type;
2296 static const int num_args = ExprT2::num_args;
2298 static const bool is_linear =
false;
2301 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2302 expr1(expr1_), expr2(expr2_) {}
2306 return expr2.size();
2311 bool isActive()
const {
2312 return expr2.template isActive<Arg>();
2316 bool updateValue()
const {
2317 return expr2.updateValue();
2321 void cache()
const {
2323 const value_type_1 v1 = expr1.val();
2324 const value_type_2 v2 = expr2.val();
2325 b = -v1/(v1*v1 + v2*v2);
2330 value_type
val()
const {
2335 void computePartials(
const value_type&
bar,
2336 value_type partials[])
const {
2337 expr2.computePartials(bar*b, partials);
2341 void getTangents(
int i, value_type dots[])
const {
2342 expr2.getTangents(i, dots);
2347 value_type getTangent(
int i)
const {
2348 return expr2.template getTangent<Arg>(i);
2352 bool isLinear()
const {
2357 bool hasFastAccess()
const {
2358 return expr2.hasFastAccess();
2362 const value_type
dx(
int i)
const {
2363 return expr2.dx(i)*b;
2368 return expr2.fastAccessDx(i)*b;
2372 const value_type* getDx(
int j)
const {
2373 return expr2.getDx(j);
2379 const ExprT2& expr2;
2380 mutable value_type v;
2381 mutable value_type b;
2389 template <
typename ExprT1,
typename ExprT2>
2392 template <
typename ExprT1,
typename ExprT2>
2393 class Expr< PowerOp<ExprT1,ExprT2> > {
2397 typedef typename ExprT1::value_type value_type_1;
2398 typedef typename ExprT2::value_type value_type_2;
2400 value_type_2>::type value_type;
2401 typedef typename ExprT1::scalar_type scalar_type_1;
2402 typedef typename ExprT2::scalar_type scalar_type_2;
2404 scalar_type_2>::type scalar_type;
2406 typedef typename ExprT1::base_expr_type base_expr_type_1;
2407 typedef typename ExprT2::base_expr_type base_expr_type_2;
2409 base_expr_type_2>::type base_expr_type;
2411 static const int num_args1 = ExprT1::num_args;
2412 static const int num_args2 = ExprT2::num_args;
2413 static const int num_args = num_args1 + num_args2;
2415 static const bool is_linear =
false;
2418 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2419 expr1(expr1_), expr2(expr2_) {}
2423 int sz1 = expr1.size(), sz2 = expr2.size();
2424 return sz1 > sz2 ? sz1 : sz2;
2429 bool isActive()
const {
2430 if (Arg < num_args1)
2431 return expr1.template isActive<Arg>();
2433 return expr2.template isActive<Arg-num_args1>();
2437 bool updateValue()
const {
2438 return expr1.updateValue() && expr2.updateValue();
2442 void cache()
const {
2445 const value_type_1 v1 = expr1.val();
2446 const value_type_2 v2 = expr2.val();
2448 if (v1 == scalar_type(0.0)) {
2449 a = scalar_type(0.0);
2450 b = scalar_type(0.0);
2459 value_type
val()
const {
2464 void computePartials(
const value_type&
bar,
2465 value_type partials[])
const {
2467 expr1.computePartials(bar*
a, partials);
2469 expr2.computePartials(bar*b, partials+num_args1);
2473 void getTangents(
int i, value_type dots[])
const {
2474 expr1.getTangents(i, dots);
2475 expr2.getTangents(i, dots+num_args1);
2480 value_type getTangent(
int i)
const {
2481 if (Arg < num_args1)
2482 return expr1.template getTangent<Arg>(i);
2484 return expr2.template getTangent<Arg-num_args1>(i);
2488 bool isLinear()
const {
2493 bool hasFastAccess()
const {
2494 return expr1.hasFastAccess() && expr2.hasFastAccess();
2498 const value_type
dx(
int i)
const {
2499 if (expr1.size() > 0 && expr2.size() > 0)
2500 return expr1.dx(i)*
a + expr2.dx(i)*b;
2501 else if (expr1.size() > 0)
2502 return expr1.dx(i)*
a;
2504 return expr1.val()*b;
2509 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
2513 const value_type* getDx(
int j)
const {
2515 return expr1.getDx(j);
2517 return expr2.getDx(j-num_args1);
2522 const ExprT1& expr1;
2523 const ExprT2& expr2;
2524 mutable value_type v;
2525 mutable value_type
a;
2526 mutable value_type b;
2530 template <
typename ExprT1,
typename T2>
2531 class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
2535 typedef ConstExpr<T2> ExprT2;
2536 typedef typename ExprT1::value_type value_type_1;
2537 typedef typename ExprT2::value_type value_type_2;
2539 value_type_2>::type value_type;
2540 typedef typename ExprT1::scalar_type scalar_type_1;
2541 typedef typename ExprT2::scalar_type scalar_type_2;
2543 scalar_type_2>::type scalar_type;
2545 typedef typename ExprT1::base_expr_type base_expr_type_1;
2546 typedef typename ExprT2::base_expr_type base_expr_type_2;
2548 base_expr_type_2>::type base_expr_type;
2550 static const int num_args = ExprT1::num_args;
2552 static const bool is_linear =
false;
2555 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2556 expr1(expr1_), expr2(expr2_) {}
2560 return expr1.size();
2565 bool isActive()
const {
2566 return expr1.template isActive<Arg>();
2570 bool updateValue()
const {
2571 return expr1.updateValue();
2575 void cache()
const {
2577 const value_type_1 v1 = expr1.val();
2578 const value_type_2 v2 = expr2.val();
2580 if (v1 == scalar_type(0.0)) {
2581 a = scalar_type(0.0);
2589 value_type
val()
const {
2594 void computePartials(
const value_type&
bar,
2595 value_type partials[])
const {
2596 expr1.computePartials(bar*
a, partials);
2600 void getTangents(
int i, value_type dots[])
const {
2601 expr1.getTangents(i, dots);
2606 value_type getTangent(
int i)
const {
2607 return expr1.template getTangent<Arg>(i);
2611 bool isLinear()
const {
2616 bool hasFastAccess()
const {
2617 return expr1.hasFastAccess();
2621 const value_type
dx(
int i)
const {
2622 return expr1.dx(i)*
a;
2627 return expr1.fastAccessDx(i)*
a;
2631 const value_type* getDx(
int j)
const {
2632 return expr1.getDx(j);
2637 const ExprT1& expr1;
2639 mutable value_type v;
2640 mutable value_type
a;
2644 template <
typename T1,
typename ExprT2>
2645 class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
2649 typedef ConstExpr<T1> ExprT1;
2650 typedef typename ExprT1::value_type value_type_1;
2651 typedef typename ExprT2::value_type value_type_2;
2653 value_type_2>::type value_type;
2654 typedef typename ExprT1::scalar_type scalar_type_1;
2655 typedef typename ExprT2::scalar_type scalar_type_2;
2657 scalar_type_2>::type scalar_type;
2659 typedef typename ExprT1::base_expr_type base_expr_type_1;
2660 typedef typename ExprT2::base_expr_type base_expr_type_2;
2662 base_expr_type_2>::type base_expr_type;
2664 static const int num_args = ExprT2::num_args;
2666 static const bool is_linear =
false;
2669 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2670 expr1(expr1_), expr2(expr2_) {}
2674 return expr2.size();
2679 bool isActive()
const {
2680 return expr2.template isActive<Arg>();
2684 bool updateValue()
const {
2685 return expr2.updateValue();
2689 void cache()
const {
2691 const value_type_1 v1 = expr1.val();
2692 const value_type_2 v2 = expr2.val();
2694 if (v1 == scalar_type(0.0)) {
2695 b = scalar_type(0.0);
2703 value_type
val()
const {
2708 void computePartials(
const value_type&
bar,
2709 value_type partials[])
const {
2710 expr2.computePartials(bar*b, partials);
2714 void getTangents(
int i, value_type dots[])
const {
2715 expr2.getTangents(i, dots);
2720 value_type getTangent(
int i)
const {
2721 return expr2.template getTangent<Arg>(i);
2725 bool isLinear()
const {
2730 bool hasFastAccess()
const {
2731 return expr2.hasFastAccess();
2735 const value_type
dx(
int i)
const {
2736 return expr2.dx(i)*b;
2741 return expr2.fastAccessDx(i)*b;
2745 const value_type* getDx(
int j)
const {
2746 return expr2.getDx(j);
2752 const ExprT2& expr2;
2753 mutable value_type v;
2754 mutable value_type b;
2762 template <
typename ExprT1,
typename ExprT2>
2765 template <
typename ExprT1,
typename ExprT2>
2766 class Expr< MaxOp<ExprT1,ExprT2> > {
2770 typedef typename ExprT1::value_type value_type_1;
2771 typedef typename ExprT2::value_type value_type_2;
2773 value_type_2>::type value_type;
2774 typedef typename ExprT1::scalar_type scalar_type_1;
2775 typedef typename ExprT2::scalar_type scalar_type_2;
2777 scalar_type_2>::type scalar_type;
2779 typedef typename ExprT1::base_expr_type base_expr_type_1;
2780 typedef typename ExprT2::base_expr_type base_expr_type_2;
2782 base_expr_type_2>::type base_expr_type;
2784 static const int num_args1 = ExprT1::num_args;
2785 static const int num_args2 = ExprT2::num_args;
2786 static const int num_args = num_args1 + num_args2;
2788 static const bool is_linear =
false;
2791 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2792 expr1(expr1_), expr2(expr2_) {}
2796 int sz1 = expr1.size(), sz2 = expr2.size();
2797 return sz1 > sz2 ? sz1 : sz2;
2802 bool isActive()
const {
2803 if (Arg < num_args1)
2804 return expr1.template isActive<Arg>();
2806 return expr2.template isActive<Arg-num_args1>();
2810 bool updateValue()
const {
2811 return expr1.updateValue() && expr2.updateValue();
2815 void cache()
const {
2818 const value_type_1 v1 = expr1.val();
2819 const value_type_2 v2 = expr2.val();
2820 max_v1 = (v1 >= v2);
2821 v = max_v1 ? v1 : v2;
2825 value_type
val()
const {
2830 void computePartials(
const value_type&
bar,
2831 value_type partials[])
const {
2832 if (num_args1 > 0) {
2834 expr1.computePartials(bar, partials);
2836 expr1.computePartials(value_type(0.0), partials);
2838 if (num_args2 > 0) {
2840 expr2.computePartials(value_type(0.0), partials+num_args1);
2842 expr2.computePartials(bar, partials+num_args1);
2847 void getTangents(
int i, value_type dots[])
const {
2848 expr1.getTangents(i, dots);
2849 expr2.getTangents(i, dots+num_args1);
2854 value_type getTangent(
int i)
const {
2855 if (Arg < num_args1)
2856 return expr1.template getTangent<Arg>(i);
2858 return expr2.template getTangent<Arg-num_args1>(i);
2862 bool isLinear()
const {
2867 bool hasFastAccess()
const {
2868 return expr1.hasFastAccess() && expr2.hasFastAccess();
2872 const value_type
dx(
int i)
const {
2873 return max_v1 ? expr1.dx(i) : expr2.dx(i);
2878 return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2882 const value_type* getDx(
int j)
const {
2884 return expr1.getDx(j);
2886 return expr2.getDx(j-num_args1);
2891 const ExprT1& expr1;
2892 const ExprT2& expr2;
2893 mutable value_type v;
2894 mutable bool max_v1;
2898 template <
typename ExprT1,
typename T2>
2899 class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2903 typedef ConstExpr<T2> ExprT2;
2904 typedef typename ExprT1::value_type value_type_1;
2905 typedef typename ExprT2::value_type value_type_2;
2907 value_type_2>::type value_type;
2908 typedef typename ExprT1::scalar_type scalar_type_1;
2909 typedef typename ExprT2::scalar_type scalar_type_2;
2911 scalar_type_2>::type scalar_type;
2913 typedef typename ExprT1::base_expr_type base_expr_type_1;
2914 typedef typename ExprT2::base_expr_type base_expr_type_2;
2916 base_expr_type_2>::type base_expr_type;
2918 static const int num_args = ExprT1::num_args;
2920 static const bool is_linear =
false;
2923 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2924 expr1(expr1_), expr2(expr2_) {}
2928 return expr1.size();
2933 bool isActive()
const {
2934 return expr1.template isActive<Arg>();
2938 bool updateValue()
const {
2939 return expr1.updateValue();
2943 void cache()
const {
2945 const value_type_1 v1 = expr1.val();
2946 const value_type_2 v2 = expr2.val();
2947 max_v1 = (v1 >= v2);
2948 v = max_v1 ? v1 : v2;
2952 value_type
val()
const {
2957 void computePartials(
const value_type&
bar,
2958 value_type partials[])
const {
2960 expr1.computePartials(bar, partials);
2962 expr1.computePartials(value_type(0.0), partials);
2966 void getTangents(
int i, value_type dots[])
const {
2967 expr1.getTangents(i, dots);
2972 value_type getTangent(
int i)
const {
2973 return expr1.template getTangent<Arg>(i);
2977 bool isLinear()
const {
2982 bool hasFastAccess()
const {
2983 return expr1.hasFastAccess();
2987 const value_type
dx(
int i)
const {
2988 return max_v1 ? expr1.dx(i) : value_type(0.0);
2993 return max_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
2997 const value_type* getDx(
int j)
const {
2998 return expr1.getDx(j);
3003 const ExprT1& expr1;
3005 mutable value_type v;
3006 mutable bool max_v1;
3010 template <
typename T1,
typename ExprT2>
3011 class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
3015 typedef ConstExpr<T1> ExprT1;
3016 typedef typename ExprT1::value_type value_type_1;
3017 typedef typename ExprT2::value_type value_type_2;
3019 value_type_2>::type value_type;
3020 typedef typename ExprT1::scalar_type scalar_type_1;
3021 typedef typename ExprT2::scalar_type scalar_type_2;
3023 scalar_type_2>::type scalar_type;
3025 typedef typename ExprT1::base_expr_type base_expr_type_1;
3026 typedef typename ExprT2::base_expr_type base_expr_type_2;
3028 base_expr_type_2>::type base_expr_type;
3030 static const int num_args = ExprT2::num_args;
3032 static const bool is_linear =
false;
3035 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3036 expr1(expr1_), expr2(expr2_) {}
3040 return expr2.size();
3045 bool isActive()
const {
3046 return expr2.template isActive<Arg>();
3050 bool updateValue()
const {
3051 return expr2.updateValue();
3055 void cache()
const {
3057 const value_type_1 v1 = expr1.val();
3058 const value_type_2 v2 = expr2.val();
3059 max_v1 = (v1 >= v2);
3060 v = max_v1 ? v1 : v2;
3064 value_type
val()
const {
3069 void computePartials(
const value_type&
bar,
3070 value_type partials[])
const {
3072 expr2.computePartials(value_type(0.0), partials);
3074 expr2.computePartials(bar, partials);
3078 void getTangents(
int i, value_type dots[])
const {
3079 expr2.getTangents(i, dots);
3084 value_type getTangent(
int i)
const {
3085 return expr2.template getTangent<Arg>(i);
3089 bool isLinear()
const {
3094 bool hasFastAccess()
const {
3095 return expr2.hasFastAccess();
3099 const value_type
dx(
int i)
const {
3100 return max_v1 ? value_type(0.0) : expr2.dx(i);
3105 return max_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3109 const value_type* getDx(
int j)
const {
3110 return expr2.getDx(j);
3116 const ExprT2& expr2;
3117 mutable value_type v;
3118 mutable bool max_v1;
3126 template <
typename ExprT1,
typename ExprT2>
3129 template <
typename ExprT1,
typename ExprT2>
3130 class Expr< MinOp<ExprT1,ExprT2> > {
3134 typedef typename ExprT1::value_type value_type_1;
3135 typedef typename ExprT2::value_type value_type_2;
3137 value_type_2>::type value_type;
3138 typedef typename ExprT1::scalar_type scalar_type_1;
3139 typedef typename ExprT2::scalar_type scalar_type_2;
3141 scalar_type_2>::type scalar_type;
3143 typedef typename ExprT1::base_expr_type base_expr_type_1;
3144 typedef typename ExprT2::base_expr_type base_expr_type_2;
3146 base_expr_type_2>::type base_expr_type;
3148 static const int num_args1 = ExprT1::num_args;
3149 static const int num_args2 = ExprT2::num_args;
3150 static const int num_args = num_args1 + num_args2;
3152 static const bool is_linear =
false;
3155 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3156 expr1(expr1_), expr2(expr2_) {}
3160 int sz1 = expr1.size(), sz2 = expr2.size();
3161 return sz1 > sz2 ? sz1 : sz2;
3166 bool isActive()
const {
3167 if (Arg < num_args1)
3168 return expr1.template isActive<Arg>();
3170 return expr2.template isActive<Arg-num_args1>();
3174 bool updateValue()
const {
3175 return expr1.updateValue() && expr2.updateValue();
3179 void cache()
const {
3182 const value_type_1 v1 = expr1.val();
3183 const value_type_2 v2 = expr2.val();
3184 min_v1 = (v1 <= v2);
3185 v = min_v1 ? v1 : v2;
3189 value_type
val()
const {
3194 void computePartials(
const value_type&
bar,
3195 value_type partials[])
const {
3196 if (num_args1 > 0) {
3198 expr1.computePartials(bar, partials);
3200 expr1.computePartials(value_type(0.0), partials);
3202 if (num_args2 > 0) {
3204 expr2.computePartials(value_type(0.0), partials+num_args1);
3206 expr2.computePartials(bar, partials+num_args1);
3211 void getTangents(
int i, value_type dots[])
const {
3212 expr1.getTangents(i, dots);
3213 expr2.getTangents(i, dots+num_args1);
3218 value_type getTangent(
int i)
const {
3219 if (Arg < num_args1)
3220 return expr1.template getTangent<Arg>(i);
3222 return expr2.template getTangent<Arg-num_args1>(i);
3226 bool isLinear()
const {
3231 bool hasFastAccess()
const {
3232 return expr1.hasFastAccess() && expr2.hasFastAccess();
3236 const value_type
dx(
int i)
const {
3237 return min_v1 ? expr1.dx(i) : expr2.dx(i);
3242 return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
3246 const value_type* getDx(
int j)
const {
3248 return expr1.getDx(j);
3250 return expr2.getDx(j-num_args1);
3255 const ExprT1& expr1;
3256 const ExprT2& expr2;
3257 mutable value_type v;
3258 mutable bool min_v1;
3262 template <
typename ExprT1,
typename T2>
3263 class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
3267 typedef ConstExpr<T2> ExprT2;
3268 typedef typename ExprT1::value_type value_type_1;
3269 typedef typename ExprT2::value_type value_type_2;
3271 value_type_2>::type value_type;
3272 typedef typename ExprT1::scalar_type scalar_type_1;
3273 typedef typename ExprT2::scalar_type scalar_type_2;
3275 scalar_type_2>::type scalar_type;
3277 typedef typename ExprT1::base_expr_type base_expr_type_1;
3278 typedef typename ExprT2::base_expr_type base_expr_type_2;
3280 base_expr_type_2>::type base_expr_type;
3282 static const int num_args = ExprT1::num_args;
3284 static const bool is_linear =
false;
3287 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3288 expr1(expr1_), expr2(expr2_) {}
3292 return expr1.size();
3297 bool isActive()
const {
3298 return expr1.template isActive<Arg>();
3302 bool updateValue()
const {
3303 return expr1.updateValue();
3307 void cache()
const {
3309 const value_type_1 v1 = expr1.val();
3310 const value_type_2 v2 = expr2.val();
3311 min_v1 = (v1 <= v2);
3312 v = min_v1 ? v1 : v2;
3316 value_type
val()
const {
3321 void computePartials(
const value_type&
bar,
3322 value_type partials[])
const {
3324 expr1.computePartials(bar, partials);
3326 expr1.computePartials(value_type(0.0), partials);
3330 void getTangents(
int i, value_type dots[])
const {
3331 expr1.getTangents(i, dots);
3336 value_type getTangent(
int i)
const {
3337 return expr1.template getTangent<Arg>(i);
3341 bool isLinear()
const {
3346 bool hasFastAccess()
const {
3347 return expr1.hasFastAccess();
3351 const value_type
dx(
int i)
const {
3352 return min_v1 ? expr1.dx(i) : value_type(0.0);
3357 return min_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3361 const value_type* getDx(
int j)
const {
3362 return expr1.getDx(j);
3367 const ExprT1& expr1;
3369 mutable value_type v;
3370 mutable bool min_v1;
3374 template <
typename T1,
typename ExprT2>
3375 class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
3379 typedef ConstExpr<T1> ExprT1;
3380 typedef typename ExprT1::value_type value_type_1;
3381 typedef typename ExprT2::value_type value_type_2;
3383 value_type_2>::type value_type;
3384 typedef typename ExprT1::scalar_type scalar_type_1;
3385 typedef typename ExprT2::scalar_type scalar_type_2;
3387 scalar_type_2>::type scalar_type;
3389 typedef typename ExprT1::base_expr_type base_expr_type_1;
3390 typedef typename ExprT2::base_expr_type base_expr_type_2;
3392 base_expr_type_2>::type base_expr_type;
3394 static const int num_args = ExprT2::num_args;
3396 static const bool is_linear =
false;
3399 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3400 expr1(expr1_), expr2(expr2_) {}
3404 return expr2.size();
3409 bool isActive()
const {
3410 return expr2.template isActive<Arg>();
3414 bool updateValue()
const {
3415 return expr2.updateValue();
3419 void cache()
const {
3421 const value_type_1 v1 = expr1.val();
3422 const value_type_2 v2 = expr2.val();
3423 min_v1 = (v1 <= v2);
3424 v = min_v1 ? v1 : v2;
3428 value_type
val()
const {
3433 void computePartials(
const value_type&
bar,
3434 value_type partials[])
const {
3436 expr2.computePartials(value_type(0.0), partials);
3438 expr2.computePartials(bar, partials);
3442 void getTangents(
int i, value_type dots[])
const {
3443 expr2.getTangents(i, dots);
3448 value_type getTangent(
int i)
const {
3449 return expr2.template getTangent<Arg>(i);
3453 bool isLinear()
const {
3458 bool hasFastAccess()
const {
3459 return expr2.hasFastAccess();
3463 const value_type
dx(
int i)
const {
3464 return min_v1 ? value_type(0.0) : expr2.dx(i);
3469 return min_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3473 const value_type* getDx(
int j)
const {
3474 return expr2.getDx(j);
3480 const ExprT2& expr2;
3481 mutable value_type v;
3482 mutable bool min_v1;
3490 #define FAD_BINARYOP_MACRO(OPNAME,OP) \
3491 namespace Sacado { \
3492 namespace ELRCacheFad { \
3494 template <typename T1, typename T2> \
3495 KOKKOS_INLINE_FUNCTION \
3496 SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
3497 OPNAME (const T1& expr1, const T2& expr2) \
3499 typedef OP< T1, T2 > expr_t; \
3501 return Expr<expr_t>(expr1, expr2); \
3504 template <typename T> \
3505 KOKKOS_INLINE_FUNCTION \
3506 Expr< OP< Expr<T>, Expr<T> > > \
3507 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
3509 typedef OP< Expr<T>, Expr<T> > expr_t; \
3511 return Expr<expr_t>(expr1, expr2); \
3514 template <typename T> \
3515 KOKKOS_INLINE_FUNCTION \
3516 Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
3518 OPNAME (const typename Expr<T>::value_type& c, \
3519 const Expr<T>& expr) \
3521 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3522 typedef OP< ConstT, Expr<T> > expr_t; \
3524 return Expr<expr_t>(ConstT(c), expr); \
3527 template <typename T> \
3528 KOKKOS_INLINE_FUNCTION \
3529 Expr< OP< Expr<T>, \
3530 ConstExpr<typename Expr<T>::value_type> > > \
3531 OPNAME (const Expr<T>& expr, \
3532 const typename Expr<T>::value_type& c) \
3534 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3535 typedef OP< Expr<T>, ConstT > expr_t; \
3537 return Expr<expr_t>(expr, ConstT(c)); \
3540 template <typename T> \
3541 KOKKOS_INLINE_FUNCTION \
3542 SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
3543 OPNAME (const typename Expr<T>::scalar_type& c, \
3544 const Expr<T>& expr) \
3546 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3547 typedef OP< ConstT, Expr<T> > expr_t; \
3549 return Expr<expr_t>(ConstT(c), expr); \
3552 template <typename T> \
3553 KOKKOS_INLINE_FUNCTION \
3554 SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
3555 OPNAME (const Expr<T>& expr, \
3556 const typename Expr<T>::scalar_type& c) \
3558 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3559 typedef OP< Expr<T>, ConstT > expr_t; \
3561 return Expr<expr_t>(expr, ConstT(c)); \
3576 #undef FAD_BINARYOP_MACRO
3580 #define FAD_RELOP_MACRO(OP) \
3581 namespace Sacado { \
3582 namespace ELRCacheFad { \
3583 template <typename ExprT1, typename ExprT2> \
3584 KOKKOS_INLINE_FUNCTION \
3586 operator OP (const Expr<ExprT1>& expr1, \
3587 const Expr<ExprT2>& expr2) \
3591 return expr1.val() OP expr2.val(); \
3594 template <typename ExprT2> \
3595 KOKKOS_INLINE_FUNCTION \
3597 operator OP (const typename Expr<ExprT2>::value_type& a, \
3598 const Expr<ExprT2>& expr2) \
3601 return a OP expr2.val(); \
3604 template <typename ExprT1> \
3605 KOKKOS_INLINE_FUNCTION \
3607 operator OP (const Expr<ExprT1>& expr1, \
3608 const typename Expr<ExprT1>::value_type& b) \
3611 return expr1.val() OP b; \
3627 #undef FAD_RELOP_MACRO
3631 namespace ELRCacheFad {
3633 template <
typename ExprT>
3638 return ! expr.val();
3648 namespace ELRCacheFad {
3650 template <
typename ExprT>
3654 bool is_zero = (x.val() == 0.0);
3655 for (
int i=0; i<x.size(); i++)
3656 is_zero = is_zero && (x.dx(i) == 0.0);
3664 #define FAD_BOOL_MACRO(OP) \
3665 namespace Sacado { \
3666 namespace ELRCacheFad { \
3667 template <typename ExprT1, typename ExprT2> \
3668 KOKKOS_INLINE_FUNCTION \
3670 operator OP (const Expr<ExprT1>& expr1, \
3671 const Expr<ExprT2>& expr2) \
3673 return toBool(expr1) OP toBool(expr2); \
3676 template <typename ExprT2> \
3677 KOKKOS_INLINE_FUNCTION \
3679 operator OP (const typename Expr<ExprT2>::value_type& a, \
3680 const Expr<ExprT2>& expr2) \
3682 return a OP toBool(expr2); \
3685 template <typename ExprT1> \
3686 KOKKOS_INLINE_FUNCTION \
3688 operator OP (const Expr<ExprT1>& expr1, \
3689 const typename Expr<ExprT1>::value_type& b) \
3691 return toBool(expr1) OP b; \
3699 #undef FAD_BOOL_MACRO
3705 namespace ELRCacheFad {
3707 template <
typename ExprT>
3708 std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
3709 os << x.val() <<
" [";
3711 for (
int i=0; i< x.size(); i++) {
3712 os <<
" " << x.dx(i);
3723 #endif // SACADO_CACHEFAD_OPS_HPP
KOKKOS_INLINE_FUNCTION const value_type * getDx(int j) const
KOKKOS_INLINE_FUNCTION bool isLinear() const
KOKKOS_INLINE_FUNCTION bool isActive() const
KOKKOS_INLINE_FUNCTION const value_type * getDx(int j) const
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
ExprT::value_type value_type
ExprT::base_expr_type base_expr_type
KOKKOS_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
KOKKOS_INLINE_FUNCTION bool isLinear() const
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
KOKKOS_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
KOKKOS_INLINE_FUNCTION value_type val() const
KOKKOS_INLINE_FUNCTION void cache() const
KOKKOS_INLINE_FUNCTION value_type val() const
KOKKOS_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MinOp
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
ExprT::value_type value_type
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION value_type getTangent(int i) const
KOKKOS_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
ExprT::value_type value_type
value_type getTangent(int i) const
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
KOKKOS_INLINE_FUNCTION mpl::enable_if_c< ExprLevel< Expr< T1 > >::value==ExprLevel< Expr< T2 > >::value, Expr< PowerOp< Expr< T1 >, Expr< T2 > > > >::type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 Atan2Op
KOKKOS_INLINE_FUNCTION bool isLinear() const
#define KOKKOS_INLINE_FUNCTION
KOKKOS_INLINE_FUNCTION void cache() const
KOKKOS_INLINE_FUNCTION T safe_sqrt(const T &x)
ExprT::base_expr_type base_expr_type
ExprT::value_type value_type
KOKKOS_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
KOKKOS_INLINE_FUNCTION value_type getTangent(int i) const
KOKKOS_INLINE_FUNCTION int size() const
#define FAD_BINARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, CDX1, CDX2, FASTACCESSDX, VAL_CONST_DX_1, VAL_CONST_DX_2, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
ExprT::scalar_type scalar_type
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
#define FAD_RELOP_MACRO(OP)
KOKKOS_INLINE_FUNCTION bool isLinear() const
KOKKOS_INLINE_FUNCTION bool updateValue() const
ExprT::scalar_type scalar_type
Wrapper for a generic expression template.
KOKKOS_INLINE_FUNCTION bool isActive() const
ExprT::base_expr_type base_expr_type
KOKKOS_INLINE_FUNCTION value_type val() const
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 DivisionOp
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION bool isActive() const
KOKKOS_INLINE_FUNCTION int size() const
ExprT::scalar_type scalar_type
KOKKOS_INLINE_FUNCTION bool updateValue() const
#define FAD_BOOL_MACRO(OP)
KOKKOS_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
atan2(expr1.val(), expr2.val())
KOKKOS_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
ExprT::scalar_type scalar_type
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
KOKKOS_INLINE_FUNCTION const value_type * getDx(int j) const
KOKKOS_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
KOKKOS_INLINE_FUNCTION Expr< UnaryPlusOp< Expr< T > > > operator+(const Expr< T > &expr)
ExprT::base_expr_type base_expr_type
KOKKOS_INLINE_FUNCTION bool isActive() const
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
KOKKOS_INLINE_FUNCTION int size() const
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
KOKKOS_INLINE_FUNCTION void cache() const
KOKKOS_INLINE_FUNCTION const value_type * getDx(int j) const
KOKKOS_INLINE_FUNCTION value_type val() const
KOKKOS_INLINE_FUNCTION void cache() const
KOKKOS_INLINE_FUNCTION value_type getTangent(int i) const
KOKKOS_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
KOKKOS_INLINE_FUNCTION int size() const
KOKKOS_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
KOKKOS_INLINE_FUNCTION bool updateValue() const
KOKKOS_INLINE_FUNCTION bool updateValue() const
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
KOKKOS_INLINE_FUNCTION Expr< UnaryMinusOp< Expr< T > > > operator-(const Expr< T > &expr)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 PowerOp