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 SACADO_INLINE_FUNCTION \ 500 explicit Expr(const ExprT& expr_) : expr(expr_) {} \ 502 SACADO_INLINE_FUNCTION \ 503 int size() const { return expr.size(); } \ 506 SACADO_INLINE_FUNCTION \ 507 bool isActive() const { return expr.template isActive<Arg>(); } \ 509 SACADO_INLINE_FUNCTION \ 510 bool updateValue() const { return expr.updateValue(); } \ 512 SACADO_INLINE_FUNCTION \ 513 void cache() const { \ 519 SACADO_INLINE_FUNCTION \ 520 value_type val() const { \ 524 SACADO_INLINE_FUNCTION \ 525 void computePartials(const value_type& bar, \ 526 value_type partials[]) const { \ 527 expr.computePartials(bar*a, partials); \ 530 SACADO_INLINE_FUNCTION \ 531 void getTangents(int i, value_type dots[]) const { \ 532 expr.getTangents(i, dots); } \ 535 SACADO_INLINE_FUNCTION \ 536 value_type getTangent(int i) const { \ 537 return expr.template getTangent<Arg>(i); \ 540 SACADO_INLINE_FUNCTION \ 541 bool isLinear() const { \ 545 SACADO_INLINE_FUNCTION \ 546 bool hasFastAccess() const { \ 547 return expr.hasFastAccess(); \ 550 SACADO_INLINE_FUNCTION \ 551 const value_type dx(int i) const { \ 552 return expr.dx(i)*a; \ 555 SACADO_INLINE_FUNCTION \ 556 const value_type fastAccessDx(int i) const { \ 557 return expr.fastAccessDx(i)*a; \ 560 SACADO_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 SACADO_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)))),
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),
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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 (expr2.size() == 0 && v2 == scalar_type(1.0)) {
2449 a = scalar_type(1.0);
2450 b = scalar_type(0.0);
2452 else if (v1 == scalar_type(0.0)) {
2453 a = scalar_type(0.0);
2454 b = scalar_type(0.0);
2463 value_type
val()
const {
2468 void computePartials(
const value_type&
bar,
2469 value_type partials[])
const {
2471 expr1.computePartials(
bar*
a, partials);
2473 expr2.computePartials(
bar*b, partials+num_args1);
2477 void getTangents(
int i, value_type dots[])
const {
2478 expr1.getTangents(
i, dots);
2479 expr2.getTangents(
i, dots+num_args1);
2484 value_type getTangent(
int i)
const {
2485 if (Arg < num_args1)
2486 return expr1.template getTangent<Arg>(
i);
2488 return expr2.template getTangent<Arg-num_args1>(
i);
2492 bool isLinear()
const {
2497 bool hasFastAccess()
const {
2498 return expr1.hasFastAccess() && expr2.hasFastAccess();
2502 const value_type
dx(
int i)
const {
2503 if (expr1.size() > 0 && expr2.size() > 0)
2504 return expr1.dx(
i)*
a + expr2.dx(
i)*b;
2505 else if (expr1.size() > 0)
2506 return expr1.dx(
i)*
a;
2508 return expr1.val()*b;
2513 return expr1.fastAccessDx(
i)*
a + expr2.fastAccessDx(
i)*b;
2517 const value_type* getDx(
int j)
const {
2519 return expr1.getDx(j);
2521 return expr2.getDx(j-num_args1);
2526 const ExprT1& expr1;
2527 const ExprT2& expr2;
2528 mutable value_type v;
2529 mutable value_type
a;
2530 mutable value_type b;
2534 template <
typename ExprT1,
typename T2>
2535 class Expr<
PowerOp<ExprT1, ConstExpr<
T2> > > {
2539 typedef ConstExpr<T2> ExprT2;
2540 typedef typename ExprT1::value_type value_type_1;
2541 typedef typename ExprT2::value_type value_type_2;
2543 value_type_2>::type value_type;
2544 typedef typename ExprT1::scalar_type scalar_type_1;
2545 typedef typename ExprT2::scalar_type scalar_type_2;
2547 scalar_type_2>::type scalar_type;
2549 typedef typename ExprT1::base_expr_type base_expr_type_1;
2550 typedef typename ExprT2::base_expr_type base_expr_type_2;
2552 base_expr_type_2>::type base_expr_type;
2554 static const int num_args = ExprT1::num_args;
2556 static const bool is_linear =
false;
2559 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2560 expr1(expr1_), expr2(expr2_) {}
2564 return expr1.size();
2569 bool isActive()
const {
2570 return expr1.template isActive<Arg>();
2574 bool updateValue()
const {
2575 return expr1.updateValue();
2579 void cache()
const {
2581 const value_type_1 v1 = expr1.val();
2582 const value_type_2 v2 = expr2.val();
2584 if (v2 == scalar_type(1.0)) {
2585 a = scalar_type(1.0);
2587 else if (v1 == scalar_type(0.0)) {
2588 a = scalar_type(0.0);
2596 value_type
val()
const {
2601 void computePartials(
const value_type&
bar,
2602 value_type partials[])
const {
2603 expr1.computePartials(
bar*
a, partials);
2607 void getTangents(
int i, value_type dots[])
const {
2608 expr1.getTangents(
i, dots);
2613 value_type getTangent(
int i)
const {
2614 return expr1.template getTangent<Arg>(
i);
2618 bool isLinear()
const {
2623 bool hasFastAccess()
const {
2624 return expr1.hasFastAccess();
2628 const value_type
dx(
int i)
const {
2629 return expr1.dx(
i)*
a;
2634 return expr1.fastAccessDx(
i)*
a;
2638 const value_type* getDx(
int j)
const {
2639 return expr1.getDx(j);
2644 const ExprT1& expr1;
2646 mutable value_type v;
2647 mutable value_type
a;
2651 template <
typename T1,
typename ExprT2>
2652 class Expr<
PowerOp< ConstExpr<
T1>,ExprT2> > {
2656 typedef ConstExpr<T1> ExprT1;
2657 typedef typename ExprT1::value_type value_type_1;
2658 typedef typename ExprT2::value_type value_type_2;
2660 value_type_2>::type value_type;
2661 typedef typename ExprT1::scalar_type scalar_type_1;
2662 typedef typename ExprT2::scalar_type scalar_type_2;
2664 scalar_type_2>::type scalar_type;
2666 typedef typename ExprT1::base_expr_type base_expr_type_1;
2667 typedef typename ExprT2::base_expr_type base_expr_type_2;
2669 base_expr_type_2>::type base_expr_type;
2671 static const int num_args = ExprT2::num_args;
2673 static const bool is_linear =
false;
2676 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2677 expr1(expr1_), expr2(expr2_) {}
2681 return expr2.size();
2686 bool isActive()
const {
2687 return expr2.template isActive<Arg>();
2691 bool updateValue()
const {
2692 return expr2.updateValue();
2696 void cache()
const {
2698 const value_type_1 v1 = expr1.val();
2699 const value_type_2 v2 = expr2.val();
2701 if (v1 == scalar_type(0.0)) {
2702 b = scalar_type(0.0);
2710 value_type
val()
const {
2715 void computePartials(
const value_type&
bar,
2716 value_type partials[])
const {
2717 expr2.computePartials(
bar*b, partials);
2721 void getTangents(
int i, value_type dots[])
const {
2722 expr2.getTangents(
i, dots);
2727 value_type getTangent(
int i)
const {
2728 return expr2.template getTangent<Arg>(
i);
2732 bool isLinear()
const {
2737 bool hasFastAccess()
const {
2738 return expr2.hasFastAccess();
2742 const value_type
dx(
int i)
const {
2743 return expr2.dx(
i)*b;
2748 return expr2.fastAccessDx(
i)*b;
2752 const value_type* getDx(
int j)
const {
2753 return expr2.getDx(j);
2759 const ExprT2& expr2;
2760 mutable value_type v;
2761 mutable value_type b;
2769 template <
typename ExprT1,
typename ExprT2>
2772 template <
typename ExprT1,
typename ExprT2>
2773 class Expr<
MaxOp<ExprT1,ExprT2> > {
2777 typedef typename ExprT1::value_type value_type_1;
2778 typedef typename ExprT2::value_type value_type_2;
2780 value_type_2>::type value_type;
2781 typedef typename ExprT1::scalar_type scalar_type_1;
2782 typedef typename ExprT2::scalar_type scalar_type_2;
2784 scalar_type_2>::type scalar_type;
2786 typedef typename ExprT1::base_expr_type base_expr_type_1;
2787 typedef typename ExprT2::base_expr_type base_expr_type_2;
2789 base_expr_type_2>::type base_expr_type;
2791 static const int num_args1 = ExprT1::num_args;
2792 static const int num_args2 = ExprT2::num_args;
2793 static const int num_args = num_args1 + num_args2;
2795 static const bool is_linear =
false;
2798 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2799 expr1(expr1_), expr2(expr2_) {}
2803 int sz1 = expr1.size(), sz2 = expr2.size();
2804 return sz1 > sz2 ? sz1 : sz2;
2809 bool isActive()
const {
2810 if (Arg < num_args1)
2811 return expr1.template isActive<Arg>();
2813 return expr2.template isActive<Arg-num_args1>();
2817 bool updateValue()
const {
2818 return expr1.updateValue() && expr2.updateValue();
2822 void cache()
const {
2825 const value_type_1 v1 = expr1.val();
2826 const value_type_2 v2 = expr2.val();
2827 max_v1 = (v1 >= v2);
2828 v = max_v1 ? v1 : v2;
2832 value_type
val()
const {
2837 void computePartials(
const value_type&
bar,
2838 value_type partials[])
const {
2839 if (num_args1 > 0) {
2841 expr1.computePartials(
bar, partials);
2843 expr1.computePartials(value_type(0.0), partials);
2845 if (num_args2 > 0) {
2847 expr2.computePartials(value_type(0.0), partials+num_args1);
2849 expr2.computePartials(
bar, partials+num_args1);
2854 void getTangents(
int i, value_type dots[])
const {
2855 expr1.getTangents(
i, dots);
2856 expr2.getTangents(
i, dots+num_args1);
2861 value_type getTangent(
int i)
const {
2862 if (Arg < num_args1)
2863 return expr1.template getTangent<Arg>(
i);
2865 return expr2.template getTangent<Arg-num_args1>(
i);
2869 bool isLinear()
const {
2874 bool hasFastAccess()
const {
2875 return expr1.hasFastAccess() && expr2.hasFastAccess();
2879 const value_type
dx(
int i)
const {
2880 return max_v1 ? expr1.dx(
i) : expr2.dx(
i);
2885 return max_v1 ? expr1.fastAccessDx(
i) : expr2.fastAccessDx(
i);
2889 const value_type* getDx(
int j)
const {
2891 return expr1.getDx(j);
2893 return expr2.getDx(j-num_args1);
2898 const ExprT1& expr1;
2899 const ExprT2& expr2;
2900 mutable value_type v;
2901 mutable bool max_v1;
2905 template <
typename ExprT1,
typename T2>
2906 class Expr<
MaxOp<ExprT1, ConstExpr<
T2> > > {
2910 typedef ConstExpr<T2> ExprT2;
2911 typedef typename ExprT1::value_type value_type_1;
2912 typedef typename ExprT2::value_type value_type_2;
2914 value_type_2>::type value_type;
2915 typedef typename ExprT1::scalar_type scalar_type_1;
2916 typedef typename ExprT2::scalar_type scalar_type_2;
2918 scalar_type_2>::type scalar_type;
2920 typedef typename ExprT1::base_expr_type base_expr_type_1;
2921 typedef typename ExprT2::base_expr_type base_expr_type_2;
2923 base_expr_type_2>::type base_expr_type;
2925 static const int num_args = ExprT1::num_args;
2927 static const bool is_linear =
false;
2930 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2931 expr1(expr1_), expr2(expr2_) {}
2935 return expr1.size();
2940 bool isActive()
const {
2941 return expr1.template isActive<Arg>();
2945 bool updateValue()
const {
2946 return expr1.updateValue();
2950 void cache()
const {
2952 const value_type_1 v1 = expr1.val();
2953 const value_type_2 v2 = expr2.val();
2954 max_v1 = (v1 >= v2);
2955 v = max_v1 ? v1 : v2;
2959 value_type
val()
const {
2964 void computePartials(
const value_type&
bar,
2965 value_type partials[])
const {
2967 expr1.computePartials(
bar, partials);
2969 expr1.computePartials(value_type(0.0), partials);
2973 void getTangents(
int i, value_type dots[])
const {
2974 expr1.getTangents(
i, dots);
2979 value_type getTangent(
int i)
const {
2980 return expr1.template getTangent<Arg>(
i);
2984 bool isLinear()
const {
2989 bool hasFastAccess()
const {
2990 return expr1.hasFastAccess();
2994 const value_type
dx(
int i)
const {
2995 return max_v1 ? expr1.dx(
i) : value_type(0.0);
3000 return max_v1 ? expr1.fastAccessDx(
i) : value_type(0.0);
3004 const value_type* getDx(
int j)
const {
3005 return expr1.getDx(j);
3010 const ExprT1& expr1;
3012 mutable value_type v;
3013 mutable bool max_v1;
3017 template <
typename T1,
typename ExprT2>
3018 class Expr<
MaxOp< ConstExpr<
T1>,ExprT2> > {
3022 typedef ConstExpr<T1> ExprT1;
3023 typedef typename ExprT1::value_type value_type_1;
3024 typedef typename ExprT2::value_type value_type_2;
3026 value_type_2>::type value_type;
3027 typedef typename ExprT1::scalar_type scalar_type_1;
3028 typedef typename ExprT2::scalar_type scalar_type_2;
3030 scalar_type_2>::type scalar_type;
3032 typedef typename ExprT1::base_expr_type base_expr_type_1;
3033 typedef typename ExprT2::base_expr_type base_expr_type_2;
3035 base_expr_type_2>::type base_expr_type;
3037 static const int num_args = ExprT2::num_args;
3039 static const bool is_linear =
false;
3042 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3043 expr1(expr1_), expr2(expr2_) {}
3047 return expr2.size();
3052 bool isActive()
const {
3053 return expr2.template isActive<Arg>();
3057 bool updateValue()
const {
3058 return expr2.updateValue();
3062 void cache()
const {
3064 const value_type_1 v1 = expr1.val();
3065 const value_type_2 v2 = expr2.val();
3066 max_v1 = (v1 >= v2);
3067 v = max_v1 ? v1 : v2;
3071 value_type
val()
const {
3076 void computePartials(
const value_type&
bar,
3077 value_type partials[])
const {
3079 expr2.computePartials(value_type(0.0), partials);
3081 expr2.computePartials(
bar, partials);
3085 void getTangents(
int i, value_type dots[])
const {
3086 expr2.getTangents(
i, dots);
3091 value_type getTangent(
int i)
const {
3092 return expr2.template getTangent<Arg>(
i);
3096 bool isLinear()
const {
3101 bool hasFastAccess()
const {
3102 return expr2.hasFastAccess();
3106 const value_type
dx(
int i)
const {
3107 return max_v1 ? value_type(0.0) : expr2.dx(
i);
3112 return max_v1 ? value_type(0.0) : expr2.fastAccessDx(
i);
3116 const value_type* getDx(
int j)
const {
3117 return expr2.getDx(j);
3123 const ExprT2& expr2;
3124 mutable value_type v;
3125 mutable bool max_v1;
3133 template <
typename ExprT1,
typename ExprT2>
3136 template <
typename ExprT1,
typename ExprT2>
3137 class Expr<
MinOp<ExprT1,ExprT2> > {
3141 typedef typename ExprT1::value_type value_type_1;
3142 typedef typename ExprT2::value_type value_type_2;
3144 value_type_2>::type value_type;
3145 typedef typename ExprT1::scalar_type scalar_type_1;
3146 typedef typename ExprT2::scalar_type scalar_type_2;
3148 scalar_type_2>::type scalar_type;
3150 typedef typename ExprT1::base_expr_type base_expr_type_1;
3151 typedef typename ExprT2::base_expr_type base_expr_type_2;
3153 base_expr_type_2>::type base_expr_type;
3155 static const int num_args1 = ExprT1::num_args;
3156 static const int num_args2 = ExprT2::num_args;
3157 static const int num_args = num_args1 + num_args2;
3159 static const bool is_linear =
false;
3162 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3163 expr1(expr1_), expr2(expr2_) {}
3167 int sz1 = expr1.size(), sz2 = expr2.size();
3168 return sz1 > sz2 ? sz1 : sz2;
3173 bool isActive()
const {
3174 if (Arg < num_args1)
3175 return expr1.template isActive<Arg>();
3177 return expr2.template isActive<Arg-num_args1>();
3181 bool updateValue()
const {
3182 return expr1.updateValue() && expr2.updateValue();
3186 void cache()
const {
3189 const value_type_1 v1 = expr1.val();
3190 const value_type_2 v2 = expr2.val();
3191 min_v1 = (v1 <= v2);
3192 v = min_v1 ? v1 : v2;
3196 value_type
val()
const {
3201 void computePartials(
const value_type&
bar,
3202 value_type partials[])
const {
3203 if (num_args1 > 0) {
3205 expr1.computePartials(
bar, partials);
3207 expr1.computePartials(value_type(0.0), partials);
3209 if (num_args2 > 0) {
3211 expr2.computePartials(value_type(0.0), partials+num_args1);
3213 expr2.computePartials(
bar, partials+num_args1);
3218 void getTangents(
int i, value_type dots[])
const {
3219 expr1.getTangents(
i, dots);
3220 expr2.getTangents(
i, dots+num_args1);
3225 value_type getTangent(
int i)
const {
3226 if (Arg < num_args1)
3227 return expr1.template getTangent<Arg>(
i);
3229 return expr2.template getTangent<Arg-num_args1>(
i);
3233 bool isLinear()
const {
3238 bool hasFastAccess()
const {
3239 return expr1.hasFastAccess() && expr2.hasFastAccess();
3243 const value_type
dx(
int i)
const {
3244 return min_v1 ? expr1.dx(
i) : expr2.dx(
i);
3249 return min_v1 ? expr1.fastAccessDx(
i) : expr2.fastAccessDx(
i);
3253 const value_type* getDx(
int j)
const {
3255 return expr1.getDx(j);
3257 return expr2.getDx(j-num_args1);
3262 const ExprT1& expr1;
3263 const ExprT2& expr2;
3264 mutable value_type v;
3265 mutable bool min_v1;
3269 template <
typename ExprT1,
typename T2>
3270 class Expr<
MinOp<ExprT1, ConstExpr<
T2> > > {
3274 typedef ConstExpr<T2> ExprT2;
3275 typedef typename ExprT1::value_type value_type_1;
3276 typedef typename ExprT2::value_type value_type_2;
3278 value_type_2>::type value_type;
3279 typedef typename ExprT1::scalar_type scalar_type_1;
3280 typedef typename ExprT2::scalar_type scalar_type_2;
3282 scalar_type_2>::type scalar_type;
3284 typedef typename ExprT1::base_expr_type base_expr_type_1;
3285 typedef typename ExprT2::base_expr_type base_expr_type_2;
3287 base_expr_type_2>::type base_expr_type;
3289 static const int num_args = ExprT1::num_args;
3291 static const bool is_linear =
false;
3294 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3295 expr1(expr1_), expr2(expr2_) {}
3299 return expr1.size();
3304 bool isActive()
const {
3305 return expr1.template isActive<Arg>();
3309 bool updateValue()
const {
3310 return expr1.updateValue();
3314 void cache()
const {
3316 const value_type_1 v1 = expr1.val();
3317 const value_type_2 v2 = expr2.val();
3318 min_v1 = (v1 <= v2);
3319 v = min_v1 ? v1 : v2;
3323 value_type
val()
const {
3328 void computePartials(
const value_type&
bar,
3329 value_type partials[])
const {
3331 expr1.computePartials(
bar, partials);
3333 expr1.computePartials(value_type(0.0), partials);
3337 void getTangents(
int i, value_type dots[])
const {
3338 expr1.getTangents(
i, dots);
3343 value_type getTangent(
int i)
const {
3344 return expr1.template getTangent<Arg>(
i);
3348 bool isLinear()
const {
3353 bool hasFastAccess()
const {
3354 return expr1.hasFastAccess();
3358 const value_type
dx(
int i)
const {
3359 return min_v1 ? expr1.dx(
i) : value_type(0.0);
3364 return min_v1 ? expr1.fastAccessDx(
i) : value_type(0.0);
3368 const value_type* getDx(
int j)
const {
3369 return expr1.getDx(j);
3374 const ExprT1& expr1;
3376 mutable value_type v;
3377 mutable bool min_v1;
3381 template <
typename T1,
typename ExprT2>
3382 class Expr<
MinOp< ConstExpr<
T1>,ExprT2> > {
3386 typedef ConstExpr<T1> ExprT1;
3387 typedef typename ExprT1::value_type value_type_1;
3388 typedef typename ExprT2::value_type value_type_2;
3390 value_type_2>::type value_type;
3391 typedef typename ExprT1::scalar_type scalar_type_1;
3392 typedef typename ExprT2::scalar_type scalar_type_2;
3394 scalar_type_2>::type scalar_type;
3396 typedef typename ExprT1::base_expr_type base_expr_type_1;
3397 typedef typename ExprT2::base_expr_type base_expr_type_2;
3399 base_expr_type_2>::type base_expr_type;
3401 static const int num_args = ExprT2::num_args;
3403 static const bool is_linear =
false;
3406 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3407 expr1(expr1_), expr2(expr2_) {}
3411 return expr2.size();
3416 bool isActive()
const {
3417 return expr2.template isActive<Arg>();
3421 bool updateValue()
const {
3422 return expr2.updateValue();
3426 void cache()
const {
3428 const value_type_1 v1 = expr1.val();
3429 const value_type_2 v2 = expr2.val();
3430 min_v1 = (v1 <= v2);
3431 v = min_v1 ? v1 : v2;
3435 value_type
val()
const {
3440 void computePartials(
const value_type&
bar,
3441 value_type partials[])
const {
3443 expr2.computePartials(value_type(0.0), partials);
3445 expr2.computePartials(
bar, partials);
3449 void getTangents(
int i, value_type dots[])
const {
3450 expr2.getTangents(
i, dots);
3455 value_type getTangent(
int i)
const {
3456 return expr2.template getTangent<Arg>(
i);
3460 bool isLinear()
const {
3465 bool hasFastAccess()
const {
3466 return expr2.hasFastAccess();
3470 const value_type
dx(
int i)
const {
3471 return min_v1 ? value_type(0.0) : expr2.dx(
i);
3476 return min_v1 ? value_type(0.0) : expr2.fastAccessDx(
i);
3480 const value_type* getDx(
int j)
const {
3481 return expr2.getDx(j);
3487 const ExprT2& expr2;
3488 mutable value_type v;
3489 mutable bool min_v1;
3497 #define FAD_BINARYOP_MACRO(OPNAME,OP) \ 3498 namespace Sacado { \ 3499 namespace ELRCacheFad { \ 3501 template <typename T1, typename T2> \ 3502 SACADO_INLINE_FUNCTION \ 3503 SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \ 3504 OPNAME (const T1& expr1, const T2& expr2) \ 3506 typedef OP< T1, T2 > expr_t; \ 3508 return Expr<expr_t>(expr1, expr2); \ 3511 template <typename T> \ 3512 SACADO_INLINE_FUNCTION \ 3513 Expr< OP< Expr<T>, Expr<T> > > \ 3514 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \ 3516 typedef OP< Expr<T>, Expr<T> > expr_t; \ 3518 return Expr<expr_t>(expr1, expr2); \ 3521 template <typename T> \ 3522 SACADO_INLINE_FUNCTION \ 3523 Expr< OP< ConstExpr<typename Expr<T>::value_type>, \ 3525 OPNAME (const typename Expr<T>::value_type& c, \ 3526 const Expr<T>& expr) \ 3528 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \ 3529 typedef OP< ConstT, Expr<T> > expr_t; \ 3531 return Expr<expr_t>(ConstT(c), expr); \ 3534 template <typename T> \ 3535 SACADO_INLINE_FUNCTION \ 3536 Expr< OP< Expr<T>, \ 3537 ConstExpr<typename Expr<T>::value_type> > > \ 3538 OPNAME (const Expr<T>& expr, \ 3539 const typename Expr<T>::value_type& c) \ 3541 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \ 3542 typedef OP< Expr<T>, ConstT > expr_t; \ 3544 return Expr<expr_t>(expr, ConstT(c)); \ 3547 template <typename T> \ 3548 SACADO_INLINE_FUNCTION \ 3549 SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \ 3550 OPNAME (const typename Expr<T>::scalar_type& c, \ 3551 const Expr<T>& expr) \ 3553 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \ 3554 typedef OP< ConstT, Expr<T> > expr_t; \ 3556 return Expr<expr_t>(ConstT(c), expr); \ 3559 template <typename T> \ 3560 SACADO_INLINE_FUNCTION \ 3561 SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \ 3562 OPNAME (const Expr<T>& expr, \ 3563 const typename Expr<T>::scalar_type& c) \ 3565 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \ 3566 typedef OP< Expr<T>, ConstT > expr_t; \ 3568 return Expr<expr_t>(expr, ConstT(c)); \ 3583 #undef FAD_BINARYOP_MACRO 3587 #define FAD_RELOP_MACRO(OP) \ 3588 namespace Sacado { \ 3589 namespace ELRCacheFad { \ 3590 template <typename ExprT1, typename ExprT2> \ 3591 SACADO_INLINE_FUNCTION \ 3593 operator OP (const Expr<ExprT1>& expr1, \ 3594 const Expr<ExprT2>& expr2) \ 3598 return expr1.val() OP expr2.val(); \ 3601 template <typename ExprT2> \ 3602 SACADO_INLINE_FUNCTION \ 3604 operator OP (const typename Expr<ExprT2>::value_type& a, \ 3605 const Expr<ExprT2>& expr2) \ 3608 return a OP expr2.val(); \ 3611 template <typename ExprT1> \ 3612 SACADO_INLINE_FUNCTION \ 3614 operator OP (const Expr<ExprT1>& expr1, \ 3615 const typename Expr<ExprT1>::value_type& b) \ 3618 return expr1.val() OP b; \ 3634 #undef FAD_RELOP_MACRO 3638 namespace ELRCacheFad {
3640 template <
typename ExprT>
3645 return ! expr.val();
3655 namespace ELRCacheFad {
3657 template <
typename ExprT>
3661 bool is_zero = (
x.val() == 0.0);
3662 for (
int i=0;
i<
x.size();
i++)
3663 is_zero = is_zero && (
x.dx(
i) == 0.0);
3671 #define FAD_BOOL_MACRO(OP) \ 3672 namespace Sacado { \ 3673 namespace ELRCacheFad { \ 3674 template <typename ExprT1, typename ExprT2> \ 3675 SACADO_INLINE_FUNCTION \ 3677 operator OP (const Expr<ExprT1>& expr1, \ 3678 const Expr<ExprT2>& expr2) \ 3680 return toBool(expr1) OP toBool(expr2); \ 3683 template <typename ExprT2> \ 3684 SACADO_INLINE_FUNCTION \ 3686 operator OP (const typename Expr<ExprT2>::value_type& a, \ 3687 const Expr<ExprT2>& expr2) \ 3689 return a OP toBool(expr2); \ 3692 template <typename ExprT1> \ 3693 SACADO_INLINE_FUNCTION \ 3695 operator OP (const Expr<ExprT1>& expr1, \ 3696 const typename Expr<ExprT1>::value_type& b) \ 3698 return toBool(expr1) OP b; \ 3706 #undef FAD_BOOL_MACRO 3712 namespace ELRCacheFad {
3714 template <
typename ExprT>
3715 std::ostream& operator << (std::ostream& os, const Expr<ExprT>&
x) {
3716 os <<
x.val() <<
" [";
3718 for (
int i=0;
i<
x.size();
i++) {
3719 os <<
" " <<
x.dx(
i);
3730 #endif // SACADO_CACHEFAD_OPS_HPP SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
ExprT::value_type value_type
SACADO_INLINE_FUNCTION bool isActive() const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
ExprT::base_expr_type base_expr_type
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
value_type getTangent(int i) const
#define FAD_UNARYOP_MACRO(OPNAME, OP, PARTIAL, VALUE)
SACADO_INLINE_FUNCTION bool isLinear() const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION value_type val() const
ExprT::value_type value_type
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
SACADO_INLINE_FUNCTION int size() const
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
ExprT::value_type value_type
SACADO_INLINE_FUNCTION const value_type dx(int i) const
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
SACADO_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
SACADO_INLINE_FUNCTION int size() const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) 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
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
ExprT::base_expr_type base_expr_type
ExprT::value_type value_type
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION void cache() const
ExprT::scalar_type scalar_type
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
SACADO_INLINE_FUNCTION Expr< UnaryPlusOp< Expr< T > > > operator+(const Expr< T > &expr)
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION int size() const
#define FAD_RELOP_MACRO(OP)
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
ExprT::scalar_type scalar_type
Wrapper for a generic expression template.
ExprT::base_expr_type base_expr_type
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
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
ExprT::scalar_type scalar_type
SACADO_INLINE_FUNCTION bool isLinear() const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
#define FAD_BOOL_MACRO(OP)
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
atan2(expr1.val(), expr2.val())
SACADO_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
SACADO_INLINE_FUNCTION bool isLinear() const
ExprT::scalar_type scalar_type
SACADO_INLINE_FUNCTION T safe_sqrt(const T &x)
SACADO_INLINE_FUNCTION bool isActive() const
ExprT::base_expr_type base_expr_type
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION Expr< UnaryMinusOp< Expr< T > > > operator-(const Expr< T > &expr)
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_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)
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION void cache() const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION bool isLinear() const
#define SACADO_INLINE_FUNCTION
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
SACADO_INLINE_FUNCTION bool isActive() const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
#define FAD_BINARYOP_MACRO(OPNAME, OP)
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION int size() const
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION bool isActive() const
SACADO_INLINE_FUNCTION void cache() const
SACADO_INLINE_FUNCTION void cache() const
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