Sacado_CacheFad_Ops.hpp

Go to the documentation of this file.
00001 // $Id: Sacado_CacheFad_Ops.hpp,v 1.19.2.1 2009/03/05 20:35:25 etphipp Exp $ 
00002 // $Source: /space/CVS/Trilinos/packages/sacado/src/Sacado_CacheFad_Ops.hpp,v $ 
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 <cmath>
00059 #include <algorithm>  // for std::min and std::max
00060 #include <ostream>  // for std::ostream
00061 
00062 #define FAD_UNARYOP_MACRO(OPNAME,OP,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                   \
00075       Expr(const ExprT& expr_) : expr(expr_)  {}      \
00076                   \
00077       int size() const { return expr.size(); }        \
00078                   \
00079       bool hasFastAccess() const { return expr.hasFastAccess(); } \
00080                   \
00081       bool isPassive() const { return expr.isPassive();}    \
00082                   \
00083       value_type val() const {            \
00084   v = expr.val();             \
00085   PARTIAL;              \
00086   return VALUE;             \
00087       }                 \
00088                   \
00089       value_type dx(int i) const {          \
00090   return DX;              \
00091       }                 \
00092                   \
00093       value_type fastAccessDx(int i) const {        \
00094   return FASTACCESSDX;            \
00095       }                 \
00096                   \
00097     protected:                \
00098                   \
00099       const ExprT& expr;            \
00100       mutable value_type v;           \
00101       mutable value_type a;           \
00102     };                  \
00103                   \
00104     template <typename T>           \
00105     inline Expr< OP< Expr<T> > >          \
00106     OPNAME (const Expr<T>& expr)          \
00107     {                 \
00108       typedef OP< Expr<T> > expr_t;         \
00109                         \
00110       return Expr<expr_t>(expr);          \
00111     }                 \
00112   }                 \
00113 }
00114 
00115 FAD_UNARYOP_MACRO(operator+,
00116       UnaryPlusOp, 
00117       ;,
00118       v,
00119       expr.dx(i),
00120       expr.fastAccessDx(i))
00121 FAD_UNARYOP_MACRO(operator-,
00122       UnaryMinusOp,
00123       ;, 
00124       -v,
00125       -expr.dx(i),
00126       -expr.fastAccessDx(i))
00127 FAD_UNARYOP_MACRO(exp,
00128       ExpOp, 
00129       a = std::exp(v),
00130       a,
00131       expr.dx(i)*a,
00132       expr.fastAccessDx(i)*a)
00133 FAD_UNARYOP_MACRO(log,
00134       LogOp, 
00135       ;,
00136       std::log(v),
00137       expr.dx(i)/v,
00138       expr.fastAccessDx(i)/v)
00139 FAD_UNARYOP_MACRO(log10,
00140       Log10Op, 
00141       a = std::log(value_type(10))*v,
00142       std::log10(v),
00143       expr.dx(i)/a,
00144       expr.fastAccessDx(i)/a)
00145 FAD_UNARYOP_MACRO(sqrt,
00146       SqrtOp,
00147       a = value_type(2)*std::sqrt(v),
00148       std::sqrt(v),
00149       expr.dx(i)/a,
00150       expr.fastAccessDx(i)/a)
00151 FAD_UNARYOP_MACRO(cos,
00152       CosOp, 
00153       a = std::sin(v),
00154       std::cos(v),
00155       -expr.dx(i)*a,
00156       -expr.fastAccessDx(i)*a)
00157 FAD_UNARYOP_MACRO(sin,
00158       SinOp, 
00159       a = std::cos(v),
00160       std::sin(v),
00161       expr.dx(i)*a,
00162       expr.fastAccessDx(i)*a)
00163 FAD_UNARYOP_MACRO(tan,
00164       TanOp, 
00165       value_type t = std::tan(v); a = value_type(1)+t*t,
00166       t,
00167       expr.dx(i)*a,
00168       expr.fastAccessDx(i)*a)
00169 FAD_UNARYOP_MACRO(acos,
00170       ACosOp, 
00171       a = - std::sqrt(value_type(1)-v*v),
00172       std::acos(v),
00173       expr.dx(i)/a,
00174       expr.fastAccessDx(i)/a)
00175 FAD_UNARYOP_MACRO(asin,
00176       ASinOp, 
00177       a = std::sqrt(value_type(1)-v*v),
00178       std::asin(v),
00179       expr.dx(i)/a,
00180       expr.fastAccessDx(i)/a)
00181 FAD_UNARYOP_MACRO(atan,
00182       ATanOp, 
00183       a = (value_type(1)+v*v),
00184       std::atan(v),
00185       expr.dx(i)/a,
00186       expr.fastAccessDx(i)/a)
00187 FAD_UNARYOP_MACRO(cosh,
00188       CoshOp, 
00189       a = std::sinh(v),
00190       std::cosh(v),
00191       expr.dx(i)*a,
00192       expr.fastAccessDx(i)*a)
00193 FAD_UNARYOP_MACRO(sinh,
00194       SinhOp, 
00195       a = std::cosh(v),
00196       std::sinh(v),
00197       expr.dx(i)*a,
00198       expr.fastAccessDx(i)*a)
00199 FAD_UNARYOP_MACRO(tanh,
00200       TanhOp, 
00201       a = std::cosh(v); a = a*a,
00202       std::tanh(v),
00203       expr.dx(i)/a,
00204       expr.fastAccessDx(i)/a)
00205 FAD_UNARYOP_MACRO(acosh,
00206       ACoshOp, 
00207       a = std::sqrt((v-value_type(1))*(v+value_type(1))),
00208       acosh(v),
00209       expr.dx(i)/a,
00210       expr.fastAccessDx(i)/a)
00211 FAD_UNARYOP_MACRO(asinh,
00212       ASinhOp, 
00213       a = std::sqrt(value_type(1)+v*v),
00214       asinh(v),
00215       expr.dx(i)/a,
00216       expr.fastAccessDx(i)/a)
00217 FAD_UNARYOP_MACRO(atanh,
00218       ATanhOp, 
00219       a = value_type(1)-v*v,
00220       atanh(v),
00221       expr.dx(i)/a,
00222       expr.fastAccessDx(i)/a)
00223 FAD_UNARYOP_MACRO(abs,
00224       AbsOp, 
00225       ;,
00226       std::abs(v),
00227       v >= 0 ? value_type(+expr.dx(i)) : value_type(-expr.dx(i)),
00228       v >= 0 ? value_type(+expr.fastAccessDx(i)) : 
00229         value_type(-expr.fastAccessDx(i)))
00230 FAD_UNARYOP_MACRO(fabs,
00231       FAbsOp, 
00232       ;,
00233       std::fabs(v),
00234       v >= 0 ? value_type(+expr.dx(i)) : value_type(-expr.dx(i)),
00235       v >= 0 ? value_type(+expr.fastAccessDx(i)) : 
00236         value_type(-expr.fastAccessDx(i)))
00237 
00238 #undef FAD_UNARYOP_MACRO
00239 
00240 #define FAD_BINARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE,DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
00241 namespace Sacado {              \
00242   namespace CacheFad {              \
00243                   \
00244     template <typename ExprT1, typename ExprT2>       \
00245     class OP {};              \
00246                   \
00247     template <typename ExprT1, typename ExprT2>       \
00248     class Expr< OP<ExprT1,ExprT2> > {         \
00249                   \
00250     public:               \
00251                   \
00252       typedef typename ExprT1::value_type value_type_1;     \
00253       typedef typename ExprT2::value_type value_type_2;     \
00254       typedef typename Sacado::Promote<value_type_1,      \
00255                value_type_2>::type value_type;  \
00256                   \
00257       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00258   expr1(expr1_), expr2(expr2_) {}         \
00259                   \
00260       int size() const {            \
00261   int sz1 = expr1.size(), sz2 = expr2.size();     \
00262   return sz1 > sz2 ? sz1 : sz2;         \
00263       }                 \
00264                   \
00265       bool hasFastAccess() const {          \
00266   return expr1.hasFastAccess() && expr2.hasFastAccess();    \
00267       }                 \
00268                   \
00269       bool isPassive() const {            \
00270   return expr1.isPassive() && expr2.isPassive();      \
00271       }                 \
00272                   \
00273       value_type val() const {            \
00274   v1 = expr1.val();           \
00275   v2 = expr2.val();           \
00276   PARTIAL;              \
00277   return VALUE;             \
00278       }                 \
00279                   \
00280       value_type dx(int i) const {          \
00281   return DX;              \
00282       }                 \
00283                   \
00284       value_type fastAccessDx(int i) const {        \
00285   return FASTACCESSDX;            \
00286       }                 \
00287                   \
00288     protected:                \
00289                   \
00290       const ExprT1& expr1;            \
00291       const ExprT2& expr2;            \
00292       mutable value_type_1 v1;            \
00293       mutable value_type_2 v2;            \
00294       mutable value_type a;           \
00295       mutable value_type b;           \
00296     };                  \
00297                   \
00298     template <typename ExprT1>            \
00299     class Expr< OP<ExprT1, ConstExpr<typename ExprT1::value_type> >  >{ \
00300                   \
00301     public:               \
00302                   \
00303       typedef typename ExprT1::value_type value_type;     \
00304       typedef ConstExpr<typename ExprT1::value_type> ExprT2;    \
00305                   \
00306       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00307   expr1(expr1_), expr2(expr2_) {}         \
00308                   \
00309       int size() const {            \
00310   return expr1.size();            \
00311       }                 \
00312                   \
00313       bool hasFastAccess() const {          \
00314   return expr1.hasFastAccess();         \
00315       }                 \
00316                   \
00317       bool isPassive() const {            \
00318   return expr1.isPassive();         \
00319       }                 \
00320                   \
00321       value_type val() const {            \
00322   v1 = expr1.val();           \
00323   v2 = expr2.val();           \
00324   PARTIAL;              \
00325   return VALUE;             \
00326       }                 \
00327                   \
00328       value_type dx(int i) const {          \
00329   return CONST_DX_2;            \
00330       }                 \
00331                   \
00332       value_type fastAccessDx(int i) const {        \
00333   return CONST_FASTACCESSDX_2;          \
00334       }                 \
00335                   \
00336     protected:                \
00337                   \
00338       const ExprT1& expr1;            \
00339       const ExprT2 expr2;           \
00340       mutable value_type v1;            \
00341       mutable value_type v2;            \
00342       mutable value_type a;           \
00343       mutable value_type b;           \
00344     };                  \
00345                   \
00346     template <typename ExprT2>            \
00347     class Expr< OP<ConstExpr<typename ExprT2::value_type>, ExprT2 >  >{ \
00348                   \
00349     public:               \
00350                   \
00351       typedef typename ExprT2::value_type value_type;     \
00352       typedef ConstExpr<typename ExprT2::value_type> ExprT1;    \
00353                   \
00354       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00355   expr1(expr1_), expr2(expr2_) {}         \
00356                   \
00357       int size() const {            \
00358   return expr2.size();            \
00359       }                 \
00360                   \
00361       bool hasFastAccess() const {          \
00362   return expr2.hasFastAccess();         \
00363       }                 \
00364                   \
00365       bool isPassive() const {            \
00366   return expr2.isPassive();         \
00367       }                 \
00368                   \
00369       value_type val() const {            \
00370   v1 = expr1.val();           \
00371   v2 = expr2.val();           \
00372   PARTIAL;              \
00373   return VALUE;             \
00374       }                 \
00375                   \
00376       value_type dx(int i) const {          \
00377   return CONST_DX_1;            \
00378       }                 \
00379                   \
00380       value_type fastAccessDx(int i) const {        \
00381   return CONST_FASTACCESSDX_1;          \
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     };                  \
00393                   \
00394     template <typename T1, typename T2>         \
00395     inline Expr< OP< Expr<T1>, Expr<T2> > >       \
00396     OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2)   \
00397     {                 \
00398       typedef OP< Expr<T1>, Expr<T2> > expr_t;        \
00399                       \
00400       return Expr<expr_t>(expr1, expr2);        \
00401     }                 \
00402                   \
00403     template <typename T>           \
00404     inline Expr< OP< Expr<T>, Expr<T> > >       \
00405     OPNAME (const Expr<T>& expr1, const Expr<T>& expr2)     \
00406     {                 \
00407       typedef OP< Expr<T>, Expr<T> > expr_t;        \
00408                       \
00409       return Expr<expr_t>(expr1, expr2);        \
00410     }                 \
00411                   \
00412     template <typename T>           \
00413     inline Expr< OP< ConstExpr<typename Expr<T>::value_type>,   \
00414            Expr<T> > >        \
00415     OPNAME (const typename Expr<T>::value_type& c,      \
00416       const Expr<T>& expr)          \
00417     {                 \
00418       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
00419       typedef OP< ConstT, Expr<T> > expr_t;       \
00420                   \
00421       return Expr<expr_t>(ConstT(c), expr);       \
00422     }                 \
00423                   \
00424     template <typename T>           \
00425     inline Expr< OP< Expr<T>,           \
00426          ConstExpr<typename Expr<T>::value_type> > >  \
00427     OPNAME (const Expr<T>& expr,          \
00428       const typename Expr<T>::value_type& c)      \
00429     {                 \
00430       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
00431       typedef OP< Expr<T>, ConstT > expr_t;       \
00432                   \
00433       return Expr<expr_t>(expr, ConstT(c));       \
00434     }                 \
00435   }                 \
00436 }
00437 
00438 FAD_BINARYOP_MACRO(operator+,
00439        AdditionOp, 
00440        ;,
00441        v1 + v2,
00442        expr1.dx(i) + expr2.dx(i),
00443        expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
00444        expr2.dx(i),
00445        expr1.dx(i),
00446        expr2.fastAccessDx(i),
00447        expr1.fastAccessDx(i))
00448 FAD_BINARYOP_MACRO(operator-,
00449        SubtractionOp, 
00450        ;,
00451        v1 - v2,
00452        expr1.dx(i) - expr2.dx(i),
00453        expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
00454        -expr2.dx(i),
00455        expr1.dx(i),
00456        -expr2.fastAccessDx(i),
00457        expr1.fastAccessDx(i))
00458 FAD_BINARYOP_MACRO(operator*,
00459        MultiplicationOp, 
00460        ;,
00461        v1*v2,
00462        v1*expr2.dx(i) + expr1.dx(i)*v2,
00463        v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2,
00464        v1*expr2.dx(i),
00465        expr1.dx(i)*v2,
00466        v1*expr2.fastAccessDx(i),
00467        expr1.fastAccessDx(i)*v2)
00468 FAD_BINARYOP_MACRO(operator/,
00469        DivisionOp, 
00470        value_type c = v1/v2; a = value_type(1)/v2; b = -c/v2,
00471        c,
00472        expr1.dx(i)*a + expr2.dx(i)*b,
00473        expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b,
00474        expr2.dx(i)*b,
00475        expr1.dx(i)*a,
00476        expr2.fastAccessDx(i)*b,
00477        expr1.fastAccessDx(i)*a)
00478 FAD_BINARYOP_MACRO(atan2,
00479        Atan2Op,
00480        a=v1*v1 + v2*v2,
00481        std::atan2(v1,v2),
00482        (expr1.dx(i)*v2 - expr2.dx(i)*v1)/a,
00483        (expr1.fastAccessDx(i)*v2 - expr2.fastAccessDx(i)*v1)/a,
00484        (-expr2.dx(i)*v1)/a,
00485        (expr1.dx(i)*v2)/a,
00486        (-expr2.fastAccessDx(i)*v1)/a,
00487        (expr1.fastAccessDx(i)*v2)/a)
00488 FAD_BINARYOP_MACRO(pow,
00489        PowerOp,
00490        value_type c= std::pow(v1,v2); a=c*v2/v1; b=c*std::log(v1),
00491        c,
00492        expr1.dx(i)*a + expr2.dx(i)*b,
00493        expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b,
00494        expr2.dx(i)*b,
00495        expr1.dx(i)*a,
00496        expr2.fastAccessDx(i)*b,
00497        expr1.fastAccessDx(i)*a)
00498 FAD_BINARYOP_MACRO(max,
00499        MaxOp,
00500        ;,
00501        std::max(expr1.val(), expr2.val()),
00502        expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00503        expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
00504                                     expr2.fastAccessDx(i),
00505        expr1.val() >= expr2.val() ? value_type(0) : expr2.dx(i),
00506        expr1.val() >= expr2.val() ? expr1.dx(i) : value_type(0),
00507        expr1.val() >= expr2.val() ? value_type(0) : 
00508                                     expr2.fastAccessDx(i),
00509        expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
00510                                     value_type(0))
00511 FAD_BINARYOP_MACRO(min,
00512        MinOp,
00513        ;,
00514        std::min(expr1.val(), expr2.val()),
00515        expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00516        expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
00517                                     expr2.fastAccessDx(i),
00518        expr1.val() <= expr2.val() ? value_type(0) : expr2.dx(i),
00519        expr1.val() <= expr2.val() ? expr1.dx(i) : value_type(0),
00520        expr1.val() <= expr2.val() ? value_type(0) : 
00521                                     expr2.fastAccessDx(i),
00522        expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
00523                                     value_type(0))
00524 
00525 #undef FAD_BINARYOP_MACRO
00526   
00527   // The general definition of max/min works for Fad variables too, except
00528   // we need to add a case when the argument types are different.  This 
00529   // can't conflict with the general definition, so we need to use
00530   // Substitution Failure Is Not An Error
00531 #include "Sacado_mpl_disable_if.hpp"
00532 #include "Sacado_mpl_is_same.hpp"
00533 
00534 #define FAD_SFINAE_BINARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE,DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
00535 namespace Sacado {              \
00536   namespace CacheFad {              \
00537                   \
00538     template <typename ExprT1, typename ExprT2>       \
00539     class OP {                \
00540                   \
00541     public:               \
00542                   \
00543       typedef typename ExprT1::value_type value_type_1;     \
00544       typedef typename ExprT2::value_type value_type_2;     \
00545       typedef typename Sacado::Promote<value_type_1,      \
00546                value_type_2>::type value_type;  \
00547                   \
00548       OP(const ExprT1& expr1, const ExprT2& expr2) {}     \
00549                   \
00550       value_type              \
00551       computeValue(const ExprT1& expr1, const ExprT2& expr2) const {  \
00552   v1 = expr1.val();           \
00553   v2 = expr2.val();           \
00554   PARTIAL;              \
00555   return VALUE;             \
00556       }                 \
00557                   \
00558       value_type              \
00559       computeDx(int i, const ExprT1& expr1,       \
00560     const ExprT2& expr2) const {        \
00561   return DX;              \
00562       }                 \
00563                   \
00564       value_type              \
00565       computeFastAccessDx(int i, const ExprT1& expr1,     \
00566         const ExprT2& expr2) const {      \
00567   return FASTACCESSDX;            \
00568       }                 \
00569                   \
00570     protected:                \
00571                   \
00572       mutable value_type_1 v1;            \
00573       mutable value_type_2 v2;            \
00574       mutable value_type a;           \
00575       mutable value_type b;           \
00576     };                  \
00577                   \
00578     template <typename ExprT1>            \
00579     class OP<ExprT1, ConstExpr<typename ExprT1::value_type> > {   \
00580                   \
00581     public:               \
00582                   \
00583       typedef typename ExprT1::value_type value_type;     \
00584       typedef ConstExpr<typename ExprT1::value_type> ExprT2;    \
00585                   \
00586       OP(const ExprT1& expr1, const ExprT2& expr2) {}     \
00587                   \
00588       value_type              \
00589       computeValue(const ExprT1& expr1, const ExprT2& expr2) const {  \
00590   v1 = expr1.val();           \
00591   v2 = expr2.val();           \
00592   PARTIAL;              \
00593   return VALUE;             \
00594       }                 \
00595                   \
00596       value_type              \
00597       computeDx(int i, const ExprT1& expr1,       \
00598     const ExprT2& expr2) const {        \
00599   return CONST_DX_2;            \
00600       }                 \
00601                   \
00602       value_type              \
00603       computeFastAccessDx(int i, const ExprT1& expr1,     \
00604         const ExprT2& expr2) const {      \
00605   return CONST_FASTACCESSDX_2;          \
00606       }                 \
00607                   \
00608     protected:                \
00609                   \
00610       mutable value_type v1;            \
00611       mutable value_type v2;            \
00612       mutable value_type a;           \
00613       mutable value_type b;           \
00614     };                  \
00615                   \
00616     template <typename ExprT2>            \
00617     class OP<ConstExpr<typename ExprT2::value_type>, ExprT2 > {   \
00618                   \
00619     public:               \
00620                   \
00621       typedef typename ExprT2::value_type value_type;     \
00622       typedef ConstExpr<typename ExprT2::value_type> ExprT1;    \
00623                   \
00624       OP(const ExprT1& expr1, const ExprT2& expr2) {}     \
00625                   \
00626       value_type              \
00627       computeValue(const ExprT1& expr1, const ExprT2& expr2) const {  \
00628   v1 = expr1.val();           \
00629   v2 = expr2.val();           \
00630   PARTIAL;              \
00631   return VALUE;             \
00632       }                 \
00633                   \
00634       value_type              \
00635       computeDx(int i, const ExprT1& expr1,       \
00636     const ExprT2& expr2) const {        \
00637   return CONST_DX_1;            \
00638       }                 \
00639                   \
00640       value_type              \
00641       computeFastAccessDx(int i, const ExprT1& expr1,     \
00642         const ExprT2& expr2) const {      \
00643   return CONST_FASTACCESSDX_1;          \
00644       }                 \
00645                   \
00646     protected:                \
00647                   \
00648       mutable value_type v1;            \
00649       mutable value_type v2;            \
00650       mutable value_type a;           \
00651       mutable value_type b;           \
00652     };                  \
00653                   \
00654     template <typename T1, typename T2>         \
00655     inline                                                              \
00656     typename                                                            \
00657     mpl::disable_if< mpl::is_same<T1,T2>,                               \
00658                      Expr<BinaryExpr<Expr<T1>, Expr<T2>, OP> > >::type  \
00659     OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2)   \
00660     {                 \
00661       typedef BinaryExpr< Expr<T1>, Expr<T2>, OP > expr_t;    \
00662                       \
00663       return Expr<expr_t>(expr_t(expr1, expr2));      \
00664     }                 \
00665                   \
00666     template <typename T>           \
00667     inline Expr< BinaryExpr< ConstExpr<typename Expr<T>::value_type>, \
00668            Expr<T>, OP > >        \
00669     OPNAME (const typename Expr<T>::value_type& c,      \
00670       const Expr<T>& expr)          \
00671     {                 \
00672       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
00673       typedef BinaryExpr< ConstT, Expr<T>, OP > expr_t;     \
00674                   \
00675       return Expr<expr_t>(expr_t(ConstT(c), expr));     \
00676     }                 \
00677                   \
00678     template <typename T>           \
00679     inline Expr< BinaryExpr< Expr<T>,         \
00680            ConstExpr<typename Expr<T>::value_type>, \
00681            OP > >         \
00682     OPNAME (const Expr<T>& expr,          \
00683       const typename Expr<T>::value_type& c)      \
00684     {                 \
00685       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
00686       typedef BinaryExpr< Expr<T>, ConstT, OP > expr_t;     \
00687                   \
00688       return Expr<expr_t>(expr_t(expr, ConstT(c)));     \
00689     }                 \
00690   }                 \
00691 }
00692 
00693 // FAD_SFINAE_BINARYOP_MACRO(max,
00694 //       MaxOp,
00695 //       ;,
00696 //       std::max(expr1.val(), expr2.val()),
00697 //       expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00698 //       expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
00699 //                                    expr2.fastAccessDx(i),
00700 //       expr1.val() >= expr2.val() ? value_type(0) : expr2.dx(i),
00701 //       expr1.val() >= expr2.val() ? expr1.dx(i) : value_type(0),
00702 //       expr1.val() >= expr2.val() ? value_type(0) : 
00703 //                                    expr2.fastAccessDx(i),
00704 //       expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
00705 //                                    value_type(0))
00706 // FAD_SFINAE_BINARYOP_MACRO(min,
00707 //       MinOp,
00708 //       ;,
00709 //       std::min(expr1.val(), expr2.val()),
00710 //       expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00711 //       expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
00712 //                                    expr2.fastAccessDx(i),
00713 //       expr1.val() <= expr2.val() ? value_type(0) : expr2.dx(i),
00714 //       expr1.val() <= expr2.val() ? expr1.dx(i) : value_type(0),
00715 //       expr1.val() <= expr2.val() ? value_type(0) : 
00716 //                                    expr2.fastAccessDx(i),
00717 //       expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
00718 //                                    value_type(0))
00719 
00720 #undef FAD_SFINAE_BINARYOP_MACRO
00721 
00722 //-------------------------- Relational Operators -----------------------
00723 
00724 #define FAD_RELOP_MACRO(OP)           \
00725 namespace Sacado {              \
00726   namespace CacheFad {              \
00727     template <typename ExprT1, typename ExprT2>       \
00728     inline bool               \
00729     operator OP (const Expr<ExprT1>& expr1,       \
00730      const Expr<ExprT2>& expr2)       \
00731     {                 \
00732       return expr1.val() OP expr2.val();        \
00733     }                 \
00734                   \
00735     template <typename ExprT2>            \
00736     inline bool               \
00737     operator OP (const typename Expr<ExprT2>::value_type& a,    \
00738      const Expr<ExprT2>& expr2)       \
00739     {                 \
00740       return a OP expr2.val();            \
00741     }                 \
00742                   \
00743     template <typename ExprT1>            \
00744     inline bool               \
00745     operator OP (const Expr<ExprT1>& expr1,       \
00746      const typename Expr<ExprT1>::value_type& b)    \
00747     {                 \
00748       return expr1.val() OP b;            \
00749     }                 \
00750   }                 \
00751 }
00752 
00753 FAD_RELOP_MACRO(==)
00754 FAD_RELOP_MACRO(!=)
00755 FAD_RELOP_MACRO(<)
00756 FAD_RELOP_MACRO(>)
00757 FAD_RELOP_MACRO(<=)
00758 FAD_RELOP_MACRO(>=)
00759 FAD_RELOP_MACRO(<<=)
00760 FAD_RELOP_MACRO(>>=)
00761 FAD_RELOP_MACRO(&)
00762 FAD_RELOP_MACRO(|)
00763 
00764 #undef FAD_RELOP_MACRO
00765 
00766 namespace Sacado {
00767 
00768   namespace CacheFad {
00769 
00770     template <typename ExprT>
00771     inline bool operator ! (const Expr<ExprT>& expr) 
00772     {
00773       return ! expr.val();
00774     }
00775 
00776   } // namespace CacheFad
00777 
00778 } // namespace Sacado
00779 
00780 //-------------------------- I/O Operators -----------------------
00781 
00782 namespace Sacado {
00783 
00784   namespace CacheFad {
00785 
00786     template <typename ExprT>
00787     std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
00788       os << x.val() << "  [";
00789       
00790       for (int i=0; i< x.size(); i++) {
00791   os << " " << x.dx(i);
00792       }
00793 
00794       os << " ]\n";
00795       return os;
00796     }
00797 
00798   } // namespace CacheFad
00799 
00800 } // namespace Sacado
00801 
00802 
00803 #endif // SACADO_CACHEFAD_OPS_HPP

Generated on Wed May 12 21:59:04 2010 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.4.7