52 #ifndef SACADO_ELRCACHEFAD_OPS_HPP 
   53 #define SACADO_ELRCACHEFAD_OPS_HPP 
   62   namespace ELRCacheFad {
 
   68     template <
typename ExprT>
 
   71     template <
typename ExprT>
 
   80       static const int num_args = ExprT::num_args;
 
   82       static const bool is_linear = 
true;
 
   85       explicit Expr(
const ExprT& expr_) : expr(expr_)  {}
 
   88       int size()
 const { 
return expr.size(); }
 
   92       bool isActive()
 const { 
return expr.template isActive<Arg>(); }
 
  110         expr.computePartials(bar, partials);
 
  115         expr.getTangents(i, dots); }
 
  119         return expr.template getTangent<Arg>(i);
 
  124         return expr.isLinear();
 
  129         return expr.hasFastAccess();
 
  139         return expr.fastAccessDx(i);
 
  144         return expr.getDx(j);
 
  152     template <
typename T>
 
  165     template <
typename ExprT>
 
  168     template <
typename ExprT>
 
  177       static const int num_args = ExprT::num_args;
 
  179       static const bool is_linear = 
true;
 
  182       explicit Expr(
const ExprT& expr_) : expr(expr_)  {}
 
  185       int size()
 const { 
return expr.size(); }
 
  189       bool isActive()
 const { 
return expr.template isActive<Arg>(); }
 
  207         expr.computePartials(-bar, partials);
 
  212         expr.getTangents(i, dots); }
 
  217         return expr.template getTangent<Arg>(i);
 
  222         return expr.isLinear();
 
  227         return expr.hasFastAccess();
 
  237         return -expr.fastAccessDx(i);
 
  242         return expr.getDx(j);
 
  250     template <
typename T>
 
  264     template <
typename ExprT>
 
  267     template <
typename ExprT>
 
  276       static const int num_args = ExprT::num_args;
 
  278       static const bool is_linear = 
false;
 
  281       explicit Expr(
const ExprT& expr_) : expr(expr_)  {}
 
  284       int size()
 const { 
return expr.size(); }
 
  288       bool isActive()
 const { 
return expr.template isActive<Arg>(); }
 
  309           expr.computePartials(bar, partials);
 
  311           expr.computePartials(-bar, partials);
 
  316         expr.getTangents(i, dots); }
 
  321         return expr.template getTangent<Arg>(i);
 
  331         return expr.hasFastAccess();
 
  336         if (v_pos) 
return expr.dx(i);
 
  337         else return -expr.dx(i);
 
  342         if (v_pos) 
return expr.fastAccessDx(i);
 
  343         else return -expr.fastAccessDx(i);
 
  348         return expr.getDx(j);
 
  358     template <
typename T>
 
  372     template <
typename ExprT>
 
  375     template <
typename ExprT>
 
  384       static const int num_args = ExprT::num_args;
 
  386       static const bool is_linear = 
false;
 
  389       explicit Expr(
const ExprT& expr_) : expr(expr_)  {}
 
  392       int size()
 const { 
return expr.size(); }
 
  396       bool isActive()
 const { 
return expr.template isActive<Arg>(); }
 
  417           expr.computePartials(bar, partials);
 
  419           expr.computePartials(-bar, partials);
 
  424         expr.getTangents(i, dots); }
 
  429         return expr.template getTangent<Arg>(i);
 
  439         return expr.hasFastAccess();
 
  444         if (v_pos) 
return expr.dx(i);
 
  445         else return -expr.dx(i);
 
  450         if (v_pos) 
return expr.fastAccessDx(i);
 
  451         else return -expr.fastAccessDx(i);
 
  456         return expr.getDx(j);
 
  466     template <
typename T>
 
  479 #define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE)                      \ 
  481   namespace ELRCacheFad {                                               \ 
  483     template <typename ExprT>                                           \ 
  486     template <typename ExprT>                                           \ 
  487     class Expr< OP<ExprT> > {                                           \ 
  490       typedef typename ExprT::value_type value_type;                    \ 
  491       typedef typename ExprT::scalar_type scalar_type;                  \ 
  493       typedef typename ExprT::base_expr_type base_expr_type;            \ 
  495       static const int num_args = ExprT::num_args;                      \ 
  497       static const bool is_linear = false;                              \ 
  499       KOKKOS_INLINE_FUNCTION                                            \ 
  500       explicit 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)),
 
  602                   a = (v == value_type(0.0) ? value_type(0.0) : value_type(scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)))),
 
  614                   a = scalar_type(1.0)+std::tan(v)*std::tan(v),
 
  618                   a = scalar_type(-1.0)/std::sqrt(scalar_type(1.0)-v*v),
 
  622                   a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)-v*v),
 
  626                   a = scalar_type(1.0)/(scalar_type(1.0)+v*v),
 
  638                   a = scalar_type(1.0)-std::tanh(v)*std::tanh(v),
 
  642                   a = scalar_type(1.0)/std::sqrt((v-scalar_type(1.0))*(v+scalar_type(1.0))),
 
  646                   a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)+v*v),
 
  650                   a = scalar_type(1.0)/(scalar_type(1.0)-v*v),
 
  652 #ifdef HAVE_SACADO_CXX11 
  655                   a = scalar_type(1.0)/(scalar_type(3.0)*
std::cbrt(v*v)),
 
  659 #undef FAD_UNARYOP_MACRO 
  665   namespace ELRCacheFad {
 
  671     template <
typename ExprT1, 
typename ExprT2>
 
  674     template <
typename ExprT1, 
typename ExprT2>
 
  675     class Expr< AdditionOp<ExprT1,ExprT2> > {
 
  679       typedef typename ExprT1::value_type value_type_1;
 
  680       typedef typename ExprT2::value_type value_type_2;
 
  682                                        value_type_2>::type value_type;
 
  683       typedef typename ExprT1::scalar_type scalar_type_1;
 
  684       typedef typename ExprT2::scalar_type scalar_type_2;
 
  686                                        scalar_type_2>::type scalar_type;
 
  688       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
  689       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
  691                                        base_expr_type_2>::type base_expr_type;
 
  693       static const int num_args1 = ExprT1::num_args;
 
  694       static const int num_args2 = ExprT2::num_args;
 
  695       static const int num_args = num_args1 + num_args2;
 
  697       static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
 
  700       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
  701         expr1(expr1_), expr2(expr2_) {}
 
  705         int sz1 = expr1.size(), sz2 = expr2.size();
 
  706         return sz1 > sz2 ? sz1 : sz2;
 
  711       bool isActive()
 const {
 
  713           return expr1.template isActive<Arg>();
 
  715           return expr2.template isActive<Arg-num_args1>();
 
  719       bool updateValue()
 const {
 
  720         return expr1.updateValue() && expr2.updateValue();
 
  730       value_type 
val()
 const {
 
  731         return expr1.val()+expr2.val();
 
  735       void computePartials(
const value_type& 
bar,
 
  736                            value_type partials[])
 const {
 
  738           expr1.computePartials(bar, partials);
 
  740           expr2.computePartials(bar, partials+num_args1);
 
  744       void getTangents(
int i, value_type dots[])
 const {
 
  745         expr1.getTangents(i, dots);
 
  746         expr2.getTangents(i, dots+num_args1);
 
  751       value_type getTangent(
int i)
 const {
 
  753           return expr1.template getTangent<Arg>(i);
 
  755           return expr2.template getTangent<Arg-num_args1>(i);
 
  759       bool isLinear()
 const {
 
  760         return expr1.isLinear() && expr2.isLinear();
 
  764       bool hasFastAccess()
 const {
 
  765         return expr1.hasFastAccess() && expr2.hasFastAccess();
 
  769       const value_type 
dx(
int i)
 const {
 
  770         return expr1.dx(i) + expr2.dx(i);
 
  775         return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
 
  779       const value_type* getDx(
int j)
 const {
 
  781           return expr1.getDx(j);
 
  783           return expr2.getDx(j-num_args1);
 
  793     template <
typename ExprT1, 
typename T2>
 
  794     class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
 
  798       typedef ConstExpr<T2> ExprT2;
 
  799       typedef typename ExprT1::value_type value_type_1;
 
  800       typedef typename ExprT2::value_type value_type_2;
 
  802                                        value_type_2>::type value_type;
 
  803       typedef typename ExprT1::scalar_type scalar_type_1;
 
  804       typedef typename ExprT2::scalar_type scalar_type_2;
 
  806                                        scalar_type_2>::type scalar_type;
 
  808       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
  809       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
  811                                        base_expr_type_2>::type base_expr_type;
 
  813       static const int num_args = ExprT1::num_args;
 
  815       static const bool is_linear = ExprT1::is_linear;
 
  818       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
  819         expr1(expr1_), expr2(expr2_) {}
 
  828       bool isActive()
 const {
 
  829         return expr1.template isActive<Arg>();
 
  833       bool updateValue()
 const {
 
  834         return expr1.updateValue();
 
  843       value_type 
val()
 const {
 
  844         return expr1.val() + expr2.val();
 
  848       void computePartials(
const value_type& 
bar,
 
  849                            value_type partials[])
 const {
 
  850         expr1.computePartials(bar, partials);
 
  854       void getTangents(
int i, value_type dots[])
 const {
 
  855         expr1.getTangents(i, dots);
 
  860       value_type getTangent(
int i)
 const {
 
  861         return expr1.template getTangent<Arg>(i);
 
  865       bool isLinear()
 const {
 
  866         return expr1.isLinear();
 
  870       bool hasFastAccess()
 const {
 
  871         return expr1.hasFastAccess();
 
  875       const value_type 
dx(
int i)
 const {
 
  881         return expr1.fastAccessDx(i);
 
  885       const value_type* getDx(
int j)
 const {
 
  886         return expr1.getDx(j);
 
  896     template <
typename T1, 
typename ExprT2>
 
  897     class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
 
  901       typedef ConstExpr<T1> ExprT1;
 
  902       typedef typename ExprT1::value_type value_type_1;
 
  903       typedef typename ExprT2::value_type value_type_2;
 
  905                                        value_type_2>::type value_type;
 
  906       typedef typename ExprT1::scalar_type scalar_type_1;
 
  907       typedef typename ExprT2::scalar_type scalar_type_2;
 
  909                                        scalar_type_2>::type scalar_type;
 
  911       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
  912       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
  914                                        base_expr_type_2>::type base_expr_type;
 
  916       static const int num_args = ExprT2::num_args;
 
  918       static const bool is_linear = ExprT2::is_linear;
 
  921       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
  922         expr1(expr1_), expr2(expr2_) {}
 
  931       bool isActive()
 const {
 
  932         return expr2.template isActive<Arg>();
 
  936       bool updateValue()
 const {
 
  937         return expr2.updateValue();
 
  946       value_type 
val()
 const {
 
  947         return expr1.val() + expr2.val();
 
  951       void computePartials(
const value_type& 
bar,
 
  952                            value_type partials[])
 const {
 
  953         expr2.computePartials(bar, partials);
 
  957       void getTangents(
int i, value_type dots[])
 const {
 
  958         expr2.getTangents(i, dots);
 
  963       value_type getTangent(
int i)
 const {
 
  964         return expr2.template getTangent<Arg>(i);
 
  968       bool isLinear()
 const {
 
  969         return expr2.isLinear();
 
  973       bool hasFastAccess()
 const {
 
  974         return expr2.hasFastAccess();
 
  978       const value_type 
dx(
int i)
 const {
 
  984         return expr2.fastAccessDx(i);
 
  988       const value_type* getDx(
int j)
 const {
 
  989         return expr2.getDx(j);
 
 1003     template <
typename ExprT1, 
typename ExprT2>
 
 1006     template <
typename ExprT1, 
typename ExprT2>
 
 1007     class Expr< SubtractionOp<ExprT1,ExprT2> > {
 
 1011       typedef typename ExprT1::value_type value_type_1;
 
 1012       typedef typename ExprT2::value_type value_type_2;
 
 1014                                        value_type_2>::type value_type;
 
 1015       typedef typename ExprT1::scalar_type scalar_type_1;
 
 1016       typedef typename ExprT2::scalar_type scalar_type_2;
 
 1018                                        scalar_type_2>::type scalar_type;
 
 1020       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 1021       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 1023                                        base_expr_type_2>::type base_expr_type;
 
 1025       static const int num_args1 = ExprT1::num_args;
 
 1026       static const int num_args2 = ExprT2::num_args;
 
 1027       static const int num_args = num_args1 + num_args2;
 
 1029       static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
 
 1032       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 1033         expr1(expr1_), expr2(expr2_) {}
 
 1037         int sz1 = expr1.size(), sz2 = expr2.size();
 
 1038         return sz1 > sz2 ? sz1 : sz2;
 
 1043       bool isActive()
 const {
 
 1044         if (Arg < num_args1)
 
 1045           return expr1.template isActive<Arg>();
 
 1047           return expr2.template isActive<Arg-num_args1>();
 
 1051       bool updateValue()
 const {
 
 1052         return expr1.updateValue() && expr2.updateValue();
 
 1056       void cache()
 const {
 
 1062       value_type 
val()
 const {
 
 1063         return expr1.val()-expr2.val();
 
 1067       void computePartials(
const value_type& 
bar,
 
 1068                            value_type partials[])
 const {
 
 1070           expr1.computePartials(bar, partials);
 
 1072           expr2.computePartials(-bar, partials+num_args1);
 
 1076       void getTangents(
int i, value_type dots[])
 const {
 
 1077         expr1.getTangents(i, dots);
 
 1078         expr2.getTangents(i, dots+num_args1);
 
 1083       value_type getTangent(
int i)
 const {
 
 1084         if (Arg < num_args1)
 
 1085           return expr1.template getTangent<Arg>(i);
 
 1087           return expr2.template getTangent<Arg-num_args1>(i);
 
 1091       bool isLinear()
 const {
 
 1092         return expr1.isLinear() && expr2.isLinear();
 
 1096       bool hasFastAccess()
 const {
 
 1097         return expr1.hasFastAccess() && expr2.hasFastAccess();
 
 1101       const value_type 
dx(
int i)
 const {
 
 1102         return expr1.dx(i) - expr2.dx(i);
 
 1107         return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
 
 1111       const value_type* getDx(
int j)
 const {
 
 1113           return expr1.getDx(j);
 
 1115           return expr2.getDx(j-num_args1);
 
 1120       const ExprT1& expr1;
 
 1121       const ExprT2& expr2;
 
 1125     template <
typename ExprT1, 
typename T2>
 
 1126     class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
 
 1130       typedef ConstExpr<T2> ExprT2;
 
 1131       typedef typename ExprT1::value_type value_type_1;
 
 1132       typedef typename ExprT2::value_type value_type_2;
 
 1134                                        value_type_2>::type value_type;
 
 1135       typedef typename ExprT1::scalar_type scalar_type_1;
 
 1136       typedef typename ExprT2::scalar_type scalar_type_2;
 
 1138                                        scalar_type_2>::type scalar_type;
 
 1140       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 1141       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 1143                                        base_expr_type_2>::type base_expr_type;
 
 1145       static const int num_args = ExprT1::num_args;
 
 1147       static const bool is_linear = ExprT1::is_linear;
 
 1150       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 1151         expr1(expr1_), expr2(expr2_) {}
 
 1155         return expr1.size();
 
 1160       bool isActive()
 const {
 
 1161         return expr1.template isActive<Arg>();
 
 1165       bool updateValue()
 const {
 
 1166         return expr1.updateValue();
 
 1170       void cache()
 const {
 
 1175       value_type 
val()
 const {
 
 1176         return expr1.val() - expr2.val();
 
 1180       void computePartials(
const value_type& 
bar,
 
 1181                            value_type partials[])
 const {
 
 1182         expr1.computePartials(bar, partials);
 
 1186       void getTangents(
int i, value_type dots[])
 const {
 
 1187         expr1.getTangents(i, dots);
 
 1192       value_type getTangent(
int i)
 const {
 
 1193         return expr1.template getTangent<Arg>(i);
 
 1197       bool isLinear()
 const {
 
 1198         return expr1.isLinear();
 
 1202       bool hasFastAccess()
 const {
 
 1203         return expr1.hasFastAccess();
 
 1207       const value_type 
dx(
int i)
 const {
 
 1213         return expr1.fastAccessDx(i);
 
 1217       const value_type* getDx(
int j)
 const {
 
 1218         return expr1.getDx(j);
 
 1223       const ExprT1& expr1;
 
 1228     template <
typename T1, 
typename ExprT2>
 
 1229     class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
 
 1233       typedef ConstExpr<T1> ExprT1;
 
 1234       typedef typename ExprT1::value_type value_type_1;
 
 1235       typedef typename ExprT2::value_type value_type_2;
 
 1237                                        value_type_2>::type value_type;
 
 1238       typedef typename ExprT1::scalar_type scalar_type_1;
 
 1239       typedef typename ExprT2::scalar_type scalar_type_2;
 
 1241                                        scalar_type_2>::type scalar_type;
 
 1243       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 1244       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 1246                                        base_expr_type_2>::type base_expr_type;
 
 1248       static const int num_args = ExprT2::num_args;
 
 1250       static const bool is_linear = ExprT2::is_linear;
 
 1253       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 1254         expr1(expr1_), expr2(expr2_) {}
 
 1258         return expr2.size();
 
 1263       bool isActive()
 const {
 
 1264         return expr2.template isActive<Arg>();
 
 1268       bool updateValue()
 const {
 
 1269         return expr2.updateValue();
 
 1273       void cache()
 const {
 
 1278       value_type 
val()
 const {
 
 1279         return expr1.val() - expr2.val();
 
 1283       void computePartials(
const value_type& 
bar,
 
 1284                            value_type partials[])
 const {
 
 1285         expr2.computePartials(-bar, partials);
 
 1289       void getTangents(
int i, value_type dots[])
 const {
 
 1290         expr2.getTangents(i, dots);
 
 1295       value_type getTangent(
int i)
 const {
 
 1296         return expr2.template getTangent<Arg>(i);
 
 1300       bool isLinear()
 const {
 
 1301         return expr2.isLinear();
 
 1305       bool hasFastAccess()
 const {
 
 1306         return expr2.hasFastAccess();
 
 1310       const value_type 
dx(
int i)
 const {
 
 1311         return -expr2.dx(i);
 
 1316         return -expr2.fastAccessDx(i);
 
 1320       const value_type* getDx(
int j)
 const {
 
 1321         return expr2.getDx(j);
 
 1327       const ExprT2& expr2;
 
 1335     template <
typename ExprT1, 
typename ExprT2>
 
 1338     template <
typename ExprT1, 
typename ExprT2>
 
 1339     class Expr< MultiplicationOp<ExprT1,ExprT2> > {
 
 1343       typedef typename ExprT1::value_type value_type_1;
 
 1344       typedef typename ExprT2::value_type value_type_2;
 
 1346                                        value_type_2>::type value_type;
 
 1347       typedef typename ExprT1::scalar_type scalar_type_1;
 
 1348       typedef typename ExprT2::scalar_type scalar_type_2;
 
 1350                                        scalar_type_2>::type scalar_type;
 
 1352       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 1353       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 1355                                        base_expr_type_2>::type base_expr_type;
 
 1357       static const int num_args1 = ExprT1::num_args;
 
 1358       static const int num_args2 = ExprT2::num_args;
 
 1359       static const int num_args = num_args1 + num_args2;
 
 1361       static const bool is_linear = 
false;
 
 1364       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 1365         expr1(expr1_), expr2(expr2_) {}
 
 1369         int sz1 = expr1.size(), sz2 = expr2.size();
 
 1370         return sz1 > sz2 ? sz1 : sz2;
 
 1375       bool isActive()
 const {
 
 1376         if (Arg < num_args1)
 
 1377           return expr1.template isActive<Arg>();
 
 1379           return expr2.template isActive<Arg-num_args1>();
 
 1383       bool updateValue()
 const {
 
 1384         return expr1.updateValue() && expr2.updateValue();
 
 1388       void cache()
 const {
 
 1396       value_type 
val()
 const {
 
 1401       void computePartials(
const value_type& 
bar,
 
 1402                            value_type partials[])
 const {
 
 1404           expr1.computePartials(bar*v2, partials);
 
 1406           expr2.computePartials(bar*v1, partials+num_args1);
 
 1410       void getTangents(
int i, value_type dots[])
 const {
 
 1411         expr1.getTangents(i, dots);
 
 1412         expr2.getTangents(i, dots+num_args1);
 
 1417       value_type getTangent(
int i)
 const {
 
 1418         if (Arg < num_args1)
 
 1419           return expr1.template getTangent<Arg>(i);
 
 1421           return expr2.template getTangent<Arg-num_args1>(i);
 
 1425       bool isLinear()
 const {
 
 1430       bool hasFastAccess()
 const {
 
 1431         return expr1.hasFastAccess() && expr2.hasFastAccess();
 
 1435       const value_type 
dx(
int i)
 const {
 
 1436         if (expr1.size() > 0 && expr2.size() > 0)
 
 1437           return v1*expr2.dx(i) + expr1.dx(i)*v2;
 
 1438         else if (expr1.size() > 0)
 
 1439           return expr1.dx(i)*v2;
 
 1441           return v1*expr2.dx(i);
 
 1446         return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
 
 1450       const value_type* getDx(
int j)
 const {
 
 1452           return expr1.getDx(j);
 
 1454           return expr2.getDx(j-num_args1);
 
 1459       const ExprT1& expr1;
 
 1460       const ExprT2& expr2;
 
 1461       mutable value_type_1 v1;
 
 1462       mutable value_type_2 v2;
 
 1466     template <
typename ExprT1, 
typename T2>
 
 1467     class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
 
 1471       typedef ConstExpr<T2> ExprT2;
 
 1472       typedef typename ExprT1::value_type value_type_1;
 
 1473       typedef typename ExprT2::value_type value_type_2;
 
 1475                                        value_type_2>::type value_type;
 
 1476       typedef typename ExprT1::scalar_type scalar_type_1;
 
 1477       typedef typename ExprT2::scalar_type scalar_type_2;
 
 1479                                        scalar_type_2>::type scalar_type;
 
 1481       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 1482       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 1484                                        base_expr_type_2>::type base_expr_type;
 
 1486       static const int num_args = ExprT1::num_args;
 
 1488       static const bool is_linear = ExprT1::is_linear;
 
 1491       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 1492         expr1(expr1_), expr2(expr2_) {}
 
 1496         return expr1.size();
 
 1501       bool isActive()
 const {
 
 1502         return expr1.template isActive<Arg>();
 
 1506       bool updateValue()
 const {
 
 1507         return expr1.updateValue();
 
 1511       void cache()
 const {
 
 1516       value_type 
val()
 const {
 
 1517         return expr1.val()*expr2.val();
 
 1521       void computePartials(
const value_type& 
bar,
 
 1522                            value_type partials[])
 const {
 
 1523         expr1.computePartials(bar*expr2.val(), partials);
 
 1527       void getTangents(
int i, value_type dots[])
 const {
 
 1528         expr1.getTangents(i, dots);
 
 1533       value_type getTangent(
int i)
 const {
 
 1534         return expr1.template getTangent<Arg>(i);
 
 1538       bool isLinear()
 const {
 
 1539         return expr1.isLinear();
 
 1543       bool hasFastAccess()
 const {
 
 1544         return expr1.hasFastAccess();
 
 1548       const value_type 
dx(
int i)
 const {
 
 1549         return expr1.dx(i)*expr2.val();
 
 1554         return expr1.fastAccessDx(i)*expr2.val();
 
 1558       const value_type* getDx(
int j)
 const {
 
 1559         return expr1.getDx(j);
 
 1564       const ExprT1& expr1;
 
 1569     template <
typename T1, 
typename ExprT2>
 
 1570     class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
 
 1574       typedef ConstExpr<T1> ExprT1;
 
 1575       typedef typename ExprT1::value_type value_type_1;
 
 1576       typedef typename ExprT2::value_type value_type_2;
 
 1578                                        value_type_2>::type value_type;
 
 1579       typedef typename ExprT1::scalar_type scalar_type_1;
 
 1580       typedef typename ExprT2::scalar_type scalar_type_2;
 
 1582                                        scalar_type_2>::type scalar_type;
 
 1584       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 1585       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 1587                                        base_expr_type_2>::type base_expr_type;
 
 1589       static const int num_args = ExprT2::num_args;
 
 1591       static const bool is_linear = ExprT2::is_linear;
 
 1594       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 1595         expr1(expr1_), expr2(expr2_) {}
 
 1599         return expr2.size();
 
 1604       bool isActive()
 const {
 
 1605         return expr2.template isActive<Arg>();
 
 1609       bool updateValue()
 const {
 
 1610         return expr2.updateValue();
 
 1614       void cache()
 const {
 
 1619       value_type 
val()
 const {
 
 1620         return expr1.val()*expr2.val();
 
 1624       void computePartials(
const value_type& 
bar,
 
 1625                            value_type partials[])
 const {
 
 1626         expr2.computePartials(bar*expr1.val(), partials);
 
 1630       void getTangents(
int i, value_type dots[])
 const {
 
 1631         expr2.getTangents(i, dots);
 
 1636       value_type getTangent(
int i)
 const {
 
 1637         return expr2.template getTangent<Arg>(i);
 
 1641       bool isLinear()
 const {
 
 1642         return expr2.isLinear();
 
 1646       bool hasFastAccess()
 const {
 
 1647         return expr2.hasFastAccess();
 
 1651       const value_type 
dx(
int i)
 const {
 
 1652         return expr1.val()*expr2.dx(i);
 
 1657         return expr1.val()*expr2.fastAccessDx(i);
 
 1661       const value_type* getDx(
int j)
 const {
 
 1662         return expr2.getDx(j);
 
 1668       const ExprT2& expr2;
 
 1676     template <
typename ExprT1, 
typename ExprT2>
 
 1679     template <
typename ExprT1, 
typename ExprT2>
 
 1680     class Expr< DivisionOp<ExprT1,ExprT2> > {
 
 1684       typedef typename ExprT1::value_type value_type_1;
 
 1685       typedef typename ExprT2::value_type value_type_2;
 
 1687                                        value_type_2>::type value_type;
 
 1688       typedef typename ExprT1::scalar_type scalar_type_1;
 
 1689       typedef typename ExprT2::scalar_type scalar_type_2;
 
 1691                                        scalar_type_2>::type scalar_type;
 
 1693       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 1694       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 1696                                        base_expr_type_2>::type base_expr_type;
 
 1698       static const int num_args1 = ExprT1::num_args;
 
 1699       static const int num_args2 = ExprT2::num_args;
 
 1700       static const int num_args = num_args1 + num_args2;
 
 1702       static const bool is_linear = 
false;
 
 1705       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 1706         expr1(expr1_), expr2(expr2_) {}
 
 1710         int sz1 = expr1.size(), sz2 = expr2.size();
 
 1711         return sz1 > sz2 ? sz1 : sz2;
 
 1716       bool isActive()
 const {
 
 1717         if (Arg < num_args1)
 
 1718           return expr1.template isActive<Arg>();
 
 1720           return expr2.template isActive<Arg-num_args1>();
 
 1724       bool updateValue()
 const {
 
 1725         return expr1.updateValue() && expr2.updateValue();
 
 1729       void cache()
 const {
 
 1732         const value_type_1 v1 = expr1.val();
 
 1733         const value_type_2 v2 = expr2.val();
 
 1734         a = scalar_type(1.0)/v2;
 
 1740       value_type 
val()
 const {
 
 1745       void computePartials(
const value_type& 
bar,
 
 1746                            value_type partials[])
 const {
 
 1748           expr1.computePartials(bar*
a, partials);
 
 1750           expr2.computePartials(bar*b, partials+num_args1);
 
 1754       void getTangents(
int i, value_type dots[])
 const {
 
 1755         expr1.getTangents(i, dots);
 
 1756         expr2.getTangents(i, dots+num_args1);
 
 1761       value_type getTangent(
int i)
 const {
 
 1762         if (Arg < num_args1)
 
 1763           return expr1.template getTangent<Arg>(i);
 
 1765           return expr2.template getTangent<Arg-num_args1>(i);
 
 1769       bool isLinear()
 const {
 
 1774       bool hasFastAccess()
 const {
 
 1775         return expr1.hasFastAccess() && expr2.hasFastAccess();
 
 1779       const value_type 
dx(
int i)
 const {
 
 1780         if (expr1.size() > 0 && expr2.size() > 0)
 
 1781           return expr1.dx(i)*
a + expr2.dx(i)*b;
 
 1782         else if (expr1.size() > 0)
 
 1783           return expr1.dx(i)*
a;
 
 1785           return expr1.val()*b;
 
 1790         return  expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
 
 1794       const value_type* getDx(
int j)
 const {
 
 1796           return expr1.getDx(j);
 
 1798           return expr2.getDx(j-num_args1);
 
 1803       const ExprT1& expr1;
 
 1804       const ExprT2& expr2;
 
 1805       mutable value_type v;
 
 1806       mutable value_type 
a;
 
 1807       mutable value_type b;
 
 1811     template <
typename ExprT1, 
typename T2>
 
 1812     class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
 
 1816       typedef ConstExpr<T2> ExprT2;
 
 1817       typedef typename ExprT1::value_type value_type_1;
 
 1818       typedef typename ExprT2::value_type value_type_2;
 
 1820                                        value_type_2>::type value_type;
 
 1821       typedef typename ExprT1::scalar_type scalar_type_1;
 
 1822       typedef typename ExprT2::scalar_type scalar_type_2;
 
 1824                                        scalar_type_2>::type scalar_type;
 
 1826       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 1827       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 1829                                        base_expr_type_2>::type base_expr_type;
 
 1831       static const int num_args = ExprT1::num_args;
 
 1833       static const bool is_linear = ExprT1::is_linear;
 
 1836       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 1837         expr1(expr1_), expr2(expr2_) {}
 
 1841         return expr1.size();
 
 1846       bool isActive()
 const {
 
 1847         return expr1.template isActive<Arg>();
 
 1851       bool updateValue()
 const {
 
 1852         return expr1.updateValue();
 
 1856       void cache()
 const {
 
 1858         const value_type_1 v1 = expr1.val();
 
 1859         a = scalar_type(1.0)/expr2.val();
 
 1864       value_type 
val()
 const {
 
 1869       void computePartials(
const value_type& 
bar,
 
 1870                            value_type partials[])
 const {
 
 1871         expr1.computePartials(bar*
a, partials);
 
 1875       void getTangents(
int i, value_type dots[])
 const {
 
 1876         expr1.getTangents(i, dots);
 
 1881       value_type getTangent(
int i)
 const {
 
 1882         return expr1.template getTangent<Arg>(i);
 
 1886       bool isLinear()
 const {
 
 1887         return expr1.isLinear();
 
 1891       bool hasFastAccess()
 const {
 
 1892         return expr1.hasFastAccess();
 
 1896       const value_type 
dx(
int i)
 const {
 
 1897         return expr1.dx(i)*
a;
 
 1902         return expr1.fastAccessDx(i)*
a;
 
 1906       const value_type* getDx(
int j)
 const {
 
 1907         return expr1.getDx(j);
 
 1912       const ExprT1& expr1;
 
 1914       mutable value_type v;
 
 1915       mutable value_type 
a;
 
 1919     template <
typename T1, 
typename ExprT2>
 
 1920     class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
 
 1924       typedef ConstExpr<T1> ExprT1;
 
 1925       typedef typename ExprT1::value_type value_type_1;
 
 1926       typedef typename ExprT2::value_type value_type_2;
 
 1928                                        value_type_2>::type value_type;
 
 1929       typedef typename ExprT1::scalar_type scalar_type_1;
 
 1930       typedef typename ExprT2::scalar_type scalar_type_2;
 
 1932                                        scalar_type_2>::type scalar_type;
 
 1934       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 1935       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 1937                                        base_expr_type_2>::type base_expr_type;
 
 1939       static const int num_args = ExprT2::num_args;
 
 1941       static const bool is_linear = 
false;
 
 1944       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 1945         expr1(expr1_), expr2(expr2_) {}
 
 1949         return expr2.size();
 
 1954       bool isActive()
 const {
 
 1955         return expr2.template isActive<Arg>();
 
 1959       bool updateValue()
 const {
 
 1960         return expr2.updateValue();
 
 1964       void cache()
 const {
 
 1966         const value_type_2 v2 = expr2.val();
 
 1972       value_type 
val()
 const {
 
 1977       void computePartials(
const value_type& 
bar,
 
 1978                            value_type partials[])
 const {
 
 1979         expr2.computePartials(bar*b, partials);
 
 1983       void getTangents(
int i, value_type dots[])
 const {
 
 1984         expr2.getTangents(i, dots);
 
 1989       value_type getTangent(
int i)
 const {
 
 1990         return expr2.template getTangent<Arg>(i);
 
 1994       bool isLinear()
 const {
 
 1999       bool hasFastAccess()
 const {
 
 2000         return expr2.hasFastAccess();
 
 2004       const value_type 
dx(
int i)
 const {
 
 2005         return expr2.dx(i)*b;
 
 2010         return expr2.fastAccessDx(i)*b;
 
 2014       const value_type* getDx(
int j)
 const {
 
 2015         return expr2.getDx(j);
 
 2021       const ExprT2& expr2;
 
 2022       mutable value_type v;
 
 2023       mutable value_type b;
 
 2031     template <
typename ExprT1, 
typename ExprT2>
 
 2034     template <
typename ExprT1, 
typename ExprT2>
 
 2035     class Expr< Atan2Op<ExprT1,ExprT2> > {
 
 2039       typedef typename ExprT1::value_type value_type_1;
 
 2040       typedef typename ExprT2::value_type value_type_2;
 
 2042                                        value_type_2>::type value_type;
 
 2043       typedef typename ExprT1::scalar_type scalar_type_1;
 
 2044       typedef typename ExprT2::scalar_type scalar_type_2;
 
 2046                                        scalar_type_2>::type scalar_type;
 
 2048       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 2049       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 2051                                        base_expr_type_2>::type base_expr_type;
 
 2053       static const int num_args1 = ExprT1::num_args;
 
 2054       static const int num_args2 = ExprT2::num_args;
 
 2055       static const int num_args = num_args1 + num_args2;
 
 2057       static const bool is_linear = 
false;
 
 2060       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 2061         expr1(expr1_), expr2(expr2_) {}
 
 2065         int sz1 = expr1.size(), sz2 = expr2.size();
 
 2066         return sz1 > sz2 ? sz1 : sz2;
 
 2071       bool isActive()
 const {
 
 2072         if (Arg < num_args1)
 
 2073           return expr1.template isActive<Arg>();
 
 2075           return expr2.template isActive<Arg-num_args1>();
 
 2079       bool updateValue()
 const {
 
 2080         return expr1.updateValue() && expr2.updateValue();
 
 2084       void cache()
 const {
 
 2087         const value_type_1 v1 = expr1.val();
 
 2088         const value_type_2 v2 = expr2.val();
 
 2089         a = scalar_type(1.0)/(v1*v1 + v2*v2);
 
 2096       value_type 
val()
 const {
 
 2101       void computePartials(
const value_type& 
bar,
 
 2102                            value_type partials[])
 const {
 
 2104           expr1.computePartials(bar*
a, partials);
 
 2106           expr2.computePartials(bar*b, partials+num_args1);
 
 2110       void getTangents(
int i, value_type dots[])
 const {
 
 2111         expr1.getTangents(i, dots);
 
 2112         expr2.getTangents(i, dots+num_args1);
 
 2117       value_type getTangent(
int i)
 const {
 
 2118         if (Arg < num_args1)
 
 2119           return expr1.template getTangent<Arg>(i);
 
 2121           return expr2.template getTangent<Arg-num_args1>(i);
 
 2125       bool isLinear()
 const {
 
 2130       bool hasFastAccess()
 const {
 
 2131         return expr1.hasFastAccess() && expr2.hasFastAccess();
 
 2135       const value_type 
dx(
int i)
 const {
 
 2136         if (expr1.size() > 0 && expr2.size() > 0)
 
 2137           return expr1.dx(i)*
a + expr2.dx(i)*b;
 
 2138         else if (expr1.size() > 0)
 
 2139           return expr1.dx(i)*
a;
 
 2141           return expr1.val()*b;
 
 2146         return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
 
 2150       const value_type* getDx(
int j)
 const {
 
 2152           return expr1.getDx(j);
 
 2154           return expr2.getDx(j-num_args1);
 
 2159       const ExprT1& expr1;
 
 2160       const ExprT2& expr2;
 
 2161       mutable value_type v;
 
 2162       mutable value_type 
a;
 
 2163       mutable value_type b;
 
 2167     template <
typename ExprT1, 
typename T2>
 
 2168     class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
 
 2172       typedef ConstExpr<T2> ExprT2;
 
 2173       typedef typename ExprT1::value_type value_type_1;
 
 2174       typedef typename ExprT2::value_type value_type_2;
 
 2176                                        value_type_2>::type value_type;
 
 2177       typedef typename ExprT1::scalar_type scalar_type_1;
 
 2178       typedef typename ExprT2::scalar_type scalar_type_2;
 
 2180                                        scalar_type_2>::type scalar_type;
 
 2182       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 2183       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 2185                                        base_expr_type_2>::type base_expr_type;
 
 2187       static const int num_args = ExprT1::num_args;
 
 2189       static const bool is_linear = 
false;
 
 2192       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 2193         expr1(expr1_), expr2(expr2_) {}
 
 2197         return expr1.size();
 
 2202       bool isActive()
 const {
 
 2203         return expr1.template isActive<Arg>();
 
 2207       bool updateValue()
 const {
 
 2208         return expr1.updateValue();
 
 2212       void cache()
 const {
 
 2214         const value_type_1 v1 = expr1.val();
 
 2215         const value_type_2 v2 = expr2.val();
 
 2216         a = v2/(v1*v1 + v2*v2);
 
 2221       value_type 
val()
 const {
 
 2226       void computePartials(
const value_type& 
bar,
 
 2227                            value_type partials[])
 const {
 
 2228         expr1.computePartials(bar*
a, partials);
 
 2232       void getTangents(
int i, value_type dots[])
 const {
 
 2233         expr1.getTangents(i, dots);
 
 2238       value_type getTangent(
int i)
 const {
 
 2239         return expr1.template getTangent<Arg>(i);
 
 2243       bool isLinear()
 const {
 
 2248       bool hasFastAccess()
 const {
 
 2249         return expr1.hasFastAccess();
 
 2253       const value_type 
dx(
int i)
 const {
 
 2254         return expr1.dx(i)*
a;
 
 2259         return expr1.fastAccessDx(i)*
a;
 
 2263       const value_type* getDx(
int j)
 const {
 
 2264         return expr1.getDx(j);
 
 2269       const ExprT1& expr1;
 
 2271       mutable value_type v;
 
 2272       mutable value_type 
a;
 
 2276     template <
typename T1, 
typename ExprT2>
 
 2277     class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
 
 2281       typedef ConstExpr<T1> ExprT1;
 
 2282       typedef typename ExprT1::value_type value_type_1;
 
 2283       typedef typename ExprT2::value_type value_type_2;
 
 2285                                        value_type_2>::type value_type;
 
 2286       typedef typename ExprT1::scalar_type scalar_type_1;
 
 2287       typedef typename ExprT2::scalar_type scalar_type_2;
 
 2289                                        scalar_type_2>::type scalar_type;
 
 2291       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 2292       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 2294                                        base_expr_type_2>::type base_expr_type;
 
 2296       static const int num_args = ExprT2::num_args;
 
 2298       static const bool is_linear = 
false;
 
 2301       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 2302         expr1(expr1_), expr2(expr2_) {}
 
 2306         return expr2.size();
 
 2311       bool isActive()
 const {
 
 2312         return expr2.template isActive<Arg>();
 
 2316       bool updateValue()
 const {
 
 2317         return expr2.updateValue();
 
 2321       void cache()
 const {
 
 2323         const value_type_1 v1 = expr1.val();
 
 2324         const value_type_2 v2 = expr2.val();
 
 2325         b = -v1/(v1*v1 + v2*v2);
 
 2330       value_type 
val()
 const {
 
 2335       void computePartials(
const value_type& 
bar,
 
 2336                            value_type partials[])
 const {
 
 2337         expr2.computePartials(bar*b, partials);
 
 2341       void getTangents(
int i, value_type dots[])
 const {
 
 2342         expr2.getTangents(i, dots);
 
 2347       value_type getTangent(
int i)
 const {
 
 2348         return expr2.template getTangent<Arg>(i);
 
 2352       bool isLinear()
 const {
 
 2357       bool hasFastAccess()
 const {
 
 2358         return expr2.hasFastAccess();
 
 2362       const value_type 
dx(
int i)
 const {
 
 2363         return expr2.dx(i)*b;
 
 2368         return expr2.fastAccessDx(i)*b;
 
 2372       const value_type* getDx(
int j)
 const {
 
 2373         return expr2.getDx(j);
 
 2379       const ExprT2& expr2;
 
 2380       mutable value_type v;
 
 2381       mutable value_type b;
 
 2389     template <
typename ExprT1, 
typename ExprT2>
 
 2392     template <
typename ExprT1, 
typename ExprT2>
 
 2393     class Expr< PowerOp<ExprT1,ExprT2> > {
 
 2397       typedef typename ExprT1::value_type value_type_1;
 
 2398       typedef typename ExprT2::value_type value_type_2;
 
 2400                                        value_type_2>::type value_type;
 
 2401       typedef typename ExprT1::scalar_type scalar_type_1;
 
 2402       typedef typename ExprT2::scalar_type scalar_type_2;
 
 2404                                        scalar_type_2>::type scalar_type;
 
 2406       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 2407       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 2409                                        base_expr_type_2>::type base_expr_type;
 
 2411       static const int num_args1 = ExprT1::num_args;
 
 2412       static const int num_args2 = ExprT2::num_args;
 
 2413       static const int num_args = num_args1 + num_args2;
 
 2415       static const bool is_linear = 
false;
 
 2418       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 2419         expr1(expr1_), expr2(expr2_) {}
 
 2423         int sz1 = expr1.size(), sz2 = expr2.size();
 
 2424         return sz1 > sz2 ? sz1 : sz2;
 
 2429       bool isActive()
 const {
 
 2430         if (Arg < num_args1)
 
 2431           return expr1.template isActive<Arg>();
 
 2433           return expr2.template isActive<Arg-num_args1>();
 
 2437       bool updateValue()
 const {
 
 2438         return expr1.updateValue() && expr2.updateValue();
 
 2442       void cache()
 const {
 
 2445         const value_type_1 v1 = expr1.val();
 
 2446         const value_type_2 v2 = expr2.val();
 
 2448         if (v1 == scalar_type(0.0)) {
 
 2449           a = scalar_type(0.0);
 
 2450           b = scalar_type(0.0);
 
 2459       value_type 
val()
 const {
 
 2464       void computePartials(
const value_type& 
bar,
 
 2465                            value_type partials[])
 const {
 
 2467           expr1.computePartials(bar*
a, partials);
 
 2469           expr2.computePartials(bar*b, partials+num_args1);
 
 2473       void getTangents(
int i, value_type dots[])
 const {
 
 2474         expr1.getTangents(i, dots);
 
 2475         expr2.getTangents(i, dots+num_args1);
 
 2480       value_type getTangent(
int i)
 const {
 
 2481         if (Arg < num_args1)
 
 2482           return expr1.template getTangent<Arg>(i);
 
 2484           return expr2.template getTangent<Arg-num_args1>(i);
 
 2488       bool isLinear()
 const {
 
 2493       bool hasFastAccess()
 const {
 
 2494         return expr1.hasFastAccess() && expr2.hasFastAccess();
 
 2498       const value_type 
dx(
int i)
 const {
 
 2499         if (expr1.size() > 0 && expr2.size() > 0)
 
 2500           return expr1.dx(i)*
a + expr2.dx(i)*b;
 
 2501         else if (expr1.size() > 0)
 
 2502           return expr1.dx(i)*
a;
 
 2504           return expr1.val()*b;
 
 2509         return expr1.fastAccessDx(i)*
a + expr2.fastAccessDx(i)*b;
 
 2513       const value_type* getDx(
int j)
 const {
 
 2515           return expr1.getDx(j);
 
 2517           return expr2.getDx(j-num_args1);
 
 2522       const ExprT1& expr1;
 
 2523       const ExprT2& expr2;
 
 2524       mutable value_type v;
 
 2525       mutable value_type 
a;
 
 2526       mutable value_type b;
 
 2530     template <
typename ExprT1, 
typename T2>
 
 2531     class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
 
 2535       typedef ConstExpr<T2> ExprT2;
 
 2536       typedef typename ExprT1::value_type value_type_1;
 
 2537       typedef typename ExprT2::value_type value_type_2;
 
 2539                                        value_type_2>::type value_type;
 
 2540       typedef typename ExprT1::scalar_type scalar_type_1;
 
 2541       typedef typename ExprT2::scalar_type scalar_type_2;
 
 2543                                        scalar_type_2>::type scalar_type;
 
 2545       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 2546       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 2548                                        base_expr_type_2>::type base_expr_type;
 
 2550       static const int num_args = ExprT1::num_args;
 
 2552       static const bool is_linear = 
false;
 
 2555       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 2556         expr1(expr1_), expr2(expr2_) {}
 
 2560         return expr1.size();
 
 2565       bool isActive()
 const {
 
 2566         return expr1.template isActive<Arg>();
 
 2570       bool updateValue()
 const {
 
 2571         return expr1.updateValue();
 
 2575       void cache()
 const {
 
 2577         const value_type_1 v1 = expr1.val();
 
 2578         const value_type_2 v2 = expr2.val();
 
 2580         if (v1 == scalar_type(0.0)) {
 
 2581           a = scalar_type(0.0);
 
 2589       value_type 
val()
 const {
 
 2594       void computePartials(
const value_type& 
bar,
 
 2595                            value_type partials[])
 const {
 
 2596         expr1.computePartials(bar*
a, partials);
 
 2600       void getTangents(
int i, value_type dots[])
 const {
 
 2601         expr1.getTangents(i, dots);
 
 2606       value_type getTangent(
int i)
 const {
 
 2607         return expr1.template getTangent<Arg>(i);
 
 2611       bool isLinear()
 const {
 
 2616       bool hasFastAccess()
 const {
 
 2617         return expr1.hasFastAccess();
 
 2621       const value_type 
dx(
int i)
 const {
 
 2622         return expr1.dx(i)*
a;
 
 2627         return expr1.fastAccessDx(i)*
a;
 
 2631       const value_type* getDx(
int j)
 const {
 
 2632         return expr1.getDx(j);
 
 2637       const ExprT1& expr1;
 
 2639       mutable value_type v;
 
 2640       mutable value_type 
a;
 
 2644     template <
typename T1, 
typename ExprT2>
 
 2645     class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
 
 2649       typedef ConstExpr<T1> ExprT1;
 
 2650       typedef typename ExprT1::value_type value_type_1;
 
 2651       typedef typename ExprT2::value_type value_type_2;
 
 2653                                        value_type_2>::type value_type;
 
 2654       typedef typename ExprT1::scalar_type scalar_type_1;
 
 2655       typedef typename ExprT2::scalar_type scalar_type_2;
 
 2657                                        scalar_type_2>::type scalar_type;
 
 2659       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 2660       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 2662                                        base_expr_type_2>::type base_expr_type;
 
 2664       static const int num_args = ExprT2::num_args;
 
 2666       static const bool is_linear = 
false;
 
 2669       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 2670         expr1(expr1_), expr2(expr2_) {}
 
 2674         return expr2.size();
 
 2679       bool isActive()
 const {
 
 2680         return expr2.template isActive<Arg>();
 
 2684       bool updateValue()
 const {
 
 2685         return expr2.updateValue();
 
 2689       void cache()
 const {
 
 2691         const value_type_1 v1 = expr1.val();
 
 2692         const value_type_2 v2 = expr2.val();
 
 2694         if (v1 == scalar_type(0.0)) {
 
 2695           b = scalar_type(0.0);
 
 2703       value_type 
val()
 const {
 
 2708       void computePartials(
const value_type& 
bar,
 
 2709                            value_type partials[])
 const {
 
 2710         expr2.computePartials(bar*b, partials);
 
 2714       void getTangents(
int i, value_type dots[])
 const {
 
 2715         expr2.getTangents(i, dots);
 
 2720       value_type getTangent(
int i)
 const {
 
 2721         return expr2.template getTangent<Arg>(i);
 
 2725       bool isLinear()
 const {
 
 2730       bool hasFastAccess()
 const {
 
 2731         return expr2.hasFastAccess();
 
 2735       const value_type 
dx(
int i)
 const {
 
 2736         return expr2.dx(i)*b;
 
 2741         return expr2.fastAccessDx(i)*b;
 
 2745       const value_type* getDx(
int j)
 const {
 
 2746         return expr2.getDx(j);
 
 2752       const ExprT2& expr2;
 
 2753       mutable value_type v;
 
 2754       mutable value_type b;
 
 2762     template <
typename ExprT1, 
typename ExprT2>
 
 2765     template <
typename ExprT1, 
typename ExprT2>
 
 2766     class Expr< MaxOp<ExprT1,ExprT2> > {
 
 2770       typedef typename ExprT1::value_type value_type_1;
 
 2771       typedef typename ExprT2::value_type value_type_2;
 
 2773                                        value_type_2>::type value_type;
 
 2774       typedef typename ExprT1::scalar_type scalar_type_1;
 
 2775       typedef typename ExprT2::scalar_type scalar_type_2;
 
 2777                                        scalar_type_2>::type scalar_type;
 
 2779       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 2780       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 2782                                        base_expr_type_2>::type base_expr_type;
 
 2784       static const int num_args1 = ExprT1::num_args;
 
 2785       static const int num_args2 = ExprT2::num_args;
 
 2786       static const int num_args = num_args1 + num_args2;
 
 2788       static const bool is_linear = 
false;
 
 2791       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 2792         expr1(expr1_), expr2(expr2_) {}
 
 2796         int sz1 = expr1.size(), sz2 = expr2.size();
 
 2797         return sz1 > sz2 ? sz1 : sz2;
 
 2802       bool isActive()
 const {
 
 2803         if (Arg < num_args1)
 
 2804           return expr1.template isActive<Arg>();
 
 2806           return expr2.template isActive<Arg-num_args1>();
 
 2810       bool updateValue()
 const {
 
 2811         return expr1.updateValue() && expr2.updateValue();
 
 2815       void cache()
 const {
 
 2818         const value_type_1 v1 = expr1.val();
 
 2819         const value_type_2 v2 = expr2.val();
 
 2820         max_v1 = (v1 >= v2);
 
 2821         v = max_v1 ? v1 : v2;
 
 2825       value_type 
val()
 const {
 
 2830       void computePartials(
const value_type& 
bar,
 
 2831                            value_type partials[])
 const {
 
 2832         if (num_args1 > 0) {
 
 2834             expr1.computePartials(bar, partials);
 
 2836             expr1.computePartials(value_type(0.0), partials);
 
 2838         if (num_args2 > 0) {
 
 2840             expr2.computePartials(value_type(0.0), partials+num_args1);
 
 2842             expr2.computePartials(bar, partials+num_args1);
 
 2847       void getTangents(
int i, value_type dots[])
 const {
 
 2848         expr1.getTangents(i, dots);
 
 2849         expr2.getTangents(i, dots+num_args1);
 
 2854       value_type getTangent(
int i)
 const {
 
 2855         if (Arg < num_args1)
 
 2856           return expr1.template getTangent<Arg>(i);
 
 2858           return expr2.template getTangent<Arg-num_args1>(i);
 
 2862       bool isLinear()
 const {
 
 2867       bool hasFastAccess()
 const {
 
 2868         return expr1.hasFastAccess() && expr2.hasFastAccess();
 
 2872       const value_type 
dx(
int i)
 const {
 
 2873         return max_v1 ? expr1.dx(i) : expr2.dx(i);
 
 2878         return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
 
 2882       const value_type* getDx(
int j)
 const {
 
 2884           return expr1.getDx(j);
 
 2886           return expr2.getDx(j-num_args1);
 
 2891       const ExprT1& expr1;
 
 2892       const ExprT2& expr2;
 
 2893       mutable value_type v;
 
 2894       mutable bool max_v1;
 
 2898     template <
typename ExprT1, 
typename T2>
 
 2899     class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
 
 2903       typedef ConstExpr<T2> ExprT2;
 
 2904       typedef typename ExprT1::value_type value_type_1;
 
 2905       typedef typename ExprT2::value_type value_type_2;
 
 2907                                        value_type_2>::type value_type;
 
 2908       typedef typename ExprT1::scalar_type scalar_type_1;
 
 2909       typedef typename ExprT2::scalar_type scalar_type_2;
 
 2911                                        scalar_type_2>::type scalar_type;
 
 2913       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 2914       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 2916                                        base_expr_type_2>::type base_expr_type;
 
 2918       static const int num_args = ExprT1::num_args;
 
 2920       static const bool is_linear = 
false;
 
 2923       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 2924         expr1(expr1_), expr2(expr2_) {}
 
 2928         return expr1.size();
 
 2933       bool isActive()
 const {
 
 2934         return expr1.template isActive<Arg>();
 
 2938       bool updateValue()
 const {
 
 2939         return expr1.updateValue();
 
 2943       void cache()
 const {
 
 2945         const value_type_1 v1 = expr1.val();
 
 2946         const value_type_2 v2 = expr2.val();
 
 2947         max_v1 = (v1 >= v2);
 
 2948         v = max_v1 ? v1 : v2;
 
 2952       value_type 
val()
 const {
 
 2957       void computePartials(
const value_type& 
bar,
 
 2958                            value_type partials[])
 const {
 
 2960           expr1.computePartials(bar, partials);
 
 2962           expr1.computePartials(value_type(0.0), partials);
 
 2966       void getTangents(
int i, value_type dots[])
 const {
 
 2967         expr1.getTangents(i, dots);
 
 2972       value_type getTangent(
int i)
 const {
 
 2973         return expr1.template getTangent<Arg>(i);
 
 2977       bool isLinear()
 const {
 
 2982       bool hasFastAccess()
 const {
 
 2983         return expr1.hasFastAccess();
 
 2987       const value_type 
dx(
int i)
 const {
 
 2988         return max_v1 ? expr1.dx(i) : value_type(0.0);
 
 2993         return max_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
 
 2997       const value_type* getDx(
int j)
 const {
 
 2998         return expr1.getDx(j);
 
 3003       const ExprT1& expr1;
 
 3005       mutable value_type v;
 
 3006       mutable bool max_v1;
 
 3010     template <
typename T1, 
typename ExprT2>
 
 3011     class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
 
 3015       typedef ConstExpr<T1> ExprT1;
 
 3016       typedef typename ExprT1::value_type value_type_1;
 
 3017       typedef typename ExprT2::value_type value_type_2;
 
 3019                                        value_type_2>::type value_type;
 
 3020       typedef typename ExprT1::scalar_type scalar_type_1;
 
 3021       typedef typename ExprT2::scalar_type scalar_type_2;
 
 3023                                        scalar_type_2>::type scalar_type;
 
 3025       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 3026       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 3028                                        base_expr_type_2>::type base_expr_type;
 
 3030       static const int num_args = ExprT2::num_args;
 
 3032       static const bool is_linear = 
false;
 
 3035       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 3036         expr1(expr1_), expr2(expr2_) {}
 
 3040         return expr2.size();
 
 3045       bool isActive()
 const {
 
 3046         return expr2.template isActive<Arg>();
 
 3050       bool updateValue()
 const {
 
 3051         return expr2.updateValue();
 
 3055       void cache()
 const {
 
 3057         const value_type_1 v1 = expr1.val();
 
 3058         const value_type_2 v2 = expr2.val();
 
 3059         max_v1 = (v1 >= v2);
 
 3060         v = max_v1 ? v1 : v2;
 
 3064       value_type 
val()
 const {
 
 3069       void computePartials(
const value_type& 
bar,
 
 3070                            value_type partials[])
 const {
 
 3072           expr2.computePartials(value_type(0.0), partials);
 
 3074           expr2.computePartials(bar, partials);
 
 3078       void getTangents(
int i, value_type dots[])
 const {
 
 3079         expr2.getTangents(i, dots);
 
 3084       value_type getTangent(
int i)
 const {
 
 3085         return expr2.template getTangent<Arg>(i);
 
 3089       bool isLinear()
 const {
 
 3094       bool hasFastAccess()
 const {
 
 3095         return expr2.hasFastAccess();
 
 3099       const value_type 
dx(
int i)
 const {
 
 3100         return max_v1 ? value_type(0.0) : expr2.dx(i);
 
 3105         return max_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
 
 3109       const value_type* getDx(
int j)
 const {
 
 3110         return expr2.getDx(j);
 
 3116       const ExprT2& expr2;
 
 3117       mutable value_type v;
 
 3118       mutable bool max_v1;
 
 3126     template <
typename ExprT1, 
typename ExprT2>
 
 3129     template <
typename ExprT1, 
typename ExprT2>
 
 3130     class Expr< MinOp<ExprT1,ExprT2> > {
 
 3134       typedef typename ExprT1::value_type value_type_1;
 
 3135       typedef typename ExprT2::value_type value_type_2;
 
 3137                                        value_type_2>::type value_type;
 
 3138       typedef typename ExprT1::scalar_type scalar_type_1;
 
 3139       typedef typename ExprT2::scalar_type scalar_type_2;
 
 3141                                        scalar_type_2>::type scalar_type;
 
 3143       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 3144       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 3146                                        base_expr_type_2>::type base_expr_type;
 
 3148       static const int num_args1 = ExprT1::num_args;
 
 3149       static const int num_args2 = ExprT2::num_args;
 
 3150       static const int num_args = num_args1 + num_args2;
 
 3152       static const bool is_linear = 
false;
 
 3155       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 3156         expr1(expr1_), expr2(expr2_) {}
 
 3160         int sz1 = expr1.size(), sz2 = expr2.size();
 
 3161         return sz1 > sz2 ? sz1 : sz2;
 
 3166       bool isActive()
 const {
 
 3167         if (Arg < num_args1)
 
 3168           return expr1.template isActive<Arg>();
 
 3170           return expr2.template isActive<Arg-num_args1>();
 
 3174       bool updateValue()
 const {
 
 3175         return expr1.updateValue() && expr2.updateValue();
 
 3179       void cache()
 const {
 
 3182         const value_type_1 v1 = expr1.val();
 
 3183         const value_type_2 v2 = expr2.val();
 
 3184         min_v1 = (v1 <= v2);
 
 3185         v = min_v1 ? v1 : v2;
 
 3189       value_type 
val()
 const {
 
 3194       void computePartials(
const value_type& 
bar,
 
 3195                            value_type partials[])
 const {
 
 3196         if (num_args1 > 0) {
 
 3198             expr1.computePartials(bar, partials);
 
 3200             expr1.computePartials(value_type(0.0), partials);
 
 3202         if (num_args2 > 0) {
 
 3204             expr2.computePartials(value_type(0.0), partials+num_args1);
 
 3206             expr2.computePartials(bar, partials+num_args1);
 
 3211       void getTangents(
int i, value_type dots[])
 const {
 
 3212         expr1.getTangents(i, dots);
 
 3213         expr2.getTangents(i, dots+num_args1);
 
 3218       value_type getTangent(
int i)
 const {
 
 3219         if (Arg < num_args1)
 
 3220           return expr1.template getTangent<Arg>(i);
 
 3222           return expr2.template getTangent<Arg-num_args1>(i);
 
 3226       bool isLinear()
 const {
 
 3231       bool hasFastAccess()
 const {
 
 3232         return expr1.hasFastAccess() && expr2.hasFastAccess();
 
 3236       const value_type 
dx(
int i)
 const {
 
 3237         return min_v1 ? expr1.dx(i) : expr2.dx(i);
 
 3242         return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
 
 3246       const value_type* getDx(
int j)
 const {
 
 3248           return expr1.getDx(j);
 
 3250           return expr2.getDx(j-num_args1);
 
 3255       const ExprT1& expr1;
 
 3256       const ExprT2& expr2;
 
 3257       mutable value_type v;
 
 3258       mutable bool min_v1;
 
 3262     template <
typename ExprT1, 
typename T2>
 
 3263     class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
 
 3267       typedef ConstExpr<T2> ExprT2;
 
 3268       typedef typename ExprT1::value_type value_type_1;
 
 3269       typedef typename ExprT2::value_type value_type_2;
 
 3271                                        value_type_2>::type value_type;
 
 3272       typedef typename ExprT1::scalar_type scalar_type_1;
 
 3273       typedef typename ExprT2::scalar_type scalar_type_2;
 
 3275                                        scalar_type_2>::type scalar_type;
 
 3277       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 3278       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 3280                                        base_expr_type_2>::type base_expr_type;
 
 3282       static const int num_args = ExprT1::num_args;
 
 3284       static const bool is_linear = 
false;
 
 3287       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 3288         expr1(expr1_), expr2(expr2_) {}
 
 3292         return expr1.size();
 
 3297       bool isActive()
 const {
 
 3298         return expr1.template isActive<Arg>();
 
 3302       bool updateValue()
 const {
 
 3303         return expr1.updateValue();
 
 3307       void cache()
 const {
 
 3309         const value_type_1 v1 = expr1.val();
 
 3310         const value_type_2 v2 = expr2.val();
 
 3311         min_v1 = (v1 <= v2);
 
 3312         v = min_v1 ? v1 : v2;
 
 3316       value_type 
val()
 const {
 
 3321       void computePartials(
const value_type& 
bar,
 
 3322                            value_type partials[])
 const {
 
 3324           expr1.computePartials(bar, partials);
 
 3326           expr1.computePartials(value_type(0.0), partials);
 
 3330       void getTangents(
int i, value_type dots[])
 const {
 
 3331         expr1.getTangents(i, dots);
 
 3336       value_type getTangent(
int i)
 const {
 
 3337         return expr1.template getTangent<Arg>(i);
 
 3341       bool isLinear()
 const {
 
 3346       bool hasFastAccess()
 const {
 
 3347         return expr1.hasFastAccess();
 
 3351       const value_type 
dx(
int i)
 const {
 
 3352         return min_v1 ? expr1.dx(i) : value_type(0.0);
 
 3357         return min_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
 
 3361       const value_type* getDx(
int j)
 const {
 
 3362         return expr1.getDx(j);
 
 3367       const ExprT1& expr1;
 
 3369       mutable value_type v;
 
 3370       mutable bool min_v1;
 
 3374     template <
typename T1, 
typename ExprT2>
 
 3375     class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
 
 3379       typedef ConstExpr<T1> ExprT1;
 
 3380       typedef typename ExprT1::value_type value_type_1;
 
 3381       typedef typename ExprT2::value_type value_type_2;
 
 3383                                        value_type_2>::type value_type;
 
 3384       typedef typename ExprT1::scalar_type scalar_type_1;
 
 3385       typedef typename ExprT2::scalar_type scalar_type_2;
 
 3387                                        scalar_type_2>::type scalar_type;
 
 3389       typedef typename ExprT1::base_expr_type base_expr_type_1;
 
 3390       typedef typename ExprT2::base_expr_type base_expr_type_2;
 
 3392                                        base_expr_type_2>::type base_expr_type;
 
 3394       static const int num_args = ExprT2::num_args;
 
 3396       static const bool is_linear = 
false;
 
 3399       Expr(
const ExprT1& expr1_, 
const ExprT2& expr2_) :
 
 3400         expr1(expr1_), expr2(expr2_) {}
 
 3404         return expr2.size();
 
 3409       bool isActive()
 const {
 
 3410         return expr2.template isActive<Arg>();
 
 3414       bool updateValue()
 const {
 
 3415         return expr2.updateValue();
 
 3419       void cache()
 const {
 
 3421         const value_type_1 v1 = expr1.val();
 
 3422         const value_type_2 v2 = expr2.val();
 
 3423         min_v1 = (v1 <= v2);
 
 3424         v = min_v1 ? v1 : v2;
 
 3428       value_type 
val()
 const {
 
 3433       void computePartials(
const value_type& 
bar,
 
 3434                            value_type partials[])
 const {
 
 3436           expr2.computePartials(value_type(0.0), partials);
 
 3438           expr2.computePartials(bar, partials);
 
 3442       void getTangents(
int i, value_type dots[])
 const {
 
 3443         expr2.getTangents(i, dots);
 
 3448       value_type getTangent(
int i)
 const {
 
 3449         return expr2.template getTangent<Arg>(i);
 
 3453       bool isLinear()
 const {
 
 3458       bool hasFastAccess()
 const {
 
 3459         return expr2.hasFastAccess();
 
 3463       const value_type 
dx(
int i)
 const {
 
 3464         return min_v1 ? value_type(0.0) : expr2.dx(i);
 
 3469         return min_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
 
 3473       const value_type* getDx(
int j)
 const {
 
 3474         return expr2.getDx(j);
 
 3480       const ExprT2& expr2;
 
 3481       mutable value_type v;
 
 3482       mutable bool min_v1;
 
 3490 #define FAD_BINARYOP_MACRO(OPNAME,OP)                                   \ 
 3491 namespace Sacado {                                                      \ 
 3492   namespace ELRCacheFad {                                               \ 
 3494     template <typename T1, typename T2>                                 \ 
 3495     KOKKOS_INLINE_FUNCTION                                              \ 
 3496     SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP)                                  \ 
 3497     OPNAME (const T1& expr1, const T2& expr2)                           \ 
 3499       typedef OP< T1, T2 > expr_t;                                      \ 
 3501       return Expr<expr_t>(expr1, expr2);                                \ 
 3504     template <typename T>                                               \ 
 3505     KOKKOS_INLINE_FUNCTION                                              \ 
 3506     Expr< OP< Expr<T>, Expr<T> > >                                      \ 
 3507     OPNAME (const Expr<T>& expr1, const Expr<T>& expr2)                 \ 
 3509       typedef OP< Expr<T>, Expr<T> > expr_t;                            \ 
 3511       return Expr<expr_t>(expr1, expr2);                                \ 
 3514     template <typename T>                                               \ 
 3515     KOKKOS_INLINE_FUNCTION                                              \ 
 3516     Expr< OP< ConstExpr<typename Expr<T>::value_type>,                  \ 
 3518     OPNAME (const typename Expr<T>::value_type& c,                      \ 
 3519             const Expr<T>& expr)                                        \ 
 3521       typedef ConstExpr<typename Expr<T>::value_type> ConstT;           \ 
 3522       typedef OP< ConstT, Expr<T> > expr_t;                             \ 
 3524       return Expr<expr_t>(ConstT(c), expr);                             \ 
 3527     template <typename T>                                               \ 
 3528     KOKKOS_INLINE_FUNCTION                                              \ 
 3529     Expr< OP< Expr<T>,                                                  \ 
 3530               ConstExpr<typename Expr<T>::value_type> > >               \ 
 3531     OPNAME (const Expr<T>& expr,                                        \ 
 3532             const typename Expr<T>::value_type& c)                      \ 
 3534       typedef ConstExpr<typename Expr<T>::value_type> ConstT;           \ 
 3535       typedef OP< Expr<T>, ConstT > expr_t;                             \ 
 3537       return Expr<expr_t>(expr, ConstT(c));                             \ 
 3540     template <typename T>                                               \ 
 3541     KOKKOS_INLINE_FUNCTION                                              \ 
 3542     SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP)                                \ 
 3543     OPNAME (const typename Expr<T>::scalar_type& c,                     \ 
 3544             const Expr<T>& expr)                                        \ 
 3546       typedef ConstExpr<typename Expr<T>::scalar_type> ConstT;          \ 
 3547       typedef OP< ConstT, Expr<T> > expr_t;                             \ 
 3549       return Expr<expr_t>(ConstT(c), expr);                             \ 
 3552     template <typename T>                                               \ 
 3553     KOKKOS_INLINE_FUNCTION                                              \ 
 3554     SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP)                                \ 
 3555     OPNAME (const Expr<T>& expr,                                        \ 
 3556             const typename Expr<T>::scalar_type& c)                     \ 
 3558       typedef ConstExpr<typename Expr<T>::scalar_type> ConstT;          \ 
 3559       typedef OP< Expr<T>, ConstT > expr_t;                             \ 
 3561       return Expr<expr_t>(expr, ConstT(c));                             \ 
 3576 #undef FAD_BINARYOP_MACRO 
 3580 #define FAD_RELOP_MACRO(OP)                                             \ 
 3581 namespace Sacado {                                                      \ 
 3582   namespace ELRCacheFad {                                               \ 
 3583     template <typename ExprT1, typename ExprT2>                         \ 
 3584     KOKKOS_INLINE_FUNCTION                                              \ 
 3586     operator OP (const Expr<ExprT1>& expr1,                             \ 
 3587                  const Expr<ExprT2>& expr2)                             \ 
 3591       return expr1.val() OP expr2.val();                                \ 
 3594     template <typename ExprT2>                                            \ 
 3595     KOKKOS_INLINE_FUNCTION                                              \ 
 3597     operator OP (const typename Expr<ExprT2>::value_type& a,            \ 
 3598                  const Expr<ExprT2>& expr2)                             \ 
 3601       return a OP expr2.val();                                          \ 
 3604     template <typename ExprT1>                                          \ 
 3605     KOKKOS_INLINE_FUNCTION                                              \ 
 3607     operator OP (const Expr<ExprT1>& expr1,                             \ 
 3608                  const typename Expr<ExprT1>::value_type& b)            \ 
 3611       return expr1.val() OP b;                                          \ 
 3627 #undef FAD_RELOP_MACRO 
 3631   namespace ELRCacheFad {
 
 3633     template <
typename ExprT>
 
 3638       return ! expr.val();
 
 3648   namespace ELRCacheFad {
 
 3650     template <
typename ExprT>
 
 3654       bool is_zero = (x.val() == 0.0);
 
 3655       for (
int i=0; i<x.size(); i++)
 
 3656         is_zero = is_zero && (x.dx(i) == 0.0);
 
 3664 #define FAD_BOOL_MACRO(OP)                                              \ 
 3665 namespace Sacado {                                                      \ 
 3666   namespace ELRCacheFad {                                               \ 
 3667     template <typename ExprT1, typename ExprT2>                         \ 
 3668     KOKKOS_INLINE_FUNCTION                                              \ 
 3670     operator OP (const Expr<ExprT1>& expr1,                             \ 
 3671                  const Expr<ExprT2>& expr2)                             \ 
 3673       return toBool(expr1) OP toBool(expr2);                            \ 
 3676     template <typename ExprT2>                                          \ 
 3677     KOKKOS_INLINE_FUNCTION                                              \ 
 3679     operator OP (const typename Expr<ExprT2>::value_type& a,            \ 
 3680                  const Expr<ExprT2>& expr2)                             \ 
 3682       return a OP toBool(expr2);                                        \ 
 3685     template <typename ExprT1>                                          \ 
 3686     KOKKOS_INLINE_FUNCTION                                              \ 
 3688     operator OP (const Expr<ExprT1>& expr1,                             \ 
 3689                  const typename Expr<ExprT1>::value_type& b)            \ 
 3691       return toBool(expr1) OP b;                                        \ 
 3699 #undef FAD_BOOL_MACRO 
 3705   namespace ELRCacheFad {
 
 3707     template <
typename ExprT>
 
 3708     std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
 
 3709       os << x.val() << 
" [";
 
 3711       for (
int i=0; i< x.size(); i++) {
 
 3712         os << 
" " << x.dx(i);
 
 3723 #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
 
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_)
 
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 
 
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
 
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 
 
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 bool isLinear() const 
 
#define KOKKOS_INLINE_FUNCTION
 
KOKKOS_INLINE_FUNCTION void cache() const 
 
KOKKOS_INLINE_FUNCTION T safe_sqrt(const T &x)
 
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 
 
#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)
 
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 
 
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 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 
 
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