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 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 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 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 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 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)),
610 a = scalar_type(1.0)+std::tan(v)*std::tan(v),
614 a = scalar_type(-1.0)/std::sqrt(scalar_type(1.0)-v*v),
618 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)-v*v),
622 a = scalar_type(1.0)/(scalar_type(1.0)+v*v),
634 a = scalar_type(1.0)/(std::cosh(v)*std::cosh(v)),
638 a = scalar_type(1.0)/std::sqrt((v-scalar_type(1.0))*(v+scalar_type(1.0))),
642 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)+v*v),
646 a = scalar_type(1.0)/(scalar_type(1.0)-v*v),
648 #ifdef HAVE_SACADO_CXX11
651 a = scalar_type(1.0)/(scalar_type(3.0)*
std::cbrt(v*v)),
655 #undef FAD_UNARYOP_MACRO
661 namespace ELRCacheFad {
667 template <
typename ExprT1,
typename ExprT2>
670 template <
typename ExprT1,
typename ExprT2>
671 class Expr< AdditionOp<ExprT1,ExprT2> > {
675 typedef typename ExprT1::value_type value_type_1;
676 typedef typename ExprT2::value_type value_type_2;
678 value_type_2>::type value_type;
679 typedef typename ExprT1::scalar_type scalar_type_1;
680 typedef typename ExprT2::scalar_type scalar_type_2;
682 scalar_type_2>::type scalar_type;
684 typedef typename ExprT1::base_expr_type base_expr_type_1;
685 typedef typename ExprT2::base_expr_type base_expr_type_2;
687 base_expr_type_2>::type base_expr_type;
689 static const int num_args1 = ExprT1::num_args;
690 static const int num_args2 = ExprT2::num_args;
691 static const int num_args = num_args1 + num_args2;
693 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
696 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
697 expr1(expr1_), expr2(expr2_) {}
701 int sz1 = expr1.size(), sz2 = expr2.size();
702 return sz1 > sz2 ? sz1 : sz2;
707 bool isActive()
const {
709 return expr1.template isActive<Arg>();
711 return expr2.template isActive<Arg-num_args1>();
715 bool updateValue()
const {
716 return expr1.updateValue() && expr2.updateValue();
726 value_type
val()
const {
727 return expr1.val()+expr2.val();
731 void computePartials(
const value_type&
bar,
732 value_type partials[])
const {
734 expr1.computePartials(bar, partials);
736 expr2.computePartials(bar, partials+num_args1);
740 void getTangents(
int i, value_type dots[])
const {
741 expr1.getTangents(i, dots);
742 expr2.getTangents(i, dots+num_args1);
747 value_type getTangent(
int i)
const {
749 return expr1.template getTangent<Arg>(i);
751 return expr2.template getTangent<Arg-num_args1>(i);
755 bool isLinear()
const {
756 return expr1.isLinear() && expr2.isLinear();
760 bool hasFastAccess()
const {
761 return expr1.hasFastAccess() && expr2.hasFastAccess();
765 const value_type
dx(
int i)
const {
766 return expr1.dx(i) + expr2.dx(i);
771 return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
775 const value_type* getDx(
int j)
const {
777 return expr1.getDx(j);
779 return expr2.getDx(j-num_args1);
789 template <
typename ExprT1,
typename T2>
790 class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
794 typedef ConstExpr<T2> ExprT2;
795 typedef typename ExprT1::value_type value_type_1;
796 typedef typename ExprT2::value_type value_type_2;
798 value_type_2>::type value_type;
799 typedef typename ExprT1::scalar_type scalar_type_1;
800 typedef typename ExprT2::scalar_type scalar_type_2;
802 scalar_type_2>::type scalar_type;
804 typedef typename ExprT1::base_expr_type base_expr_type_1;
805 typedef typename ExprT2::base_expr_type base_expr_type_2;
807 base_expr_type_2>::type base_expr_type;
809 static const int num_args = ExprT1::num_args;
811 static const bool is_linear = ExprT1::is_linear;
814 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
815 expr1(expr1_), expr2(expr2_) {}
824 bool isActive()
const {
825 return expr1.template isActive<Arg>();
829 bool updateValue()
const {
830 return expr1.updateValue();
839 value_type
val()
const {
840 return expr1.val() + expr2.val();
844 void computePartials(
const value_type&
bar,
845 value_type partials[])
const {
846 expr1.computePartials(bar, partials);
850 void getTangents(
int i, value_type dots[])
const {
851 expr1.getTangents(i, dots);
856 value_type getTangent(
int i)
const {
857 return expr1.template getTangent<Arg>(i);
861 bool isLinear()
const {
862 return expr1.isLinear();
866 bool hasFastAccess()
const {
867 return expr1.hasFastAccess();
871 const value_type
dx(
int i)
const {
877 return expr1.fastAccessDx(i);
881 const value_type* getDx(
int j)
const {
882 return expr1.getDx(j);
892 template <
typename T1,
typename ExprT2>
893 class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
897 typedef ConstExpr<T1> ExprT1;
898 typedef typename ExprT1::value_type value_type_1;
899 typedef typename ExprT2::value_type value_type_2;
901 value_type_2>::type value_type;
902 typedef typename ExprT1::scalar_type scalar_type_1;
903 typedef typename ExprT2::scalar_type scalar_type_2;
905 scalar_type_2>::type scalar_type;
907 typedef typename ExprT1::base_expr_type base_expr_type_1;
908 typedef typename ExprT2::base_expr_type base_expr_type_2;
910 base_expr_type_2>::type base_expr_type;
912 static const int num_args = ExprT2::num_args;
914 static const bool is_linear = ExprT2::is_linear;
917 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
918 expr1(expr1_), expr2(expr2_) {}
927 bool isActive()
const {
928 return expr2.template isActive<Arg>();
932 bool updateValue()
const {
933 return expr2.updateValue();
942 value_type
val()
const {
943 return expr1.val() + expr2.val();
947 void computePartials(
const value_type&
bar,
948 value_type partials[])
const {
949 expr2.computePartials(bar, partials);
953 void getTangents(
int i, value_type dots[])
const {
954 expr2.getTangents(i, dots);
959 value_type getTangent(
int i)
const {
960 return expr2.template getTangent<Arg>(i);
964 bool isLinear()
const {
965 return expr2.isLinear();
969 bool hasFastAccess()
const {
970 return expr2.hasFastAccess();
974 const value_type
dx(
int i)
const {
980 return expr2.fastAccessDx(i);
984 const value_type* getDx(
int j)
const {
985 return expr2.getDx(j);
999 template <
typename ExprT1,
typename ExprT2>
1002 template <
typename ExprT1,
typename ExprT2>
1003 class Expr< SubtractionOp<ExprT1,ExprT2> > {
1007 typedef typename ExprT1::value_type value_type_1;
1008 typedef typename ExprT2::value_type value_type_2;
1010 value_type_2>::type value_type;
1011 typedef typename ExprT1::scalar_type scalar_type_1;
1012 typedef typename ExprT2::scalar_type scalar_type_2;
1014 scalar_type_2>::type scalar_type;
1016 typedef typename ExprT1::base_expr_type base_expr_type_1;
1017 typedef typename ExprT2::base_expr_type base_expr_type_2;
1019 base_expr_type_2>::type base_expr_type;
1021 static const int num_args1 = ExprT1::num_args;
1022 static const int num_args2 = ExprT2::num_args;
1023 static const int num_args = num_args1 + num_args2;
1025 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
1028 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1029 expr1(expr1_), expr2(expr2_) {}
1033 int sz1 = expr1.size(), sz2 = expr2.size();
1034 return sz1 > sz2 ? sz1 : sz2;
1039 bool isActive()
const {
1040 if (Arg < num_args1)
1041 return expr1.template isActive<Arg>();
1043 return expr2.template isActive<Arg-num_args1>();
1047 bool updateValue()
const {
1048 return expr1.updateValue() && expr2.updateValue();
1052 void cache()
const {
1058 value_type
val()
const {
1059 return expr1.val()-expr2.val();
1063 void computePartials(
const value_type&
bar,
1064 value_type partials[])
const {
1066 expr1.computePartials(bar, partials);
1068 expr2.computePartials(-bar, partials+num_args1);
1072 void getTangents(
int i, value_type dots[])
const {
1073 expr1.getTangents(i, dots);
1074 expr2.getTangents(i, dots+num_args1);
1079 value_type getTangent(
int i)
const {
1080 if (Arg < num_args1)
1081 return expr1.template getTangent<Arg>(i);
1083 return expr2.template getTangent<Arg-num_args1>(i);
1087 bool isLinear()
const {
1088 return expr1.isLinear() && expr2.isLinear();
1092 bool hasFastAccess()
const {
1093 return expr1.hasFastAccess() && expr2.hasFastAccess();
1097 const value_type
dx(
int i)
const {
1098 return expr1.dx(i) - expr2.dx(i);
1103 return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
1107 const value_type* getDx(
int j)
const {
1109 return expr1.getDx(j);
1111 return expr2.getDx(j-num_args1);
1116 const ExprT1& expr1;
1117 const ExprT2& expr2;
1121 template <
typename ExprT1,
typename T2>
1122 class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
1126 typedef ConstExpr<T2> ExprT2;
1127 typedef typename ExprT1::value_type value_type_1;
1128 typedef typename ExprT2::value_type value_type_2;
1130 value_type_2>::type value_type;
1131 typedef typename ExprT1::scalar_type scalar_type_1;
1132 typedef typename ExprT2::scalar_type scalar_type_2;
1134 scalar_type_2>::type scalar_type;
1136 typedef typename ExprT1::base_expr_type base_expr_type_1;
1137 typedef typename ExprT2::base_expr_type base_expr_type_2;
1139 base_expr_type_2>::type base_expr_type;
1141 static const int num_args = ExprT1::num_args;
1143 static const bool is_linear = ExprT1::is_linear;
1146 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1147 expr1(expr1_), expr2(expr2_) {}
1151 return expr1.size();
1156 bool isActive()
const {
1157 return expr1.template isActive<Arg>();
1161 bool updateValue()
const {
1162 return expr1.updateValue();
1166 void cache()
const {
1171 value_type
val()
const {
1172 return expr1.val() - expr2.val();
1176 void computePartials(
const value_type&
bar,
1177 value_type partials[])
const {
1178 expr1.computePartials(bar, partials);
1182 void getTangents(
int i, value_type dots[])
const {
1183 expr1.getTangents(i, dots);
1188 value_type getTangent(
int i)
const {
1189 return expr1.template getTangent<Arg>(i);
1193 bool isLinear()
const {
1194 return expr1.isLinear();
1198 bool hasFastAccess()
const {
1199 return expr1.hasFastAccess();
1203 const value_type
dx(
int i)
const {
1209 return expr1.fastAccessDx(i);
1213 const value_type* getDx(
int j)
const {
1214 return expr1.getDx(j);
1219 const ExprT1& expr1;
1224 template <
typename T1,
typename ExprT2>
1225 class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
1229 typedef ConstExpr<T1> ExprT1;
1230 typedef typename ExprT1::value_type value_type_1;
1231 typedef typename ExprT2::value_type value_type_2;
1233 value_type_2>::type value_type;
1234 typedef typename ExprT1::scalar_type scalar_type_1;
1235 typedef typename ExprT2::scalar_type scalar_type_2;
1237 scalar_type_2>::type scalar_type;
1239 typedef typename ExprT1::base_expr_type base_expr_type_1;
1240 typedef typename ExprT2::base_expr_type base_expr_type_2;
1242 base_expr_type_2>::type base_expr_type;
1244 static const int num_args = ExprT2::num_args;
1246 static const bool is_linear = ExprT2::is_linear;
1249 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1250 expr1(expr1_), expr2(expr2_) {}
1254 return expr2.size();
1259 bool isActive()
const {
1260 return expr2.template isActive<Arg>();
1264 bool updateValue()
const {
1265 return expr2.updateValue();
1269 void cache()
const {
1274 value_type
val()
const {
1275 return expr1.val() - expr2.val();
1279 void computePartials(
const value_type&
bar,
1280 value_type partials[])
const {
1281 expr2.computePartials(-bar, partials);
1285 void getTangents(
int i, value_type dots[])
const {
1286 expr2.getTangents(i, dots);
1291 value_type getTangent(
int i)
const {
1292 return expr2.template getTangent<Arg>(i);
1296 bool isLinear()
const {
1297 return expr2.isLinear();
1301 bool hasFastAccess()
const {
1302 return expr2.hasFastAccess();
1306 const value_type
dx(
int i)
const {
1307 return -expr2.dx(i);
1312 return -expr2.fastAccessDx(i);
1316 const value_type* getDx(
int j)
const {
1317 return expr2.getDx(j);
1323 const ExprT2& expr2;
1331 template <
typename ExprT1,
typename ExprT2>
1334 template <
typename ExprT1,
typename ExprT2>
1335 class Expr< MultiplicationOp<ExprT1,ExprT2> > {
1339 typedef typename ExprT1::value_type value_type_1;
1340 typedef typename ExprT2::value_type value_type_2;
1342 value_type_2>::type value_type;
1343 typedef typename ExprT1::scalar_type scalar_type_1;
1344 typedef typename ExprT2::scalar_type scalar_type_2;
1346 scalar_type_2>::type scalar_type;
1348 typedef typename ExprT1::base_expr_type base_expr_type_1;
1349 typedef typename ExprT2::base_expr_type base_expr_type_2;
1351 base_expr_type_2>::type base_expr_type;
1353 static const int num_args1 = ExprT1::num_args;
1354 static const int num_args2 = ExprT2::num_args;
1355 static const int num_args = num_args1 + num_args2;
1357 static const bool is_linear =
false;
1360 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1361 expr1(expr1_), expr2(expr2_) {}
1365 int sz1 = expr1.size(), sz2 = expr2.size();
1366 return sz1 > sz2 ? sz1 : sz2;
1371 bool isActive()
const {
1372 if (Arg < num_args1)
1373 return expr1.template isActive<Arg>();
1375 return expr2.template isActive<Arg-num_args1>();
1379 bool updateValue()
const {
1380 return expr1.updateValue() && expr2.updateValue();
1384 void cache()
const {
1392 value_type
val()
const {
1397 void computePartials(
const value_type&
bar,
1398 value_type partials[])
const {
1400 expr1.computePartials(bar*v2, partials);
1402 expr2.computePartials(bar*v1, partials+num_args1);
1406 void getTangents(
int i, value_type dots[])
const {
1407 expr1.getTangents(i, dots);
1408 expr2.getTangents(i, dots+num_args1);
1413 value_type getTangent(
int i)
const {
1414 if (Arg < num_args1)
1415 return expr1.template getTangent<Arg>(i);
1417 return expr2.template getTangent<Arg-num_args1>(i);
1421 bool isLinear()
const {
1426 bool hasFastAccess()
const {
1427 return expr1.hasFastAccess() && expr2.hasFastAccess();
1431 const value_type
dx(
int i)
const {
1432 if (expr1.size() > 0 && expr2.size() > 0)
1433 return v1*expr2.dx(i) + expr1.dx(i)*v2;
1434 else if (expr1.size() > 0)
1435 return expr1.dx(i)*v2;
1437 return v1*expr2.dx(i);
1442 return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1446 const value_type* getDx(
int j)
const {
1448 return expr1.getDx(j);
1450 return expr2.getDx(j-num_args1);
1455 const ExprT1& expr1;
1456 const ExprT2& expr2;
1457 mutable value_type_1 v1;
1458 mutable value_type_2 v2;
1462 template <
typename ExprT1,
typename T2>
1463 class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1467 typedef ConstExpr<T2> ExprT2;
1468 typedef typename ExprT1::value_type value_type_1;
1469 typedef typename ExprT2::value_type value_type_2;
1471 value_type_2>::type value_type;
1472 typedef typename ExprT1::scalar_type scalar_type_1;
1473 typedef typename ExprT2::scalar_type scalar_type_2;
1475 scalar_type_2>::type scalar_type;
1477 typedef typename ExprT1::base_expr_type base_expr_type_1;
1478 typedef typename ExprT2::base_expr_type base_expr_type_2;
1480 base_expr_type_2>::type base_expr_type;
1482 static const int num_args = ExprT1::num_args;
1484 static const bool is_linear = ExprT1::is_linear;
1487 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1488 expr1(expr1_), expr2(expr2_) {}
1492 return expr1.size();
1497 bool isActive()
const {
1498 return expr1.template isActive<Arg>();
1502 bool updateValue()
const {
1503 return expr1.updateValue();
1507 void cache()
const {
1512 value_type
val()
const {
1513 return expr1.val()*expr2.val();
1517 void computePartials(
const value_type&
bar,
1518 value_type partials[])
const {
1519 expr1.computePartials(bar*expr2.val(), partials);
1523 void getTangents(
int i, value_type dots[])
const {
1524 expr1.getTangents(i, dots);
1529 value_type getTangent(
int i)
const {
1530 return expr1.template getTangent<Arg>(i);
1534 bool isLinear()
const {
1535 return expr1.isLinear();
1539 bool hasFastAccess()
const {
1540 return expr1.hasFastAccess();
1544 const value_type
dx(
int i)
const {
1545 return expr1.dx(i)*expr2.val();
1550 return expr1.fastAccessDx(i)*expr2.val();
1554 const value_type* getDx(
int j)
const {
1555 return expr1.getDx(j);
1560 const ExprT1& expr1;
1565 template <
typename T1,
typename ExprT2>
1566 class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1570 typedef ConstExpr<T1> ExprT1;
1571 typedef typename ExprT1::value_type value_type_1;
1572 typedef typename ExprT2::value_type value_type_2;
1574 value_type_2>::type value_type;
1575 typedef typename ExprT1::scalar_type scalar_type_1;
1576 typedef typename ExprT2::scalar_type scalar_type_2;
1578 scalar_type_2>::type scalar_type;
1580 typedef typename ExprT1::base_expr_type base_expr_type_1;
1581 typedef typename ExprT2::base_expr_type base_expr_type_2;
1583 base_expr_type_2>::type base_expr_type;
1585 static const int num_args = ExprT2::num_args;
1587 static const bool is_linear = ExprT2::is_linear;
1590 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1591 expr1(expr1_), expr2(expr2_) {}
1595 return expr2.size();
1600 bool isActive()
const {
1601 return expr2.template isActive<Arg>();
1605 bool updateValue()
const {
1606 return expr2.updateValue();
1610 void cache()
const {
1615 value_type
val()
const {
1616 return expr1.val()*expr2.val();
1620 void computePartials(
const value_type&
bar,
1621 value_type partials[])
const {
1622 expr2.computePartials(bar*expr1.val(), partials);
1626 void getTangents(
int i, value_type dots[])
const {
1627 expr2.getTangents(i, dots);
1632 value_type getTangent(
int i)
const {
1633 return expr2.template getTangent<Arg>(i);
1637 bool isLinear()
const {
1638 return expr2.isLinear();
1642 bool hasFastAccess()
const {
1643 return expr2.hasFastAccess();
1647 const value_type
dx(
int i)
const {
1648 return expr1.val()*expr2.dx(i);
1653 return expr1.val()*expr2.fastAccessDx(i);
1657 const value_type* getDx(
int j)
const {
1658 return expr2.getDx(j);
1664 const ExprT2& expr2;
1672 template <
typename ExprT1,
typename ExprT2>
1675 template <
typename ExprT1,
typename ExprT2>
1676 class Expr< DivisionOp<ExprT1,ExprT2> > {
1680 typedef typename ExprT1::value_type value_type_1;
1681 typedef typename ExprT2::value_type value_type_2;
1683 value_type_2>::type value_type;
1684 typedef typename ExprT1::scalar_type scalar_type_1;
1685 typedef typename ExprT2::scalar_type scalar_type_2;
1687 scalar_type_2>::type scalar_type;
1689 typedef typename ExprT1::base_expr_type base_expr_type_1;
1690 typedef typename ExprT2::base_expr_type base_expr_type_2;
1692 base_expr_type_2>::type base_expr_type;
1694 static const int num_args1 = ExprT1::num_args;
1695 static const int num_args2 = ExprT2::num_args;
1696 static const int num_args = num_args1 + num_args2;
1698 static const bool is_linear =
false;
1701 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1702 expr1(expr1_), expr2(expr2_) {}
1706 int sz1 = expr1.size(), sz2 = expr2.size();
1707 return sz1 > sz2 ? sz1 : sz2;
1712 bool isActive()
const {
1713 if (Arg < num_args1)
1714 return expr1.template isActive<Arg>();
1716 return expr2.template isActive<Arg-num_args1>();
1720 bool updateValue()
const {
1721 return expr1.updateValue() && expr2.updateValue();
1725 void cache()
const {
1728 const value_type_1 v1 = expr1.val();
1729 const value_type_2 v2 = expr2.val();
1730 a = scalar_type(1.0)/v2;
1736 value_type
val()
const {
1741 void computePartials(
const value_type&
bar,
1742 value_type partials[])
const {
1744 expr1.computePartials(bar*
a, partials);
1746 expr2.computePartials(bar*b, partials+num_args1);
1750 void getTangents(
int i, value_type dots[])
const {
1751 expr1.getTangents(i, dots);
1752 expr2.getTangents(i, dots+num_args1);
1757 value_type getTangent(
int i)
const {
1758 if (Arg < num_args1)
1759 return expr1.template getTangent<Arg>(i);
1761 return expr2.template getTangent<Arg-num_args1>(i);
1765 bool isLinear()
const {
1770 bool hasFastAccess()
const {
1771 return expr1.hasFastAccess() && expr2.hasFastAccess();
1775 const value_type
dx(
int i)
const {
1776 if (expr1.size() > 0 && expr2.size() > 0)
1777 return expr1.dx(i)*
a + expr2.dx(i)*b;
1778 else if (expr1.size() > 0)
1779 return expr1.dx(i)*
a;
1781 return expr1.val()*b;
1786 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
1790 const value_type* getDx(
int j)
const {
1792 return expr1.getDx(j);
1794 return expr2.getDx(j-num_args1);
1799 const ExprT1& expr1;
1800 const ExprT2& expr2;
1801 mutable value_type v;
1802 mutable value_type
a;
1803 mutable value_type b;
1807 template <
typename ExprT1,
typename T2>
1808 class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1812 typedef ConstExpr<T2> ExprT2;
1813 typedef typename ExprT1::value_type value_type_1;
1814 typedef typename ExprT2::value_type value_type_2;
1816 value_type_2>::type value_type;
1817 typedef typename ExprT1::scalar_type scalar_type_1;
1818 typedef typename ExprT2::scalar_type scalar_type_2;
1820 scalar_type_2>::type scalar_type;
1822 typedef typename ExprT1::base_expr_type base_expr_type_1;
1823 typedef typename ExprT2::base_expr_type base_expr_type_2;
1825 base_expr_type_2>::type base_expr_type;
1827 static const int num_args = ExprT1::num_args;
1829 static const bool is_linear = ExprT1::is_linear;
1832 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1833 expr1(expr1_), expr2(expr2_) {}
1837 return expr1.size();
1842 bool isActive()
const {
1843 return expr1.template isActive<Arg>();
1847 bool updateValue()
const {
1848 return expr1.updateValue();
1852 void cache()
const {
1854 const value_type_1 v1 = expr1.val();
1855 a = scalar_type(1.0)/expr2.val();
1860 value_type
val()
const {
1865 void computePartials(
const value_type&
bar,
1866 value_type partials[])
const {
1867 expr1.computePartials(bar*
a, partials);
1871 void getTangents(
int i, value_type dots[])
const {
1872 expr1.getTangents(i, dots);
1877 value_type getTangent(
int i)
const {
1878 return expr1.template getTangent<Arg>(i);
1882 bool isLinear()
const {
1883 return expr1.isLinear();
1887 bool hasFastAccess()
const {
1888 return expr1.hasFastAccess();
1892 const value_type
dx(
int i)
const {
1893 return expr1.dx(i)*
a;
1898 return expr1.fastAccessDx(i)*
a;
1902 const value_type* getDx(
int j)
const {
1903 return expr1.getDx(j);
1908 const ExprT1& expr1;
1910 mutable value_type v;
1911 mutable value_type
a;
1915 template <
typename T1,
typename ExprT2>
1916 class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1920 typedef ConstExpr<T1> ExprT1;
1921 typedef typename ExprT1::value_type value_type_1;
1922 typedef typename ExprT2::value_type value_type_2;
1924 value_type_2>::type value_type;
1925 typedef typename ExprT1::scalar_type scalar_type_1;
1926 typedef typename ExprT2::scalar_type scalar_type_2;
1928 scalar_type_2>::type scalar_type;
1930 typedef typename ExprT1::base_expr_type base_expr_type_1;
1931 typedef typename ExprT2::base_expr_type base_expr_type_2;
1933 base_expr_type_2>::type base_expr_type;
1935 static const int num_args = ExprT2::num_args;
1937 static const bool is_linear =
false;
1940 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1941 expr1(expr1_), expr2(expr2_) {}
1945 return expr2.size();
1950 bool isActive()
const {
1951 return expr2.template isActive<Arg>();
1955 bool updateValue()
const {
1956 return expr2.updateValue();
1960 void cache()
const {
1962 const value_type_2 v2 = expr2.val();
1968 value_type
val()
const {
1973 void computePartials(
const value_type&
bar,
1974 value_type partials[])
const {
1975 expr2.computePartials(bar*b, partials);
1979 void getTangents(
int i, value_type dots[])
const {
1980 expr2.getTangents(i, dots);
1985 value_type getTangent(
int i)
const {
1986 return expr2.template getTangent<Arg>(i);
1990 bool isLinear()
const {
1995 bool hasFastAccess()
const {
1996 return expr2.hasFastAccess();
2000 const value_type
dx(
int i)
const {
2001 return expr2.dx(i)*b;
2006 return expr2.fastAccessDx(i)*b;
2010 const value_type* getDx(
int j)
const {
2011 return expr2.getDx(j);
2017 const ExprT2& expr2;
2018 mutable value_type v;
2019 mutable value_type b;
2027 template <
typename ExprT1,
typename ExprT2>
2030 template <
typename ExprT1,
typename ExprT2>
2031 class Expr< Atan2Op<ExprT1,ExprT2> > {
2035 typedef typename ExprT1::value_type value_type_1;
2036 typedef typename ExprT2::value_type value_type_2;
2038 value_type_2>::type value_type;
2039 typedef typename ExprT1::scalar_type scalar_type_1;
2040 typedef typename ExprT2::scalar_type scalar_type_2;
2042 scalar_type_2>::type scalar_type;
2044 typedef typename ExprT1::base_expr_type base_expr_type_1;
2045 typedef typename ExprT2::base_expr_type base_expr_type_2;
2047 base_expr_type_2>::type base_expr_type;
2049 static const int num_args1 = ExprT1::num_args;
2050 static const int num_args2 = ExprT2::num_args;
2051 static const int num_args = num_args1 + num_args2;
2053 static const bool is_linear =
false;
2056 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2057 expr1(expr1_), expr2(expr2_) {}
2061 int sz1 = expr1.size(), sz2 = expr2.size();
2062 return sz1 > sz2 ? sz1 : sz2;
2067 bool isActive()
const {
2068 if (Arg < num_args1)
2069 return expr1.template isActive<Arg>();
2071 return expr2.template isActive<Arg-num_args1>();
2075 bool updateValue()
const {
2076 return expr1.updateValue() && expr2.updateValue();
2080 void cache()
const {
2083 const value_type_1 v1 = expr1.val();
2084 const value_type_2 v2 = expr2.val();
2085 a = scalar_type(1.0)/(v1*v1 + v2*v2);
2092 value_type
val()
const {
2097 void computePartials(
const value_type&
bar,
2098 value_type partials[])
const {
2100 expr1.computePartials(bar*
a, partials);
2102 expr2.computePartials(bar*b, partials+num_args1);
2106 void getTangents(
int i, value_type dots[])
const {
2107 expr1.getTangents(i, dots);
2108 expr2.getTangents(i, dots+num_args1);
2113 value_type getTangent(
int i)
const {
2114 if (Arg < num_args1)
2115 return expr1.template getTangent<Arg>(i);
2117 return expr2.template getTangent<Arg-num_args1>(i);
2121 bool isLinear()
const {
2126 bool hasFastAccess()
const {
2127 return expr1.hasFastAccess() && expr2.hasFastAccess();
2131 const value_type
dx(
int i)
const {
2132 if (expr1.size() > 0 && expr2.size() > 0)
2133 return expr1.dx(i)*
a + expr2.dx(i)*b;
2134 else if (expr1.size() > 0)
2135 return expr1.dx(i)*
a;
2137 return expr1.val()*b;
2142 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
2146 const value_type* getDx(
int j)
const {
2148 return expr1.getDx(j);
2150 return expr2.getDx(j-num_args1);
2155 const ExprT1& expr1;
2156 const ExprT2& expr2;
2157 mutable value_type v;
2158 mutable value_type
a;
2159 mutable value_type b;
2163 template <
typename ExprT1,
typename T2>
2164 class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
2168 typedef ConstExpr<T2> ExprT2;
2169 typedef typename ExprT1::value_type value_type_1;
2170 typedef typename ExprT2::value_type value_type_2;
2172 value_type_2>::type value_type;
2173 typedef typename ExprT1::scalar_type scalar_type_1;
2174 typedef typename ExprT2::scalar_type scalar_type_2;
2176 scalar_type_2>::type scalar_type;
2178 typedef typename ExprT1::base_expr_type base_expr_type_1;
2179 typedef typename ExprT2::base_expr_type base_expr_type_2;
2181 base_expr_type_2>::type base_expr_type;
2183 static const int num_args = ExprT1::num_args;
2185 static const bool is_linear =
false;
2188 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2189 expr1(expr1_), expr2(expr2_) {}
2193 return expr1.size();
2198 bool isActive()
const {
2199 return expr1.template isActive<Arg>();
2203 bool updateValue()
const {
2204 return expr1.updateValue();
2208 void cache()
const {
2210 const value_type_1 v1 = expr1.val();
2211 const value_type_2 v2 = expr2.val();
2212 a = v2/(v1*v1 + v2*v2);
2217 value_type
val()
const {
2222 void computePartials(
const value_type&
bar,
2223 value_type partials[])
const {
2224 expr1.computePartials(bar*
a, partials);
2228 void getTangents(
int i, value_type dots[])
const {
2229 expr1.getTangents(i, dots);
2234 value_type getTangent(
int i)
const {
2235 return expr1.template getTangent<Arg>(i);
2239 bool isLinear()
const {
2244 bool hasFastAccess()
const {
2245 return expr1.hasFastAccess();
2249 const value_type
dx(
int i)
const {
2250 return expr1.dx(i)*
a;
2255 return expr1.fastAccessDx(i)*
a;
2259 const value_type* getDx(
int j)
const {
2260 return expr1.getDx(j);
2265 const ExprT1& expr1;
2267 mutable value_type v;
2268 mutable value_type
a;
2272 template <
typename T1,
typename ExprT2>
2273 class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
2277 typedef ConstExpr<T1> ExprT1;
2278 typedef typename ExprT1::value_type value_type_1;
2279 typedef typename ExprT2::value_type value_type_2;
2281 value_type_2>::type value_type;
2282 typedef typename ExprT1::scalar_type scalar_type_1;
2283 typedef typename ExprT2::scalar_type scalar_type_2;
2285 scalar_type_2>::type scalar_type;
2287 typedef typename ExprT1::base_expr_type base_expr_type_1;
2288 typedef typename ExprT2::base_expr_type base_expr_type_2;
2290 base_expr_type_2>::type base_expr_type;
2292 static const int num_args = ExprT2::num_args;
2294 static const bool is_linear =
false;
2297 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2298 expr1(expr1_), expr2(expr2_) {}
2302 return expr2.size();
2307 bool isActive()
const {
2308 return expr2.template isActive<Arg>();
2312 bool updateValue()
const {
2313 return expr2.updateValue();
2317 void cache()
const {
2319 const value_type_1 v1 = expr1.val();
2320 const value_type_2 v2 = expr2.val();
2321 b = -v1/(v1*v1 + v2*v2);
2326 value_type
val()
const {
2331 void computePartials(
const value_type&
bar,
2332 value_type partials[])
const {
2333 expr2.computePartials(bar*b, partials);
2337 void getTangents(
int i, value_type dots[])
const {
2338 expr2.getTangents(i, dots);
2343 value_type getTangent(
int i)
const {
2344 return expr2.template getTangent<Arg>(i);
2348 bool isLinear()
const {
2353 bool hasFastAccess()
const {
2354 return expr2.hasFastAccess();
2358 const value_type
dx(
int i)
const {
2359 return expr2.dx(i)*b;
2364 return expr2.fastAccessDx(i)*b;
2368 const value_type* getDx(
int j)
const {
2369 return expr2.getDx(j);
2375 const ExprT2& expr2;
2376 mutable value_type v;
2377 mutable value_type b;
2385 template <
typename ExprT1,
typename ExprT2>
2388 template <
typename ExprT1,
typename ExprT2>
2389 class Expr< PowerOp<ExprT1,ExprT2> > {
2393 typedef typename ExprT1::value_type value_type_1;
2394 typedef typename ExprT2::value_type value_type_2;
2396 value_type_2>::type value_type;
2397 typedef typename ExprT1::scalar_type scalar_type_1;
2398 typedef typename ExprT2::scalar_type scalar_type_2;
2400 scalar_type_2>::type scalar_type;
2402 typedef typename ExprT1::base_expr_type base_expr_type_1;
2403 typedef typename ExprT2::base_expr_type base_expr_type_2;
2405 base_expr_type_2>::type base_expr_type;
2407 static const int num_args1 = ExprT1::num_args;
2408 static const int num_args2 = ExprT2::num_args;
2409 static const int num_args = num_args1 + num_args2;
2411 static const bool is_linear =
false;
2414 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2415 expr1(expr1_), expr2(expr2_) {}
2419 int sz1 = expr1.size(), sz2 = expr2.size();
2420 return sz1 > sz2 ? sz1 : sz2;
2425 bool isActive()
const {
2426 if (Arg < num_args1)
2427 return expr1.template isActive<Arg>();
2429 return expr2.template isActive<Arg-num_args1>();
2433 bool updateValue()
const {
2434 return expr1.updateValue() && expr2.updateValue();
2438 void cache()
const {
2441 const value_type_1 v1 = expr1.val();
2442 const value_type_2 v2 = expr2.val();
2444 if (v1 == scalar_type(0.0)) {
2445 a = scalar_type(0.0);
2446 b = scalar_type(0.0);
2455 value_type
val()
const {
2460 void computePartials(
const value_type&
bar,
2461 value_type partials[])
const {
2463 expr1.computePartials(bar*
a, partials);
2465 expr2.computePartials(bar*b, partials+num_args1);
2469 void getTangents(
int i, value_type dots[])
const {
2470 expr1.getTangents(i, dots);
2471 expr2.getTangents(i, dots+num_args1);
2476 value_type getTangent(
int i)
const {
2477 if (Arg < num_args1)
2478 return expr1.template getTangent<Arg>(i);
2480 return expr2.template getTangent<Arg-num_args1>(i);
2484 bool isLinear()
const {
2489 bool hasFastAccess()
const {
2490 return expr1.hasFastAccess() && expr2.hasFastAccess();
2494 const value_type
dx(
int i)
const {
2495 if (expr1.size() > 0 && expr2.size() > 0)
2496 return expr1.dx(i)*
a + expr2.dx(i)*b;
2497 else if (expr1.size() > 0)
2498 return expr1.dx(i)*
a;
2500 return expr1.val()*b;
2505 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
2509 const value_type* getDx(
int j)
const {
2511 return expr1.getDx(j);
2513 return expr2.getDx(j-num_args1);
2518 const ExprT1& expr1;
2519 const ExprT2& expr2;
2520 mutable value_type v;
2521 mutable value_type
a;
2522 mutable value_type b;
2526 template <
typename ExprT1,
typename T2>
2527 class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
2531 typedef ConstExpr<T2> ExprT2;
2532 typedef typename ExprT1::value_type value_type_1;
2533 typedef typename ExprT2::value_type value_type_2;
2535 value_type_2>::type value_type;
2536 typedef typename ExprT1::scalar_type scalar_type_1;
2537 typedef typename ExprT2::scalar_type scalar_type_2;
2539 scalar_type_2>::type scalar_type;
2541 typedef typename ExprT1::base_expr_type base_expr_type_1;
2542 typedef typename ExprT2::base_expr_type base_expr_type_2;
2544 base_expr_type_2>::type base_expr_type;
2546 static const int num_args = ExprT1::num_args;
2548 static const bool is_linear =
false;
2551 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2552 expr1(expr1_), expr2(expr2_) {}
2556 return expr1.size();
2561 bool isActive()
const {
2562 return expr1.template isActive<Arg>();
2566 bool updateValue()
const {
2567 return expr1.updateValue();
2571 void cache()
const {
2573 const value_type_1 v1 = expr1.val();
2574 const value_type_2 v2 = expr2.val();
2576 if (v1 == scalar_type(0.0)) {
2577 a = scalar_type(0.0);
2585 value_type
val()
const {
2590 void computePartials(
const value_type&
bar,
2591 value_type partials[])
const {
2592 expr1.computePartials(bar*
a, partials);
2596 void getTangents(
int i, value_type dots[])
const {
2597 expr1.getTangents(i, dots);
2602 value_type getTangent(
int i)
const {
2603 return expr1.template getTangent<Arg>(i);
2607 bool isLinear()
const {
2612 bool hasFastAccess()
const {
2613 return expr1.hasFastAccess();
2617 const value_type
dx(
int i)
const {
2618 return expr1.dx(i)*
a;
2623 return expr1.fastAccessDx(i)*
a;
2627 const value_type* getDx(
int j)
const {
2628 return expr1.getDx(j);
2633 const ExprT1& expr1;
2635 mutable value_type v;
2636 mutable value_type
a;
2640 template <
typename T1,
typename ExprT2>
2641 class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
2645 typedef ConstExpr<T1> ExprT1;
2646 typedef typename ExprT1::value_type value_type_1;
2647 typedef typename ExprT2::value_type value_type_2;
2649 value_type_2>::type value_type;
2650 typedef typename ExprT1::scalar_type scalar_type_1;
2651 typedef typename ExprT2::scalar_type scalar_type_2;
2653 scalar_type_2>::type scalar_type;
2655 typedef typename ExprT1::base_expr_type base_expr_type_1;
2656 typedef typename ExprT2::base_expr_type base_expr_type_2;
2658 base_expr_type_2>::type base_expr_type;
2660 static const int num_args = ExprT2::num_args;
2662 static const bool is_linear =
false;
2665 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2666 expr1(expr1_), expr2(expr2_) {}
2670 return expr2.size();
2675 bool isActive()
const {
2676 return expr2.template isActive<Arg>();
2680 bool updateValue()
const {
2681 return expr2.updateValue();
2685 void cache()
const {
2687 const value_type_1 v1 = expr1.val();
2688 const value_type_2 v2 = expr2.val();
2690 if (v1 == scalar_type(0.0)) {
2691 b = scalar_type(0.0);
2699 value_type
val()
const {
2704 void computePartials(
const value_type&
bar,
2705 value_type partials[])
const {
2706 expr2.computePartials(bar*b, partials);
2710 void getTangents(
int i, value_type dots[])
const {
2711 expr2.getTangents(i, dots);
2716 value_type getTangent(
int i)
const {
2717 return expr2.template getTangent<Arg>(i);
2721 bool isLinear()
const {
2726 bool hasFastAccess()
const {
2727 return expr2.hasFastAccess();
2731 const value_type
dx(
int i)
const {
2732 return expr2.dx(i)*b;
2737 return expr2.fastAccessDx(i)*b;
2741 const value_type* getDx(
int j)
const {
2742 return expr2.getDx(j);
2748 const ExprT2& expr2;
2749 mutable value_type v;
2750 mutable value_type b;
2758 template <
typename ExprT1,
typename ExprT2>
2761 template <
typename ExprT1,
typename ExprT2>
2762 class Expr< MaxOp<ExprT1,ExprT2> > {
2766 typedef typename ExprT1::value_type value_type_1;
2767 typedef typename ExprT2::value_type value_type_2;
2769 value_type_2>::type value_type;
2770 typedef typename ExprT1::scalar_type scalar_type_1;
2771 typedef typename ExprT2::scalar_type scalar_type_2;
2773 scalar_type_2>::type scalar_type;
2775 typedef typename ExprT1::base_expr_type base_expr_type_1;
2776 typedef typename ExprT2::base_expr_type base_expr_type_2;
2778 base_expr_type_2>::type base_expr_type;
2780 static const int num_args1 = ExprT1::num_args;
2781 static const int num_args2 = ExprT2::num_args;
2782 static const int num_args = num_args1 + num_args2;
2784 static const bool is_linear =
false;
2787 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2788 expr1(expr1_), expr2(expr2_) {}
2792 int sz1 = expr1.size(), sz2 = expr2.size();
2793 return sz1 > sz2 ? sz1 : sz2;
2798 bool isActive()
const {
2799 if (Arg < num_args1)
2800 return expr1.template isActive<Arg>();
2802 return expr2.template isActive<Arg-num_args1>();
2806 bool updateValue()
const {
2807 return expr1.updateValue() && expr2.updateValue();
2811 void cache()
const {
2814 const value_type_1 v1 = expr1.val();
2815 const value_type_2 v2 = expr2.val();
2816 max_v1 = (v1 >= v2);
2817 v = max_v1 ? v1 : v2;
2821 value_type
val()
const {
2826 void computePartials(
const value_type&
bar,
2827 value_type partials[])
const {
2828 if (num_args1 > 0) {
2830 expr1.computePartials(bar, partials);
2832 expr1.computePartials(value_type(0.0), partials);
2834 if (num_args2 > 0) {
2836 expr2.computePartials(value_type(0.0), partials+num_args1);
2838 expr2.computePartials(bar, partials+num_args1);
2843 void getTangents(
int i, value_type dots[])
const {
2844 expr1.getTangents(i, dots);
2845 expr2.getTangents(i, dots+num_args1);
2850 value_type getTangent(
int i)
const {
2851 if (Arg < num_args1)
2852 return expr1.template getTangent<Arg>(i);
2854 return expr2.template getTangent<Arg-num_args1>(i);
2858 bool isLinear()
const {
2863 bool hasFastAccess()
const {
2864 return expr1.hasFastAccess() && expr2.hasFastAccess();
2868 const value_type
dx(
int i)
const {
2869 return max_v1 ? expr1.dx(i) : expr2.dx(i);
2874 return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2878 const value_type* getDx(
int j)
const {
2880 return expr1.getDx(j);
2882 return expr2.getDx(j-num_args1);
2887 const ExprT1& expr1;
2888 const ExprT2& expr2;
2889 mutable value_type v;
2890 mutable bool max_v1;
2894 template <
typename ExprT1,
typename T2>
2895 class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2899 typedef ConstExpr<T2> ExprT2;
2900 typedef typename ExprT1::value_type value_type_1;
2901 typedef typename ExprT2::value_type value_type_2;
2903 value_type_2>::type value_type;
2904 typedef typename ExprT1::scalar_type scalar_type_1;
2905 typedef typename ExprT2::scalar_type scalar_type_2;
2907 scalar_type_2>::type scalar_type;
2909 typedef typename ExprT1::base_expr_type base_expr_type_1;
2910 typedef typename ExprT2::base_expr_type base_expr_type_2;
2912 base_expr_type_2>::type base_expr_type;
2914 static const int num_args = ExprT1::num_args;
2916 static const bool is_linear =
false;
2919 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2920 expr1(expr1_), expr2(expr2_) {}
2924 return expr1.size();
2929 bool isActive()
const {
2930 return expr1.template isActive<Arg>();
2934 bool updateValue()
const {
2935 return expr1.updateValue();
2939 void cache()
const {
2941 const value_type_1 v1 = expr1.val();
2942 const value_type_2 v2 = expr2.val();
2943 max_v1 = (v1 >= v2);
2944 v = max_v1 ? v1 : v2;
2948 value_type
val()
const {
2953 void computePartials(
const value_type&
bar,
2954 value_type partials[])
const {
2956 expr1.computePartials(bar, partials);
2958 expr1.computePartials(value_type(0.0), partials);
2962 void getTangents(
int i, value_type dots[])
const {
2963 expr1.getTangents(i, dots);
2968 value_type getTangent(
int i)
const {
2969 return expr1.template getTangent<Arg>(i);
2973 bool isLinear()
const {
2978 bool hasFastAccess()
const {
2979 return expr1.hasFastAccess();
2983 const value_type
dx(
int i)
const {
2984 return max_v1 ? expr1.dx(i) : value_type(0.0);
2989 return max_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
2993 const value_type* getDx(
int j)
const {
2994 return expr1.getDx(j);
2999 const ExprT1& expr1;
3001 mutable value_type v;
3002 mutable bool max_v1;
3006 template <
typename T1,
typename ExprT2>
3007 class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
3011 typedef ConstExpr<T1> ExprT1;
3012 typedef typename ExprT1::value_type value_type_1;
3013 typedef typename ExprT2::value_type value_type_2;
3015 value_type_2>::type value_type;
3016 typedef typename ExprT1::scalar_type scalar_type_1;
3017 typedef typename ExprT2::scalar_type scalar_type_2;
3019 scalar_type_2>::type scalar_type;
3021 typedef typename ExprT1::base_expr_type base_expr_type_1;
3022 typedef typename ExprT2::base_expr_type base_expr_type_2;
3024 base_expr_type_2>::type base_expr_type;
3026 static const int num_args = ExprT2::num_args;
3028 static const bool is_linear =
false;
3031 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3032 expr1(expr1_), expr2(expr2_) {}
3036 return expr2.size();
3041 bool isActive()
const {
3042 return expr2.template isActive<Arg>();
3046 bool updateValue()
const {
3047 return expr2.updateValue();
3051 void cache()
const {
3053 const value_type_1 v1 = expr1.val();
3054 const value_type_2 v2 = expr2.val();
3055 max_v1 = (v1 >= v2);
3056 v = max_v1 ? v1 : v2;
3060 value_type
val()
const {
3065 void computePartials(
const value_type&
bar,
3066 value_type partials[])
const {
3068 expr2.computePartials(value_type(0.0), partials);
3070 expr2.computePartials(bar, partials);
3074 void getTangents(
int i, value_type dots[])
const {
3075 expr2.getTangents(i, dots);
3080 value_type getTangent(
int i)
const {
3081 return expr2.template getTangent<Arg>(i);
3085 bool isLinear()
const {
3090 bool hasFastAccess()
const {
3091 return expr2.hasFastAccess();
3095 const value_type
dx(
int i)
const {
3096 return max_v1 ? value_type(0.0) : expr2.dx(i);
3101 return max_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3105 const value_type* getDx(
int j)
const {
3106 return expr2.getDx(j);
3112 const ExprT2& expr2;
3113 mutable value_type v;
3114 mutable bool max_v1;
3122 template <
typename ExprT1,
typename ExprT2>
3125 template <
typename ExprT1,
typename ExprT2>
3126 class Expr< MinOp<ExprT1,ExprT2> > {
3130 typedef typename ExprT1::value_type value_type_1;
3131 typedef typename ExprT2::value_type value_type_2;
3133 value_type_2>::type value_type;
3134 typedef typename ExprT1::scalar_type scalar_type_1;
3135 typedef typename ExprT2::scalar_type scalar_type_2;
3137 scalar_type_2>::type scalar_type;
3139 typedef typename ExprT1::base_expr_type base_expr_type_1;
3140 typedef typename ExprT2::base_expr_type base_expr_type_2;
3142 base_expr_type_2>::type base_expr_type;
3144 static const int num_args1 = ExprT1::num_args;
3145 static const int num_args2 = ExprT2::num_args;
3146 static const int num_args = num_args1 + num_args2;
3148 static const bool is_linear =
false;
3151 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3152 expr1(expr1_), expr2(expr2_) {}
3156 int sz1 = expr1.size(), sz2 = expr2.size();
3157 return sz1 > sz2 ? sz1 : sz2;
3162 bool isActive()
const {
3163 if (Arg < num_args1)
3164 return expr1.template isActive<Arg>();
3166 return expr2.template isActive<Arg-num_args1>();
3170 bool updateValue()
const {
3171 return expr1.updateValue() && expr2.updateValue();
3175 void cache()
const {
3178 const value_type_1 v1 = expr1.val();
3179 const value_type_2 v2 = expr2.val();
3180 min_v1 = (v1 <= v2);
3181 v = min_v1 ? v1 : v2;
3185 value_type
val()
const {
3190 void computePartials(
const value_type&
bar,
3191 value_type partials[])
const {
3192 if (num_args1 > 0) {
3194 expr1.computePartials(bar, partials);
3196 expr1.computePartials(value_type(0.0), partials);
3198 if (num_args2 > 0) {
3200 expr2.computePartials(value_type(0.0), partials+num_args1);
3202 expr2.computePartials(bar, partials+num_args1);
3207 void getTangents(
int i, value_type dots[])
const {
3208 expr1.getTangents(i, dots);
3209 expr2.getTangents(i, dots+num_args1);
3214 value_type getTangent(
int i)
const {
3215 if (Arg < num_args1)
3216 return expr1.template getTangent<Arg>(i);
3218 return expr2.template getTangent<Arg-num_args1>(i);
3222 bool isLinear()
const {
3227 bool hasFastAccess()
const {
3228 return expr1.hasFastAccess() && expr2.hasFastAccess();
3232 const value_type
dx(
int i)
const {
3233 return min_v1 ? expr1.dx(i) : expr2.dx(i);
3238 return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
3242 const value_type* getDx(
int j)
const {
3244 return expr1.getDx(j);
3246 return expr2.getDx(j-num_args1);
3251 const ExprT1& expr1;
3252 const ExprT2& expr2;
3253 mutable value_type v;
3254 mutable bool min_v1;
3258 template <
typename ExprT1,
typename T2>
3259 class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
3263 typedef ConstExpr<T2> ExprT2;
3264 typedef typename ExprT1::value_type value_type_1;
3265 typedef typename ExprT2::value_type value_type_2;
3267 value_type_2>::type value_type;
3268 typedef typename ExprT1::scalar_type scalar_type_1;
3269 typedef typename ExprT2::scalar_type scalar_type_2;
3271 scalar_type_2>::type scalar_type;
3273 typedef typename ExprT1::base_expr_type base_expr_type_1;
3274 typedef typename ExprT2::base_expr_type base_expr_type_2;
3276 base_expr_type_2>::type base_expr_type;
3278 static const int num_args = ExprT1::num_args;
3280 static const bool is_linear =
false;
3283 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3284 expr1(expr1_), expr2(expr2_) {}
3288 return expr1.size();
3293 bool isActive()
const {
3294 return expr1.template isActive<Arg>();
3298 bool updateValue()
const {
3299 return expr1.updateValue();
3303 void cache()
const {
3305 const value_type_1 v1 = expr1.val();
3306 const value_type_2 v2 = expr2.val();
3307 min_v1 = (v1 <= v2);
3308 v = min_v1 ? v1 : v2;
3312 value_type
val()
const {
3317 void computePartials(
const value_type&
bar,
3318 value_type partials[])
const {
3320 expr1.computePartials(bar, partials);
3322 expr1.computePartials(value_type(0.0), partials);
3326 void getTangents(
int i, value_type dots[])
const {
3327 expr1.getTangents(i, dots);
3332 value_type getTangent(
int i)
const {
3333 return expr1.template getTangent<Arg>(i);
3337 bool isLinear()
const {
3342 bool hasFastAccess()
const {
3343 return expr1.hasFastAccess();
3347 const value_type
dx(
int i)
const {
3348 return min_v1 ? expr1.dx(i) : value_type(0.0);
3353 return min_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3357 const value_type* getDx(
int j)
const {
3358 return expr1.getDx(j);
3363 const ExprT1& expr1;
3365 mutable value_type v;
3366 mutable bool min_v1;
3370 template <
typename T1,
typename ExprT2>
3371 class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
3375 typedef ConstExpr<T1> ExprT1;
3376 typedef typename ExprT1::value_type value_type_1;
3377 typedef typename ExprT2::value_type value_type_2;
3379 value_type_2>::type value_type;
3380 typedef typename ExprT1::scalar_type scalar_type_1;
3381 typedef typename ExprT2::scalar_type scalar_type_2;
3383 scalar_type_2>::type scalar_type;
3385 typedef typename ExprT1::base_expr_type base_expr_type_1;
3386 typedef typename ExprT2::base_expr_type base_expr_type_2;
3388 base_expr_type_2>::type base_expr_type;
3390 static const int num_args = ExprT2::num_args;
3392 static const bool is_linear =
false;
3395 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3396 expr1(expr1_), expr2(expr2_) {}
3400 return expr2.size();
3405 bool isActive()
const {
3406 return expr2.template isActive<Arg>();
3410 bool updateValue()
const {
3411 return expr2.updateValue();
3415 void cache()
const {
3417 const value_type_1 v1 = expr1.val();
3418 const value_type_2 v2 = expr2.val();
3419 min_v1 = (v1 <= v2);
3420 v = min_v1 ? v1 : v2;
3424 value_type
val()
const {
3429 void computePartials(
const value_type&
bar,
3430 value_type partials[])
const {
3432 expr2.computePartials(value_type(0.0), partials);
3434 expr2.computePartials(bar, partials);
3438 void getTangents(
int i, value_type dots[])
const {
3439 expr2.getTangents(i, dots);
3444 value_type getTangent(
int i)
const {
3445 return expr2.template getTangent<Arg>(i);
3449 bool isLinear()
const {
3454 bool hasFastAccess()
const {
3455 return expr2.hasFastAccess();
3459 const value_type
dx(
int i)
const {
3460 return min_v1 ? value_type(0.0) : expr2.dx(i);
3465 return min_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3469 const value_type* getDx(
int j)
const {
3470 return expr2.getDx(j);
3476 const ExprT2& expr2;
3477 mutable value_type v;
3478 mutable bool min_v1;
3486 #define FAD_BINARYOP_MACRO(OPNAME,OP) \
3487 namespace Sacado { \
3488 namespace ELRCacheFad { \
3490 template <typename T1, typename T2> \
3491 KOKKOS_INLINE_FUNCTION \
3492 SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
3493 OPNAME (const T1& expr1, const T2& expr2) \
3495 typedef OP< T1, T2 > expr_t; \
3497 return Expr<expr_t>(expr1, expr2); \
3500 template <typename T> \
3501 KOKKOS_INLINE_FUNCTION \
3502 Expr< OP< Expr<T>, Expr<T> > > \
3503 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
3505 typedef OP< Expr<T>, Expr<T> > expr_t; \
3507 return Expr<expr_t>(expr1, expr2); \
3510 template <typename T> \
3511 KOKKOS_INLINE_FUNCTION \
3512 Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
3514 OPNAME (const typename Expr<T>::value_type& c, \
3515 const Expr<T>& expr) \
3517 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3518 typedef OP< ConstT, Expr<T> > expr_t; \
3520 return Expr<expr_t>(ConstT(c), expr); \
3523 template <typename T> \
3524 KOKKOS_INLINE_FUNCTION \
3525 Expr< OP< Expr<T>, \
3526 ConstExpr<typename Expr<T>::value_type> > > \
3527 OPNAME (const Expr<T>& expr, \
3528 const typename Expr<T>::value_type& c) \
3530 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3531 typedef OP< Expr<T>, ConstT > expr_t; \
3533 return Expr<expr_t>(expr, ConstT(c)); \
3536 template <typename T> \
3537 KOKKOS_INLINE_FUNCTION \
3538 SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
3539 OPNAME (const typename Expr<T>::scalar_type& c, \
3540 const Expr<T>& expr) \
3542 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3543 typedef OP< ConstT, Expr<T> > expr_t; \
3545 return Expr<expr_t>(ConstT(c), expr); \
3548 template <typename T> \
3549 KOKKOS_INLINE_FUNCTION \
3550 SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
3551 OPNAME (const Expr<T>& expr, \
3552 const typename Expr<T>::scalar_type& c) \
3554 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3555 typedef OP< Expr<T>, ConstT > expr_t; \
3557 return Expr<expr_t>(expr, ConstT(c)); \
3572 #undef FAD_BINARYOP_MACRO
3576 #define FAD_RELOP_MACRO(OP) \
3577 namespace Sacado { \
3578 namespace ELRCacheFad { \
3579 template <typename ExprT1, typename ExprT2> \
3580 KOKKOS_INLINE_FUNCTION \
3582 operator OP (const Expr<ExprT1>& expr1, \
3583 const Expr<ExprT2>& expr2) \
3587 return expr1.val() OP expr2.val(); \
3590 template <typename ExprT2> \
3591 KOKKOS_INLINE_FUNCTION \
3593 operator OP (const typename Expr<ExprT2>::value_type& a, \
3594 const Expr<ExprT2>& expr2) \
3597 return a OP expr2.val(); \
3600 template <typename ExprT1> \
3601 KOKKOS_INLINE_FUNCTION \
3603 operator OP (const Expr<ExprT1>& expr1, \
3604 const typename Expr<ExprT1>::value_type& b) \
3607 return expr1.val() OP b; \
3623 #undef FAD_RELOP_MACRO
3627 namespace ELRCacheFad {
3629 template <
typename ExprT>
3634 return ! expr.val();
3644 namespace ELRCacheFad {
3646 template <
typename ExprT>
3650 bool is_zero = (x.val() == 0.0);
3651 for (
int i=0; i<x.size(); i++)
3652 is_zero = is_zero && (x.dx(i) == 0.0);
3660 #define FAD_BOOL_MACRO(OP) \
3661 namespace Sacado { \
3662 namespace ELRCacheFad { \
3663 template <typename ExprT1, typename ExprT2> \
3664 KOKKOS_INLINE_FUNCTION \
3666 operator OP (const Expr<ExprT1>& expr1, \
3667 const Expr<ExprT2>& expr2) \
3669 return toBool(expr1) OP toBool(expr2); \
3672 template <typename ExprT2> \
3673 KOKKOS_INLINE_FUNCTION \
3675 operator OP (const typename Expr<ExprT2>::value_type& a, \
3676 const Expr<ExprT2>& expr2) \
3678 return a OP toBool(expr2); \
3681 template <typename ExprT1> \
3682 KOKKOS_INLINE_FUNCTION \
3684 operator OP (const Expr<ExprT1>& expr1, \
3685 const typename Expr<ExprT1>::value_type& b) \
3687 return toBool(expr1) OP b; \
3695 #undef FAD_BOOL_MACRO
3701 namespace ELRCacheFad {
3703 template <
typename ExprT>
3704 std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
3705 os << x.val() <<
" [";
3707 for (
int i=0; i< x.size(); i++) {
3708 os <<
" " << x.dx(i);
3719 #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
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
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_)
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 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 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
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 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 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
KOKKOS_INLINE_FUNCTION bool isLinear() const
#define KOKKOS_INLINE_FUNCTION
KOKKOS_INLINE_FUNCTION void cache() const
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
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
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
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 SubtractionOp
#define FAD_BINARYOP_MACRO(OPNAME, OP)
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