Sacado Package Browser (Single Doxygen Collection) Version of the Day
Sacado_CacheFad_Ops.hpp
Go to the documentation of this file.
00001 // $Id$ 
00002 // $Source$ 
00003 // @HEADER
00004 // ***********************************************************************
00005 // 
00006 //                           Sacado Package
00007 //                 Copyright (2006) Sandia Corporation
00008 // 
00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00010 // the U.S. Government retains certain rights in this software.
00011 // 
00012 // This library is free software; you can redistribute it and/or modify
00013 // it under the terms of the GNU Lesser General Public License as
00014 // published by the Free Software Foundation; either version 2.1 of the
00015 // License, or (at your option) any later version.
00016 //  
00017 // This library is distributed in the hope that it will be useful, but
00018 // WITHOUT ANY WARRANTY; without even the implied warranty of
00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020 // Lesser General Public License for more details.
00021 //  
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License along with this library; if not, write to the Free Software
00024 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00025 // USA
00026 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
00027 // (etphipp@sandia.gov).
00028 // 
00029 // ***********************************************************************
00030 //
00031 // The forward-mode AD classes in Sacado are a derivative work of the
00032 // expression template classes in the Fad package by Nicolas Di Cesare.  
00033 // The following banner is included in the original Fad source code:
00034 //
00035 // ************ DO NOT REMOVE THIS BANNER ****************
00036 //
00037 //  Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
00038 //  http://www.ann.jussieu.fr/~dicesare
00039 //
00040 //            CEMRACS 98 : C++ courses, 
00041 //         templates : new C++ techniques 
00042 //            for scientific computing 
00043 // 
00044 //********************************************************
00045 //
00046 //  A short implementation ( not all operators and 
00047 //  functions are overloaded ) of 1st order Automatic
00048 //  Differentiation in forward mode (FAD) using
00049 //  EXPRESSION TEMPLATES.
00050 //
00051 //********************************************************
00052 // @HEADER
00053 
00054 #ifndef SACADO_CACHEFAD_OPS_HPP
00055 #define SACADO_CACHEFAD_OPS_HPP
00056 
00057 #include "Sacado_CacheFad_Expression.hpp"
00058 #include "Sacado_cmath.hpp"
00059 #include "Sacado_dummy_arg.hpp"
00060 #include <ostream>  // for std::ostream
00061 
00062 #define FAD_UNARYOP_MACRO(OPNAME,OP,DECL,PARTIAL,VALUE,DX,FASTACCESSDX) \
00063 namespace Sacado {              \
00064   namespace CacheFad {              \
00065                   \
00066     template <typename ExprT>           \
00067     class OP {};              \
00068                   \
00069     template <typename ExprT>           \
00070     class Expr< OP<ExprT> > {           \
00071     public:               \
00072                   \
00073       typedef typename ExprT::value_type value_type;      \
00074       typedef typename ExprT::scalar_type scalar_type;      \
00075                   \
00076       Expr(const ExprT& expr_) : expr(expr_)  {}      \
00077                   \
00078       int size() const { return expr.size(); }        \
00079                   \
00080       bool hasFastAccess() const { return expr.hasFastAccess(); } \
00081                   \
00082       bool isPassive() const { return expr.isPassive();}    \
00083                   \
00084       bool updateValue() const { return expr.updateValue(); }   \
00085                   \
00086       void cache() const {            \
00087   expr.cache();             \
00088         v = expr.val();             \
00089   PARTIAL;              \
00090       }                 \
00091                   \
00092       value_type val() const {            \
00093   return VALUE;             \
00094       }                 \
00095                   \
00096       value_type dx(int i) const {          \
00097   return DX;              \
00098       }                 \
00099                   \
00100       value_type fastAccessDx(int i) const {        \
00101   return FASTACCESSDX;            \
00102       }                 \
00103                   \
00104     protected:                \
00105                   \
00106       const ExprT& expr;            \
00107       mutable value_type v;           \
00108       mutable value_type a;           \
00109       DECL                \
00110                   \
00111     template <typename T>           \
00112     inline Expr< OP< Expr<T> > >          \
00113     OPNAME (const Expr<T>& expr)          \
00114     {                 \
00115       typedef OP< Expr<T> > expr_t;         \
00116                         \
00117       return Expr<expr_t>(expr);          \
00118     }                 \
00119   }                 \
00120 }
00121 
00122 FAD_UNARYOP_MACRO(operator+,
00123       UnaryPlusOp, 
00124       };,
00125       ;,
00126       v,
00127       expr.dx(i),
00128       expr.fastAccessDx(i))
00129 FAD_UNARYOP_MACRO(operator-,
00130       UnaryMinusOp,
00131       };,
00132       ;, 
00133       -v,
00134       -expr.dx(i),
00135       -expr.fastAccessDx(i))
00136 FAD_UNARYOP_MACRO(exp,
00137       ExpOp, 
00138       };,
00139       a = std::exp(v),
00140       a,
00141       expr.dx(i)*a,
00142       expr.fastAccessDx(i)*a)
00143 FAD_UNARYOP_MACRO(log,
00144       LogOp, 
00145       };,
00146       ;,
00147       std::log(v),
00148       expr.dx(i)/v,
00149       expr.fastAccessDx(i)/v)
00150 FAD_UNARYOP_MACRO(log10,
00151       Log10Op, 
00152       };,
00153       a = std::log(value_type(10))*v,
00154       std::log10(v),
00155       expr.dx(i)/a,
00156       expr.fastAccessDx(i)/a)
00157 FAD_UNARYOP_MACRO(sqrt,
00158       SqrtOp,
00159       };,
00160       a = value_type(2)*std::sqrt(v),
00161       std::sqrt(v),
00162       expr.dx(i)/a,
00163       expr.fastAccessDx(i)/a)
00164 FAD_UNARYOP_MACRO(cos,
00165       CosOp, 
00166       };,
00167       a = std::sin(v),
00168       std::cos(v),
00169       -expr.dx(i)*a,
00170       -expr.fastAccessDx(i)*a)
00171 FAD_UNARYOP_MACRO(sin,
00172       SinOp, 
00173       };,
00174       a = std::cos(v),
00175       std::sin(v),
00176       expr.dx(i)*a,
00177       expr.fastAccessDx(i)*a)
00178 FAD_UNARYOP_MACRO(tan,
00179       TanOp, 
00180       mutable value_type c;};,
00181       c = std::tan(v); a = value_type(1)+c*c,
00182       c,
00183       expr.dx(i)*a,
00184       expr.fastAccessDx(i)*a)
00185 FAD_UNARYOP_MACRO(acos,
00186       ACosOp, 
00187       };,
00188       a = - std::sqrt(value_type(1)-v*v),
00189       std::acos(v),
00190       expr.dx(i)/a,
00191       expr.fastAccessDx(i)/a)
00192 FAD_UNARYOP_MACRO(asin,
00193       ASinOp, 
00194       };,
00195       a = std::sqrt(value_type(1)-v*v),
00196       std::asin(v),
00197       expr.dx(i)/a,
00198       expr.fastAccessDx(i)/a)
00199 FAD_UNARYOP_MACRO(atan,
00200       ATanOp, 
00201       };,
00202       a = (value_type(1)+v*v),
00203       std::atan(v),
00204       expr.dx(i)/a,
00205       expr.fastAccessDx(i)/a)
00206 FAD_UNARYOP_MACRO(cosh,
00207       CoshOp, 
00208       };,
00209       a = std::sinh(v),
00210       std::cosh(v),
00211       expr.dx(i)*a,
00212       expr.fastAccessDx(i)*a)
00213 FAD_UNARYOP_MACRO(sinh,
00214       SinhOp, 
00215       };,
00216       a = std::cosh(v),
00217       std::sinh(v),
00218       expr.dx(i)*a,
00219       expr.fastAccessDx(i)*a)
00220 FAD_UNARYOP_MACRO(tanh,
00221       TanhOp, 
00222       };,
00223       a = std::cosh(v); a = a*a,
00224       std::tanh(v),
00225       expr.dx(i)/a,
00226       expr.fastAccessDx(i)/a)
00227 FAD_UNARYOP_MACRO(acosh,
00228       ACoshOp, 
00229       };,
00230       a = std::sqrt((v-value_type(1))*(v+value_type(1))),
00231       std::acosh(v),
00232       expr.dx(i)/a,
00233       expr.fastAccessDx(i)/a)
00234 FAD_UNARYOP_MACRO(asinh,
00235       ASinhOp, 
00236       };,
00237       a = std::sqrt(value_type(1)+v*v),
00238       std::asinh(v),
00239       expr.dx(i)/a,
00240       expr.fastAccessDx(i)/a)
00241 FAD_UNARYOP_MACRO(atanh,
00242       ATanhOp, 
00243       };,
00244       a = value_type(1)-v*v,
00245       std::atanh(v),
00246       expr.dx(i)/a,
00247       expr.fastAccessDx(i)/a)
00248 FAD_UNARYOP_MACRO(abs,
00249       AbsOp, 
00250       };,
00251       ;,
00252       std::abs(v),
00253       v >= 0 ? value_type(+expr.dx(i)) : value_type(-expr.dx(i)),
00254       v >= 0 ? value_type(+expr.fastAccessDx(i)) : 
00255         value_type(-expr.fastAccessDx(i)))
00256 FAD_UNARYOP_MACRO(fabs,
00257       FAbsOp, 
00258       };,
00259       ;,
00260       std::fabs(v),
00261       v >= 0 ? value_type(+expr.dx(i)) : value_type(-expr.dx(i)),
00262       v >= 0 ? value_type(+expr.fastAccessDx(i)) : 
00263         value_type(-expr.fastAccessDx(i)))
00264 
00265 #undef FAD_UNARYOP_MACRO
00266 
00267 #define FAD_BINARYOP_MACRO(OPNAME,OP,DECL,PARTIAL,VALUE,DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
00268 namespace Sacado {              \
00269   namespace CacheFad {              \
00270                   \
00271     template <typename ExprT1, typename ExprT2>       \
00272     class OP {};              \
00273                   \
00274     template <typename ExprT1, typename ExprT2>       \
00275     class Expr< OP<ExprT1,ExprT2> > {         \
00276                   \
00277     public:               \
00278                   \
00279       typedef typename ExprT1::value_type value_type_1;     \
00280       typedef typename ExprT2::value_type value_type_2;     \
00281       typedef typename Sacado::Promote<value_type_1,      \
00282                value_type_2>::type value_type;  \
00283       typedef typename ExprT1::scalar_type scalar_type_1;   \
00284       typedef typename ExprT2::scalar_type scalar_type_2;   \
00285       typedef typename Sacado::Promote<scalar_type_1,     \
00286                scalar_type_2>::type scalar_type; \
00287                   \
00288       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00289   expr1(expr1_), expr2(expr2_) {}         \
00290                   \
00291       int size() const {            \
00292   int sz1 = expr1.size(), sz2 = expr2.size();     \
00293   return sz1 > sz2 ? sz1 : sz2;         \
00294       }                 \
00295                   \
00296       bool hasFastAccess() const {          \
00297   return expr1.hasFastAccess() && expr2.hasFastAccess();    \
00298       }                 \
00299                   \
00300       bool isPassive() const {            \
00301   return expr1.isPassive() && expr2.isPassive();      \
00302       }                 \
00303                   \
00304       bool updateValue() const {          \
00305   return expr1.updateValue() && expr2.updateValue();    \
00306       }                 \
00307                   \
00308       void cache() const {            \
00309   expr1.cache();              \
00310   expr2.cache();              \
00311         v1 = expr1.val();           \
00312   v2 = expr2.val();           \
00313   PARTIAL;              \
00314       }                 \
00315                   \
00316       value_type val() const {            \
00317   return VALUE;             \
00318       }                 \
00319                   \
00320       value_type dx(int i) const {          \
00321   return DX;              \
00322       }                 \
00323                   \
00324       value_type fastAccessDx(int i) const {        \
00325   return FASTACCESSDX;            \
00326       }                 \
00327                   \
00328     protected:                \
00329                   \
00330       const ExprT1& expr1;            \
00331       const ExprT2& expr2;            \
00332       mutable value_type_1 v1;            \
00333       mutable value_type_2 v2;            \
00334       mutable value_type a;           \
00335       mutable value_type b;           \
00336       DECL                \
00337                   \
00338     template <typename ExprT1>            \
00339     class Expr< OP<ExprT1, ConstExpr<typename ExprT1::value_type> >  >{ \
00340                   \
00341     public:               \
00342                   \
00343       typedef typename ExprT1::value_type value_type;     \
00344       typedef typename ExprT1::scalar_type scalar_type;     \
00345       typedef ConstExpr<typename ExprT1::value_type> ExprT2;    \
00346                   \
00347       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00348   expr1(expr1_), expr2(expr2_) {}         \
00349                   \
00350       int size() const {            \
00351   return expr1.size();            \
00352       }                 \
00353                   \
00354       bool hasFastAccess() const {          \
00355   return expr1.hasFastAccess();         \
00356       }                 \
00357                   \
00358       bool isPassive() const {            \
00359   return expr1.isPassive();         \
00360       }                 \
00361                   \
00362       bool updateValue() const { return expr1.updateValue(); }    \
00363                   \
00364       void cache() const {            \
00365   expr1.cache();              \
00366   expr2.cache();              \
00367         v1 = expr1.val();           \
00368   v2 = expr2.val();           \
00369   PARTIAL;              \
00370       }                 \
00371                   \
00372       value_type val() const {            \
00373   return VALUE;             \
00374       }                 \
00375                   \
00376       value_type dx(int i) const {          \
00377   return CONST_DX_2;            \
00378       }                 \
00379                   \
00380       value_type fastAccessDx(int i) const {        \
00381   return CONST_FASTACCESSDX_2;          \
00382       }                 \
00383                   \
00384     protected:                \
00385                   \
00386       const ExprT1& expr1;            \
00387       const ExprT2 expr2;           \
00388       mutable value_type v1;            \
00389       mutable value_type v2;            \
00390       mutable value_type a;           \
00391       mutable value_type b;           \
00392       DECL                \
00393                   \
00394     template <typename ExprT2>            \
00395     class Expr< OP<ConstExpr<typename ExprT2::value_type>, ExprT2 >  >{ \
00396                   \
00397     public:               \
00398                   \
00399       typedef typename ExprT2::value_type value_type;     \
00400       typedef typename ExprT2::scalar_type scalar_type;     \
00401       typedef ConstExpr<typename ExprT2::value_type> ExprT1;    \
00402                   \
00403       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00404   expr1(expr1_), expr2(expr2_) {}         \
00405                   \
00406       int size() const {            \
00407   return expr2.size();            \
00408       }                 \
00409                   \
00410       bool hasFastAccess() const {          \
00411   return expr2.hasFastAccess();         \
00412       }                 \
00413                   \
00414       bool isPassive() const {            \
00415   return expr2.isPassive();         \
00416       }                 \
00417                   \
00418       bool updateValue() const { return expr2.updateValue(); }    \
00419                   \
00420       void cache() const {            \
00421   expr1.cache();              \
00422   expr2.cache();              \
00423         v1 = expr1.val();           \
00424   v2 = expr2.val();           \
00425   PARTIAL;              \
00426       }                 \
00427                   \
00428       value_type val() const {            \
00429   return VALUE;             \
00430       }                 \
00431                   \
00432       value_type dx(int i) const {          \
00433   return CONST_DX_1;            \
00434       }                 \
00435                   \
00436       value_type fastAccessDx(int i) const {        \
00437   return CONST_FASTACCESSDX_1;          \
00438       }                 \
00439                   \
00440     protected:                \
00441                   \
00442       const ExprT1 expr1;           \
00443       const ExprT2& expr2;            \
00444       mutable value_type v1;            \
00445       mutable value_type v2;            \
00446       mutable value_type a;           \
00447       mutable value_type b;           \
00448       DECL                \
00449                   \
00450     template <typename ExprT1>            \
00451     class Expr< OP<ExprT1, ConstExpr<typename dummy<typename ExprT1::value_type,typename ExprT1::scalar_type>::type> > >{ \
00452                   \
00453     public:               \
00454                   \
00455       typedef typename ExprT1::value_type value_type;     \
00456       typedef typename ExprT1::scalar_type scalar_type;     \
00457       typedef ConstExpr<scalar_type> ExprT2;        \
00458                   \
00459       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00460   expr1(expr1_), expr2(expr2_) {}         \
00461                   \
00462       int size() const {            \
00463   return expr1.size();            \
00464       }                 \
00465                   \
00466       bool hasFastAccess() const {          \
00467   return expr1.hasFastAccess();         \
00468       }                 \
00469                   \
00470       bool isPassive() const {            \
00471   return expr1.isPassive();         \
00472       }                 \
00473                   \
00474       bool updateValue() const { return expr1.updateValue(); }    \
00475                   \
00476       void cache() const {            \
00477   expr1.cache();              \
00478   expr2.cache();              \
00479         v1 = expr1.val();           \
00480   v2 = expr2.val();           \
00481   PARTIAL;              \
00482       }                 \
00483                   \
00484       value_type val() const {            \
00485   return VALUE;             \
00486       }                 \
00487                   \
00488       value_type dx(int i) const {          \
00489   return CONST_DX_2;            \
00490       }                 \
00491                   \
00492       value_type fastAccessDx(int i) const {        \
00493   return CONST_FASTACCESSDX_2;          \
00494       }                 \
00495                   \
00496     protected:                \
00497                   \
00498       const ExprT1& expr1;            \
00499       const ExprT2 expr2;           \
00500       mutable value_type v1;            \
00501       mutable value_type v2;            \
00502       mutable value_type a;           \
00503       mutable value_type b;           \
00504       DECL                \
00505                   \
00506     template <typename ExprT2>            \
00507     class Expr< OP<ConstExpr<typename dummy<typename ExprT2::value_type,typename ExprT2::scalar_type>::type>, ExprT2 >  >{  \
00508                   \
00509     public:               \
00510                   \
00511       typedef typename ExprT2::value_type value_type;     \
00512       typedef typename ExprT2::scalar_type scalar_type;     \
00513       typedef ConstExpr<scalar_type> ExprT1;        \
00514                   \
00515       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00516   expr1(expr1_), expr2(expr2_) {}         \
00517                   \
00518       int size() const {            \
00519   return expr2.size();            \
00520       }                 \
00521                   \
00522       bool hasFastAccess() const {          \
00523   return expr2.hasFastAccess();         \
00524       }                 \
00525                   \
00526       bool isPassive() const {            \
00527   return expr2.isPassive();         \
00528       }                 \
00529                   \
00530       bool updateValue() const { return expr2.updateValue(); }    \
00531                   \
00532       void cache() const {            \
00533   expr1.cache();              \
00534   expr2.cache();              \
00535         v1 = expr1.val();           \
00536   v2 = expr2.val();           \
00537   PARTIAL;              \
00538       }                 \
00539                   \
00540       value_type val() const {            \
00541   return VALUE;             \
00542       }                 \
00543                   \
00544       value_type dx(int i) const {          \
00545   return CONST_DX_1;            \
00546       }                 \
00547                   \
00548       value_type fastAccessDx(int i) const {        \
00549   return CONST_FASTACCESSDX_1;          \
00550       }                 \
00551                   \
00552     protected:                \
00553                   \
00554       const ExprT1 expr1;           \
00555       const ExprT2& expr2;            \
00556       mutable value_type v1;            \
00557       mutable value_type v2;            \
00558       mutable value_type a;           \
00559       mutable value_type b;           \
00560       DECL                \
00561                   \
00562     template <typename T1, typename T2>         \
00563     inline Expr< OP< Expr<T1>, Expr<T2> > >       \
00564     OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2)   \
00565     {                 \
00566       typedef OP< Expr<T1>, Expr<T2> > expr_t;        \
00567                       \
00568       return Expr<expr_t>(expr1, expr2);        \
00569     }                 \
00570                   \
00571     template <typename T>           \
00572     inline Expr< OP< Expr<T>, Expr<T> > >       \
00573     OPNAME (const Expr<T>& expr1, const Expr<T>& expr2)     \
00574     {                 \
00575       typedef OP< Expr<T>, Expr<T> > expr_t;        \
00576                       \
00577       return Expr<expr_t>(expr1, expr2);        \
00578     }                 \
00579                   \
00580     template <typename T>           \
00581     inline Expr< OP< ConstExpr<typename Expr<T>::value_type>,   \
00582            Expr<T> > >        \
00583     OPNAME (const typename Expr<T>::value_type& c,      \
00584       const Expr<T>& expr)          \
00585     {                 \
00586       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
00587       typedef OP< ConstT, Expr<T> > expr_t;       \
00588                   \
00589       return Expr<expr_t>(ConstT(c), expr);       \
00590     }                 \
00591                   \
00592     template <typename T>           \
00593     inline Expr< OP< Expr<T>,           \
00594          ConstExpr<typename Expr<T>::value_type> > >  \
00595     OPNAME (const Expr<T>& expr,          \
00596       const typename Expr<T>::value_type& c)      \
00597     {                 \
00598       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
00599       typedef OP< Expr<T>, ConstT > expr_t;       \
00600                   \
00601       return Expr<expr_t>(expr, ConstT(c));       \
00602     }                 \
00603                   \
00604     template <typename T>           \
00605     inline Expr< OP< ConstExpr<typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type>, \
00606            Expr<T> > >        \
00607     OPNAME (const typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type& c,      \
00608       const Expr<T>& expr)          \
00609     {                 \
00610       typedef typename Expr<T>::value_type value_type;      \
00611       typedef typename Expr<T>::scalar_type scalar_type;    \
00612       typedef typename dummy<value_type,scalar_type>::type const_type;  \
00613       typedef ConstExpr<const_type> ConstT;       \
00614       typedef OP< ConstT, Expr<T> > expr_t;       \
00615                   \
00616       return Expr<expr_t>(ConstT(c), expr);       \
00617     }                 \
00618                   \
00619     template <typename T>           \
00620     inline Expr< OP< Expr<T>,           \
00621          ConstExpr<typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type> > >  \
00622     OPNAME (const Expr<T>& expr,          \
00623       const typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type& c)      \
00624     {                 \
00625       typedef typename Expr<T>::value_type value_type;      \
00626       typedef typename Expr<T>::scalar_type scalar_type;    \
00627       typedef typename dummy<value_type,scalar_type>::type const_type;  \
00628       typedef ConstExpr<const_type> ConstT;       \
00629       typedef OP< Expr<T>, ConstT > expr_t;       \
00630                   \
00631       return Expr<expr_t>(expr, ConstT(c));       \
00632     }                 \
00633   }                 \
00634 }
00635 
00636 FAD_BINARYOP_MACRO(operator+,
00637        AdditionOp, 
00638        };,
00639        ;,
00640        v1 + v2,
00641        expr1.dx(i) + expr2.dx(i),
00642        expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
00643        expr2.dx(i),
00644        expr1.dx(i),
00645        expr2.fastAccessDx(i),
00646        expr1.fastAccessDx(i))
00647 FAD_BINARYOP_MACRO(operator-,
00648        SubtractionOp, 
00649        };,
00650        ;,
00651        v1 - v2,
00652        expr1.dx(i) - expr2.dx(i),
00653        expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
00654        -expr2.dx(i),
00655        expr1.dx(i),
00656        -expr2.fastAccessDx(i),
00657        expr1.fastAccessDx(i))
00658 // FAD_BINARYOP_MACRO(operator*,
00659 //       MultiplicationOp, 
00660 //                 ;,
00661 //       ;,
00662 //       v1*v2,
00663 //       v1*expr2.dx(i) + expr1.dx(i)*v2,
00664 //       v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2,
00665 //       v1*expr2.dx(i),
00666 //       expr1.dx(i)*v2,
00667 //       v1*expr2.fastAccessDx(i),
00668 //       expr1.fastAccessDx(i)*v2)
00669 
00670 namespace Sacado {              
00671   namespace CacheFad {              
00672                   
00673     template <typename ExprT1, typename ExprT2>       
00674     class MultiplicationOp {};              
00675                   
00676     template <typename ExprT1, typename ExprT2>       
00677     class Expr< MultiplicationOp<ExprT1,ExprT2> > {
00678 
00679     public:               
00680                   
00681       typedef typename ExprT1::value_type value_type_1;     
00682       typedef typename ExprT2::value_type value_type_2;     
00683       typedef typename Sacado::Promote<value_type_1,      
00684                value_type_2>::type value_type;  
00685       typedef typename ExprT1::scalar_type scalar_type_1;   
00686       typedef typename ExprT2::scalar_type scalar_type_2;   
00687       typedef typename Sacado::Promote<scalar_type_1,     
00688                scalar_type_2>::type scalar_type; 
00689                   
00690       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00691   expr1(expr1_), expr2(expr2_) {}         
00692                   
00693       int size() const {            
00694   int sz1 = expr1.size(), sz2 = expr2.size();     
00695   return sz1 > sz2 ? sz1 : sz2;         
00696       }                 
00697                   
00698       bool hasFastAccess() const {          
00699   return expr1.hasFastAccess() && expr2.hasFastAccess();    
00700       }                 
00701                   
00702       bool isPassive() const {            
00703   return expr1.isPassive() && expr2.isPassive();      
00704       }                 
00705 
00706       bool updateValue() const { 
00707   return expr1.updateValue() && expr2.updateValue(); 
00708       }
00709 
00710       void cache() const {
00711   expr1.cache();
00712   expr2.cache();
00713   v1 = expr1.val();
00714   v2 = expr2.val();
00715       }
00716                   
00717       value_type val() const {            
00718   return v1*v2;             
00719       }                 
00720                   
00721       value_type dx(int i) const {          
00722   //return v1*expr2.dx(i) + expr1.dx(i)*v2;
00723   if (expr1.size() > 0 && expr2.size() > 0)
00724     return v1*expr2.dx(i) + expr1.dx(i)*v2;
00725   else if (expr1.size() > 0)
00726     return expr1.dx(i)*v2;
00727   else
00728     return v1*expr2.dx(i);
00729       }                 
00730                   
00731       value_type fastAccessDx(int i) const {        
00732   return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
00733       }                 
00734                   
00735     protected:                
00736                   
00737       const ExprT1& expr1;            
00738       const ExprT2& expr2;            
00739       mutable value_type_1 v1;            
00740       mutable value_type_2 v2;            
00741       mutable value_type a;           
00742       mutable value_type b;           
00743     };                  
00744                   
00745     template <typename ExprT1>            
00746     class Expr< MultiplicationOp<ExprT1, ConstExpr<typename ExprT1::value_type> >  >{ 
00747                   
00748     public:               
00749                   
00750       typedef typename ExprT1::value_type value_type;     
00751       typedef typename ExprT1::scalar_type scalar_type;     
00752       typedef ConstExpr<typename ExprT1::value_type> ExprT2;    
00753                   
00754       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00755   expr1(expr1_), expr2(expr2_) {}         
00756                   
00757       int size() const {            
00758   return expr1.size();            
00759       }                 
00760                   
00761       bool hasFastAccess() const {          
00762   return expr1.hasFastAccess();         
00763       }                 
00764                   
00765       bool isPassive() const {            
00766   return expr1.isPassive();         
00767       }                 
00768 
00769       bool updateValue() const { return expr1.updateValue(); }
00770 
00771       void cache() const {
00772   expr1.cache();
00773   expr2.cache();
00774   v1 = expr1.val();
00775   v2 = expr2.val();
00776       }
00777                   
00778       value_type val() const {
00779   return v1*v2;             
00780       }                 
00781                   
00782       value_type dx(int i) const {          
00783   return expr1.dx(i)*v2;            
00784       }                 
00785                   
00786       value_type fastAccessDx(int i) const {        
00787   return expr1.fastAccessDx(i)*v2;          
00788       }                 
00789                   
00790     protected:                
00791                   
00792       const ExprT1& expr1;            
00793       const ExprT2 expr2;           
00794       mutable value_type v1;            
00795       mutable value_type v2;            
00796       mutable value_type a;           
00797       mutable value_type b;           
00798     };                  
00799                   
00800     template <typename ExprT2>            
00801     class Expr< MultiplicationOp<ConstExpr<typename ExprT2::value_type>, ExprT2 >  >{ 
00802                   
00803     public:               
00804                   
00805       typedef typename ExprT2::value_type value_type;     
00806       typedef typename ExprT2::scalar_type scalar_type;     
00807       typedef ConstExpr<typename ExprT2::value_type> ExprT1;    
00808                   
00809       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00810   expr1(expr1_), expr2(expr2_) {}         
00811                   
00812       int size() const {            
00813   return expr2.size();            
00814       }                 
00815                   
00816       bool hasFastAccess() const {          
00817   return expr2.hasFastAccess();         
00818       }                 
00819                   
00820       bool isPassive() const {            
00821   return expr2.isPassive();         
00822       }                 
00823 
00824       bool updateValue() const { return expr2.updateValue(); }
00825 
00826       void cache() const {
00827   expr1.cache();
00828   expr2.cache();
00829   v1 = expr1.val();
00830   v2 = expr2.val();
00831       }
00832                   
00833       value_type val() const {
00834   return v1*v2;             
00835       }                 
00836                   
00837       value_type dx(int i) const {          
00838   return v1*expr2.dx(i);            
00839       }                 
00840                   
00841       value_type fastAccessDx(int i) const {        
00842   return v1*expr2.fastAccessDx(i);          
00843       }                 
00844                   
00845     protected:                     
00846                   
00847       const ExprT1 expr1;           
00848       const ExprT2& expr2;            
00849       mutable value_type v1;            
00850       mutable value_type v2;            
00851       mutable value_type a;           
00852       mutable value_type b;           
00853     };                  
00854                   
00855     template <typename ExprT1>            
00856     class Expr< MultiplicationOp<ExprT1, ConstExpr<typename dummy<typename ExprT1::value_type,typename ExprT1::scalar_type>::type> > >{ 
00857                   
00858     public:               
00859                   
00860       typedef typename ExprT1::value_type value_type;     
00861       typedef typename ExprT1::scalar_type scalar_type;     
00862       typedef ConstExpr<scalar_type> ExprT2;        
00863                   
00864       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00865   expr1(expr1_), expr2(expr2_) {}         
00866                   
00867       int size() const {            
00868   return expr1.size();            
00869       }                 
00870                   
00871       bool hasFastAccess() const {          
00872   return expr1.hasFastAccess();         
00873       }                 
00874                   
00875       bool isPassive() const {            
00876   return expr1.isPassive();         
00877       }                 
00878 
00879       bool updateValue() const { return expr1.updateValue(); }
00880 
00881       void cache() const {
00882   expr1.cache();
00883   expr2.cache();
00884   v1 = expr1.val();
00885   v2 = expr2.val();
00886       }
00887                   
00888       value_type val() const {
00889   return v1*v2;             
00890       }                 
00891                   
00892       value_type dx(int i) const {          
00893   return expr1.dx(i)*v2;            
00894       }                 
00895                   
00896       value_type fastAccessDx(int i) const {        
00897   return expr1.fastAccessDx(i)*v2;          
00898       }                 
00899                   
00900     protected:                
00901                   
00902       const ExprT1& expr1;            
00903       const ExprT2 expr2;           
00904       mutable value_type v1;            
00905       mutable value_type v2;            
00906       mutable value_type a;           
00907       mutable value_type b;           
00908     };                  
00909                   
00910     template <typename ExprT2>            
00911     class Expr< MultiplicationOp<ConstExpr<typename dummy<typename ExprT2::value_type,typename ExprT2::scalar_type>::type>, ExprT2 >  >{  
00912                   
00913     public:               
00914                   
00915       typedef typename ExprT2::value_type value_type;     
00916       typedef typename ExprT2::scalar_type scalar_type;     
00917       typedef ConstExpr<scalar_type> ExprT1;        
00918                   
00919       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00920   expr1(expr1_), expr2(expr2_) {}         
00921                   
00922       int size() const {            
00923   return expr2.size();            
00924       }                 
00925                   
00926       bool hasFastAccess() const {          
00927   return expr2.hasFastAccess();         
00928       }               
00929                     
00930       bool isPassive() const {            
00931   return expr2.isPassive();         
00932       }                 
00933 
00934       bool updateValue() const { return expr2.updateValue(); }
00935 
00936       void cache() const {
00937   expr1.cache();
00938   expr2.cache();
00939   v1 = expr1.val();
00940   v2 = expr2.val();
00941       }
00942                   
00943       value_type val() const {
00944   return v1*v2;             
00945       }                 
00946                   
00947       value_type dx(int i) const {          
00948   return v1*expr2.dx(i);            
00949       }                 
00950                   
00951       value_type fastAccessDx(int i) const {        
00952   return v1*expr2.fastAccessDx(i);          
00953       }                 
00954                   
00955     protected:                
00956                   
00957       const ExprT1 expr1;           
00958       const ExprT2& expr2;            
00959       mutable value_type v1;            
00960       mutable value_type v2;            
00961       mutable value_type a;           
00962       mutable value_type b;           
00963     };                  
00964                   
00965     template <typename T1, typename T2>         
00966     inline Expr< MultiplicationOp< Expr<T1>, Expr<T2> > > 
00967     operator* (const Expr<T1>& expr1, const Expr<T2>& expr2)    
00968     {                 
00969       typedef MultiplicationOp< Expr<T1>, Expr<T2> > expr_t;
00970       return Expr<expr_t>(expr1, expr2);        
00971     }                 
00972                   
00973     template <typename T>           
00974     inline Expr< MultiplicationOp< Expr<T>, Expr<T> > >       
00975     operator* (const Expr<T>& expr1, const Expr<T>& expr2)      
00976     {                 
00977       typedef MultiplicationOp< Expr<T>, Expr<T> > expr_t;
00978       return Expr<expr_t>(expr1, expr2);        
00979     }                 
00980                   
00981     template <typename T>           
00982     inline Expr< MultiplicationOp< ConstExpr<typename Expr<T>::value_type>,
00983            Expr<T> > >        
00984     operator* (const typename Expr<T>::value_type& c,     
00985       const Expr<T>& expr)          
00986     {                 
00987       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   
00988       typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
00989       return Expr<expr_t>(ConstT(c), expr);       
00990     }                 
00991                   
00992     template <typename T>                
00993     inline Expr< MultiplicationOp< Expr<T>,
00994            ConstExpr<typename Expr<T>::value_type> > >  
00995     operator* (const Expr<T>& expr,         
00996       const typename Expr<T>::value_type& c)      
00997     {                 
00998       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   
00999       typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
01000       return Expr<expr_t>(expr, ConstT(c));       
01001     }                 
01002                       
01003     template <typename T>           
01004     inline Expr< MultiplicationOp< ConstExpr<typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type>, 
01005            Expr<T> > >        
01006     operator* (const typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type& c,     
01007       const Expr<T>& expr)          
01008     {                 
01009       typedef typename Expr<T>::value_type value_type;      
01010       typedef typename Expr<T>::scalar_type scalar_type;    
01011       typedef typename dummy<value_type,scalar_type>::type const_type;  
01012       typedef ConstExpr<const_type> ConstT;       
01013       typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
01014       return Expr<expr_t>(ConstT(c), expr);       
01015     }                 
01016                   
01017     template <typename T>           
01018     inline Expr< MultiplicationOp< Expr<T>,           
01019          ConstExpr<typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type> > >  
01020     operator* (const Expr<T>& expr,         
01021       const typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type& c)      
01022     {                 
01023       typedef typename Expr<T>::value_type value_type;      
01024       typedef typename Expr<T>::scalar_type scalar_type;    
01025       typedef typename dummy<value_type,scalar_type>::type const_type;  
01026       typedef ConstExpr<const_type> ConstT;       
01027       typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
01028       return Expr<expr_t>(expr, ConstT(c));       
01029     }                 
01030   }                 
01031 }
01032 
01033 
01034 
01035 FAD_BINARYOP_MACRO(operator/,
01036        DivisionOp, 
01037        mutable value_type c;};,
01038        c = v1/v2; a = value_type(1)/v2; b = -c/v2,
01039        c,
01040        expr1.dx(i)*a + expr2.dx(i)*b,
01041        expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b,
01042        expr2.dx(i)*b,
01043        expr1.dx(i)*a,
01044        expr2.fastAccessDx(i)*b,
01045        expr1.fastAccessDx(i)*a)
01046 FAD_BINARYOP_MACRO(atan2,
01047        Atan2Op,
01048        };,
01049        a=v1*v1 + v2*v2,
01050        std::atan2(v1,v2),
01051        (expr1.dx(i)*v2 - expr2.dx(i)*v1)/a,
01052        (expr1.fastAccessDx(i)*v2 - expr2.fastAccessDx(i)*v1)/a,
01053        (-expr2.dx(i)*v1)/a,
01054        (expr1.dx(i)*v2)/a,
01055        (-expr2.fastAccessDx(i)*v1)/a,
01056        (expr1.fastAccessDx(i)*v2)/a)
01057 FAD_BINARYOP_MACRO(pow,
01058        PowerOp,
01059        mutable value_type c;};,
01060        c=std::pow(v1,v2); a=(v1 == 0 ? value_type(0) : value_type(c*v2/v1)); b=(v1 == 0 ? value_type(0) : value_type(c*std::log(v1))),
01061        c,
01062        v1 == 0 ? value_type(0) : value_type(expr1.dx(i)*a + expr2.dx(i)*b),
01063        v1 == 0 ? value_type(0) : value_type(expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b),
01064        v1 == 0 ? value_type(0) : value_type(expr2.dx(i)*b),
01065        v1 == 0 ? value_type(0) : value_type(expr1.dx(i)*a),
01066        v1 == 0 ? value_type(0) : value_type(expr2.fastAccessDx(i)*b),
01067        v1 == 0 ? value_type(0) : value_type(expr1.fastAccessDx(i)*a))
01068 FAD_BINARYOP_MACRO(max,
01069        MaxOp,
01070        };,
01071        ;,
01072        std::max(expr1.val(), expr2.val()),
01073        expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
01074        expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
01075                                     expr2.fastAccessDx(i),
01076        expr1.val() >= expr2.val() ? value_type(0) : expr2.dx(i),
01077        expr1.val() >= expr2.val() ? expr1.dx(i) : value_type(0),
01078        expr1.val() >= expr2.val() ? value_type(0) : 
01079                                     expr2.fastAccessDx(i),
01080        expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
01081                                     value_type(0))
01082 FAD_BINARYOP_MACRO(min,
01083        MinOp,
01084        };,
01085        ;,
01086        std::min(expr1.val(), expr2.val()),
01087        expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
01088        expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
01089                                     expr2.fastAccessDx(i),
01090        expr1.val() <= expr2.val() ? value_type(0) : expr2.dx(i),
01091        expr1.val() <= expr2.val() ? expr1.dx(i) : value_type(0),
01092        expr1.val() <= expr2.val() ? value_type(0) : 
01093                                     expr2.fastAccessDx(i),
01094        expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
01095                                     value_type(0))
01096 
01097 #undef FAD_BINARYOP_MACRO
01098   
01099   // The general definition of max/min works for Fad variables too, except
01100   // we need to add a case when the argument types are different.  This 
01101   // can't conflict with the general definition, so we need to use
01102   // Substitution Failure Is Not An Error
01103 #include "Sacado_mpl_disable_if.hpp"
01104 #include "Sacado_mpl_is_same.hpp"
01105 
01106 #define FAD_SFINAE_BINARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE,DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
01107 namespace Sacado {              \
01108   namespace CacheFad {              \
01109                   \
01110     template <typename ExprT1, typename ExprT2>       \
01111     class OP {                \
01112                   \
01113     public:               \
01114                   \
01115       typedef typename ExprT1::value_type value_type_1;     \
01116       typedef typename ExprT2::value_type value_type_2;     \
01117       typedef typename Sacado::Promote<value_type_1,      \
01118                value_type_2>::type value_type;  \
01119                   \
01120       OP(const ExprT1& expr1, const ExprT2& expr2) {}     \
01121                   \
01122       value_type              \
01123       computeValue(const ExprT1& expr1, const ExprT2& expr2) const {  \
01124   v1 = expr1.val();           \
01125   v2 = expr2.val();           \
01126   PARTIAL;              \
01127   return VALUE;             \
01128       }                 \
01129                   \
01130       value_type              \
01131       computeDx(int i, const ExprT1& expr1,       \
01132     const ExprT2& expr2) const {        \
01133   return DX;              \
01134       }                 \
01135                   \
01136       value_type              \
01137       computeFastAccessDx(int i, const ExprT1& expr1,     \
01138         const ExprT2& expr2) const {      \
01139   return FASTACCESSDX;            \
01140       }                 \
01141                   \
01142     protected:                \
01143                   \
01144       mutable value_type_1 v1;            \
01145       mutable value_type_2 v2;            \
01146       mutable value_type a;           \
01147       mutable value_type b;           \
01148     };                  \
01149                   \
01150     template <typename ExprT1>            \
01151     class OP<ExprT1, ConstExpr<typename ExprT1::value_type> > {   \
01152                   \
01153     public:               \
01154                   \
01155       typedef typename ExprT1::value_type value_type;     \
01156       typedef ConstExpr<typename ExprT1::value_type> ExprT2;    \
01157                   \
01158       OP(const ExprT1& expr1, const ExprT2& expr2) {}     \
01159                   \
01160       value_type              \
01161       computeValue(const ExprT1& expr1, const ExprT2& expr2) const {  \
01162   v1 = expr1.val();           \
01163   v2 = expr2.val();           \
01164   PARTIAL;              \
01165   return VALUE;             \
01166       }                 \
01167                   \
01168       value_type              \
01169       computeDx(int i, const ExprT1& expr1,       \
01170     const ExprT2& expr2) const {        \
01171   return CONST_DX_2;            \
01172       }                 \
01173                   \
01174       value_type              \
01175       computeFastAccessDx(int i, const ExprT1& expr1,     \
01176         const ExprT2& expr2) const {      \
01177   return CONST_FASTACCESSDX_2;          \
01178       }                 \
01179                   \
01180     protected:                \
01181                   \
01182       mutable value_type v1;            \
01183       mutable value_type v2;            \
01184       mutable value_type a;           \
01185       mutable value_type b;           \
01186     };                  \
01187                   \
01188     template <typename ExprT2>            \
01189     class OP<ConstExpr<typename ExprT2::value_type>, ExprT2 > {   \
01190                   \
01191     public:               \
01192                   \
01193       typedef typename ExprT2::value_type value_type;     \
01194       typedef ConstExpr<typename ExprT2::value_type> ExprT1;    \
01195                   \
01196       OP(const ExprT1& expr1, const ExprT2& expr2) {}     \
01197                   \
01198       value_type              \
01199       computeValue(const ExprT1& expr1, const ExprT2& expr2) const {  \
01200   v1 = expr1.val();           \
01201   v2 = expr2.val();           \
01202   PARTIAL;              \
01203   return VALUE;             \
01204       }                 \
01205                   \
01206       value_type              \
01207       computeDx(int i, const ExprT1& expr1,       \
01208     const ExprT2& expr2) const {        \
01209   return CONST_DX_1;            \
01210       }                 \
01211                   \
01212       value_type              \
01213       computeFastAccessDx(int i, const ExprT1& expr1,     \
01214         const ExprT2& expr2) const {      \
01215   return CONST_FASTACCESSDX_1;          \
01216       }                 \
01217                   \
01218     protected:                \
01219                   \
01220       mutable value_type v1;            \
01221       mutable value_type v2;            \
01222       mutable value_type a;           \
01223       mutable value_type b;           \
01224     };                  \
01225                   \
01226     template <typename T1, typename T2>         \
01227     inline                                                              \
01228     typename                                                            \
01229     mpl::disable_if< mpl::is_same<T1,T2>,                               \
01230                      Expr<BinaryExpr<Expr<T1>, Expr<T2>, OP> > >::type  \
01231     OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2)   \
01232     {                 \
01233       typedef BinaryExpr< Expr<T1>, Expr<T2>, OP > expr_t;    \
01234                       \
01235       return Expr<expr_t>(expr_t(expr1, expr2));      \
01236     }                 \
01237                   \
01238     template <typename T>           \
01239     inline Expr< BinaryExpr< ConstExpr<typename Expr<T>::value_type>, \
01240            Expr<T>, OP > >        \
01241     OPNAME (const typename Expr<T>::value_type& c,      \
01242       const Expr<T>& expr)          \
01243     {                 \
01244       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
01245       typedef BinaryExpr< ConstT, Expr<T>, OP > expr_t;     \
01246                   \
01247       return Expr<expr_t>(expr_t(ConstT(c), expr));     \
01248     }                 \
01249                   \
01250     template <typename T>           \
01251     inline Expr< BinaryExpr< Expr<T>,         \
01252            ConstExpr<typename Expr<T>::value_type>, \
01253            OP > >         \
01254     OPNAME (const Expr<T>& expr,          \
01255       const typename Expr<T>::value_type& c)      \
01256     {                 \
01257       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
01258       typedef BinaryExpr< Expr<T>, ConstT, OP > expr_t;     \
01259                   \
01260       return Expr<expr_t>(expr_t(expr, ConstT(c)));     \
01261     }                 \
01262   }                 \
01263 }
01264 
01265 // FAD_SFINAE_BINARYOP_MACRO(max,
01266 //       MaxOp,
01267 //       ;,
01268 //       std::max(expr1.val(), expr2.val()),
01269 //       expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
01270 //       expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
01271 //                                    expr2.fastAccessDx(i),
01272 //       expr1.val() >= expr2.val() ? value_type(0) : expr2.dx(i),
01273 //       expr1.val() >= expr2.val() ? expr1.dx(i) : value_type(0),
01274 //       expr1.val() >= expr2.val() ? value_type(0) : 
01275 //                                    expr2.fastAccessDx(i),
01276 //       expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
01277 //                                    value_type(0))
01278 // FAD_SFINAE_BINARYOP_MACRO(min,
01279 //       MinOp,
01280 //       ;,
01281 //       std::min(expr1.val(), expr2.val()),
01282 //       expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
01283 //       expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
01284 //                                    expr2.fastAccessDx(i),
01285 //       expr1.val() <= expr2.val() ? value_type(0) : expr2.dx(i),
01286 //       expr1.val() <= expr2.val() ? expr1.dx(i) : value_type(0),
01287 //       expr1.val() <= expr2.val() ? value_type(0) : 
01288 //                                    expr2.fastAccessDx(i),
01289 //       expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
01290 //                                    value_type(0))
01291 
01292 #undef FAD_SFINAE_BINARYOP_MACRO
01293 
01294 //-------------------------- Relational Operators -----------------------
01295 
01296 #define FAD_RELOP_MACRO(OP)           \
01297 namespace Sacado {              \
01298   namespace CacheFad {              \
01299     template <typename ExprT1, typename ExprT2>       \
01300     inline bool               \
01301     operator OP (const Expr<ExprT1>& expr1,       \
01302      const Expr<ExprT2>& expr2)       \
01303     {                 \
01304       return expr1.val() OP expr2.val();        \
01305     }                 \
01306                   \
01307     template <typename ExprT2>            \
01308     inline bool               \
01309     operator OP (const typename Expr<ExprT2>::value_type& a,    \
01310      const Expr<ExprT2>& expr2)       \
01311     {                 \
01312       return a OP expr2.val();            \
01313     }                 \
01314                   \
01315     template <typename ExprT1>            \
01316     inline bool               \
01317     operator OP (const Expr<ExprT1>& expr1,       \
01318      const typename Expr<ExprT1>::value_type& b)    \
01319     {                 \
01320       return expr1.val() OP b;            \
01321     }                 \
01322   }                 \
01323 }
01324 
01325 FAD_RELOP_MACRO(==)
01326 FAD_RELOP_MACRO(!=)
01327 FAD_RELOP_MACRO(<)
01328 FAD_RELOP_MACRO(>)
01329 FAD_RELOP_MACRO(<=)
01330 FAD_RELOP_MACRO(>=)
01331 FAD_RELOP_MACRO(<<=)
01332 FAD_RELOP_MACRO(>>=)
01333 FAD_RELOP_MACRO(&)
01334 FAD_RELOP_MACRO(|)
01335 
01336 #undef FAD_RELOP_MACRO
01337 
01338 namespace Sacado {
01339 
01340   namespace CacheFad {
01341 
01342     template <typename ExprT>
01343     inline bool operator ! (const Expr<ExprT>& expr) 
01344     {
01345       return ! expr.val();
01346     }
01347 
01348   } // namespace CacheFad
01349 
01350 } // namespace Sacado
01351 
01352 //-------------------------- I/O Operators -----------------------
01353 
01354 namespace Sacado {
01355 
01356   namespace CacheFad {
01357 
01358     template <typename ExprT>
01359     std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
01360       os << x.val() << " [";
01361       
01362       for (int i=0; i< x.size(); i++) {
01363         os << " " << x.dx(i);
01364       }
01365 
01366       os << " ]";
01367       return os;
01368     }
01369 
01370   } // namespace CacheFad
01371 
01372 } // namespace Sacado
01373 
01374 
01375 #endif // SACADO_CACHEFAD_OPS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines