52 #ifndef SACADO_ELRCACHEFAD_OPS_HPP
53 #define SACADO_ELRCACHEFAD_OPS_HPP
61 namespace ELRCacheFad {
67 template <
typename ExprT>
70 template <
typename ExprT>
79 static const int num_args = ExprT::num_args;
81 static const bool is_linear =
true;
84 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
87 int size()
const {
return expr.size(); }
91 bool isActive()
const {
return expr.template isActive<Arg>(); }
109 expr.computePartials(bar, partials);
114 expr.getTangents(i, dots); }
118 return expr.template getTangent<Arg>(
i);
123 return expr.isLinear();
128 return expr.hasFastAccess();
138 return expr.fastAccessDx(i);
143 return expr.getDx(j);
151 template <
typename T>
164 template <
typename ExprT>
167 template <
typename ExprT>
176 static const int num_args = ExprT::num_args;
178 static const bool is_linear =
true;
181 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
184 int size()
const {
return expr.size(); }
188 bool isActive()
const {
return expr.template isActive<Arg>(); }
206 expr.computePartials(-bar, partials);
211 expr.getTangents(i, dots); }
216 return expr.template getTangent<Arg>(
i);
221 return expr.isLinear();
226 return expr.hasFastAccess();
236 return -expr.fastAccessDx(i);
241 return expr.getDx(j);
249 template <
typename T>
263 template <
typename ExprT>
266 template <
typename ExprT>
275 static const int num_args = ExprT::num_args;
277 static const bool is_linear =
false;
280 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
283 int size()
const {
return expr.size(); }
287 bool isActive()
const {
return expr.template isActive<Arg>(); }
308 expr.computePartials(bar, partials);
310 expr.computePartials(-bar, partials);
315 expr.getTangents(i, dots); }
320 return expr.template getTangent<Arg>(
i);
330 return expr.hasFastAccess();
335 if (v_pos)
return expr.dx(i);
336 else return -expr.dx(i);
341 if (v_pos)
return expr.fastAccessDx(i);
342 else return -expr.fastAccessDx(i);
347 return expr.getDx(j);
357 template <
typename T>
371 template <
typename ExprT>
374 template <
typename ExprT>
383 static const int num_args = ExprT::num_args;
385 static const bool is_linear =
false;
388 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
391 int size()
const {
return expr.size(); }
395 bool isActive()
const {
return expr.template isActive<Arg>(); }
416 expr.computePartials(bar, partials);
418 expr.computePartials(-bar, partials);
423 expr.getTangents(i, dots); }
428 return expr.template getTangent<Arg>(
i);
438 return expr.hasFastAccess();
443 if (v_pos)
return expr.dx(i);
444 else return -expr.dx(i);
449 if (v_pos)
return expr.fastAccessDx(i);
450 else return -expr.fastAccessDx(i);
455 return expr.getDx(j);
465 template <
typename T>
478 #define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE) \
480 namespace ELRCacheFad { \
482 template <typename ExprT> \
485 template <typename ExprT> \
486 class Expr< OP<ExprT> > { \
489 typedef typename ExprT::value_type value_type; \
490 typedef typename ExprT::scalar_type scalar_type; \
492 typedef typename ExprT::base_expr_type base_expr_type; \
494 static const int num_args = ExprT::num_args; \
496 static const bool is_linear = false; \
498 SACADO_INLINE_FUNCTION \
499 explicit Expr(const ExprT& expr_) : expr(expr_) {} \
501 SACADO_INLINE_FUNCTION \
502 int size() const { return expr.size(); } \
505 SACADO_INLINE_FUNCTION \
506 bool isActive() const { return expr.template isActive<Arg>(); } \
508 SACADO_INLINE_FUNCTION \
509 bool updateValue() const { return expr.updateValue(); } \
511 SACADO_INLINE_FUNCTION \
512 void cache() const { \
518 SACADO_INLINE_FUNCTION \
519 value_type val() const { \
523 SACADO_INLINE_FUNCTION \
524 void computePartials(const value_type& bar, \
525 value_type partials[]) const { \
526 expr.computePartials(bar*a, partials); \
529 SACADO_INLINE_FUNCTION \
530 void getTangents(int i, value_type dots[]) const { \
531 expr.getTangents(i, dots); } \
534 SACADO_INLINE_FUNCTION \
535 value_type getTangent(int i) const { \
536 return expr.template getTangent<Arg>(i); \
539 SACADO_INLINE_FUNCTION \
540 bool isLinear() const { \
544 SACADO_INLINE_FUNCTION \
545 bool hasFastAccess() const { \
546 return expr.hasFastAccess(); \
549 SACADO_INLINE_FUNCTION \
550 const value_type dx(int i) const { \
551 return expr.dx(i)*a; \
554 SACADO_INLINE_FUNCTION \
555 const value_type fastAccessDx(int i) const { \
556 return expr.fastAccessDx(i)*a; \
559 SACADO_INLINE_FUNCTION \
560 const value_type* getDx(int j) const { \
561 return expr.getDx(j); \
567 mutable value_type v; \
568 mutable value_type a; \
571 template <typename T> \
572 SACADO_INLINE_FUNCTION \
573 Expr< OP< Expr<T> > > \
574 OPNAME (const Expr<T>& expr) \
576 typedef OP< Expr<T> > expr_t; \
578 return Expr<expr_t>(expr); \
589 a=scalar_type(1.0)/v,
593 a = scalar_type(1.0)/(std::log(scalar_type(10.0))*v),
597 a = scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)),
601 a = (v == value_type(0.0) ? value_type(0.0) : value_type(scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)))),
613 a = scalar_type(1.0)+std::tan(v)*std::tan(v),
617 a = scalar_type(-1.0)/std::sqrt(scalar_type(1.0)-v*v),
621 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)-v*v),
625 a = scalar_type(1.0)/(scalar_type(1.0)+v*v),
637 a = scalar_type(1.0)-std::tanh(v)*std::tanh(v),
641 a = scalar_type(1.0)/std::sqrt((v-scalar_type(1.0))*(v+scalar_type(1.0))),
645 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)+v*v),
649 a = scalar_type(1.0)/(scalar_type(1.0)-v*v),
653 a = scalar_type(1.0)/(scalar_type(3.0)*std::cbrt(v*v)),
656 #undef FAD_UNARYOP_MACRO
662 namespace ELRCacheFad {
668 template <
typename ExprT1,
typename ExprT2>
671 template <
typename ExprT1,
typename ExprT2>
672 class Expr< AdditionOp<ExprT1,ExprT2> > {
676 typedef typename ExprT1::value_type value_type_1;
677 typedef typename ExprT2::value_type value_type_2;
679 value_type_2>::type value_type;
680 typedef typename ExprT1::scalar_type scalar_type_1;
681 typedef typename ExprT2::scalar_type scalar_type_2;
683 scalar_type_2>::type scalar_type;
685 typedef typename ExprT1::base_expr_type base_expr_type_1;
686 typedef typename ExprT2::base_expr_type base_expr_type_2;
688 base_expr_type_2>::type base_expr_type;
690 static const int num_args1 = ExprT1::num_args;
691 static const int num_args2 = ExprT2::num_args;
692 static const int num_args = num_args1 + num_args2;
694 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
697 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
698 expr1(expr1_), expr2(expr2_) {}
702 int sz1 = expr1.size(), sz2 = expr2.size();
703 return sz1 > sz2 ? sz1 : sz2;
708 bool isActive()
const {
710 return expr1.template isActive<Arg>();
712 return expr2.template isActive<Arg-num_args1>();
716 bool updateValue()
const {
717 return expr1.updateValue() && expr2.updateValue();
727 value_type
val()
const {
728 return expr1.val()+expr2.val();
732 void computePartials(
const value_type&
bar,
733 value_type partials[])
const {
735 expr1.computePartials(bar, partials);
737 expr2.computePartials(bar, partials+num_args1);
741 void getTangents(
int i, value_type dots[])
const {
742 expr1.getTangents(i, dots);
743 expr2.getTangents(i, dots+num_args1);
748 value_type getTangent(
int i)
const {
750 return expr1.template getTangent<Arg>(
i);
752 return expr2.template getTangent<Arg-num_args1>(
i);
756 bool isLinear()
const {
757 return expr1.isLinear() && expr2.isLinear();
761 bool hasFastAccess()
const {
762 return expr1.hasFastAccess() && expr2.hasFastAccess();
766 const value_type
dx(
int i)
const {
767 return expr1.dx(i) + expr2.dx(i);
772 return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
776 const value_type* getDx(
int j)
const {
778 return expr1.getDx(j);
780 return expr2.getDx(j-num_args1);
790 template <
typename ExprT1,
typename T2>
791 class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
795 typedef ConstExpr<T2> ExprT2;
796 typedef typename ExprT1::value_type value_type_1;
797 typedef typename ExprT2::value_type value_type_2;
799 value_type_2>::type value_type;
800 typedef typename ExprT1::scalar_type scalar_type_1;
801 typedef typename ExprT2::scalar_type scalar_type_2;
803 scalar_type_2>::type scalar_type;
805 typedef typename ExprT1::base_expr_type base_expr_type_1;
806 typedef typename ExprT2::base_expr_type base_expr_type_2;
808 base_expr_type_2>::type base_expr_type;
810 static const int num_args = ExprT1::num_args;
812 static const bool is_linear = ExprT1::is_linear;
815 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
816 expr1(expr1_), expr2(expr2_) {}
825 bool isActive()
const {
826 return expr1.template isActive<Arg>();
830 bool updateValue()
const {
831 return expr1.updateValue();
840 value_type
val()
const {
841 return expr1.val() + expr2.val();
845 void computePartials(
const value_type&
bar,
846 value_type partials[])
const {
847 expr1.computePartials(bar, partials);
851 void getTangents(
int i, value_type dots[])
const {
852 expr1.getTangents(i, dots);
857 value_type getTangent(
int i)
const {
858 return expr1.template getTangent<Arg>(
i);
862 bool isLinear()
const {
863 return expr1.isLinear();
867 bool hasFastAccess()
const {
868 return expr1.hasFastAccess();
872 const value_type
dx(
int i)
const {
878 return expr1.fastAccessDx(i);
882 const value_type* getDx(
int j)
const {
883 return expr1.getDx(j);
893 template <
typename T1,
typename ExprT2>
894 class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
898 typedef ConstExpr<T1> ExprT1;
899 typedef typename ExprT1::value_type value_type_1;
900 typedef typename ExprT2::value_type value_type_2;
902 value_type_2>::type value_type;
903 typedef typename ExprT1::scalar_type scalar_type_1;
904 typedef typename ExprT2::scalar_type scalar_type_2;
906 scalar_type_2>::type scalar_type;
908 typedef typename ExprT1::base_expr_type base_expr_type_1;
909 typedef typename ExprT2::base_expr_type base_expr_type_2;
911 base_expr_type_2>::type base_expr_type;
913 static const int num_args = ExprT2::num_args;
915 static const bool is_linear = ExprT2::is_linear;
918 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
919 expr1(expr1_), expr2(expr2_) {}
928 bool isActive()
const {
929 return expr2.template isActive<Arg>();
933 bool updateValue()
const {
934 return expr2.updateValue();
943 value_type
val()
const {
944 return expr1.val() + expr2.val();
948 void computePartials(
const value_type&
bar,
949 value_type partials[])
const {
950 expr2.computePartials(bar, partials);
954 void getTangents(
int i, value_type dots[])
const {
955 expr2.getTangents(i, dots);
960 value_type getTangent(
int i)
const {
961 return expr2.template getTangent<Arg>(
i);
965 bool isLinear()
const {
966 return expr2.isLinear();
970 bool hasFastAccess()
const {
971 return expr2.hasFastAccess();
975 const value_type
dx(
int i)
const {
981 return expr2.fastAccessDx(i);
985 const value_type* getDx(
int j)
const {
986 return expr2.getDx(j);
1000 template <
typename ExprT1,
typename ExprT2>
1003 template <
typename ExprT1,
typename ExprT2>
1004 class Expr< SubtractionOp<ExprT1,ExprT2> > {
1008 typedef typename ExprT1::value_type value_type_1;
1009 typedef typename ExprT2::value_type value_type_2;
1011 value_type_2>::type value_type;
1012 typedef typename ExprT1::scalar_type scalar_type_1;
1013 typedef typename ExprT2::scalar_type scalar_type_2;
1015 scalar_type_2>::type scalar_type;
1017 typedef typename ExprT1::base_expr_type base_expr_type_1;
1018 typedef typename ExprT2::base_expr_type base_expr_type_2;
1020 base_expr_type_2>::type base_expr_type;
1022 static const int num_args1 = ExprT1::num_args;
1023 static const int num_args2 = ExprT2::num_args;
1024 static const int num_args = num_args1 + num_args2;
1026 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
1029 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1030 expr1(expr1_), expr2(expr2_) {}
1034 int sz1 = expr1.size(), sz2 = expr2.size();
1035 return sz1 > sz2 ? sz1 : sz2;
1040 bool isActive()
const {
1041 if (Arg < num_args1)
1042 return expr1.template isActive<Arg>();
1044 return expr2.template isActive<Arg-num_args1>();
1048 bool updateValue()
const {
1049 return expr1.updateValue() && expr2.updateValue();
1053 void cache()
const {
1059 value_type
val()
const {
1060 return expr1.val()-expr2.val();
1064 void computePartials(
const value_type&
bar,
1065 value_type partials[])
const {
1067 expr1.computePartials(bar, partials);
1069 expr2.computePartials(-bar, partials+num_args1);
1073 void getTangents(
int i, value_type dots[])
const {
1074 expr1.getTangents(i, dots);
1075 expr2.getTangents(i, dots+num_args1);
1080 value_type getTangent(
int i)
const {
1081 if (Arg < num_args1)
1082 return expr1.template getTangent<Arg>(
i);
1084 return expr2.template getTangent<Arg-num_args1>(
i);
1088 bool isLinear()
const {
1089 return expr1.isLinear() && expr2.isLinear();
1093 bool hasFastAccess()
const {
1094 return expr1.hasFastAccess() && expr2.hasFastAccess();
1098 const value_type
dx(
int i)
const {
1099 return expr1.dx(i) - expr2.dx(i);
1104 return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
1108 const value_type* getDx(
int j)
const {
1110 return expr1.getDx(j);
1112 return expr2.getDx(j-num_args1);
1117 const ExprT1& expr1;
1118 const ExprT2& expr2;
1122 template <
typename ExprT1,
typename T2>
1123 class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
1127 typedef ConstExpr<T2> ExprT2;
1128 typedef typename ExprT1::value_type value_type_1;
1129 typedef typename ExprT2::value_type value_type_2;
1131 value_type_2>::type value_type;
1132 typedef typename ExprT1::scalar_type scalar_type_1;
1133 typedef typename ExprT2::scalar_type scalar_type_2;
1135 scalar_type_2>::type scalar_type;
1137 typedef typename ExprT1::base_expr_type base_expr_type_1;
1138 typedef typename ExprT2::base_expr_type base_expr_type_2;
1140 base_expr_type_2>::type base_expr_type;
1142 static const int num_args = ExprT1::num_args;
1144 static const bool is_linear = ExprT1::is_linear;
1147 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1148 expr1(expr1_), expr2(expr2_) {}
1152 return expr1.size();
1157 bool isActive()
const {
1158 return expr1.template isActive<Arg>();
1162 bool updateValue()
const {
1163 return expr1.updateValue();
1167 void cache()
const {
1172 value_type
val()
const {
1173 return expr1.val() - expr2.val();
1177 void computePartials(
const value_type&
bar,
1178 value_type partials[])
const {
1179 expr1.computePartials(bar, partials);
1183 void getTangents(
int i, value_type dots[])
const {
1184 expr1.getTangents(i, dots);
1189 value_type getTangent(
int i)
const {
1190 return expr1.template getTangent<Arg>(
i);
1194 bool isLinear()
const {
1195 return expr1.isLinear();
1199 bool hasFastAccess()
const {
1200 return expr1.hasFastAccess();
1204 const value_type
dx(
int i)
const {
1210 return expr1.fastAccessDx(i);
1214 const value_type* getDx(
int j)
const {
1215 return expr1.getDx(j);
1220 const ExprT1& expr1;
1225 template <
typename T1,
typename ExprT2>
1226 class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
1230 typedef ConstExpr<T1> ExprT1;
1231 typedef typename ExprT1::value_type value_type_1;
1232 typedef typename ExprT2::value_type value_type_2;
1234 value_type_2>::type value_type;
1235 typedef typename ExprT1::scalar_type scalar_type_1;
1236 typedef typename ExprT2::scalar_type scalar_type_2;
1238 scalar_type_2>::type scalar_type;
1240 typedef typename ExprT1::base_expr_type base_expr_type_1;
1241 typedef typename ExprT2::base_expr_type base_expr_type_2;
1243 base_expr_type_2>::type base_expr_type;
1245 static const int num_args = ExprT2::num_args;
1247 static const bool is_linear = ExprT2::is_linear;
1250 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1251 expr1(expr1_), expr2(expr2_) {}
1255 return expr2.size();
1260 bool isActive()
const {
1261 return expr2.template isActive<Arg>();
1265 bool updateValue()
const {
1266 return expr2.updateValue();
1270 void cache()
const {
1275 value_type
val()
const {
1276 return expr1.val() - expr2.val();
1280 void computePartials(
const value_type&
bar,
1281 value_type partials[])
const {
1282 expr2.computePartials(-bar, partials);
1286 void getTangents(
int i, value_type dots[])
const {
1287 expr2.getTangents(i, dots);
1292 value_type getTangent(
int i)
const {
1293 return expr2.template getTangent<Arg>(
i);
1297 bool isLinear()
const {
1298 return expr2.isLinear();
1302 bool hasFastAccess()
const {
1303 return expr2.hasFastAccess();
1307 const value_type
dx(
int i)
const {
1308 return -expr2.dx(i);
1313 return -expr2.fastAccessDx(i);
1317 const value_type* getDx(
int j)
const {
1318 return expr2.getDx(j);
1324 const ExprT2& expr2;
1332 template <
typename ExprT1,
typename ExprT2>
1335 template <
typename ExprT1,
typename ExprT2>
1336 class Expr< MultiplicationOp<ExprT1,ExprT2> > {
1340 typedef typename ExprT1::value_type value_type_1;
1341 typedef typename ExprT2::value_type value_type_2;
1343 value_type_2>::type value_type;
1344 typedef typename ExprT1::scalar_type scalar_type_1;
1345 typedef typename ExprT2::scalar_type scalar_type_2;
1347 scalar_type_2>::type scalar_type;
1349 typedef typename ExprT1::base_expr_type base_expr_type_1;
1350 typedef typename ExprT2::base_expr_type base_expr_type_2;
1352 base_expr_type_2>::type base_expr_type;
1354 static const int num_args1 = ExprT1::num_args;
1355 static const int num_args2 = ExprT2::num_args;
1356 static const int num_args = num_args1 + num_args2;
1358 static const bool is_linear =
false;
1361 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1362 expr1(expr1_), expr2(expr2_) {}
1366 int sz1 = expr1.size(), sz2 = expr2.size();
1367 return sz1 > sz2 ? sz1 : sz2;
1372 bool isActive()
const {
1373 if (Arg < num_args1)
1374 return expr1.template isActive<Arg>();
1376 return expr2.template isActive<Arg-num_args1>();
1380 bool updateValue()
const {
1381 return expr1.updateValue() && expr2.updateValue();
1385 void cache()
const {
1393 value_type
val()
const {
1398 void computePartials(
const value_type&
bar,
1399 value_type partials[])
const {
1401 expr1.computePartials(bar*v2, partials);
1403 expr2.computePartials(bar*v1, partials+num_args1);
1407 void getTangents(
int i, value_type dots[])
const {
1408 expr1.getTangents(i, dots);
1409 expr2.getTangents(i, dots+num_args1);
1414 value_type getTangent(
int i)
const {
1415 if (Arg < num_args1)
1416 return expr1.template getTangent<Arg>(
i);
1418 return expr2.template getTangent<Arg-num_args1>(
i);
1422 bool isLinear()
const {
1427 bool hasFastAccess()
const {
1428 return expr1.hasFastAccess() && expr2.hasFastAccess();
1432 const value_type
dx(
int i)
const {
1433 if (expr1.size() > 0 && expr2.size() > 0)
1434 return v1*expr2.dx(i) + expr1.dx(i)*v2;
1435 else if (expr1.size() > 0)
1436 return expr1.dx(i)*v2;
1438 return v1*expr2.dx(i);
1443 return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1447 const value_type* getDx(
int j)
const {
1449 return expr1.getDx(j);
1451 return expr2.getDx(j-num_args1);
1456 const ExprT1& expr1;
1457 const ExprT2& expr2;
1458 mutable value_type_1 v1;
1459 mutable value_type_2 v2;
1463 template <
typename ExprT1,
typename T2>
1464 class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1468 typedef ConstExpr<T2> ExprT2;
1469 typedef typename ExprT1::value_type value_type_1;
1470 typedef typename ExprT2::value_type value_type_2;
1472 value_type_2>::type value_type;
1473 typedef typename ExprT1::scalar_type scalar_type_1;
1474 typedef typename ExprT2::scalar_type scalar_type_2;
1476 scalar_type_2>::type scalar_type;
1478 typedef typename ExprT1::base_expr_type base_expr_type_1;
1479 typedef typename ExprT2::base_expr_type base_expr_type_2;
1481 base_expr_type_2>::type base_expr_type;
1483 static const int num_args = ExprT1::num_args;
1485 static const bool is_linear = ExprT1::is_linear;
1488 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1489 expr1(expr1_), expr2(expr2_) {}
1493 return expr1.size();
1498 bool isActive()
const {
1499 return expr1.template isActive<Arg>();
1503 bool updateValue()
const {
1504 return expr1.updateValue();
1508 void cache()
const {
1513 value_type
val()
const {
1514 return expr1.val()*expr2.val();
1518 void computePartials(
const value_type&
bar,
1519 value_type partials[])
const {
1520 expr1.computePartials(bar*expr2.val(), partials);
1524 void getTangents(
int i, value_type dots[])
const {
1525 expr1.getTangents(i, dots);
1530 value_type getTangent(
int i)
const {
1531 return expr1.template getTangent<Arg>(
i);
1535 bool isLinear()
const {
1536 return expr1.isLinear();
1540 bool hasFastAccess()
const {
1541 return expr1.hasFastAccess();
1545 const value_type
dx(
int i)
const {
1546 return expr1.dx(i)*expr2.val();
1551 return expr1.fastAccessDx(i)*expr2.val();
1555 const value_type* getDx(
int j)
const {
1556 return expr1.getDx(j);
1561 const ExprT1& expr1;
1566 template <
typename T1,
typename ExprT2>
1567 class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1571 typedef ConstExpr<T1> ExprT1;
1572 typedef typename ExprT1::value_type value_type_1;
1573 typedef typename ExprT2::value_type value_type_2;
1575 value_type_2>::type value_type;
1576 typedef typename ExprT1::scalar_type scalar_type_1;
1577 typedef typename ExprT2::scalar_type scalar_type_2;
1579 scalar_type_2>::type scalar_type;
1581 typedef typename ExprT1::base_expr_type base_expr_type_1;
1582 typedef typename ExprT2::base_expr_type base_expr_type_2;
1584 base_expr_type_2>::type base_expr_type;
1586 static const int num_args = ExprT2::num_args;
1588 static const bool is_linear = ExprT2::is_linear;
1591 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1592 expr1(expr1_), expr2(expr2_) {}
1596 return expr2.size();
1601 bool isActive()
const {
1602 return expr2.template isActive<Arg>();
1606 bool updateValue()
const {
1607 return expr2.updateValue();
1611 void cache()
const {
1616 value_type
val()
const {
1617 return expr1.val()*expr2.val();
1621 void computePartials(
const value_type&
bar,
1622 value_type partials[])
const {
1623 expr2.computePartials(bar*expr1.val(), partials);
1627 void getTangents(
int i, value_type dots[])
const {
1628 expr2.getTangents(i, dots);
1633 value_type getTangent(
int i)
const {
1634 return expr2.template getTangent<Arg>(
i);
1638 bool isLinear()
const {
1639 return expr2.isLinear();
1643 bool hasFastAccess()
const {
1644 return expr2.hasFastAccess();
1648 const value_type
dx(
int i)
const {
1649 return expr1.val()*expr2.dx(i);
1654 return expr1.val()*expr2.fastAccessDx(i);
1658 const value_type* getDx(
int j)
const {
1659 return expr2.getDx(j);
1665 const ExprT2& expr2;
1673 template <
typename ExprT1,
typename ExprT2>
1676 template <
typename ExprT1,
typename ExprT2>
1677 class Expr< DivisionOp<ExprT1,ExprT2> > {
1681 typedef typename ExprT1::value_type value_type_1;
1682 typedef typename ExprT2::value_type value_type_2;
1684 value_type_2>::type value_type;
1685 typedef typename ExprT1::scalar_type scalar_type_1;
1686 typedef typename ExprT2::scalar_type scalar_type_2;
1688 scalar_type_2>::type scalar_type;
1690 typedef typename ExprT1::base_expr_type base_expr_type_1;
1691 typedef typename ExprT2::base_expr_type base_expr_type_2;
1693 base_expr_type_2>::type base_expr_type;
1695 static const int num_args1 = ExprT1::num_args;
1696 static const int num_args2 = ExprT2::num_args;
1697 static const int num_args = num_args1 + num_args2;
1699 static const bool is_linear =
false;
1702 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1703 expr1(expr1_), expr2(expr2_) {}
1707 int sz1 = expr1.size(), sz2 = expr2.size();
1708 return sz1 > sz2 ? sz1 : sz2;
1713 bool isActive()
const {
1714 if (Arg < num_args1)
1715 return expr1.template isActive<Arg>();
1717 return expr2.template isActive<Arg-num_args1>();
1721 bool updateValue()
const {
1722 return expr1.updateValue() && expr2.updateValue();
1726 void cache()
const {
1729 const value_type_1 v1 = expr1.val();
1730 const value_type_2 v2 = expr2.val();
1731 a = scalar_type(1.0)/v2;
1737 value_type
val()
const {
1742 void computePartials(
const value_type&
bar,
1743 value_type partials[])
const {
1745 expr1.computePartials(bar*
a, partials);
1747 expr2.computePartials(bar*b, partials+num_args1);
1751 void getTangents(
int i, value_type dots[])
const {
1752 expr1.getTangents(i, dots);
1753 expr2.getTangents(i, dots+num_args1);
1758 value_type getTangent(
int i)
const {
1759 if (Arg < num_args1)
1760 return expr1.template getTangent<Arg>(
i);
1762 return expr2.template getTangent<Arg-num_args1>(
i);
1766 bool isLinear()
const {
1771 bool hasFastAccess()
const {
1772 return expr1.hasFastAccess() && expr2.hasFastAccess();
1776 const value_type
dx(
int i)
const {
1777 if (expr1.size() > 0 && expr2.size() > 0)
1778 return expr1.dx(i)*
a + expr2.dx(i)*b;
1779 else if (expr1.size() > 0)
1780 return expr1.dx(i)*
a;
1782 return expr1.val()*b;
1787 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
1791 const value_type* getDx(
int j)
const {
1793 return expr1.getDx(j);
1795 return expr2.getDx(j-num_args1);
1800 const ExprT1& expr1;
1801 const ExprT2& expr2;
1802 mutable value_type v;
1803 mutable value_type
a;
1804 mutable value_type b;
1808 template <
typename ExprT1,
typename T2>
1809 class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1813 typedef ConstExpr<T2> ExprT2;
1814 typedef typename ExprT1::value_type value_type_1;
1815 typedef typename ExprT2::value_type value_type_2;
1817 value_type_2>::type value_type;
1818 typedef typename ExprT1::scalar_type scalar_type_1;
1819 typedef typename ExprT2::scalar_type scalar_type_2;
1821 scalar_type_2>::type scalar_type;
1823 typedef typename ExprT1::base_expr_type base_expr_type_1;
1824 typedef typename ExprT2::base_expr_type base_expr_type_2;
1826 base_expr_type_2>::type base_expr_type;
1828 static const int num_args = ExprT1::num_args;
1830 static const bool is_linear = ExprT1::is_linear;
1833 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1834 expr1(expr1_), expr2(expr2_) {}
1838 return expr1.size();
1843 bool isActive()
const {
1844 return expr1.template isActive<Arg>();
1848 bool updateValue()
const {
1849 return expr1.updateValue();
1853 void cache()
const {
1855 const value_type_1 v1 = expr1.val();
1856 a = scalar_type(1.0)/expr2.val();
1861 value_type
val()
const {
1866 void computePartials(
const value_type&
bar,
1867 value_type partials[])
const {
1868 expr1.computePartials(bar*
a, partials);
1872 void getTangents(
int i, value_type dots[])
const {
1873 expr1.getTangents(i, dots);
1878 value_type getTangent(
int i)
const {
1879 return expr1.template getTangent<Arg>(
i);
1883 bool isLinear()
const {
1884 return expr1.isLinear();
1888 bool hasFastAccess()
const {
1889 return expr1.hasFastAccess();
1893 const value_type
dx(
int i)
const {
1894 return expr1.dx(i)*
a;
1899 return expr1.fastAccessDx(i)*
a;
1903 const value_type* getDx(
int j)
const {
1904 return expr1.getDx(j);
1909 const ExprT1& expr1;
1911 mutable value_type v;
1912 mutable value_type
a;
1916 template <
typename T1,
typename ExprT2>
1917 class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1921 typedef ConstExpr<T1> ExprT1;
1922 typedef typename ExprT1::value_type value_type_1;
1923 typedef typename ExprT2::value_type value_type_2;
1925 value_type_2>::type value_type;
1926 typedef typename ExprT1::scalar_type scalar_type_1;
1927 typedef typename ExprT2::scalar_type scalar_type_2;
1929 scalar_type_2>::type scalar_type;
1931 typedef typename ExprT1::base_expr_type base_expr_type_1;
1932 typedef typename ExprT2::base_expr_type base_expr_type_2;
1934 base_expr_type_2>::type base_expr_type;
1936 static const int num_args = ExprT2::num_args;
1938 static const bool is_linear =
false;
1941 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1942 expr1(expr1_), expr2(expr2_) {}
1946 return expr2.size();
1951 bool isActive()
const {
1952 return expr2.template isActive<Arg>();
1956 bool updateValue()
const {
1957 return expr2.updateValue();
1961 void cache()
const {
1963 const value_type_2 v2 = expr2.val();
1969 value_type
val()
const {
1974 void computePartials(
const value_type&
bar,
1975 value_type partials[])
const {
1976 expr2.computePartials(bar*b, partials);
1980 void getTangents(
int i, value_type dots[])
const {
1981 expr2.getTangents(i, dots);
1986 value_type getTangent(
int i)
const {
1987 return expr2.template getTangent<Arg>(
i);
1991 bool isLinear()
const {
1996 bool hasFastAccess()
const {
1997 return expr2.hasFastAccess();
2001 const value_type
dx(
int i)
const {
2002 return expr2.dx(i)*b;
2007 return expr2.fastAccessDx(i)*b;
2011 const value_type* getDx(
int j)
const {
2012 return expr2.getDx(j);
2018 const ExprT2& expr2;
2019 mutable value_type v;
2020 mutable value_type b;
2028 template <
typename ExprT1,
typename ExprT2>
2031 template <
typename ExprT1,
typename ExprT2>
2032 class Expr< Atan2Op<ExprT1,ExprT2> > {
2036 typedef typename ExprT1::value_type value_type_1;
2037 typedef typename ExprT2::value_type value_type_2;
2039 value_type_2>::type value_type;
2040 typedef typename ExprT1::scalar_type scalar_type_1;
2041 typedef typename ExprT2::scalar_type scalar_type_2;
2043 scalar_type_2>::type scalar_type;
2045 typedef typename ExprT1::base_expr_type base_expr_type_1;
2046 typedef typename ExprT2::base_expr_type base_expr_type_2;
2048 base_expr_type_2>::type base_expr_type;
2050 static const int num_args1 = ExprT1::num_args;
2051 static const int num_args2 = ExprT2::num_args;
2052 static const int num_args = num_args1 + num_args2;
2054 static const bool is_linear =
false;
2057 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2058 expr1(expr1_), expr2(expr2_) {}
2062 int sz1 = expr1.size(), sz2 = expr2.size();
2063 return sz1 > sz2 ? sz1 : sz2;
2068 bool isActive()
const {
2069 if (Arg < num_args1)
2070 return expr1.template isActive<Arg>();
2072 return expr2.template isActive<Arg-num_args1>();
2076 bool updateValue()
const {
2077 return expr1.updateValue() && expr2.updateValue();
2081 void cache()
const {
2084 const value_type_1 v1 = expr1.val();
2085 const value_type_2 v2 = expr2.val();
2086 a = scalar_type(1.0)/(v1*v1 + v2*v2);
2093 value_type
val()
const {
2098 void computePartials(
const value_type&
bar,
2099 value_type partials[])
const {
2101 expr1.computePartials(bar*
a, partials);
2103 expr2.computePartials(bar*b, partials+num_args1);
2107 void getTangents(
int i, value_type dots[])
const {
2108 expr1.getTangents(i, dots);
2109 expr2.getTangents(i, dots+num_args1);
2114 value_type getTangent(
int i)
const {
2115 if (Arg < num_args1)
2116 return expr1.template getTangent<Arg>(
i);
2118 return expr2.template getTangent<Arg-num_args1>(
i);
2122 bool isLinear()
const {
2127 bool hasFastAccess()
const {
2128 return expr1.hasFastAccess() && expr2.hasFastAccess();
2132 const value_type
dx(
int i)
const {
2133 if (expr1.size() > 0 && expr2.size() > 0)
2134 return expr1.dx(i)*
a + expr2.dx(i)*b;
2135 else if (expr1.size() > 0)
2136 return expr1.dx(i)*
a;
2138 return expr1.val()*b;
2143 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
2147 const value_type* getDx(
int j)
const {
2149 return expr1.getDx(j);
2151 return expr2.getDx(j-num_args1);
2156 const ExprT1& expr1;
2157 const ExprT2& expr2;
2158 mutable value_type v;
2159 mutable value_type
a;
2160 mutable value_type b;
2164 template <
typename ExprT1,
typename T2>
2165 class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
2169 typedef ConstExpr<T2> ExprT2;
2170 typedef typename ExprT1::value_type value_type_1;
2171 typedef typename ExprT2::value_type value_type_2;
2173 value_type_2>::type value_type;
2174 typedef typename ExprT1::scalar_type scalar_type_1;
2175 typedef typename ExprT2::scalar_type scalar_type_2;
2177 scalar_type_2>::type scalar_type;
2179 typedef typename ExprT1::base_expr_type base_expr_type_1;
2180 typedef typename ExprT2::base_expr_type base_expr_type_2;
2182 base_expr_type_2>::type base_expr_type;
2184 static const int num_args = ExprT1::num_args;
2186 static const bool is_linear =
false;
2189 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2190 expr1(expr1_), expr2(expr2_) {}
2194 return expr1.size();
2199 bool isActive()
const {
2200 return expr1.template isActive<Arg>();
2204 bool updateValue()
const {
2205 return expr1.updateValue();
2209 void cache()
const {
2211 const value_type_1 v1 = expr1.val();
2212 const value_type_2 v2 = expr2.val();
2213 a = v2/(v1*v1 + v2*v2);
2218 value_type
val()
const {
2223 void computePartials(
const value_type&
bar,
2224 value_type partials[])
const {
2225 expr1.computePartials(bar*
a, partials);
2229 void getTangents(
int i, value_type dots[])
const {
2230 expr1.getTangents(i, dots);
2235 value_type getTangent(
int i)
const {
2236 return expr1.template getTangent<Arg>(
i);
2240 bool isLinear()
const {
2245 bool hasFastAccess()
const {
2246 return expr1.hasFastAccess();
2250 const value_type
dx(
int i)
const {
2251 return expr1.dx(i)*
a;
2256 return expr1.fastAccessDx(i)*
a;
2260 const value_type* getDx(
int j)
const {
2261 return expr1.getDx(j);
2266 const ExprT1& expr1;
2268 mutable value_type v;
2269 mutable value_type
a;
2273 template <
typename T1,
typename ExprT2>
2274 class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
2278 typedef ConstExpr<T1> ExprT1;
2279 typedef typename ExprT1::value_type value_type_1;
2280 typedef typename ExprT2::value_type value_type_2;
2282 value_type_2>::type value_type;
2283 typedef typename ExprT1::scalar_type scalar_type_1;
2284 typedef typename ExprT2::scalar_type scalar_type_2;
2286 scalar_type_2>::type scalar_type;
2288 typedef typename ExprT1::base_expr_type base_expr_type_1;
2289 typedef typename ExprT2::base_expr_type base_expr_type_2;
2291 base_expr_type_2>::type base_expr_type;
2293 static const int num_args = ExprT2::num_args;
2295 static const bool is_linear =
false;
2298 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2299 expr1(expr1_), expr2(expr2_) {}
2303 return expr2.size();
2308 bool isActive()
const {
2309 return expr2.template isActive<Arg>();
2313 bool updateValue()
const {
2314 return expr2.updateValue();
2318 void cache()
const {
2320 const value_type_1 v1 = expr1.val();
2321 const value_type_2 v2 = expr2.val();
2322 b = -v1/(v1*v1 + v2*v2);
2327 value_type
val()
const {
2332 void computePartials(
const value_type&
bar,
2333 value_type partials[])
const {
2334 expr2.computePartials(bar*b, partials);
2338 void getTangents(
int i, value_type dots[])
const {
2339 expr2.getTangents(i, dots);
2344 value_type getTangent(
int i)
const {
2345 return expr2.template getTangent<Arg>(
i);
2349 bool isLinear()
const {
2354 bool hasFastAccess()
const {
2355 return expr2.hasFastAccess();
2359 const value_type
dx(
int i)
const {
2360 return expr2.dx(i)*b;
2365 return expr2.fastAccessDx(i)*b;
2369 const value_type* getDx(
int j)
const {
2370 return expr2.getDx(j);
2376 const ExprT2& expr2;
2377 mutable value_type v;
2378 mutable value_type b;
2386 template <
typename ExprT1,
typename ExprT2>
2389 template <
typename ExprT1,
typename ExprT2>
2390 class Expr< PowerOp<ExprT1,ExprT2> > {
2394 typedef typename ExprT1::value_type value_type_1;
2395 typedef typename ExprT2::value_type value_type_2;
2397 value_type_2>::type value_type;
2398 typedef typename ExprT1::scalar_type scalar_type_1;
2399 typedef typename ExprT2::scalar_type scalar_type_2;
2401 scalar_type_2>::type scalar_type;
2403 typedef typename ExprT1::base_expr_type base_expr_type_1;
2404 typedef typename ExprT2::base_expr_type base_expr_type_2;
2406 base_expr_type_2>::type base_expr_type;
2408 static const int num_args1 = ExprT1::num_args;
2409 static const int num_args2 = ExprT2::num_args;
2410 static const int num_args = num_args1 + num_args2;
2412 static const bool is_linear =
false;
2415 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2416 expr1(expr1_), expr2(expr2_) {}
2420 int sz1 = expr1.size(), sz2 = expr2.size();
2421 return sz1 > sz2 ? sz1 : sz2;
2426 bool isActive()
const {
2427 if (Arg < num_args1)
2428 return expr1.template isActive<Arg>();
2430 return expr2.template isActive<Arg-num_args1>();
2434 bool updateValue()
const {
2435 return expr1.updateValue() && expr2.updateValue();
2439 void cache()
const {
2442 const value_type_1 v1 = expr1.val();
2443 const value_type_2 v2 = expr2.val();
2445 if (expr2.size() == 0 && v2 == scalar_type(1.0)) {
2446 a = scalar_type(1.0);
2447 b = scalar_type(0.0);
2449 else if (v1 == scalar_type(0.0)) {
2450 a = scalar_type(0.0);
2451 b = scalar_type(0.0);
2460 value_type
val()
const {
2465 void computePartials(
const value_type&
bar,
2466 value_type partials[])
const {
2468 expr1.computePartials(bar*
a, partials);
2470 expr2.computePartials(bar*b, partials+num_args1);
2474 void getTangents(
int i, value_type dots[])
const {
2475 expr1.getTangents(i, dots);
2476 expr2.getTangents(i, dots+num_args1);
2481 value_type getTangent(
int i)
const {
2482 if (Arg < num_args1)
2483 return expr1.template getTangent<Arg>(
i);
2485 return expr2.template getTangent<Arg-num_args1>(
i);
2489 bool isLinear()
const {
2494 bool hasFastAccess()
const {
2495 return expr1.hasFastAccess() && expr2.hasFastAccess();
2499 const value_type
dx(
int i)
const {
2500 if (expr1.size() > 0 && expr2.size() > 0)
2501 return expr1.dx(i)*
a + expr2.dx(i)*b;
2502 else if (expr1.size() > 0)
2503 return expr1.dx(i)*
a;
2505 return expr1.val()*b;
2510 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
2514 const value_type* getDx(
int j)
const {
2516 return expr1.getDx(j);
2518 return expr2.getDx(j-num_args1);
2523 const ExprT1& expr1;
2524 const ExprT2& expr2;
2525 mutable value_type v;
2526 mutable value_type
a;
2527 mutable value_type b;
2531 template <
typename ExprT1,
typename T2>
2532 class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
2536 typedef ConstExpr<T2> ExprT2;
2537 typedef typename ExprT1::value_type value_type_1;
2538 typedef typename ExprT2::value_type value_type_2;
2540 value_type_2>::type value_type;
2541 typedef typename ExprT1::scalar_type scalar_type_1;
2542 typedef typename ExprT2::scalar_type scalar_type_2;
2544 scalar_type_2>::type scalar_type;
2546 typedef typename ExprT1::base_expr_type base_expr_type_1;
2547 typedef typename ExprT2::base_expr_type base_expr_type_2;
2549 base_expr_type_2>::type base_expr_type;
2551 static const int num_args = ExprT1::num_args;
2553 static const bool is_linear =
false;
2556 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2557 expr1(expr1_), expr2(expr2_) {}
2561 return expr1.size();
2566 bool isActive()
const {
2567 return expr1.template isActive<Arg>();
2571 bool updateValue()
const {
2572 return expr1.updateValue();
2576 void cache()
const {
2578 const value_type_1 v1 = expr1.val();
2579 const value_type_2 v2 = expr2.val();
2581 if (v2 == scalar_type(1.0)) {
2582 a = scalar_type(1.0);
2584 else if (v1 == scalar_type(0.0)) {
2585 a = scalar_type(0.0);
2593 value_type
val()
const {
2598 void computePartials(
const value_type&
bar,
2599 value_type partials[])
const {
2600 expr1.computePartials(bar*
a, partials);
2604 void getTangents(
int i, value_type dots[])
const {
2605 expr1.getTangents(i, dots);
2610 value_type getTangent(
int i)
const {
2611 return expr1.template getTangent<Arg>(
i);
2615 bool isLinear()
const {
2620 bool hasFastAccess()
const {
2621 return expr1.hasFastAccess();
2625 const value_type
dx(
int i)
const {
2626 return expr1.dx(i)*
a;
2631 return expr1.fastAccessDx(i)*
a;
2635 const value_type* getDx(
int j)
const {
2636 return expr1.getDx(j);
2641 const ExprT1& expr1;
2643 mutable value_type v;
2644 mutable value_type
a;
2648 template <
typename T1,
typename ExprT2>
2649 class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
2653 typedef ConstExpr<T1> ExprT1;
2654 typedef typename ExprT1::value_type value_type_1;
2655 typedef typename ExprT2::value_type value_type_2;
2657 value_type_2>::type value_type;
2658 typedef typename ExprT1::scalar_type scalar_type_1;
2659 typedef typename ExprT2::scalar_type scalar_type_2;
2661 scalar_type_2>::type scalar_type;
2663 typedef typename ExprT1::base_expr_type base_expr_type_1;
2664 typedef typename ExprT2::base_expr_type base_expr_type_2;
2666 base_expr_type_2>::type base_expr_type;
2668 static const int num_args = ExprT2::num_args;
2670 static const bool is_linear =
false;
2673 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2674 expr1(expr1_), expr2(expr2_) {}
2678 return expr2.size();
2683 bool isActive()
const {
2684 return expr2.template isActive<Arg>();
2688 bool updateValue()
const {
2689 return expr2.updateValue();
2693 void cache()
const {
2695 const value_type_1 v1 = expr1.val();
2696 const value_type_2 v2 = expr2.val();
2698 if (v1 == scalar_type(0.0)) {
2699 b = scalar_type(0.0);
2707 value_type
val()
const {
2712 void computePartials(
const value_type&
bar,
2713 value_type partials[])
const {
2714 expr2.computePartials(bar*b, partials);
2718 void getTangents(
int i, value_type dots[])
const {
2719 expr2.getTangents(i, dots);
2724 value_type getTangent(
int i)
const {
2725 return expr2.template getTangent<Arg>(
i);
2729 bool isLinear()
const {
2734 bool hasFastAccess()
const {
2735 return expr2.hasFastAccess();
2739 const value_type
dx(
int i)
const {
2740 return expr2.dx(i)*b;
2745 return expr2.fastAccessDx(i)*b;
2749 const value_type* getDx(
int j)
const {
2750 return expr2.getDx(j);
2756 const ExprT2& expr2;
2757 mutable value_type v;
2758 mutable value_type b;
2766 template <
typename ExprT1,
typename ExprT2>
2769 template <
typename ExprT1,
typename ExprT2>
2770 class Expr< MaxOp<ExprT1,ExprT2> > {
2774 typedef typename ExprT1::value_type value_type_1;
2775 typedef typename ExprT2::value_type value_type_2;
2777 value_type_2>::type value_type;
2778 typedef typename ExprT1::scalar_type scalar_type_1;
2779 typedef typename ExprT2::scalar_type scalar_type_2;
2781 scalar_type_2>::type scalar_type;
2783 typedef typename ExprT1::base_expr_type base_expr_type_1;
2784 typedef typename ExprT2::base_expr_type base_expr_type_2;
2786 base_expr_type_2>::type base_expr_type;
2788 static const int num_args1 = ExprT1::num_args;
2789 static const int num_args2 = ExprT2::num_args;
2790 static const int num_args = num_args1 + num_args2;
2792 static const bool is_linear =
false;
2795 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2796 expr1(expr1_), expr2(expr2_) {}
2800 int sz1 = expr1.size(), sz2 = expr2.size();
2801 return sz1 > sz2 ? sz1 : sz2;
2806 bool isActive()
const {
2807 if (Arg < num_args1)
2808 return expr1.template isActive<Arg>();
2810 return expr2.template isActive<Arg-num_args1>();
2814 bool updateValue()
const {
2815 return expr1.updateValue() && expr2.updateValue();
2819 void cache()
const {
2822 const value_type_1 v1 = expr1.val();
2823 const value_type_2 v2 = expr2.val();
2824 max_v1 = (v1 >= v2);
2825 v = max_v1 ? v1 : v2;
2829 value_type
val()
const {
2834 void computePartials(
const value_type&
bar,
2835 value_type partials[])
const {
2836 if (num_args1 > 0) {
2838 expr1.computePartials(bar, partials);
2840 expr1.computePartials(value_type(0.0), partials);
2842 if (num_args2 > 0) {
2844 expr2.computePartials(value_type(0.0), partials+num_args1);
2846 expr2.computePartials(bar, partials+num_args1);
2851 void getTangents(
int i, value_type dots[])
const {
2852 expr1.getTangents(i, dots);
2853 expr2.getTangents(i, dots+num_args1);
2858 value_type getTangent(
int i)
const {
2859 if (Arg < num_args1)
2860 return expr1.template getTangent<Arg>(
i);
2862 return expr2.template getTangent<Arg-num_args1>(
i);
2866 bool isLinear()
const {
2871 bool hasFastAccess()
const {
2872 return expr1.hasFastAccess() && expr2.hasFastAccess();
2876 const value_type
dx(
int i)
const {
2877 return max_v1 ? expr1.dx(i) : expr2.dx(i);
2882 return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2886 const value_type* getDx(
int j)
const {
2888 return expr1.getDx(j);
2890 return expr2.getDx(j-num_args1);
2895 const ExprT1& expr1;
2896 const ExprT2& expr2;
2897 mutable value_type v;
2898 mutable bool max_v1;
2902 template <
typename ExprT1,
typename T2>
2903 class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2907 typedef ConstExpr<T2> ExprT2;
2908 typedef typename ExprT1::value_type value_type_1;
2909 typedef typename ExprT2::value_type value_type_2;
2911 value_type_2>::type value_type;
2912 typedef typename ExprT1::scalar_type scalar_type_1;
2913 typedef typename ExprT2::scalar_type scalar_type_2;
2915 scalar_type_2>::type scalar_type;
2917 typedef typename ExprT1::base_expr_type base_expr_type_1;
2918 typedef typename ExprT2::base_expr_type base_expr_type_2;
2920 base_expr_type_2>::type base_expr_type;
2922 static const int num_args = ExprT1::num_args;
2924 static const bool is_linear =
false;
2927 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2928 expr1(expr1_), expr2(expr2_) {}
2932 return expr1.size();
2937 bool isActive()
const {
2938 return expr1.template isActive<Arg>();
2942 bool updateValue()
const {
2943 return expr1.updateValue();
2947 void cache()
const {
2949 const value_type_1 v1 = expr1.val();
2950 const value_type_2 v2 = expr2.val();
2951 max_v1 = (v1 >= v2);
2952 v = max_v1 ? v1 : v2;
2956 value_type
val()
const {
2961 void computePartials(
const value_type&
bar,
2962 value_type partials[])
const {
2964 expr1.computePartials(bar, partials);
2966 expr1.computePartials(value_type(0.0), partials);
2970 void getTangents(
int i, value_type dots[])
const {
2971 expr1.getTangents(i, dots);
2976 value_type getTangent(
int i)
const {
2977 return expr1.template getTangent<Arg>(
i);
2981 bool isLinear()
const {
2986 bool hasFastAccess()
const {
2987 return expr1.hasFastAccess();
2991 const value_type
dx(
int i)
const {
2992 return max_v1 ? expr1.dx(i) : value_type(0.0);
2997 return max_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3001 const value_type* getDx(
int j)
const {
3002 return expr1.getDx(j);
3007 const ExprT1& expr1;
3009 mutable value_type v;
3010 mutable bool max_v1;
3014 template <
typename T1,
typename ExprT2>
3015 class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
3019 typedef ConstExpr<T1> ExprT1;
3020 typedef typename ExprT1::value_type value_type_1;
3021 typedef typename ExprT2::value_type value_type_2;
3023 value_type_2>::type value_type;
3024 typedef typename ExprT1::scalar_type scalar_type_1;
3025 typedef typename ExprT2::scalar_type scalar_type_2;
3027 scalar_type_2>::type scalar_type;
3029 typedef typename ExprT1::base_expr_type base_expr_type_1;
3030 typedef typename ExprT2::base_expr_type base_expr_type_2;
3032 base_expr_type_2>::type base_expr_type;
3034 static const int num_args = ExprT2::num_args;
3036 static const bool is_linear =
false;
3039 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3040 expr1(expr1_), expr2(expr2_) {}
3044 return expr2.size();
3049 bool isActive()
const {
3050 return expr2.template isActive<Arg>();
3054 bool updateValue()
const {
3055 return expr2.updateValue();
3059 void cache()
const {
3061 const value_type_1 v1 = expr1.val();
3062 const value_type_2 v2 = expr2.val();
3063 max_v1 = (v1 >= v2);
3064 v = max_v1 ? v1 : v2;
3068 value_type
val()
const {
3073 void computePartials(
const value_type&
bar,
3074 value_type partials[])
const {
3076 expr2.computePartials(value_type(0.0), partials);
3078 expr2.computePartials(bar, partials);
3082 void getTangents(
int i, value_type dots[])
const {
3083 expr2.getTangents(i, dots);
3088 value_type getTangent(
int i)
const {
3089 return expr2.template getTangent<Arg>(
i);
3093 bool isLinear()
const {
3098 bool hasFastAccess()
const {
3099 return expr2.hasFastAccess();
3103 const value_type
dx(
int i)
const {
3104 return max_v1 ? value_type(0.0) : expr2.dx(i);
3109 return max_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3113 const value_type* getDx(
int j)
const {
3114 return expr2.getDx(j);
3120 const ExprT2& expr2;
3121 mutable value_type v;
3122 mutable bool max_v1;
3130 template <
typename ExprT1,
typename ExprT2>
3133 template <
typename ExprT1,
typename ExprT2>
3134 class Expr< MinOp<ExprT1,ExprT2> > {
3138 typedef typename ExprT1::value_type value_type_1;
3139 typedef typename ExprT2::value_type value_type_2;
3141 value_type_2>::type value_type;
3142 typedef typename ExprT1::scalar_type scalar_type_1;
3143 typedef typename ExprT2::scalar_type scalar_type_2;
3145 scalar_type_2>::type scalar_type;
3147 typedef typename ExprT1::base_expr_type base_expr_type_1;
3148 typedef typename ExprT2::base_expr_type base_expr_type_2;
3150 base_expr_type_2>::type base_expr_type;
3152 static const int num_args1 = ExprT1::num_args;
3153 static const int num_args2 = ExprT2::num_args;
3154 static const int num_args = num_args1 + num_args2;
3156 static const bool is_linear =
false;
3159 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3160 expr1(expr1_), expr2(expr2_) {}
3164 int sz1 = expr1.size(), sz2 = expr2.size();
3165 return sz1 > sz2 ? sz1 : sz2;
3170 bool isActive()
const {
3171 if (Arg < num_args1)
3172 return expr1.template isActive<Arg>();
3174 return expr2.template isActive<Arg-num_args1>();
3178 bool updateValue()
const {
3179 return expr1.updateValue() && expr2.updateValue();
3183 void cache()
const {
3186 const value_type_1 v1 = expr1.val();
3187 const value_type_2 v2 = expr2.val();
3188 min_v1 = (v1 <= v2);
3189 v = min_v1 ? v1 : v2;
3193 value_type
val()
const {
3198 void computePartials(
const value_type&
bar,
3199 value_type partials[])
const {
3200 if (num_args1 > 0) {
3202 expr1.computePartials(bar, partials);
3204 expr1.computePartials(value_type(0.0), partials);
3206 if (num_args2 > 0) {
3208 expr2.computePartials(value_type(0.0), partials+num_args1);
3210 expr2.computePartials(bar, partials+num_args1);
3215 void getTangents(
int i, value_type dots[])
const {
3216 expr1.getTangents(i, dots);
3217 expr2.getTangents(i, dots+num_args1);
3222 value_type getTangent(
int i)
const {
3223 if (Arg < num_args1)
3224 return expr1.template getTangent<Arg>(
i);
3226 return expr2.template getTangent<Arg-num_args1>(
i);
3230 bool isLinear()
const {
3235 bool hasFastAccess()
const {
3236 return expr1.hasFastAccess() && expr2.hasFastAccess();
3240 const value_type
dx(
int i)
const {
3241 return min_v1 ? expr1.dx(i) : expr2.dx(i);
3246 return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
3250 const value_type* getDx(
int j)
const {
3252 return expr1.getDx(j);
3254 return expr2.getDx(j-num_args1);
3259 const ExprT1& expr1;
3260 const ExprT2& expr2;
3261 mutable value_type v;
3262 mutable bool min_v1;
3266 template <
typename ExprT1,
typename T2>
3267 class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
3271 typedef ConstExpr<T2> ExprT2;
3272 typedef typename ExprT1::value_type value_type_1;
3273 typedef typename ExprT2::value_type value_type_2;
3275 value_type_2>::type value_type;
3276 typedef typename ExprT1::scalar_type scalar_type_1;
3277 typedef typename ExprT2::scalar_type scalar_type_2;
3279 scalar_type_2>::type scalar_type;
3281 typedef typename ExprT1::base_expr_type base_expr_type_1;
3282 typedef typename ExprT2::base_expr_type base_expr_type_2;
3284 base_expr_type_2>::type base_expr_type;
3286 static const int num_args = ExprT1::num_args;
3288 static const bool is_linear =
false;
3291 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3292 expr1(expr1_), expr2(expr2_) {}
3296 return expr1.size();
3301 bool isActive()
const {
3302 return expr1.template isActive<Arg>();
3306 bool updateValue()
const {
3307 return expr1.updateValue();
3311 void cache()
const {
3313 const value_type_1 v1 = expr1.val();
3314 const value_type_2 v2 = expr2.val();
3315 min_v1 = (v1 <= v2);
3316 v = min_v1 ? v1 : v2;
3320 value_type
val()
const {
3325 void computePartials(
const value_type&
bar,
3326 value_type partials[])
const {
3328 expr1.computePartials(bar, partials);
3330 expr1.computePartials(value_type(0.0), partials);
3334 void getTangents(
int i, value_type dots[])
const {
3335 expr1.getTangents(i, dots);
3340 value_type getTangent(
int i)
const {
3341 return expr1.template getTangent<Arg>(
i);
3345 bool isLinear()
const {
3350 bool hasFastAccess()
const {
3351 return expr1.hasFastAccess();
3355 const value_type
dx(
int i)
const {
3356 return min_v1 ? expr1.dx(i) : value_type(0.0);
3361 return min_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3365 const value_type* getDx(
int j)
const {
3366 return expr1.getDx(j);
3371 const ExprT1& expr1;
3373 mutable value_type v;
3374 mutable bool min_v1;
3378 template <
typename T1,
typename ExprT2>
3379 class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
3383 typedef ConstExpr<T1> ExprT1;
3384 typedef typename ExprT1::value_type value_type_1;
3385 typedef typename ExprT2::value_type value_type_2;
3387 value_type_2>::type value_type;
3388 typedef typename ExprT1::scalar_type scalar_type_1;
3389 typedef typename ExprT2::scalar_type scalar_type_2;
3391 scalar_type_2>::type scalar_type;
3393 typedef typename ExprT1::base_expr_type base_expr_type_1;
3394 typedef typename ExprT2::base_expr_type base_expr_type_2;
3396 base_expr_type_2>::type base_expr_type;
3398 static const int num_args = ExprT2::num_args;
3400 static const bool is_linear =
false;
3403 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3404 expr1(expr1_), expr2(expr2_) {}
3408 return expr2.size();
3413 bool isActive()
const {
3414 return expr2.template isActive<Arg>();
3418 bool updateValue()
const {
3419 return expr2.updateValue();
3423 void cache()
const {
3425 const value_type_1 v1 = expr1.val();
3426 const value_type_2 v2 = expr2.val();
3427 min_v1 = (v1 <= v2);
3428 v = min_v1 ? v1 : v2;
3432 value_type
val()
const {
3437 void computePartials(
const value_type&
bar,
3438 value_type partials[])
const {
3440 expr2.computePartials(value_type(0.0), partials);
3442 expr2.computePartials(bar, partials);
3446 void getTangents(
int i, value_type dots[])
const {
3447 expr2.getTangents(i, dots);
3452 value_type getTangent(
int i)
const {
3453 return expr2.template getTangent<Arg>(
i);
3457 bool isLinear()
const {
3462 bool hasFastAccess()
const {
3463 return expr2.hasFastAccess();
3467 const value_type
dx(
int i)
const {
3468 return min_v1 ? value_type(0.0) : expr2.dx(i);
3473 return min_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3477 const value_type* getDx(
int j)
const {
3478 return expr2.getDx(j);
3484 const ExprT2& expr2;
3485 mutable value_type v;
3486 mutable bool min_v1;
3494 #define FAD_BINARYOP_MACRO(OPNAME,OP) \
3495 namespace Sacado { \
3496 namespace ELRCacheFad { \
3498 template <typename T1, typename T2> \
3499 SACADO_INLINE_FUNCTION \
3500 SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
3501 OPNAME (const T1& expr1, const T2& expr2) \
3503 typedef OP< T1, T2 > expr_t; \
3505 return Expr<expr_t>(expr1, expr2); \
3508 template <typename T> \
3509 SACADO_INLINE_FUNCTION \
3510 Expr< OP< Expr<T>, Expr<T> > > \
3511 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
3513 typedef OP< Expr<T>, Expr<T> > expr_t; \
3515 return Expr<expr_t>(expr1, expr2); \
3518 template <typename T> \
3519 SACADO_INLINE_FUNCTION \
3520 Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
3522 OPNAME (const typename Expr<T>::value_type& c, \
3523 const Expr<T>& expr) \
3525 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3526 typedef OP< ConstT, Expr<T> > expr_t; \
3528 return Expr<expr_t>(ConstT(c), expr); \
3531 template <typename T> \
3532 SACADO_INLINE_FUNCTION \
3533 Expr< OP< Expr<T>, \
3534 ConstExpr<typename Expr<T>::value_type> > > \
3535 OPNAME (const Expr<T>& expr, \
3536 const typename Expr<T>::value_type& c) \
3538 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3539 typedef OP< Expr<T>, ConstT > expr_t; \
3541 return Expr<expr_t>(expr, ConstT(c)); \
3544 template <typename T> \
3545 SACADO_INLINE_FUNCTION \
3546 SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
3547 OPNAME (const typename Expr<T>::scalar_type& c, \
3548 const Expr<T>& expr) \
3550 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3551 typedef OP< ConstT, Expr<T> > expr_t; \
3553 return Expr<expr_t>(ConstT(c), expr); \
3556 template <typename T> \
3557 SACADO_INLINE_FUNCTION \
3558 SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
3559 OPNAME (const Expr<T>& expr, \
3560 const typename Expr<T>::scalar_type& c) \
3562 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3563 typedef OP< Expr<T>, ConstT > expr_t; \
3565 return Expr<expr_t>(expr, ConstT(c)); \
3580 #undef FAD_BINARYOP_MACRO
3584 #define FAD_RELOP_MACRO(OP) \
3585 namespace Sacado { \
3586 namespace ELRCacheFad { \
3587 template <typename ExprT1, typename ExprT2> \
3588 SACADO_INLINE_FUNCTION \
3590 operator OP (const Expr<ExprT1>& expr1, \
3591 const Expr<ExprT2>& expr2) \
3595 return expr1.val() OP expr2.val(); \
3598 template <typename ExprT2> \
3599 SACADO_INLINE_FUNCTION \
3601 operator OP (const typename Expr<ExprT2>::value_type& a, \
3602 const Expr<ExprT2>& expr2) \
3605 return a OP expr2.val(); \
3608 template <typename ExprT1> \
3609 SACADO_INLINE_FUNCTION \
3611 operator OP (const Expr<ExprT1>& expr1, \
3612 const typename Expr<ExprT1>::value_type& b) \
3615 return expr1.val() OP b; \
3631 #undef FAD_RELOP_MACRO
3635 namespace ELRCacheFad {
3637 template <
typename ExprT>
3642 return ! expr.val();
3652 namespace ELRCacheFad {
3654 template <
typename ExprT>
3658 bool is_zero = (x.val() == 0.0);
3659 for (
int i=0;
i<x.size();
i++)
3660 is_zero = is_zero && (x.dx(
i) == 0.0);
3668 #define FAD_BOOL_MACRO(OP) \
3669 namespace Sacado { \
3670 namespace ELRCacheFad { \
3671 template <typename ExprT1, typename ExprT2> \
3672 SACADO_INLINE_FUNCTION \
3674 operator OP (const Expr<ExprT1>& expr1, \
3675 const Expr<ExprT2>& expr2) \
3677 return toBool(expr1) OP toBool(expr2); \
3680 template <typename ExprT2> \
3681 SACADO_INLINE_FUNCTION \
3683 operator OP (const typename Expr<ExprT2>::value_type& a, \
3684 const Expr<ExprT2>& expr2) \
3686 return a OP toBool(expr2); \
3689 template <typename ExprT1> \
3690 SACADO_INLINE_FUNCTION \
3692 operator OP (const Expr<ExprT1>& expr1, \
3693 const typename Expr<ExprT1>::value_type& b) \
3695 return toBool(expr1) OP b; \
3703 #undef FAD_BOOL_MACRO
3709 namespace ELRCacheFad {
3711 template <
typename ExprT>
3712 std::ostream& operator << (std::ostream& os, const Expr<ExprT>&
x) {
3713 os <<
x.val() <<
" [";
3715 for (
int i=0;
i<
x.size();
i++) {
3716 os <<
" " <<
x.dx(
i);
3727 #endif // SACADO_CACHEFAD_OPS_HPP
SACADO_INLINE_FUNCTION bool isActive() const
SACADO_INLINE_FUNCTION void cache() 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 value_type getTangent(int i) const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
ExprT::base_expr_type base_expr_type
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
ExprT::value_type value_type
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION void cache() const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION int size() const
ExprT::value_type value_type
value_type getTangent(int i) const
SACADO_INLINE_FUNCTION int size() const
SACADO_INLINE_FUNCTION const value_type * getDx(int j) 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 bool isLinear() const
SACADO_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
SACADO_INLINE_FUNCTION bool hasFastAccess() 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 fastAccessDx(int i) const
ExprT::base_expr_type base_expr_type
ExprT::value_type value_type
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION bool updateValue() const
#define FAD_BINARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, CDX1, CDX2, FASTACCESSDX, VAL_CONST_DX_1, VAL_CONST_DX_2, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
ExprT::scalar_type scalar_type
SACADO_INLINE_FUNCTION value_type val() const
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
SACADO_INLINE_FUNCTION Expr< UnaryPlusOp< Expr< T > > > operator+(const Expr< T > &expr)
#define FAD_RELOP_MACRO(OP)
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION bool isActive() const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
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 bool isActive() const
ExprT::scalar_type scalar_type
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION void cache() const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
#define FAD_BOOL_MACRO(OP)
atan2(expr1.val(), expr2.val())
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
SACADO_INLINE_FUNCTION bool isLinear() const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION int size() const
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
ExprT::scalar_type scalar_type
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION T safe_sqrt(const T &x)
ExprT::base_expr_type base_expr_type
SACADO_INLINE_FUNCTION int size() const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION Expr< UnaryMinusOp< Expr< T > > > operator-(const Expr< T > &expr)
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION bool isActive() const
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 void cache() const
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
#define SACADO_INLINE_FUNCTION
SACADO_INLINE_FUNCTION bool isLinear() const
SACADO_INLINE_FUNCTION bool isLinear() const
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) 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