33 #ifndef SACADO_ELRCACHEFAD_OPS_HPP
34 #define SACADO_ELRCACHEFAD_OPS_HPP
42 namespace ELRCacheFad {
48 template <
typename ExprT>
51 template <
typename ExprT>
60 static const int num_args = ExprT::num_args;
62 static const bool is_linear =
true;
65 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
68 int size()
const {
return expr.size(); }
72 bool isActive()
const {
return expr.template isActive<Arg>(); }
90 expr.computePartials(bar, partials);
95 expr.getTangents(i, dots); }
99 return expr.template getTangent<Arg>(
i);
104 return expr.isLinear();
109 return expr.hasFastAccess();
119 return expr.fastAccessDx(i);
124 return expr.getDx(j);
132 template <
typename T>
145 template <
typename ExprT>
148 template <
typename ExprT>
157 static const int num_args = ExprT::num_args;
159 static const bool is_linear =
true;
162 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
165 int size()
const {
return expr.size(); }
169 bool isActive()
const {
return expr.template isActive<Arg>(); }
187 expr.computePartials(-bar, partials);
192 expr.getTangents(i, dots); }
197 return expr.template getTangent<Arg>(
i);
202 return expr.isLinear();
207 return expr.hasFastAccess();
217 return -expr.fastAccessDx(i);
222 return expr.getDx(j);
230 template <
typename T>
244 template <
typename ExprT>
247 template <
typename ExprT>
256 static const int num_args = ExprT::num_args;
258 static const bool is_linear =
false;
261 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
264 int size()
const {
return expr.size(); }
268 bool isActive()
const {
return expr.template isActive<Arg>(); }
289 expr.computePartials(bar, partials);
291 expr.computePartials(-bar, partials);
296 expr.getTangents(i, dots); }
301 return expr.template getTangent<Arg>(
i);
311 return expr.hasFastAccess();
316 if (v_pos)
return expr.dx(i);
317 else return -expr.dx(i);
322 if (v_pos)
return expr.fastAccessDx(i);
323 else return -expr.fastAccessDx(i);
328 return expr.getDx(j);
338 template <
typename T>
352 template <
typename ExprT>
355 template <
typename ExprT>
364 static const int num_args = ExprT::num_args;
366 static const bool is_linear =
false;
369 explicit Expr(
const ExprT& expr_) : expr(expr_) {}
372 int size()
const {
return expr.size(); }
376 bool isActive()
const {
return expr.template isActive<Arg>(); }
397 expr.computePartials(bar, partials);
399 expr.computePartials(-bar, partials);
404 expr.getTangents(i, dots); }
409 return expr.template getTangent<Arg>(
i);
419 return expr.hasFastAccess();
424 if (v_pos)
return expr.dx(i);
425 else return -expr.dx(i);
430 if (v_pos)
return expr.fastAccessDx(i);
431 else return -expr.fastAccessDx(i);
436 return expr.getDx(j);
446 template <
typename T>
459 #define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE) \
461 namespace ELRCacheFad { \
463 template <typename ExprT> \
466 template <typename ExprT> \
467 class Expr< OP<ExprT> > { \
470 typedef typename ExprT::value_type value_type; \
471 typedef typename ExprT::scalar_type scalar_type; \
473 typedef typename ExprT::base_expr_type base_expr_type; \
475 static const int num_args = ExprT::num_args; \
477 static const bool is_linear = false; \
479 SACADO_INLINE_FUNCTION \
480 explicit Expr(const ExprT& expr_) : expr(expr_) {} \
482 SACADO_INLINE_FUNCTION \
483 int size() const { return expr.size(); } \
486 SACADO_INLINE_FUNCTION \
487 bool isActive() const { return expr.template isActive<Arg>(); } \
489 SACADO_INLINE_FUNCTION \
490 bool updateValue() const { return expr.updateValue(); } \
492 SACADO_INLINE_FUNCTION \
493 void cache() const { \
499 SACADO_INLINE_FUNCTION \
500 value_type val() const { \
504 SACADO_INLINE_FUNCTION \
505 void computePartials(const value_type& bar, \
506 value_type partials[]) const { \
507 expr.computePartials(bar*a, partials); \
510 SACADO_INLINE_FUNCTION \
511 void getTangents(int i, value_type dots[]) const { \
512 expr.getTangents(i, dots); } \
515 SACADO_INLINE_FUNCTION \
516 value_type getTangent(int i) const { \
517 return expr.template getTangent<Arg>(i); \
520 SACADO_INLINE_FUNCTION \
521 bool isLinear() const { \
525 SACADO_INLINE_FUNCTION \
526 bool hasFastAccess() const { \
527 return expr.hasFastAccess(); \
530 SACADO_INLINE_FUNCTION \
531 const value_type dx(int i) const { \
532 return expr.dx(i)*a; \
535 SACADO_INLINE_FUNCTION \
536 const value_type fastAccessDx(int i) const { \
537 return expr.fastAccessDx(i)*a; \
540 SACADO_INLINE_FUNCTION \
541 const value_type* getDx(int j) const { \
542 return expr.getDx(j); \
548 mutable value_type v; \
549 mutable value_type a; \
552 template <typename T> \
553 SACADO_INLINE_FUNCTION \
554 Expr< OP< Expr<T> > > \
555 OPNAME (const Expr<T>& expr) \
557 typedef OP< Expr<T> > expr_t; \
559 return Expr<expr_t>(expr); \
570 a=scalar_type(1.0)/v,
574 a = scalar_type(1.0)/(std::log(scalar_type(10.0))*v),
578 a = scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)),
582 a = (v == value_type(0.0) ? value_type(0.0) : value_type(scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)))),
594 a = scalar_type(1.0)+std::tan(v)*std::tan(v),
598 a = scalar_type(-1.0)/std::sqrt(scalar_type(1.0)-v*v),
602 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)-v*v),
606 a = scalar_type(1.0)/(scalar_type(1.0)+v*v),
618 a = scalar_type(1.0)-std::tanh(v)*std::tanh(v),
622 a = scalar_type(1.0)/std::sqrt((v-scalar_type(1.0))*(v+scalar_type(1.0))),
626 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)+v*v),
630 a = scalar_type(1.0)/(scalar_type(1.0)-v*v),
634 a = scalar_type(1.0)/(scalar_type(3.0)*std::cbrt(v*v)),
637 #undef FAD_UNARYOP_MACRO
643 namespace ELRCacheFad {
649 template <
typename ExprT1,
typename ExprT2>
652 template <
typename ExprT1,
typename ExprT2>
653 class Expr< AdditionOp<ExprT1,ExprT2> > {
657 typedef typename ExprT1::value_type value_type_1;
658 typedef typename ExprT2::value_type value_type_2;
660 value_type_2>::type value_type;
661 typedef typename ExprT1::scalar_type scalar_type_1;
662 typedef typename ExprT2::scalar_type scalar_type_2;
664 scalar_type_2>::type scalar_type;
666 typedef typename ExprT1::base_expr_type base_expr_type_1;
667 typedef typename ExprT2::base_expr_type base_expr_type_2;
669 base_expr_type_2>::type base_expr_type;
671 static const int num_args1 = ExprT1::num_args;
672 static const int num_args2 = ExprT2::num_args;
673 static const int num_args = num_args1 + num_args2;
675 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
678 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
679 expr1(expr1_), expr2(expr2_) {}
683 int sz1 = expr1.size(), sz2 = expr2.size();
684 return sz1 > sz2 ? sz1 : sz2;
689 bool isActive()
const {
691 return expr1.template isActive<Arg>();
693 return expr2.template isActive<Arg-num_args1>();
697 bool updateValue()
const {
698 return expr1.updateValue() && expr2.updateValue();
708 value_type
val()
const {
709 return expr1.val()+expr2.val();
713 void computePartials(
const value_type&
bar,
714 value_type partials[])
const {
716 expr1.computePartials(bar, partials);
718 expr2.computePartials(bar, partials+num_args1);
722 void getTangents(
int i, value_type dots[])
const {
723 expr1.getTangents(i, dots);
724 expr2.getTangents(i, dots+num_args1);
729 value_type getTangent(
int i)
const {
731 return expr1.template getTangent<Arg>(
i);
733 return expr2.template getTangent<Arg-num_args1>(
i);
737 bool isLinear()
const {
738 return expr1.isLinear() && expr2.isLinear();
742 bool hasFastAccess()
const {
743 return expr1.hasFastAccess() && expr2.hasFastAccess();
747 const value_type
dx(
int i)
const {
748 return expr1.dx(i) + expr2.dx(i);
753 return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
757 const value_type* getDx(
int j)
const {
759 return expr1.getDx(j);
761 return expr2.getDx(j-num_args1);
771 template <
typename ExprT1,
typename T2>
772 class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
776 typedef ConstExpr<T2> ExprT2;
777 typedef typename ExprT1::value_type value_type_1;
778 typedef typename ExprT2::value_type value_type_2;
780 value_type_2>::type value_type;
781 typedef typename ExprT1::scalar_type scalar_type_1;
782 typedef typename ExprT2::scalar_type scalar_type_2;
784 scalar_type_2>::type scalar_type;
786 typedef typename ExprT1::base_expr_type base_expr_type_1;
787 typedef typename ExprT2::base_expr_type base_expr_type_2;
789 base_expr_type_2>::type base_expr_type;
791 static const int num_args = ExprT1::num_args;
793 static const bool is_linear = ExprT1::is_linear;
796 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
797 expr1(expr1_), expr2(expr2_) {}
806 bool isActive()
const {
807 return expr1.template isActive<Arg>();
811 bool updateValue()
const {
812 return expr1.updateValue();
821 value_type
val()
const {
822 return expr1.val() + expr2.val();
826 void computePartials(
const value_type&
bar,
827 value_type partials[])
const {
828 expr1.computePartials(bar, partials);
832 void getTangents(
int i, value_type dots[])
const {
833 expr1.getTangents(i, dots);
838 value_type getTangent(
int i)
const {
839 return expr1.template getTangent<Arg>(
i);
843 bool isLinear()
const {
844 return expr1.isLinear();
848 bool hasFastAccess()
const {
849 return expr1.hasFastAccess();
853 const value_type
dx(
int i)
const {
859 return expr1.fastAccessDx(i);
863 const value_type* getDx(
int j)
const {
864 return expr1.getDx(j);
874 template <
typename T1,
typename ExprT2>
875 class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
879 typedef ConstExpr<T1> ExprT1;
880 typedef typename ExprT1::value_type value_type_1;
881 typedef typename ExprT2::value_type value_type_2;
883 value_type_2>::type value_type;
884 typedef typename ExprT1::scalar_type scalar_type_1;
885 typedef typename ExprT2::scalar_type scalar_type_2;
887 scalar_type_2>::type scalar_type;
889 typedef typename ExprT1::base_expr_type base_expr_type_1;
890 typedef typename ExprT2::base_expr_type base_expr_type_2;
892 base_expr_type_2>::type base_expr_type;
894 static const int num_args = ExprT2::num_args;
896 static const bool is_linear = ExprT2::is_linear;
899 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
900 expr1(expr1_), expr2(expr2_) {}
909 bool isActive()
const {
910 return expr2.template isActive<Arg>();
914 bool updateValue()
const {
915 return expr2.updateValue();
924 value_type
val()
const {
925 return expr1.val() + expr2.val();
929 void computePartials(
const value_type&
bar,
930 value_type partials[])
const {
931 expr2.computePartials(bar, partials);
935 void getTangents(
int i, value_type dots[])
const {
936 expr2.getTangents(i, dots);
941 value_type getTangent(
int i)
const {
942 return expr2.template getTangent<Arg>(
i);
946 bool isLinear()
const {
947 return expr2.isLinear();
951 bool hasFastAccess()
const {
952 return expr2.hasFastAccess();
956 const value_type
dx(
int i)
const {
962 return expr2.fastAccessDx(i);
966 const value_type* getDx(
int j)
const {
967 return expr2.getDx(j);
981 template <
typename ExprT1,
typename ExprT2>
984 template <
typename ExprT1,
typename ExprT2>
985 class Expr< SubtractionOp<ExprT1,ExprT2> > {
989 typedef typename ExprT1::value_type value_type_1;
990 typedef typename ExprT2::value_type value_type_2;
992 value_type_2>::type value_type;
993 typedef typename ExprT1::scalar_type scalar_type_1;
994 typedef typename ExprT2::scalar_type scalar_type_2;
996 scalar_type_2>::type scalar_type;
998 typedef typename ExprT1::base_expr_type base_expr_type_1;
999 typedef typename ExprT2::base_expr_type base_expr_type_2;
1001 base_expr_type_2>::type base_expr_type;
1003 static const int num_args1 = ExprT1::num_args;
1004 static const int num_args2 = ExprT2::num_args;
1005 static const int num_args = num_args1 + num_args2;
1007 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
1010 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1011 expr1(expr1_), expr2(expr2_) {}
1015 int sz1 = expr1.size(), sz2 = expr2.size();
1016 return sz1 > sz2 ? sz1 : sz2;
1021 bool isActive()
const {
1022 if (Arg < num_args1)
1023 return expr1.template isActive<Arg>();
1025 return expr2.template isActive<Arg-num_args1>();
1029 bool updateValue()
const {
1030 return expr1.updateValue() && expr2.updateValue();
1034 void cache()
const {
1040 value_type
val()
const {
1041 return expr1.val()-expr2.val();
1045 void computePartials(
const value_type&
bar,
1046 value_type partials[])
const {
1048 expr1.computePartials(bar, partials);
1050 expr2.computePartials(-bar, partials+num_args1);
1054 void getTangents(
int i, value_type dots[])
const {
1055 expr1.getTangents(i, dots);
1056 expr2.getTangents(i, dots+num_args1);
1061 value_type getTangent(
int i)
const {
1062 if (Arg < num_args1)
1063 return expr1.template getTangent<Arg>(
i);
1065 return expr2.template getTangent<Arg-num_args1>(
i);
1069 bool isLinear()
const {
1070 return expr1.isLinear() && expr2.isLinear();
1074 bool hasFastAccess()
const {
1075 return expr1.hasFastAccess() && expr2.hasFastAccess();
1079 const value_type
dx(
int i)
const {
1080 return expr1.dx(i) - expr2.dx(i);
1085 return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
1089 const value_type* getDx(
int j)
const {
1091 return expr1.getDx(j);
1093 return expr2.getDx(j-num_args1);
1098 const ExprT1& expr1;
1099 const ExprT2& expr2;
1103 template <
typename ExprT1,
typename T2>
1104 class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
1108 typedef ConstExpr<T2> ExprT2;
1109 typedef typename ExprT1::value_type value_type_1;
1110 typedef typename ExprT2::value_type value_type_2;
1112 value_type_2>::type value_type;
1113 typedef typename ExprT1::scalar_type scalar_type_1;
1114 typedef typename ExprT2::scalar_type scalar_type_2;
1116 scalar_type_2>::type scalar_type;
1118 typedef typename ExprT1::base_expr_type base_expr_type_1;
1119 typedef typename ExprT2::base_expr_type base_expr_type_2;
1121 base_expr_type_2>::type base_expr_type;
1123 static const int num_args = ExprT1::num_args;
1125 static const bool is_linear = ExprT1::is_linear;
1128 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1129 expr1(expr1_), expr2(expr2_) {}
1133 return expr1.size();
1138 bool isActive()
const {
1139 return expr1.template isActive<Arg>();
1143 bool updateValue()
const {
1144 return expr1.updateValue();
1148 void cache()
const {
1153 value_type
val()
const {
1154 return expr1.val() - expr2.val();
1158 void computePartials(
const value_type&
bar,
1159 value_type partials[])
const {
1160 expr1.computePartials(bar, partials);
1164 void getTangents(
int i, value_type dots[])
const {
1165 expr1.getTangents(i, dots);
1170 value_type getTangent(
int i)
const {
1171 return expr1.template getTangent<Arg>(
i);
1175 bool isLinear()
const {
1176 return expr1.isLinear();
1180 bool hasFastAccess()
const {
1181 return expr1.hasFastAccess();
1185 const value_type
dx(
int i)
const {
1191 return expr1.fastAccessDx(i);
1195 const value_type* getDx(
int j)
const {
1196 return expr1.getDx(j);
1201 const ExprT1& expr1;
1206 template <
typename T1,
typename ExprT2>
1207 class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
1211 typedef ConstExpr<T1> ExprT1;
1212 typedef typename ExprT1::value_type value_type_1;
1213 typedef typename ExprT2::value_type value_type_2;
1215 value_type_2>::type value_type;
1216 typedef typename ExprT1::scalar_type scalar_type_1;
1217 typedef typename ExprT2::scalar_type scalar_type_2;
1219 scalar_type_2>::type scalar_type;
1221 typedef typename ExprT1::base_expr_type base_expr_type_1;
1222 typedef typename ExprT2::base_expr_type base_expr_type_2;
1224 base_expr_type_2>::type base_expr_type;
1226 static const int num_args = ExprT2::num_args;
1228 static const bool is_linear = ExprT2::is_linear;
1231 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1232 expr1(expr1_), expr2(expr2_) {}
1236 return expr2.size();
1241 bool isActive()
const {
1242 return expr2.template isActive<Arg>();
1246 bool updateValue()
const {
1247 return expr2.updateValue();
1251 void cache()
const {
1256 value_type
val()
const {
1257 return expr1.val() - expr2.val();
1261 void computePartials(
const value_type&
bar,
1262 value_type partials[])
const {
1263 expr2.computePartials(-bar, partials);
1267 void getTangents(
int i, value_type dots[])
const {
1268 expr2.getTangents(i, dots);
1273 value_type getTangent(
int i)
const {
1274 return expr2.template getTangent<Arg>(
i);
1278 bool isLinear()
const {
1279 return expr2.isLinear();
1283 bool hasFastAccess()
const {
1284 return expr2.hasFastAccess();
1288 const value_type
dx(
int i)
const {
1289 return -expr2.dx(i);
1294 return -expr2.fastAccessDx(i);
1298 const value_type* getDx(
int j)
const {
1299 return expr2.getDx(j);
1305 const ExprT2& expr2;
1313 template <
typename ExprT1,
typename ExprT2>
1316 template <
typename ExprT1,
typename ExprT2>
1317 class Expr< MultiplicationOp<ExprT1,ExprT2> > {
1321 typedef typename ExprT1::value_type value_type_1;
1322 typedef typename ExprT2::value_type value_type_2;
1324 value_type_2>::type value_type;
1325 typedef typename ExprT1::scalar_type scalar_type_1;
1326 typedef typename ExprT2::scalar_type scalar_type_2;
1328 scalar_type_2>::type scalar_type;
1330 typedef typename ExprT1::base_expr_type base_expr_type_1;
1331 typedef typename ExprT2::base_expr_type base_expr_type_2;
1333 base_expr_type_2>::type base_expr_type;
1335 static const int num_args1 = ExprT1::num_args;
1336 static const int num_args2 = ExprT2::num_args;
1337 static const int num_args = num_args1 + num_args2;
1339 static const bool is_linear =
false;
1342 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1343 expr1(expr1_), expr2(expr2_) {}
1347 int sz1 = expr1.size(), sz2 = expr2.size();
1348 return sz1 > sz2 ? sz1 : sz2;
1353 bool isActive()
const {
1354 if (Arg < num_args1)
1355 return expr1.template isActive<Arg>();
1357 return expr2.template isActive<Arg-num_args1>();
1361 bool updateValue()
const {
1362 return expr1.updateValue() && expr2.updateValue();
1366 void cache()
const {
1374 value_type
val()
const {
1379 void computePartials(
const value_type&
bar,
1380 value_type partials[])
const {
1382 expr1.computePartials(bar*v2, partials);
1384 expr2.computePartials(bar*v1, partials+num_args1);
1388 void getTangents(
int i, value_type dots[])
const {
1389 expr1.getTangents(i, dots);
1390 expr2.getTangents(i, dots+num_args1);
1395 value_type getTangent(
int i)
const {
1396 if (Arg < num_args1)
1397 return expr1.template getTangent<Arg>(
i);
1399 return expr2.template getTangent<Arg-num_args1>(
i);
1403 bool isLinear()
const {
1408 bool hasFastAccess()
const {
1409 return expr1.hasFastAccess() && expr2.hasFastAccess();
1413 const value_type
dx(
int i)
const {
1414 if (expr1.size() > 0 && expr2.size() > 0)
1415 return v1*expr2.dx(i) + expr1.dx(i)*v2;
1416 else if (expr1.size() > 0)
1417 return expr1.dx(i)*v2;
1419 return v1*expr2.dx(i);
1424 return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1428 const value_type* getDx(
int j)
const {
1430 return expr1.getDx(j);
1432 return expr2.getDx(j-num_args1);
1437 const ExprT1& expr1;
1438 const ExprT2& expr2;
1439 mutable value_type_1 v1;
1440 mutable value_type_2 v2;
1444 template <
typename ExprT1,
typename T2>
1445 class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1449 typedef ConstExpr<T2> ExprT2;
1450 typedef typename ExprT1::value_type value_type_1;
1451 typedef typename ExprT2::value_type value_type_2;
1453 value_type_2>::type value_type;
1454 typedef typename ExprT1::scalar_type scalar_type_1;
1455 typedef typename ExprT2::scalar_type scalar_type_2;
1457 scalar_type_2>::type scalar_type;
1459 typedef typename ExprT1::base_expr_type base_expr_type_1;
1460 typedef typename ExprT2::base_expr_type base_expr_type_2;
1462 base_expr_type_2>::type base_expr_type;
1464 static const int num_args = ExprT1::num_args;
1466 static const bool is_linear = ExprT1::is_linear;
1469 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1470 expr1(expr1_), expr2(expr2_) {}
1474 return expr1.size();
1479 bool isActive()
const {
1480 return expr1.template isActive<Arg>();
1484 bool updateValue()
const {
1485 return expr1.updateValue();
1489 void cache()
const {
1494 value_type
val()
const {
1495 return expr1.val()*expr2.val();
1499 void computePartials(
const value_type&
bar,
1500 value_type partials[])
const {
1501 expr1.computePartials(bar*expr2.val(), partials);
1505 void getTangents(
int i, value_type dots[])
const {
1506 expr1.getTangents(i, dots);
1511 value_type getTangent(
int i)
const {
1512 return expr1.template getTangent<Arg>(
i);
1516 bool isLinear()
const {
1517 return expr1.isLinear();
1521 bool hasFastAccess()
const {
1522 return expr1.hasFastAccess();
1526 const value_type
dx(
int i)
const {
1527 return expr1.dx(i)*expr2.val();
1532 return expr1.fastAccessDx(i)*expr2.val();
1536 const value_type* getDx(
int j)
const {
1537 return expr1.getDx(j);
1542 const ExprT1& expr1;
1547 template <
typename T1,
typename ExprT2>
1548 class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1552 typedef ConstExpr<T1> ExprT1;
1553 typedef typename ExprT1::value_type value_type_1;
1554 typedef typename ExprT2::value_type value_type_2;
1556 value_type_2>::type value_type;
1557 typedef typename ExprT1::scalar_type scalar_type_1;
1558 typedef typename ExprT2::scalar_type scalar_type_2;
1560 scalar_type_2>::type scalar_type;
1562 typedef typename ExprT1::base_expr_type base_expr_type_1;
1563 typedef typename ExprT2::base_expr_type base_expr_type_2;
1565 base_expr_type_2>::type base_expr_type;
1567 static const int num_args = ExprT2::num_args;
1569 static const bool is_linear = ExprT2::is_linear;
1572 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1573 expr1(expr1_), expr2(expr2_) {}
1577 return expr2.size();
1582 bool isActive()
const {
1583 return expr2.template isActive<Arg>();
1587 bool updateValue()
const {
1588 return expr2.updateValue();
1592 void cache()
const {
1597 value_type
val()
const {
1598 return expr1.val()*expr2.val();
1602 void computePartials(
const value_type&
bar,
1603 value_type partials[])
const {
1604 expr2.computePartials(bar*expr1.val(), partials);
1608 void getTangents(
int i, value_type dots[])
const {
1609 expr2.getTangents(i, dots);
1614 value_type getTangent(
int i)
const {
1615 return expr2.template getTangent<Arg>(
i);
1619 bool isLinear()
const {
1620 return expr2.isLinear();
1624 bool hasFastAccess()
const {
1625 return expr2.hasFastAccess();
1629 const value_type
dx(
int i)
const {
1630 return expr1.val()*expr2.dx(i);
1635 return expr1.val()*expr2.fastAccessDx(i);
1639 const value_type* getDx(
int j)
const {
1640 return expr2.getDx(j);
1646 const ExprT2& expr2;
1654 template <
typename ExprT1,
typename ExprT2>
1657 template <
typename ExprT1,
typename ExprT2>
1658 class Expr< DivisionOp<ExprT1,ExprT2> > {
1662 typedef typename ExprT1::value_type value_type_1;
1663 typedef typename ExprT2::value_type value_type_2;
1665 value_type_2>::type value_type;
1666 typedef typename ExprT1::scalar_type scalar_type_1;
1667 typedef typename ExprT2::scalar_type scalar_type_2;
1669 scalar_type_2>::type scalar_type;
1671 typedef typename ExprT1::base_expr_type base_expr_type_1;
1672 typedef typename ExprT2::base_expr_type base_expr_type_2;
1674 base_expr_type_2>::type base_expr_type;
1676 static const int num_args1 = ExprT1::num_args;
1677 static const int num_args2 = ExprT2::num_args;
1678 static const int num_args = num_args1 + num_args2;
1680 static const bool is_linear =
false;
1683 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1684 expr1(expr1_), expr2(expr2_) {}
1688 int sz1 = expr1.size(), sz2 = expr2.size();
1689 return sz1 > sz2 ? sz1 : sz2;
1694 bool isActive()
const {
1695 if (Arg < num_args1)
1696 return expr1.template isActive<Arg>();
1698 return expr2.template isActive<Arg-num_args1>();
1702 bool updateValue()
const {
1703 return expr1.updateValue() && expr2.updateValue();
1707 void cache()
const {
1710 const value_type_1 v1 = expr1.val();
1711 const value_type_2 v2 = expr2.val();
1712 a = scalar_type(1.0)/v2;
1718 value_type
val()
const {
1723 void computePartials(
const value_type&
bar,
1724 value_type partials[])
const {
1726 expr1.computePartials(bar*
a, partials);
1728 expr2.computePartials(bar*b, partials+num_args1);
1732 void getTangents(
int i, value_type dots[])
const {
1733 expr1.getTangents(i, dots);
1734 expr2.getTangents(i, dots+num_args1);
1739 value_type getTangent(
int i)
const {
1740 if (Arg < num_args1)
1741 return expr1.template getTangent<Arg>(
i);
1743 return expr2.template getTangent<Arg-num_args1>(
i);
1747 bool isLinear()
const {
1752 bool hasFastAccess()
const {
1753 return expr1.hasFastAccess() && expr2.hasFastAccess();
1757 const value_type
dx(
int i)
const {
1758 if (expr1.size() > 0 && expr2.size() > 0)
1759 return expr1.dx(i)*
a + expr2.dx(i)*b;
1760 else if (expr1.size() > 0)
1761 return expr1.dx(i)*
a;
1763 return expr1.val()*b;
1768 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
1772 const value_type* getDx(
int j)
const {
1774 return expr1.getDx(j);
1776 return expr2.getDx(j-num_args1);
1781 const ExprT1& expr1;
1782 const ExprT2& expr2;
1783 mutable value_type v;
1784 mutable value_type
a;
1785 mutable value_type b;
1789 template <
typename ExprT1,
typename T2>
1790 class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1794 typedef ConstExpr<T2> ExprT2;
1795 typedef typename ExprT1::value_type value_type_1;
1796 typedef typename ExprT2::value_type value_type_2;
1798 value_type_2>::type value_type;
1799 typedef typename ExprT1::scalar_type scalar_type_1;
1800 typedef typename ExprT2::scalar_type scalar_type_2;
1802 scalar_type_2>::type scalar_type;
1804 typedef typename ExprT1::base_expr_type base_expr_type_1;
1805 typedef typename ExprT2::base_expr_type base_expr_type_2;
1807 base_expr_type_2>::type base_expr_type;
1809 static const int num_args = ExprT1::num_args;
1811 static const bool is_linear = ExprT1::is_linear;
1814 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1815 expr1(expr1_), expr2(expr2_) {}
1819 return expr1.size();
1824 bool isActive()
const {
1825 return expr1.template isActive<Arg>();
1829 bool updateValue()
const {
1830 return expr1.updateValue();
1834 void cache()
const {
1836 const value_type_1 v1 = expr1.val();
1837 a = scalar_type(1.0)/expr2.val();
1842 value_type
val()
const {
1847 void computePartials(
const value_type&
bar,
1848 value_type partials[])
const {
1849 expr1.computePartials(bar*
a, partials);
1853 void getTangents(
int i, value_type dots[])
const {
1854 expr1.getTangents(i, dots);
1859 value_type getTangent(
int i)
const {
1860 return expr1.template getTangent<Arg>(
i);
1864 bool isLinear()
const {
1865 return expr1.isLinear();
1869 bool hasFastAccess()
const {
1870 return expr1.hasFastAccess();
1874 const value_type
dx(
int i)
const {
1875 return expr1.dx(i)*
a;
1880 return expr1.fastAccessDx(i)*
a;
1884 const value_type* getDx(
int j)
const {
1885 return expr1.getDx(j);
1890 const ExprT1& expr1;
1892 mutable value_type v;
1893 mutable value_type
a;
1897 template <
typename T1,
typename ExprT2>
1898 class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1902 typedef ConstExpr<T1> ExprT1;
1903 typedef typename ExprT1::value_type value_type_1;
1904 typedef typename ExprT2::value_type value_type_2;
1906 value_type_2>::type value_type;
1907 typedef typename ExprT1::scalar_type scalar_type_1;
1908 typedef typename ExprT2::scalar_type scalar_type_2;
1910 scalar_type_2>::type scalar_type;
1912 typedef typename ExprT1::base_expr_type base_expr_type_1;
1913 typedef typename ExprT2::base_expr_type base_expr_type_2;
1915 base_expr_type_2>::type base_expr_type;
1917 static const int num_args = ExprT2::num_args;
1919 static const bool is_linear =
false;
1922 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
1923 expr1(expr1_), expr2(expr2_) {}
1927 return expr2.size();
1932 bool isActive()
const {
1933 return expr2.template isActive<Arg>();
1937 bool updateValue()
const {
1938 return expr2.updateValue();
1942 void cache()
const {
1944 const value_type_2 v2 = expr2.val();
1950 value_type
val()
const {
1955 void computePartials(
const value_type&
bar,
1956 value_type partials[])
const {
1957 expr2.computePartials(bar*b, partials);
1961 void getTangents(
int i, value_type dots[])
const {
1962 expr2.getTangents(i, dots);
1967 value_type getTangent(
int i)
const {
1968 return expr2.template getTangent<Arg>(
i);
1972 bool isLinear()
const {
1977 bool hasFastAccess()
const {
1978 return expr2.hasFastAccess();
1982 const value_type
dx(
int i)
const {
1983 return expr2.dx(i)*b;
1988 return expr2.fastAccessDx(i)*b;
1992 const value_type* getDx(
int j)
const {
1993 return expr2.getDx(j);
1999 const ExprT2& expr2;
2000 mutable value_type v;
2001 mutable value_type b;
2009 template <
typename ExprT1,
typename ExprT2>
2012 template <
typename ExprT1,
typename ExprT2>
2013 class Expr< Atan2Op<ExprT1,ExprT2> > {
2017 typedef typename ExprT1::value_type value_type_1;
2018 typedef typename ExprT2::value_type value_type_2;
2020 value_type_2>::type value_type;
2021 typedef typename ExprT1::scalar_type scalar_type_1;
2022 typedef typename ExprT2::scalar_type scalar_type_2;
2024 scalar_type_2>::type scalar_type;
2026 typedef typename ExprT1::base_expr_type base_expr_type_1;
2027 typedef typename ExprT2::base_expr_type base_expr_type_2;
2029 base_expr_type_2>::type base_expr_type;
2031 static const int num_args1 = ExprT1::num_args;
2032 static const int num_args2 = ExprT2::num_args;
2033 static const int num_args = num_args1 + num_args2;
2035 static const bool is_linear =
false;
2038 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2039 expr1(expr1_), expr2(expr2_) {}
2043 int sz1 = expr1.size(), sz2 = expr2.size();
2044 return sz1 > sz2 ? sz1 : sz2;
2049 bool isActive()
const {
2050 if (Arg < num_args1)
2051 return expr1.template isActive<Arg>();
2053 return expr2.template isActive<Arg-num_args1>();
2057 bool updateValue()
const {
2058 return expr1.updateValue() && expr2.updateValue();
2062 void cache()
const {
2065 const value_type_1 v1 = expr1.val();
2066 const value_type_2 v2 = expr2.val();
2067 a = scalar_type(1.0)/(v1*v1 + v2*v2);
2074 value_type
val()
const {
2079 void computePartials(
const value_type&
bar,
2080 value_type partials[])
const {
2082 expr1.computePartials(bar*
a, partials);
2084 expr2.computePartials(bar*b, partials+num_args1);
2088 void getTangents(
int i, value_type dots[])
const {
2089 expr1.getTangents(i, dots);
2090 expr2.getTangents(i, dots+num_args1);
2095 value_type getTangent(
int i)
const {
2096 if (Arg < num_args1)
2097 return expr1.template getTangent<Arg>(
i);
2099 return expr2.template getTangent<Arg-num_args1>(
i);
2103 bool isLinear()
const {
2108 bool hasFastAccess()
const {
2109 return expr1.hasFastAccess() && expr2.hasFastAccess();
2113 const value_type
dx(
int i)
const {
2114 if (expr1.size() > 0 && expr2.size() > 0)
2115 return expr1.dx(i)*
a + expr2.dx(i)*b;
2116 else if (expr1.size() > 0)
2117 return expr1.dx(i)*
a;
2119 return expr1.val()*b;
2124 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
2128 const value_type* getDx(
int j)
const {
2130 return expr1.getDx(j);
2132 return expr2.getDx(j-num_args1);
2137 const ExprT1& expr1;
2138 const ExprT2& expr2;
2139 mutable value_type v;
2140 mutable value_type
a;
2141 mutable value_type b;
2145 template <
typename ExprT1,
typename T2>
2146 class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
2150 typedef ConstExpr<T2> ExprT2;
2151 typedef typename ExprT1::value_type value_type_1;
2152 typedef typename ExprT2::value_type value_type_2;
2154 value_type_2>::type value_type;
2155 typedef typename ExprT1::scalar_type scalar_type_1;
2156 typedef typename ExprT2::scalar_type scalar_type_2;
2158 scalar_type_2>::type scalar_type;
2160 typedef typename ExprT1::base_expr_type base_expr_type_1;
2161 typedef typename ExprT2::base_expr_type base_expr_type_2;
2163 base_expr_type_2>::type base_expr_type;
2165 static const int num_args = ExprT1::num_args;
2167 static const bool is_linear =
false;
2170 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2171 expr1(expr1_), expr2(expr2_) {}
2175 return expr1.size();
2180 bool isActive()
const {
2181 return expr1.template isActive<Arg>();
2185 bool updateValue()
const {
2186 return expr1.updateValue();
2190 void cache()
const {
2192 const value_type_1 v1 = expr1.val();
2193 const value_type_2 v2 = expr2.val();
2194 a = v2/(v1*v1 + v2*v2);
2199 value_type
val()
const {
2204 void computePartials(
const value_type&
bar,
2205 value_type partials[])
const {
2206 expr1.computePartials(bar*
a, partials);
2210 void getTangents(
int i, value_type dots[])
const {
2211 expr1.getTangents(i, dots);
2216 value_type getTangent(
int i)
const {
2217 return expr1.template getTangent<Arg>(
i);
2221 bool isLinear()
const {
2226 bool hasFastAccess()
const {
2227 return expr1.hasFastAccess();
2231 const value_type
dx(
int i)
const {
2232 return expr1.dx(i)*
a;
2237 return expr1.fastAccessDx(i)*
a;
2241 const value_type* getDx(
int j)
const {
2242 return expr1.getDx(j);
2247 const ExprT1& expr1;
2249 mutable value_type v;
2250 mutable value_type
a;
2254 template <
typename T1,
typename ExprT2>
2255 class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
2259 typedef ConstExpr<T1> ExprT1;
2260 typedef typename ExprT1::value_type value_type_1;
2261 typedef typename ExprT2::value_type value_type_2;
2263 value_type_2>::type value_type;
2264 typedef typename ExprT1::scalar_type scalar_type_1;
2265 typedef typename ExprT2::scalar_type scalar_type_2;
2267 scalar_type_2>::type scalar_type;
2269 typedef typename ExprT1::base_expr_type base_expr_type_1;
2270 typedef typename ExprT2::base_expr_type base_expr_type_2;
2272 base_expr_type_2>::type base_expr_type;
2274 static const int num_args = ExprT2::num_args;
2276 static const bool is_linear =
false;
2279 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2280 expr1(expr1_), expr2(expr2_) {}
2284 return expr2.size();
2289 bool isActive()
const {
2290 return expr2.template isActive<Arg>();
2294 bool updateValue()
const {
2295 return expr2.updateValue();
2299 void cache()
const {
2301 const value_type_1 v1 = expr1.val();
2302 const value_type_2 v2 = expr2.val();
2303 b = -v1/(v1*v1 + v2*v2);
2308 value_type
val()
const {
2313 void computePartials(
const value_type&
bar,
2314 value_type partials[])
const {
2315 expr2.computePartials(bar*b, partials);
2319 void getTangents(
int i, value_type dots[])
const {
2320 expr2.getTangents(i, dots);
2325 value_type getTangent(
int i)
const {
2326 return expr2.template getTangent<Arg>(
i);
2330 bool isLinear()
const {
2335 bool hasFastAccess()
const {
2336 return expr2.hasFastAccess();
2340 const value_type
dx(
int i)
const {
2341 return expr2.dx(i)*b;
2346 return expr2.fastAccessDx(i)*b;
2350 const value_type* getDx(
int j)
const {
2351 return expr2.getDx(j);
2357 const ExprT2& expr2;
2358 mutable value_type v;
2359 mutable value_type b;
2367 template <
typename ExprT1,
typename ExprT2>
2370 template <
typename ExprT1,
typename ExprT2>
2371 class Expr< PowerOp<ExprT1,ExprT2> > {
2375 typedef typename ExprT1::value_type value_type_1;
2376 typedef typename ExprT2::value_type value_type_2;
2378 value_type_2>::type value_type;
2379 typedef typename ExprT1::scalar_type scalar_type_1;
2380 typedef typename ExprT2::scalar_type scalar_type_2;
2382 scalar_type_2>::type scalar_type;
2384 typedef typename ExprT1::base_expr_type base_expr_type_1;
2385 typedef typename ExprT2::base_expr_type base_expr_type_2;
2387 base_expr_type_2>::type base_expr_type;
2389 static const int num_args1 = ExprT1::num_args;
2390 static const int num_args2 = ExprT2::num_args;
2391 static const int num_args = num_args1 + num_args2;
2393 static const bool is_linear =
false;
2396 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2397 expr1(expr1_), expr2(expr2_) {}
2401 int sz1 = expr1.size(), sz2 = expr2.size();
2402 return sz1 > sz2 ? sz1 : sz2;
2407 bool isActive()
const {
2408 if (Arg < num_args1)
2409 return expr1.template isActive<Arg>();
2411 return expr2.template isActive<Arg-num_args1>();
2415 bool updateValue()
const {
2416 return expr1.updateValue() && expr2.updateValue();
2420 void cache()
const {
2423 const value_type_1 v1 = expr1.val();
2424 const value_type_2 v2 = expr2.val();
2426 if (expr2.size() == 0 && v2 == scalar_type(1.0)) {
2427 a = scalar_type(1.0);
2428 b = scalar_type(0.0);
2430 else if (v1 == scalar_type(0.0)) {
2431 a = scalar_type(0.0);
2432 b = scalar_type(0.0);
2441 value_type
val()
const {
2446 void computePartials(
const value_type&
bar,
2447 value_type partials[])
const {
2449 expr1.computePartials(bar*
a, partials);
2451 expr2.computePartials(bar*b, partials+num_args1);
2455 void getTangents(
int i, value_type dots[])
const {
2456 expr1.getTangents(i, dots);
2457 expr2.getTangents(i, dots+num_args1);
2462 value_type getTangent(
int i)
const {
2463 if (Arg < num_args1)
2464 return expr1.template getTangent<Arg>(
i);
2466 return expr2.template getTangent<Arg-num_args1>(
i);
2470 bool isLinear()
const {
2475 bool hasFastAccess()
const {
2476 return expr1.hasFastAccess() && expr2.hasFastAccess();
2480 const value_type
dx(
int i)
const {
2481 if (expr1.size() > 0 && expr2.size() > 0)
2482 return expr1.dx(i)*
a + expr2.dx(i)*b;
2483 else if (expr1.size() > 0)
2484 return expr1.dx(i)*
a;
2486 return expr1.val()*b;
2491 return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
2495 const value_type* getDx(
int j)
const {
2497 return expr1.getDx(j);
2499 return expr2.getDx(j-num_args1);
2504 const ExprT1& expr1;
2505 const ExprT2& expr2;
2506 mutable value_type v;
2507 mutable value_type
a;
2508 mutable value_type b;
2512 template <
typename ExprT1,
typename T2>
2513 class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
2517 typedef ConstExpr<T2> ExprT2;
2518 typedef typename ExprT1::value_type value_type_1;
2519 typedef typename ExprT2::value_type value_type_2;
2521 value_type_2>::type value_type;
2522 typedef typename ExprT1::scalar_type scalar_type_1;
2523 typedef typename ExprT2::scalar_type scalar_type_2;
2525 scalar_type_2>::type scalar_type;
2527 typedef typename ExprT1::base_expr_type base_expr_type_1;
2528 typedef typename ExprT2::base_expr_type base_expr_type_2;
2530 base_expr_type_2>::type base_expr_type;
2532 static const int num_args = ExprT1::num_args;
2534 static const bool is_linear =
false;
2537 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2538 expr1(expr1_), expr2(expr2_) {}
2542 return expr1.size();
2547 bool isActive()
const {
2548 return expr1.template isActive<Arg>();
2552 bool updateValue()
const {
2553 return expr1.updateValue();
2557 void cache()
const {
2559 const value_type_1 v1 = expr1.val();
2560 const value_type_2 v2 = expr2.val();
2562 if (v2 == scalar_type(1.0)) {
2563 a = scalar_type(1.0);
2565 else if (v1 == scalar_type(0.0)) {
2566 a = scalar_type(0.0);
2574 value_type
val()
const {
2579 void computePartials(
const value_type&
bar,
2580 value_type partials[])
const {
2581 expr1.computePartials(bar*
a, partials);
2585 void getTangents(
int i, value_type dots[])
const {
2586 expr1.getTangents(i, dots);
2591 value_type getTangent(
int i)
const {
2592 return expr1.template getTangent<Arg>(
i);
2596 bool isLinear()
const {
2601 bool hasFastAccess()
const {
2602 return expr1.hasFastAccess();
2606 const value_type
dx(
int i)
const {
2607 return expr1.dx(i)*
a;
2612 return expr1.fastAccessDx(i)*
a;
2616 const value_type* getDx(
int j)
const {
2617 return expr1.getDx(j);
2622 const ExprT1& expr1;
2624 mutable value_type v;
2625 mutable value_type
a;
2629 template <
typename T1,
typename ExprT2>
2630 class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
2634 typedef ConstExpr<T1> ExprT1;
2635 typedef typename ExprT1::value_type value_type_1;
2636 typedef typename ExprT2::value_type value_type_2;
2638 value_type_2>::type value_type;
2639 typedef typename ExprT1::scalar_type scalar_type_1;
2640 typedef typename ExprT2::scalar_type scalar_type_2;
2642 scalar_type_2>::type scalar_type;
2644 typedef typename ExprT1::base_expr_type base_expr_type_1;
2645 typedef typename ExprT2::base_expr_type base_expr_type_2;
2647 base_expr_type_2>::type base_expr_type;
2649 static const int num_args = ExprT2::num_args;
2651 static const bool is_linear =
false;
2654 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2655 expr1(expr1_), expr2(expr2_) {}
2659 return expr2.size();
2664 bool isActive()
const {
2665 return expr2.template isActive<Arg>();
2669 bool updateValue()
const {
2670 return expr2.updateValue();
2674 void cache()
const {
2676 const value_type_1 v1 = expr1.val();
2677 const value_type_2 v2 = expr2.val();
2679 if (v1 == scalar_type(0.0)) {
2680 b = scalar_type(0.0);
2688 value_type
val()
const {
2693 void computePartials(
const value_type&
bar,
2694 value_type partials[])
const {
2695 expr2.computePartials(bar*b, partials);
2699 void getTangents(
int i, value_type dots[])
const {
2700 expr2.getTangents(i, dots);
2705 value_type getTangent(
int i)
const {
2706 return expr2.template getTangent<Arg>(
i);
2710 bool isLinear()
const {
2715 bool hasFastAccess()
const {
2716 return expr2.hasFastAccess();
2720 const value_type
dx(
int i)
const {
2721 return expr2.dx(i)*b;
2726 return expr2.fastAccessDx(i)*b;
2730 const value_type* getDx(
int j)
const {
2731 return expr2.getDx(j);
2737 const ExprT2& expr2;
2738 mutable value_type v;
2739 mutable value_type b;
2747 template <
typename ExprT1,
typename ExprT2>
2750 template <
typename ExprT1,
typename ExprT2>
2751 class Expr< MaxOp<ExprT1,ExprT2> > {
2755 typedef typename ExprT1::value_type value_type_1;
2756 typedef typename ExprT2::value_type value_type_2;
2758 value_type_2>::type value_type;
2759 typedef typename ExprT1::scalar_type scalar_type_1;
2760 typedef typename ExprT2::scalar_type scalar_type_2;
2762 scalar_type_2>::type scalar_type;
2764 typedef typename ExprT1::base_expr_type base_expr_type_1;
2765 typedef typename ExprT2::base_expr_type base_expr_type_2;
2767 base_expr_type_2>::type base_expr_type;
2769 static const int num_args1 = ExprT1::num_args;
2770 static const int num_args2 = ExprT2::num_args;
2771 static const int num_args = num_args1 + num_args2;
2773 static const bool is_linear =
false;
2776 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2777 expr1(expr1_), expr2(expr2_) {}
2781 int sz1 = expr1.size(), sz2 = expr2.size();
2782 return sz1 > sz2 ? sz1 : sz2;
2787 bool isActive()
const {
2788 if (Arg < num_args1)
2789 return expr1.template isActive<Arg>();
2791 return expr2.template isActive<Arg-num_args1>();
2795 bool updateValue()
const {
2796 return expr1.updateValue() && expr2.updateValue();
2800 void cache()
const {
2803 const value_type_1 v1 = expr1.val();
2804 const value_type_2 v2 = expr2.val();
2805 max_v1 = (v1 >= v2);
2806 v = max_v1 ? v1 : v2;
2810 value_type
val()
const {
2815 void computePartials(
const value_type&
bar,
2816 value_type partials[])
const {
2817 if (num_args1 > 0) {
2819 expr1.computePartials(bar, partials);
2821 expr1.computePartials(value_type(0.0), partials);
2823 if (num_args2 > 0) {
2825 expr2.computePartials(value_type(0.0), partials+num_args1);
2827 expr2.computePartials(bar, partials+num_args1);
2832 void getTangents(
int i, value_type dots[])
const {
2833 expr1.getTangents(i, dots);
2834 expr2.getTangents(i, dots+num_args1);
2839 value_type getTangent(
int i)
const {
2840 if (Arg < num_args1)
2841 return expr1.template getTangent<Arg>(
i);
2843 return expr2.template getTangent<Arg-num_args1>(
i);
2847 bool isLinear()
const {
2852 bool hasFastAccess()
const {
2853 return expr1.hasFastAccess() && expr2.hasFastAccess();
2857 const value_type
dx(
int i)
const {
2858 return max_v1 ? expr1.dx(i) : expr2.dx(i);
2863 return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2867 const value_type* getDx(
int j)
const {
2869 return expr1.getDx(j);
2871 return expr2.getDx(j-num_args1);
2876 const ExprT1& expr1;
2877 const ExprT2& expr2;
2878 mutable value_type v;
2879 mutable bool max_v1;
2883 template <
typename ExprT1,
typename T2>
2884 class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2888 typedef ConstExpr<T2> ExprT2;
2889 typedef typename ExprT1::value_type value_type_1;
2890 typedef typename ExprT2::value_type value_type_2;
2892 value_type_2>::type value_type;
2893 typedef typename ExprT1::scalar_type scalar_type_1;
2894 typedef typename ExprT2::scalar_type scalar_type_2;
2896 scalar_type_2>::type scalar_type;
2898 typedef typename ExprT1::base_expr_type base_expr_type_1;
2899 typedef typename ExprT2::base_expr_type base_expr_type_2;
2901 base_expr_type_2>::type base_expr_type;
2903 static const int num_args = ExprT1::num_args;
2905 static const bool is_linear =
false;
2908 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
2909 expr1(expr1_), expr2(expr2_) {}
2913 return expr1.size();
2918 bool isActive()
const {
2919 return expr1.template isActive<Arg>();
2923 bool updateValue()
const {
2924 return expr1.updateValue();
2928 void cache()
const {
2930 const value_type_1 v1 = expr1.val();
2931 const value_type_2 v2 = expr2.val();
2932 max_v1 = (v1 >= v2);
2933 v = max_v1 ? v1 : v2;
2937 value_type
val()
const {
2942 void computePartials(
const value_type&
bar,
2943 value_type partials[])
const {
2945 expr1.computePartials(bar, partials);
2947 expr1.computePartials(value_type(0.0), partials);
2951 void getTangents(
int i, value_type dots[])
const {
2952 expr1.getTangents(i, dots);
2957 value_type getTangent(
int i)
const {
2958 return expr1.template getTangent<Arg>(
i);
2962 bool isLinear()
const {
2967 bool hasFastAccess()
const {
2968 return expr1.hasFastAccess();
2972 const value_type
dx(
int i)
const {
2973 return max_v1 ? expr1.dx(i) : value_type(0.0);
2978 return max_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
2982 const value_type* getDx(
int j)
const {
2983 return expr1.getDx(j);
2988 const ExprT1& expr1;
2990 mutable value_type v;
2991 mutable bool max_v1;
2995 template <
typename T1,
typename ExprT2>
2996 class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
3000 typedef ConstExpr<T1> ExprT1;
3001 typedef typename ExprT1::value_type value_type_1;
3002 typedef typename ExprT2::value_type value_type_2;
3004 value_type_2>::type value_type;
3005 typedef typename ExprT1::scalar_type scalar_type_1;
3006 typedef typename ExprT2::scalar_type scalar_type_2;
3008 scalar_type_2>::type scalar_type;
3010 typedef typename ExprT1::base_expr_type base_expr_type_1;
3011 typedef typename ExprT2::base_expr_type base_expr_type_2;
3013 base_expr_type_2>::type base_expr_type;
3015 static const int num_args = ExprT2::num_args;
3017 static const bool is_linear =
false;
3020 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3021 expr1(expr1_), expr2(expr2_) {}
3025 return expr2.size();
3030 bool isActive()
const {
3031 return expr2.template isActive<Arg>();
3035 bool updateValue()
const {
3036 return expr2.updateValue();
3040 void cache()
const {
3042 const value_type_1 v1 = expr1.val();
3043 const value_type_2 v2 = expr2.val();
3044 max_v1 = (v1 >= v2);
3045 v = max_v1 ? v1 : v2;
3049 value_type
val()
const {
3054 void computePartials(
const value_type&
bar,
3055 value_type partials[])
const {
3057 expr2.computePartials(value_type(0.0), partials);
3059 expr2.computePartials(bar, partials);
3063 void getTangents(
int i, value_type dots[])
const {
3064 expr2.getTangents(i, dots);
3069 value_type getTangent(
int i)
const {
3070 return expr2.template getTangent<Arg>(
i);
3074 bool isLinear()
const {
3079 bool hasFastAccess()
const {
3080 return expr2.hasFastAccess();
3084 const value_type
dx(
int i)
const {
3085 return max_v1 ? value_type(0.0) : expr2.dx(i);
3090 return max_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3094 const value_type* getDx(
int j)
const {
3095 return expr2.getDx(j);
3101 const ExprT2& expr2;
3102 mutable value_type v;
3103 mutable bool max_v1;
3111 template <
typename ExprT1,
typename ExprT2>
3114 template <
typename ExprT1,
typename ExprT2>
3115 class Expr< MinOp<ExprT1,ExprT2> > {
3119 typedef typename ExprT1::value_type value_type_1;
3120 typedef typename ExprT2::value_type value_type_2;
3122 value_type_2>::type value_type;
3123 typedef typename ExprT1::scalar_type scalar_type_1;
3124 typedef typename ExprT2::scalar_type scalar_type_2;
3126 scalar_type_2>::type scalar_type;
3128 typedef typename ExprT1::base_expr_type base_expr_type_1;
3129 typedef typename ExprT2::base_expr_type base_expr_type_2;
3131 base_expr_type_2>::type base_expr_type;
3133 static const int num_args1 = ExprT1::num_args;
3134 static const int num_args2 = ExprT2::num_args;
3135 static const int num_args = num_args1 + num_args2;
3137 static const bool is_linear =
false;
3140 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3141 expr1(expr1_), expr2(expr2_) {}
3145 int sz1 = expr1.size(), sz2 = expr2.size();
3146 return sz1 > sz2 ? sz1 : sz2;
3151 bool isActive()
const {
3152 if (Arg < num_args1)
3153 return expr1.template isActive<Arg>();
3155 return expr2.template isActive<Arg-num_args1>();
3159 bool updateValue()
const {
3160 return expr1.updateValue() && expr2.updateValue();
3164 void cache()
const {
3167 const value_type_1 v1 = expr1.val();
3168 const value_type_2 v2 = expr2.val();
3169 min_v1 = (v1 <= v2);
3170 v = min_v1 ? v1 : v2;
3174 value_type
val()
const {
3179 void computePartials(
const value_type&
bar,
3180 value_type partials[])
const {
3181 if (num_args1 > 0) {
3183 expr1.computePartials(bar, partials);
3185 expr1.computePartials(value_type(0.0), partials);
3187 if (num_args2 > 0) {
3189 expr2.computePartials(value_type(0.0), partials+num_args1);
3191 expr2.computePartials(bar, partials+num_args1);
3196 void getTangents(
int i, value_type dots[])
const {
3197 expr1.getTangents(i, dots);
3198 expr2.getTangents(i, dots+num_args1);
3203 value_type getTangent(
int i)
const {
3204 if (Arg < num_args1)
3205 return expr1.template getTangent<Arg>(
i);
3207 return expr2.template getTangent<Arg-num_args1>(
i);
3211 bool isLinear()
const {
3216 bool hasFastAccess()
const {
3217 return expr1.hasFastAccess() && expr2.hasFastAccess();
3221 const value_type
dx(
int i)
const {
3222 return min_v1 ? expr1.dx(i) : expr2.dx(i);
3227 return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
3231 const value_type* getDx(
int j)
const {
3233 return expr1.getDx(j);
3235 return expr2.getDx(j-num_args1);
3240 const ExprT1& expr1;
3241 const ExprT2& expr2;
3242 mutable value_type v;
3243 mutable bool min_v1;
3247 template <
typename ExprT1,
typename T2>
3248 class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
3252 typedef ConstExpr<T2> ExprT2;
3253 typedef typename ExprT1::value_type value_type_1;
3254 typedef typename ExprT2::value_type value_type_2;
3256 value_type_2>::type value_type;
3257 typedef typename ExprT1::scalar_type scalar_type_1;
3258 typedef typename ExprT2::scalar_type scalar_type_2;
3260 scalar_type_2>::type scalar_type;
3262 typedef typename ExprT1::base_expr_type base_expr_type_1;
3263 typedef typename ExprT2::base_expr_type base_expr_type_2;
3265 base_expr_type_2>::type base_expr_type;
3267 static const int num_args = ExprT1::num_args;
3269 static const bool is_linear =
false;
3272 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3273 expr1(expr1_), expr2(expr2_) {}
3277 return expr1.size();
3282 bool isActive()
const {
3283 return expr1.template isActive<Arg>();
3287 bool updateValue()
const {
3288 return expr1.updateValue();
3292 void cache()
const {
3294 const value_type_1 v1 = expr1.val();
3295 const value_type_2 v2 = expr2.val();
3296 min_v1 = (v1 <= v2);
3297 v = min_v1 ? v1 : v2;
3301 value_type
val()
const {
3306 void computePartials(
const value_type&
bar,
3307 value_type partials[])
const {
3309 expr1.computePartials(bar, partials);
3311 expr1.computePartials(value_type(0.0), partials);
3315 void getTangents(
int i, value_type dots[])
const {
3316 expr1.getTangents(i, dots);
3321 value_type getTangent(
int i)
const {
3322 return expr1.template getTangent<Arg>(
i);
3326 bool isLinear()
const {
3331 bool hasFastAccess()
const {
3332 return expr1.hasFastAccess();
3336 const value_type
dx(
int i)
const {
3337 return min_v1 ? expr1.dx(i) : value_type(0.0);
3342 return min_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3346 const value_type* getDx(
int j)
const {
3347 return expr1.getDx(j);
3352 const ExprT1& expr1;
3354 mutable value_type v;
3355 mutable bool min_v1;
3359 template <
typename T1,
typename ExprT2>
3360 class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
3364 typedef ConstExpr<T1> ExprT1;
3365 typedef typename ExprT1::value_type value_type_1;
3366 typedef typename ExprT2::value_type value_type_2;
3368 value_type_2>::type value_type;
3369 typedef typename ExprT1::scalar_type scalar_type_1;
3370 typedef typename ExprT2::scalar_type scalar_type_2;
3372 scalar_type_2>::type scalar_type;
3374 typedef typename ExprT1::base_expr_type base_expr_type_1;
3375 typedef typename ExprT2::base_expr_type base_expr_type_2;
3377 base_expr_type_2>::type base_expr_type;
3379 static const int num_args = ExprT2::num_args;
3381 static const bool is_linear =
false;
3384 Expr(
const ExprT1& expr1_,
const ExprT2& expr2_) :
3385 expr1(expr1_), expr2(expr2_) {}
3389 return expr2.size();
3394 bool isActive()
const {
3395 return expr2.template isActive<Arg>();
3399 bool updateValue()
const {
3400 return expr2.updateValue();
3404 void cache()
const {
3406 const value_type_1 v1 = expr1.val();
3407 const value_type_2 v2 = expr2.val();
3408 min_v1 = (v1 <= v2);
3409 v = min_v1 ? v1 : v2;
3413 value_type
val()
const {
3418 void computePartials(
const value_type&
bar,
3419 value_type partials[])
const {
3421 expr2.computePartials(value_type(0.0), partials);
3423 expr2.computePartials(bar, partials);
3427 void getTangents(
int i, value_type dots[])
const {
3428 expr2.getTangents(i, dots);
3433 value_type getTangent(
int i)
const {
3434 return expr2.template getTangent<Arg>(
i);
3438 bool isLinear()
const {
3443 bool hasFastAccess()
const {
3444 return expr2.hasFastAccess();
3448 const value_type
dx(
int i)
const {
3449 return min_v1 ? value_type(0.0) : expr2.dx(i);
3454 return min_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3458 const value_type* getDx(
int j)
const {
3459 return expr2.getDx(j);
3465 const ExprT2& expr2;
3466 mutable value_type v;
3467 mutable bool min_v1;
3475 #define FAD_BINARYOP_MACRO(OPNAME,OP) \
3476 namespace Sacado { \
3477 namespace ELRCacheFad { \
3479 template <typename T1, typename T2> \
3480 SACADO_INLINE_FUNCTION \
3481 SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
3482 OPNAME (const T1& expr1, const T2& expr2) \
3484 typedef OP< T1, T2 > expr_t; \
3486 return Expr<expr_t>(expr1, expr2); \
3489 template <typename T> \
3490 SACADO_INLINE_FUNCTION \
3491 Expr< OP< Expr<T>, Expr<T> > > \
3492 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
3494 typedef OP< Expr<T>, Expr<T> > expr_t; \
3496 return Expr<expr_t>(expr1, expr2); \
3499 template <typename T> \
3500 SACADO_INLINE_FUNCTION \
3501 Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
3503 OPNAME (const typename Expr<T>::value_type& c, \
3504 const Expr<T>& expr) \
3506 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3507 typedef OP< ConstT, Expr<T> > expr_t; \
3509 return Expr<expr_t>(ConstT(c), expr); \
3512 template <typename T> \
3513 SACADO_INLINE_FUNCTION \
3514 Expr< OP< Expr<T>, \
3515 ConstExpr<typename Expr<T>::value_type> > > \
3516 OPNAME (const Expr<T>& expr, \
3517 const typename Expr<T>::value_type& c) \
3519 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3520 typedef OP< Expr<T>, ConstT > expr_t; \
3522 return Expr<expr_t>(expr, ConstT(c)); \
3525 template <typename T> \
3526 SACADO_INLINE_FUNCTION \
3527 SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
3528 OPNAME (const typename Expr<T>::scalar_type& c, \
3529 const Expr<T>& expr) \
3531 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3532 typedef OP< ConstT, Expr<T> > expr_t; \
3534 return Expr<expr_t>(ConstT(c), expr); \
3537 template <typename T> \
3538 SACADO_INLINE_FUNCTION \
3539 SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
3540 OPNAME (const Expr<T>& expr, \
3541 const typename Expr<T>::scalar_type& c) \
3543 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3544 typedef OP< Expr<T>, ConstT > expr_t; \
3546 return Expr<expr_t>(expr, ConstT(c)); \
3561 #undef FAD_BINARYOP_MACRO
3565 #define FAD_RELOP_MACRO(OP) \
3566 namespace Sacado { \
3567 namespace ELRCacheFad { \
3568 template <typename ExprT1, typename ExprT2> \
3569 SACADO_INLINE_FUNCTION \
3571 operator OP (const Expr<ExprT1>& expr1, \
3572 const Expr<ExprT2>& expr2) \
3576 return expr1.val() OP expr2.val(); \
3579 template <typename ExprT2> \
3580 SACADO_INLINE_FUNCTION \
3582 operator OP (const typename Expr<ExprT2>::value_type& a, \
3583 const Expr<ExprT2>& expr2) \
3586 return a OP expr2.val(); \
3589 template <typename ExprT1> \
3590 SACADO_INLINE_FUNCTION \
3592 operator OP (const Expr<ExprT1>& expr1, \
3593 const typename Expr<ExprT1>::value_type& b) \
3596 return expr1.val() OP b; \
3612 #undef FAD_RELOP_MACRO
3616 namespace ELRCacheFad {
3618 template <
typename ExprT>
3623 return ! expr.val();
3633 namespace ELRCacheFad {
3635 template <
typename ExprT>
3639 bool is_zero = (x.val() == 0.0);
3640 for (
int i=0;
i<x.size();
i++)
3641 is_zero = is_zero && (x.dx(
i) == 0.0);
3649 #define FAD_BOOL_MACRO(OP) \
3650 namespace Sacado { \
3651 namespace ELRCacheFad { \
3652 template <typename ExprT1, typename ExprT2> \
3653 SACADO_INLINE_FUNCTION \
3655 operator OP (const Expr<ExprT1>& expr1, \
3656 const Expr<ExprT2>& expr2) \
3658 return toBool(expr1) OP toBool(expr2); \
3661 template <typename ExprT2> \
3662 SACADO_INLINE_FUNCTION \
3664 operator OP (const typename Expr<ExprT2>::value_type& a, \
3665 const Expr<ExprT2>& expr2) \
3667 return a OP toBool(expr2); \
3670 template <typename ExprT1> \
3671 SACADO_INLINE_FUNCTION \
3673 operator OP (const Expr<ExprT1>& expr1, \
3674 const typename Expr<ExprT1>::value_type& b) \
3676 return toBool(expr1) OP b; \
3684 #undef FAD_BOOL_MACRO
3690 namespace ELRCacheFad {
3692 template <
typename ExprT>
3693 std::ostream& operator << (std::ostream& os, const Expr<ExprT>&
x) {
3694 os <<
x.val() <<
" [";
3696 for (
int i=0;
i<
x.size();
i++) {
3697 os <<
" " <<
x.dx(
i);
3708 #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