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