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,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       value_type val() const {            \
00085   v = expr.val();             \
00086   PARTIAL;              \
00087   return VALUE;             \
00088       }                 \
00089                   \
00090       value_type dx(int i) const {          \
00091   return DX;              \
00092       }                 \
00093                   \
00094       value_type fastAccessDx(int i) const {        \
00095   return FASTACCESSDX;            \
00096       }                 \
00097                   \
00098     protected:                \
00099                   \
00100       const ExprT& expr;            \
00101       mutable value_type v;           \
00102       mutable value_type a;           \
00103     };                  \
00104                   \
00105     template <typename T>           \
00106     inline Expr< OP< Expr<T> > >          \
00107     OPNAME (const Expr<T>& expr)          \
00108     {                 \
00109       typedef OP< Expr<T> > expr_t;         \
00110                         \
00111       return Expr<expr_t>(expr);          \
00112     }                 \
00113   }                 \
00114 }
00115 
00116 FAD_UNARYOP_MACRO(operator+,
00117       UnaryPlusOp, 
00118       ;,
00119       v,
00120       expr.dx(i),
00121       expr.fastAccessDx(i))
00122 FAD_UNARYOP_MACRO(operator-,
00123       UnaryMinusOp,
00124       ;, 
00125       -v,
00126       -expr.dx(i),
00127       -expr.fastAccessDx(i))
00128 FAD_UNARYOP_MACRO(exp,
00129       ExpOp, 
00130       a = std::exp(v),
00131       a,
00132       expr.dx(i)*a,
00133       expr.fastAccessDx(i)*a)
00134 FAD_UNARYOP_MACRO(log,
00135       LogOp, 
00136       ;,
00137       std::log(v),
00138       expr.dx(i)/v,
00139       expr.fastAccessDx(i)/v)
00140 FAD_UNARYOP_MACRO(log10,
00141       Log10Op, 
00142       a = std::log(value_type(10))*v,
00143       std::log10(v),
00144       expr.dx(i)/a,
00145       expr.fastAccessDx(i)/a)
00146 FAD_UNARYOP_MACRO(sqrt,
00147       SqrtOp,
00148       a = value_type(2)*std::sqrt(v),
00149       std::sqrt(v),
00150       expr.dx(i)/a,
00151       expr.fastAccessDx(i)/a)
00152 FAD_UNARYOP_MACRO(cos,
00153       CosOp, 
00154       a = std::sin(v),
00155       std::cos(v),
00156       -expr.dx(i)*a,
00157       -expr.fastAccessDx(i)*a)
00158 FAD_UNARYOP_MACRO(sin,
00159       SinOp, 
00160       a = std::cos(v),
00161       std::sin(v),
00162       expr.dx(i)*a,
00163       expr.fastAccessDx(i)*a)
00164 FAD_UNARYOP_MACRO(tan,
00165       TanOp, 
00166       value_type t = std::tan(v); a = value_type(1)+t*t,
00167       t,
00168       expr.dx(i)*a,
00169       expr.fastAccessDx(i)*a)
00170 FAD_UNARYOP_MACRO(acos,
00171       ACosOp, 
00172       a = - std::sqrt(value_type(1)-v*v),
00173       std::acos(v),
00174       expr.dx(i)/a,
00175       expr.fastAccessDx(i)/a)
00176 FAD_UNARYOP_MACRO(asin,
00177       ASinOp, 
00178       a = std::sqrt(value_type(1)-v*v),
00179       std::asin(v),
00180       expr.dx(i)/a,
00181       expr.fastAccessDx(i)/a)
00182 FAD_UNARYOP_MACRO(atan,
00183       ATanOp, 
00184       a = (value_type(1)+v*v),
00185       std::atan(v),
00186       expr.dx(i)/a,
00187       expr.fastAccessDx(i)/a)
00188 FAD_UNARYOP_MACRO(cosh,
00189       CoshOp, 
00190       a = std::sinh(v),
00191       std::cosh(v),
00192       expr.dx(i)*a,
00193       expr.fastAccessDx(i)*a)
00194 FAD_UNARYOP_MACRO(sinh,
00195       SinhOp, 
00196       a = std::cosh(v),
00197       std::sinh(v),
00198       expr.dx(i)*a,
00199       expr.fastAccessDx(i)*a)
00200 FAD_UNARYOP_MACRO(tanh,
00201       TanhOp, 
00202       a = std::cosh(v); a = a*a,
00203       std::tanh(v),
00204       expr.dx(i)/a,
00205       expr.fastAccessDx(i)/a)
00206 FAD_UNARYOP_MACRO(acosh,
00207       ACoshOp, 
00208       a = std::sqrt((v-value_type(1))*(v+value_type(1))),
00209       std::acosh(v),
00210       expr.dx(i)/a,
00211       expr.fastAccessDx(i)/a)
00212 FAD_UNARYOP_MACRO(asinh,
00213       ASinhOp, 
00214       a = std::sqrt(value_type(1)+v*v),
00215       std::asinh(v),
00216       expr.dx(i)/a,
00217       expr.fastAccessDx(i)/a)
00218 FAD_UNARYOP_MACRO(atanh,
00219       ATanhOp, 
00220       a = value_type(1)-v*v,
00221       std::atanh(v),
00222       expr.dx(i)/a,
00223       expr.fastAccessDx(i)/a)
00224 FAD_UNARYOP_MACRO(abs,
00225       AbsOp, 
00226       ;,
00227       std::abs(v),
00228       v >= 0 ? value_type(+expr.dx(i)) : value_type(-expr.dx(i)),
00229       v >= 0 ? value_type(+expr.fastAccessDx(i)) : 
00230         value_type(-expr.fastAccessDx(i)))
00231 FAD_UNARYOP_MACRO(fabs,
00232       FAbsOp, 
00233       ;,
00234       std::fabs(v),
00235       v >= 0 ? value_type(+expr.dx(i)) : value_type(-expr.dx(i)),
00236       v >= 0 ? value_type(+expr.fastAccessDx(i)) : 
00237         value_type(-expr.fastAccessDx(i)))
00238 
00239 #undef FAD_UNARYOP_MACRO
00240 
00241 #define FAD_BINARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE,DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
00242 namespace Sacado {              \
00243   namespace CacheFad {              \
00244                   \
00245     template <typename ExprT1, typename ExprT2>       \
00246     class OP {};              \
00247                   \
00248     template <typename ExprT1, typename ExprT2>       \
00249     class Expr< OP<ExprT1,ExprT2> > {         \
00250                   \
00251     public:               \
00252                   \
00253       typedef typename ExprT1::value_type value_type_1;     \
00254       typedef typename ExprT2::value_type value_type_2;     \
00255       typedef typename Sacado::Promote<value_type_1,      \
00256                value_type_2>::type value_type;  \
00257       typedef typename ExprT1::scalar_type scalar_type_1;   \
00258       typedef typename ExprT2::scalar_type scalar_type_2;   \
00259       typedef typename Sacado::Promote<scalar_type_1,     \
00260                scalar_type_2>::type scalar_type; \
00261                   \
00262       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00263   expr1(expr1_), expr2(expr2_) {}         \
00264                   \
00265       int size() const {            \
00266   int sz1 = expr1.size(), sz2 = expr2.size();     \
00267   return sz1 > sz2 ? sz1 : sz2;         \
00268       }                 \
00269                   \
00270       bool hasFastAccess() const {          \
00271   return expr1.hasFastAccess() && expr2.hasFastAccess();    \
00272       }                 \
00273                   \
00274       bool isPassive() const {            \
00275   return expr1.isPassive() && expr2.isPassive();      \
00276       }                 \
00277                   \
00278       value_type val() const {            \
00279   v1 = expr1.val();           \
00280   v2 = expr2.val();           \
00281   PARTIAL;              \
00282   return VALUE;             \
00283       }                 \
00284                   \
00285       value_type dx(int i) const {          \
00286   return DX;              \
00287       }                 \
00288                   \
00289       value_type fastAccessDx(int i) const {        \
00290   return FASTACCESSDX;            \
00291       }                 \
00292                   \
00293     protected:                \
00294                   \
00295       const ExprT1& expr1;            \
00296       const ExprT2& expr2;            \
00297       mutable value_type_1 v1;            \
00298       mutable value_type_2 v2;            \
00299       mutable value_type a;           \
00300       mutable value_type b;           \
00301     };                  \
00302                   \
00303     template <typename ExprT1>            \
00304     class Expr< OP<ExprT1, ConstExpr<typename ExprT1::value_type> >  >{ \
00305                   \
00306     public:               \
00307                   \
00308       typedef typename ExprT1::value_type value_type;     \
00309       typedef typename ExprT1::scalar_type scalar_type;     \
00310       typedef ConstExpr<typename ExprT1::value_type> ExprT2;    \
00311                   \
00312       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00313   expr1(expr1_), expr2(expr2_) {}         \
00314                   \
00315       int size() const {            \
00316   return expr1.size();            \
00317       }                 \
00318                   \
00319       bool hasFastAccess() const {          \
00320   return expr1.hasFastAccess();         \
00321       }                 \
00322                   \
00323       bool isPassive() const {            \
00324   return expr1.isPassive();         \
00325       }                 \
00326                   \
00327       value_type val() const {            \
00328   v1 = expr1.val();           \
00329   v2 = expr2.val();           \
00330   PARTIAL;              \
00331   return VALUE;             \
00332       }                 \
00333                   \
00334       value_type dx(int i) const {          \
00335   return CONST_DX_2;            \
00336       }                 \
00337                   \
00338       value_type fastAccessDx(int i) const {        \
00339   return CONST_FASTACCESSDX_2;          \
00340       }                 \
00341                   \
00342     protected:                \
00343                   \
00344       const ExprT1& expr1;            \
00345       const ExprT2 expr2;           \
00346       mutable value_type v1;            \
00347       mutable value_type v2;            \
00348       mutable value_type a;           \
00349       mutable value_type b;           \
00350     };                  \
00351                   \
00352     template <typename ExprT2>            \
00353     class Expr< OP<ConstExpr<typename ExprT2::value_type>, ExprT2 >  >{ \
00354                   \
00355     public:               \
00356                   \
00357       typedef typename ExprT2::value_type value_type;     \
00358       typedef typename ExprT2::scalar_type scalar_type;     \
00359       typedef ConstExpr<typename ExprT2::value_type> ExprT1;    \
00360                   \
00361       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00362   expr1(expr1_), expr2(expr2_) {}         \
00363                   \
00364       int size() const {            \
00365   return expr2.size();            \
00366       }                 \
00367                   \
00368       bool hasFastAccess() const {          \
00369   return expr2.hasFastAccess();         \
00370       }                 \
00371                   \
00372       bool isPassive() const {            \
00373   return expr2.isPassive();         \
00374       }                 \
00375                   \
00376       value_type val() const {            \
00377   v1 = expr1.val();           \
00378   v2 = expr2.val();           \
00379   PARTIAL;              \
00380   return VALUE;             \
00381       }                 \
00382                   \
00383       value_type dx(int i) const {          \
00384   return CONST_DX_1;            \
00385       }                 \
00386                   \
00387       value_type fastAccessDx(int i) const {        \
00388   return CONST_FASTACCESSDX_1;          \
00389       }                 \
00390                   \
00391     protected:                \
00392                   \
00393       const ExprT1 expr1;           \
00394       const ExprT2& expr2;            \
00395       mutable value_type v1;            \
00396       mutable value_type v2;            \
00397       mutable value_type a;           \
00398       mutable value_type b;           \
00399     };                  \
00400                   \
00401     template <typename ExprT1>            \
00402     class Expr< OP<ExprT1, ConstExpr<typename dummy<typename ExprT1::value_type,typename ExprT1::scalar_type>::type> > >{ \
00403                   \
00404     public:               \
00405                   \
00406       typedef typename ExprT1::value_type value_type;     \
00407       typedef typename ExprT1::scalar_type scalar_type;     \
00408       typedef ConstExpr<scalar_type> ExprT2;        \
00409                   \
00410       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00411   expr1(expr1_), expr2(expr2_) {}         \
00412                   \
00413       int size() const {            \
00414   return expr1.size();            \
00415       }                 \
00416                   \
00417       bool hasFastAccess() const {          \
00418   return expr1.hasFastAccess();         \
00419       }                 \
00420                   \
00421       bool isPassive() const {            \
00422   return expr1.isPassive();         \
00423       }                 \
00424                   \
00425       value_type val() const {            \
00426   v1 = expr1.val();           \
00427   v2 = expr2.val();           \
00428   PARTIAL;              \
00429   return VALUE;             \
00430       }                 \
00431                   \
00432       value_type dx(int i) const {          \
00433   return CONST_DX_2;            \
00434       }                 \
00435                   \
00436       value_type fastAccessDx(int i) const {        \
00437   return CONST_FASTACCESSDX_2;          \
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     };                  \
00449                   \
00450     template <typename ExprT2>            \
00451     class Expr< OP<ConstExpr<typename dummy<typename ExprT2::value_type,typename ExprT2::scalar_type>::type>, ExprT2 >  >{  \
00452                   \
00453     public:               \
00454                   \
00455       typedef typename ExprT2::value_type value_type;     \
00456       typedef typename ExprT2::scalar_type scalar_type;     \
00457       typedef ConstExpr<scalar_type> ExprT1;        \
00458                   \
00459       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00460   expr1(expr1_), expr2(expr2_) {}         \
00461                   \
00462       int size() const {            \
00463   return expr2.size();            \
00464       }                 \
00465                   \
00466       bool hasFastAccess() const {          \
00467   return expr2.hasFastAccess();         \
00468       }                 \
00469                   \
00470       bool isPassive() const {            \
00471   return expr2.isPassive();         \
00472       }                 \
00473                   \
00474       value_type val() const {            \
00475   v1 = expr1.val();           \
00476   v2 = expr2.val();           \
00477   PARTIAL;              \
00478   return VALUE;             \
00479       }                 \
00480                   \
00481       value_type dx(int i) const {          \
00482   return CONST_DX_1;            \
00483       }                 \
00484                   \
00485       value_type fastAccessDx(int i) const {        \
00486   return CONST_FASTACCESSDX_1;          \
00487       }                 \
00488                   \
00489     protected:                \
00490                   \
00491       const ExprT1 expr1;           \
00492       const ExprT2& expr2;            \
00493       mutable value_type v1;            \
00494       mutable value_type v2;            \
00495       mutable value_type a;           \
00496       mutable value_type b;           \
00497     };                  \
00498                   \
00499     template <typename T1, typename T2>         \
00500     inline Expr< OP< Expr<T1>, Expr<T2> > >       \
00501     OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2)   \
00502     {                 \
00503       typedef OP< Expr<T1>, Expr<T2> > expr_t;        \
00504                       \
00505       return Expr<expr_t>(expr1, expr2);        \
00506     }                 \
00507                   \
00508     template <typename T>           \
00509     inline Expr< OP< Expr<T>, Expr<T> > >       \
00510     OPNAME (const Expr<T>& expr1, const Expr<T>& expr2)     \
00511     {                 \
00512       typedef OP< Expr<T>, Expr<T> > expr_t;        \
00513                       \
00514       return Expr<expr_t>(expr1, expr2);        \
00515     }                 \
00516                   \
00517     template <typename T>           \
00518     inline Expr< OP< ConstExpr<typename Expr<T>::value_type>,   \
00519            Expr<T> > >        \
00520     OPNAME (const typename Expr<T>::value_type& c,      \
00521       const Expr<T>& expr)          \
00522     {                 \
00523       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
00524       typedef OP< ConstT, Expr<T> > expr_t;       \
00525                   \
00526       return Expr<expr_t>(ConstT(c), expr);       \
00527     }                 \
00528                   \
00529     template <typename T>           \
00530     inline Expr< OP< Expr<T>,           \
00531          ConstExpr<typename Expr<T>::value_type> > >  \
00532     OPNAME (const Expr<T>& expr,          \
00533       const typename Expr<T>::value_type& c)      \
00534     {                 \
00535       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
00536       typedef OP< Expr<T>, ConstT > expr_t;       \
00537                   \
00538       return Expr<expr_t>(expr, ConstT(c));       \
00539     }                 \
00540                   \
00541     template <typename T>           \
00542     inline Expr< OP< ConstExpr<typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type>, \
00543            Expr<T> > >        \
00544     OPNAME (const typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type& c,      \
00545       const Expr<T>& expr)          \
00546     {                 \
00547       typedef typename Expr<T>::value_type value_type;      \
00548       typedef typename Expr<T>::scalar_type scalar_type;    \
00549       typedef typename dummy<value_type,scalar_type>::type const_type;  \
00550       typedef ConstExpr<const_type> ConstT;       \
00551       typedef OP< ConstT, Expr<T> > expr_t;       \
00552                   \
00553       return Expr<expr_t>(ConstT(c), expr);       \
00554     }                 \
00555                   \
00556     template <typename T>           \
00557     inline Expr< OP< Expr<T>,           \
00558          ConstExpr<typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type> > >  \
00559     OPNAME (const Expr<T>& expr,          \
00560       const typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type& c)      \
00561     {                 \
00562       typedef typename Expr<T>::value_type value_type;      \
00563       typedef typename Expr<T>::scalar_type scalar_type;    \
00564       typedef typename dummy<value_type,scalar_type>::type const_type;  \
00565       typedef ConstExpr<const_type> ConstT;       \
00566       typedef OP< Expr<T>, ConstT > expr_t;       \
00567                   \
00568       return Expr<expr_t>(expr, ConstT(c));       \
00569     }                 \
00570   }                 \
00571 }
00572 
00573 FAD_BINARYOP_MACRO(operator+,
00574        AdditionOp, 
00575        ;,
00576        v1 + v2,
00577        expr1.dx(i) + expr2.dx(i),
00578        expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
00579        expr2.dx(i),
00580        expr1.dx(i),
00581        expr2.fastAccessDx(i),
00582        expr1.fastAccessDx(i))
00583 FAD_BINARYOP_MACRO(operator-,
00584        SubtractionOp, 
00585        ;,
00586        v1 - v2,
00587        expr1.dx(i) - expr2.dx(i),
00588        expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
00589        -expr2.dx(i),
00590        expr1.dx(i),
00591        -expr2.fastAccessDx(i),
00592        expr1.fastAccessDx(i))
00593 // FAD_BINARYOP_MACRO(operator*,
00594 //       MultiplicationOp, 
00595 //       ;,
00596 //       v1*v2,
00597 //       v1*expr2.dx(i) + expr1.dx(i)*v2,
00598 //       v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2,
00599 //       v1*expr2.dx(i),
00600 //       expr1.dx(i)*v2,
00601 //       v1*expr2.fastAccessDx(i),
00602 //       expr1.fastAccessDx(i)*v2)
00603 
00604 namespace Sacado {              
00605   namespace CacheFad {              
00606                   
00607     template <typename ExprT1, typename ExprT2>       
00608     class MultiplicationOp {};              
00609                   
00610     template <typename ExprT1, typename ExprT2>       
00611     class Expr< MultiplicationOp<ExprT1,ExprT2> > {
00612 
00613     public:               
00614                   
00615       typedef typename ExprT1::value_type value_type_1;     
00616       typedef typename ExprT2::value_type value_type_2;     
00617       typedef typename Sacado::Promote<value_type_1,      
00618                value_type_2>::type value_type;  
00619       typedef typename ExprT1::scalar_type scalar_type_1;   
00620       typedef typename ExprT2::scalar_type scalar_type_2;   
00621       typedef typename Sacado::Promote<scalar_type_1,     
00622                scalar_type_2>::type scalar_type; 
00623                   
00624       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00625   expr1(expr1_), expr2(expr2_) {}         
00626                   
00627       int size() const {            
00628   int sz1 = expr1.size(), sz2 = expr2.size();     
00629   return sz1 > sz2 ? sz1 : sz2;         
00630       }                 
00631                   
00632       bool hasFastAccess() const {          
00633   return expr1.hasFastAccess() && expr2.hasFastAccess();    
00634       }                 
00635                   
00636       bool isPassive() const {            
00637   return expr1.isPassive() && expr2.isPassive();      
00638       }                 
00639                   
00640       value_type val() const {            
00641   v1 = expr1.val();           
00642   v2 = expr2.val();           
00643   return v1*v2;             
00644       }                 
00645                   
00646       value_type dx(int i) const {          
00647   //return v1*expr2.dx(i) + expr1.dx(i)*v2;
00648   if (expr1.size() > 0 && expr2.size() > 0)
00649     return v1*expr2.dx(i) + expr1.dx(i)*v2;
00650   else if (expr1.size() > 0)
00651     return expr1.dx(i)*v2;
00652   else
00653     return v1*expr2.dx(i);
00654       }                 
00655                   
00656       value_type fastAccessDx(int i) const {        
00657   return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
00658       }                 
00659                   
00660     protected:                
00661                   
00662       const ExprT1& expr1;            
00663       const ExprT2& expr2;            
00664       mutable value_type_1 v1;            
00665       mutable value_type_2 v2;            
00666       mutable value_type a;           
00667       mutable value_type b;           
00668     };                  
00669                   
00670     template <typename ExprT1>            
00671     class Expr< MultiplicationOp<ExprT1, ConstExpr<typename ExprT1::value_type> >  >{ 
00672                   
00673     public:               
00674                   
00675       typedef typename ExprT1::value_type value_type;     
00676       typedef typename ExprT1::scalar_type scalar_type;     
00677       typedef ConstExpr<typename ExprT1::value_type> ExprT2;    
00678                   
00679       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00680   expr1(expr1_), expr2(expr2_) {}         
00681                   
00682       int size() const {            
00683   return expr1.size();            
00684       }                 
00685                   
00686       bool hasFastAccess() const {          
00687   return expr1.hasFastAccess();         
00688       }                 
00689                   
00690       bool isPassive() const {            
00691   return expr1.isPassive();         
00692       }                 
00693                   
00694       value_type val() const {            
00695   v1 = expr1.val();           
00696   v2 = expr2.val();           
00697   return v1*v2;             
00698       }                 
00699                   
00700       value_type dx(int i) const {          
00701   return expr1.dx(i)*v2;            
00702       }                 
00703                   
00704       value_type fastAccessDx(int i) const {        
00705   return expr1.fastAccessDx(i)*v2;          
00706       }                 
00707                   
00708     protected:                
00709                   
00710       const ExprT1& expr1;            
00711       const ExprT2 expr2;           
00712       mutable value_type v1;            
00713       mutable value_type v2;            
00714       mutable value_type a;           
00715       mutable value_type b;           
00716     };                  
00717                   
00718     template <typename ExprT2>            
00719     class Expr< MultiplicationOp<ConstExpr<typename ExprT2::value_type>, ExprT2 >  >{ 
00720                   
00721     public:               
00722                   
00723       typedef typename ExprT2::value_type value_type;     
00724       typedef typename ExprT2::scalar_type scalar_type;     
00725       typedef ConstExpr<typename ExprT2::value_type> ExprT1;    
00726                   
00727       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00728   expr1(expr1_), expr2(expr2_) {}         
00729                   
00730       int size() const {            
00731   return expr2.size();            
00732       }                 
00733                   
00734       bool hasFastAccess() const {          
00735   return expr2.hasFastAccess();         
00736       }                 
00737                   
00738       bool isPassive() const {            
00739   return expr2.isPassive();         
00740       }                 
00741                   
00742       value_type val() const {            
00743   v1 = expr1.val();           
00744   v2 = expr2.val();           
00745   return v1*v2;             
00746       }                 
00747                   
00748       value_type dx(int i) const {          
00749   return v1*expr2.dx(i);            
00750       }                 
00751                   
00752       value_type fastAccessDx(int i) const {        
00753   return v1*expr2.fastAccessDx(i);          
00754       }                 
00755                   
00756     protected:                     
00757                   
00758       const ExprT1 expr1;           
00759       const ExprT2& expr2;            
00760       mutable value_type v1;            
00761       mutable value_type v2;            
00762       mutable value_type a;           
00763       mutable value_type b;           
00764     };                  
00765                   
00766     template <typename ExprT1>            
00767     class Expr< MultiplicationOp<ExprT1, ConstExpr<typename dummy<typename ExprT1::value_type,typename ExprT1::scalar_type>::type> > >{ 
00768                   
00769     public:               
00770                   
00771       typedef typename ExprT1::value_type value_type;     
00772       typedef typename ExprT1::scalar_type scalar_type;     
00773       typedef ConstExpr<scalar_type> ExprT2;        
00774                   
00775       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00776   expr1(expr1_), expr2(expr2_) {}         
00777                   
00778       int size() const {            
00779   return expr1.size();            
00780       }                 
00781                   
00782       bool hasFastAccess() const {          
00783   return expr1.hasFastAccess();         
00784       }                 
00785                   
00786       bool isPassive() const {            
00787   return expr1.isPassive();         
00788       }                 
00789                   
00790       value_type val() const {            
00791   v1 = expr1.val();           
00792   v2 = expr2.val();           
00793   return v1*v2;             
00794       }                 
00795                   
00796       value_type dx(int i) const {          
00797   return expr1.dx(i)*v2;            
00798       }                 
00799                   
00800       value_type fastAccessDx(int i) const {        
00801   return expr1.fastAccessDx(i)*v2;          
00802       }                 
00803                   
00804     protected:                
00805                   
00806       const ExprT1& expr1;            
00807       const ExprT2 expr2;           
00808       mutable value_type v1;            
00809       mutable value_type v2;            
00810       mutable value_type a;           
00811       mutable value_type b;           
00812     };                  
00813                   
00814     template <typename ExprT2>            
00815     class Expr< MultiplicationOp<ConstExpr<typename dummy<typename ExprT2::value_type,typename ExprT2::scalar_type>::type>, ExprT2 >  >{  
00816                   
00817     public:               
00818                   
00819       typedef typename ExprT2::value_type value_type;     
00820       typedef typename ExprT2::scalar_type scalar_type;     
00821       typedef ConstExpr<scalar_type> ExprT1;        
00822                   
00823       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    
00824   expr1(expr1_), expr2(expr2_) {}         
00825                   
00826       int size() const {            
00827   return expr2.size();            
00828       }                 
00829                   
00830       bool hasFastAccess() const {          
00831   return expr2.hasFastAccess();         
00832       }               
00833                     
00834       bool isPassive() const {            
00835   return expr2.isPassive();         
00836       }                 
00837                   
00838       value_type val() const {            
00839   v1 = expr1.val();           
00840   v2 = expr2.val();           
00841   return v1*v2;             
00842       }                 
00843                   
00844       value_type dx(int i) const {          
00845   return v1*expr2.dx(i);            
00846       }                 
00847                   
00848       value_type fastAccessDx(int i) const {        
00849   return v1*expr2.fastAccessDx(i);          
00850       }                 
00851                   
00852     protected:                
00853                   
00854       const ExprT1 expr1;           
00855       const ExprT2& expr2;            
00856       mutable value_type v1;            
00857       mutable value_type v2;            
00858       mutable value_type a;           
00859       mutable value_type b;           
00860     };                  
00861                   
00862     template <typename T1, typename T2>         
00863     inline Expr< MultiplicationOp< Expr<T1>, Expr<T2> > > 
00864     operator* (const Expr<T1>& expr1, const Expr<T2>& expr2)    
00865     {                 
00866       typedef MultiplicationOp< Expr<T1>, Expr<T2> > expr_t;
00867       return Expr<expr_t>(expr1, expr2);        
00868     }                 
00869                   
00870     template <typename T>           
00871     inline Expr< MultiplicationOp< Expr<T>, Expr<T> > >       
00872     operator* (const Expr<T>& expr1, const Expr<T>& expr2)      
00873     {                 
00874       typedef MultiplicationOp< Expr<T>, Expr<T> > expr_t;
00875       return Expr<expr_t>(expr1, expr2);        
00876     }                 
00877                   
00878     template <typename T>           
00879     inline Expr< MultiplicationOp< ConstExpr<typename Expr<T>::value_type>,
00880            Expr<T> > >        
00881     operator* (const typename Expr<T>::value_type& c,     
00882       const Expr<T>& expr)          
00883     {                 
00884       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   
00885       typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
00886       return Expr<expr_t>(ConstT(c), expr);       
00887     }                 
00888                   
00889     template <typename T>                
00890     inline Expr< MultiplicationOp< Expr<T>,
00891            ConstExpr<typename Expr<T>::value_type> > >  
00892     operator* (const Expr<T>& expr,         
00893       const typename Expr<T>::value_type& c)      
00894     {                 
00895       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   
00896       typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
00897       return Expr<expr_t>(expr, ConstT(c));       
00898     }                 
00899                       
00900     template <typename T>           
00901     inline Expr< MultiplicationOp< ConstExpr<typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type>, 
00902            Expr<T> > >        
00903     operator* (const typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type& c,     
00904       const Expr<T>& expr)          
00905     {                 
00906       typedef typename Expr<T>::value_type value_type;      
00907       typedef typename Expr<T>::scalar_type scalar_type;    
00908       typedef typename dummy<value_type,scalar_type>::type const_type;  
00909       typedef ConstExpr<const_type> ConstT;       
00910       typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
00911       return Expr<expr_t>(ConstT(c), expr);       
00912     }                 
00913                   
00914     template <typename T>           
00915     inline Expr< MultiplicationOp< Expr<T>,           
00916          ConstExpr<typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type> > >  
00917     operator* (const Expr<T>& expr,         
00918       const typename dummy<typename Expr<T>::value_type,typename Expr<T>::scalar_type>::type& c)      
00919     {                 
00920       typedef typename Expr<T>::value_type value_type;      
00921       typedef typename Expr<T>::scalar_type scalar_type;    
00922       typedef typename dummy<value_type,scalar_type>::type const_type;  
00923       typedef ConstExpr<const_type> ConstT;       
00924       typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
00925       return Expr<expr_t>(expr, ConstT(c));       
00926     }                 
00927   }                 
00928 }
00929 
00930 
00931 
00932 FAD_BINARYOP_MACRO(operator/,
00933        DivisionOp, 
00934        value_type c = v1/v2; a = value_type(1)/v2; b = -c/v2,
00935        c,
00936        expr1.dx(i)*a + expr2.dx(i)*b,
00937        expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b,
00938        expr2.dx(i)*b,
00939        expr1.dx(i)*a,
00940        expr2.fastAccessDx(i)*b,
00941        expr1.fastAccessDx(i)*a)
00942 FAD_BINARYOP_MACRO(atan2,
00943        Atan2Op,
00944        a=v1*v1 + v2*v2,
00945        std::atan2(v1,v2),
00946        (expr1.dx(i)*v2 - expr2.dx(i)*v1)/a,
00947        (expr1.fastAccessDx(i)*v2 - expr2.fastAccessDx(i)*v1)/a,
00948        (-expr2.dx(i)*v1)/a,
00949        (expr1.dx(i)*v2)/a,
00950        (-expr2.fastAccessDx(i)*v1)/a,
00951        (expr1.fastAccessDx(i)*v2)/a)
00952 FAD_BINARYOP_MACRO(pow,
00953        PowerOp,
00954        value_type c= std::pow(v1,v2); a=c*v2/v1; b=c*std::log(v1),
00955        c,
00956        expr1.dx(i)*a + expr2.dx(i)*b,
00957        expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b,
00958        expr2.dx(i)*b,
00959        expr1.dx(i)*a,
00960        expr2.fastAccessDx(i)*b,
00961        expr1.fastAccessDx(i)*a)
00962 FAD_BINARYOP_MACRO(max,
00963        MaxOp,
00964        ;,
00965        std::max(expr1.val(), expr2.val()),
00966        expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00967        expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
00968                                     expr2.fastAccessDx(i),
00969        expr1.val() >= expr2.val() ? value_type(0) : expr2.dx(i),
00970        expr1.val() >= expr2.val() ? expr1.dx(i) : value_type(0),
00971        expr1.val() >= expr2.val() ? value_type(0) : 
00972                                     expr2.fastAccessDx(i),
00973        expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
00974                                     value_type(0))
00975 FAD_BINARYOP_MACRO(min,
00976        MinOp,
00977        ;,
00978        std::min(expr1.val(), expr2.val()),
00979        expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00980        expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
00981                                     expr2.fastAccessDx(i),
00982        expr1.val() <= expr2.val() ? value_type(0) : expr2.dx(i),
00983        expr1.val() <= expr2.val() ? expr1.dx(i) : value_type(0),
00984        expr1.val() <= expr2.val() ? value_type(0) : 
00985                                     expr2.fastAccessDx(i),
00986        expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
00987                                     value_type(0))
00988 
00989 #undef FAD_BINARYOP_MACRO
00990   
00991   // The general definition of max/min works for Fad variables too, except
00992   // we need to add a case when the argument types are different.  This 
00993   // can't conflict with the general definition, so we need to use
00994   // Substitution Failure Is Not An Error
00995 #include "Sacado_mpl_disable_if.hpp"
00996 #include "Sacado_mpl_is_same.hpp"
00997 
00998 #define FAD_SFINAE_BINARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE,DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
00999 namespace Sacado {              \
01000   namespace CacheFad {              \
01001                   \
01002     template <typename ExprT1, typename ExprT2>       \
01003     class OP {                \
01004                   \
01005     public:               \
01006                   \
01007       typedef typename ExprT1::value_type value_type_1;     \
01008       typedef typename ExprT2::value_type value_type_2;     \
01009       typedef typename Sacado::Promote<value_type_1,      \
01010                value_type_2>::type value_type;  \
01011                   \
01012       OP(const ExprT1& expr1, const ExprT2& expr2) {}     \
01013                   \
01014       value_type              \
01015       computeValue(const ExprT1& expr1, const ExprT2& expr2) const {  \
01016   v1 = expr1.val();           \
01017   v2 = expr2.val();           \
01018   PARTIAL;              \
01019   return VALUE;             \
01020       }                 \
01021                   \
01022       value_type              \
01023       computeDx(int i, const ExprT1& expr1,       \
01024     const ExprT2& expr2) const {        \
01025   return DX;              \
01026       }                 \
01027                   \
01028       value_type              \
01029       computeFastAccessDx(int i, const ExprT1& expr1,     \
01030         const ExprT2& expr2) const {      \
01031   return FASTACCESSDX;            \
01032       }                 \
01033                   \
01034     protected:                \
01035                   \
01036       mutable value_type_1 v1;            \
01037       mutable value_type_2 v2;            \
01038       mutable value_type a;           \
01039       mutable value_type b;           \
01040     };                  \
01041                   \
01042     template <typename ExprT1>            \
01043     class OP<ExprT1, ConstExpr<typename ExprT1::value_type> > {   \
01044                   \
01045     public:               \
01046                   \
01047       typedef typename ExprT1::value_type value_type;     \
01048       typedef ConstExpr<typename ExprT1::value_type> ExprT2;    \
01049                   \
01050       OP(const ExprT1& expr1, const ExprT2& expr2) {}     \
01051                   \
01052       value_type              \
01053       computeValue(const ExprT1& expr1, const ExprT2& expr2) const {  \
01054   v1 = expr1.val();           \
01055   v2 = expr2.val();           \
01056   PARTIAL;              \
01057   return VALUE;             \
01058       }                 \
01059                   \
01060       value_type              \
01061       computeDx(int i, const ExprT1& expr1,       \
01062     const ExprT2& expr2) const {        \
01063   return CONST_DX_2;            \
01064       }                 \
01065                   \
01066       value_type              \
01067       computeFastAccessDx(int i, const ExprT1& expr1,     \
01068         const ExprT2& expr2) const {      \
01069   return CONST_FASTACCESSDX_2;          \
01070       }                 \
01071                   \
01072     protected:                \
01073                   \
01074       mutable value_type v1;            \
01075       mutable value_type v2;            \
01076       mutable value_type a;           \
01077       mutable value_type b;           \
01078     };                  \
01079                   \
01080     template <typename ExprT2>            \
01081     class OP<ConstExpr<typename ExprT2::value_type>, ExprT2 > {   \
01082                   \
01083     public:               \
01084                   \
01085       typedef typename ExprT2::value_type value_type;     \
01086       typedef ConstExpr<typename ExprT2::value_type> ExprT1;    \
01087                   \
01088       OP(const ExprT1& expr1, const ExprT2& expr2) {}     \
01089                   \
01090       value_type              \
01091       computeValue(const ExprT1& expr1, const ExprT2& expr2) const {  \
01092   v1 = expr1.val();           \
01093   v2 = expr2.val();           \
01094   PARTIAL;              \
01095   return VALUE;             \
01096       }                 \
01097                   \
01098       value_type              \
01099       computeDx(int i, const ExprT1& expr1,       \
01100     const ExprT2& expr2) const {        \
01101   return CONST_DX_1;            \
01102       }                 \
01103                   \
01104       value_type              \
01105       computeFastAccessDx(int i, const ExprT1& expr1,     \
01106         const ExprT2& expr2) const {      \
01107   return CONST_FASTACCESSDX_1;          \
01108       }                 \
01109                   \
01110     protected:                \
01111                   \
01112       mutable value_type v1;            \
01113       mutable value_type v2;            \
01114       mutable value_type a;           \
01115       mutable value_type b;           \
01116     };                  \
01117                   \
01118     template <typename T1, typename T2>         \
01119     inline                                                              \
01120     typename                                                            \
01121     mpl::disable_if< mpl::is_same<T1,T2>,                               \
01122                      Expr<BinaryExpr<Expr<T1>, Expr<T2>, OP> > >::type  \
01123     OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2)   \
01124     {                 \
01125       typedef BinaryExpr< Expr<T1>, Expr<T2>, OP > expr_t;    \
01126                       \
01127       return Expr<expr_t>(expr_t(expr1, expr2));      \
01128     }                 \
01129                   \
01130     template <typename T>           \
01131     inline Expr< BinaryExpr< ConstExpr<typename Expr<T>::value_type>, \
01132            Expr<T>, OP > >        \
01133     OPNAME (const typename Expr<T>::value_type& c,      \
01134       const Expr<T>& expr)          \
01135     {                 \
01136       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
01137       typedef BinaryExpr< ConstT, Expr<T>, OP > expr_t;     \
01138                   \
01139       return Expr<expr_t>(expr_t(ConstT(c), expr));     \
01140     }                 \
01141                   \
01142     template <typename T>           \
01143     inline Expr< BinaryExpr< Expr<T>,         \
01144            ConstExpr<typename Expr<T>::value_type>, \
01145            OP > >         \
01146     OPNAME (const Expr<T>& expr,          \
01147       const typename Expr<T>::value_type& c)      \
01148     {                 \
01149       typedef ConstExpr<typename Expr<T>::value_type> ConstT;   \
01150       typedef BinaryExpr< Expr<T>, ConstT, OP > expr_t;     \
01151                   \
01152       return Expr<expr_t>(expr_t(expr, ConstT(c)));     \
01153     }                 \
01154   }                 \
01155 }
01156 
01157 // FAD_SFINAE_BINARYOP_MACRO(max,
01158 //       MaxOp,
01159 //       ;,
01160 //       std::max(expr1.val(), expr2.val()),
01161 //       expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
01162 //       expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
01163 //                                    expr2.fastAccessDx(i),
01164 //       expr1.val() >= expr2.val() ? value_type(0) : expr2.dx(i),
01165 //       expr1.val() >= expr2.val() ? expr1.dx(i) : value_type(0),
01166 //       expr1.val() >= expr2.val() ? value_type(0) : 
01167 //                                    expr2.fastAccessDx(i),
01168 //       expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
01169 //                                    value_type(0))
01170 // FAD_SFINAE_BINARYOP_MACRO(min,
01171 //       MinOp,
01172 //       ;,
01173 //       std::min(expr1.val(), expr2.val()),
01174 //       expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
01175 //       expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
01176 //                                    expr2.fastAccessDx(i),
01177 //       expr1.val() <= expr2.val() ? value_type(0) : expr2.dx(i),
01178 //       expr1.val() <= expr2.val() ? expr1.dx(i) : value_type(0),
01179 //       expr1.val() <= expr2.val() ? value_type(0) : 
01180 //                                    expr2.fastAccessDx(i),
01181 //       expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
01182 //                                    value_type(0))
01183 
01184 #undef FAD_SFINAE_BINARYOP_MACRO
01185 
01186 //-------------------------- Relational Operators -----------------------
01187 
01188 #define FAD_RELOP_MACRO(OP)           \
01189 namespace Sacado {              \
01190   namespace CacheFad {              \
01191     template <typename ExprT1, typename ExprT2>       \
01192     inline bool               \
01193     operator OP (const Expr<ExprT1>& expr1,       \
01194      const Expr<ExprT2>& expr2)       \
01195     {                 \
01196       return expr1.val() OP expr2.val();        \
01197     }                 \
01198                   \
01199     template <typename ExprT2>            \
01200     inline bool               \
01201     operator OP (const typename Expr<ExprT2>::value_type& a,    \
01202      const Expr<ExprT2>& expr2)       \
01203     {                 \
01204       return a OP expr2.val();            \
01205     }                 \
01206                   \
01207     template <typename ExprT1>            \
01208     inline bool               \
01209     operator OP (const Expr<ExprT1>& expr1,       \
01210      const typename Expr<ExprT1>::value_type& b)    \
01211     {                 \
01212       return expr1.val() OP b;            \
01213     }                 \
01214   }                 \
01215 }
01216 
01217 FAD_RELOP_MACRO(==)
01218 FAD_RELOP_MACRO(!=)
01219 FAD_RELOP_MACRO(<)
01220 FAD_RELOP_MACRO(>)
01221 FAD_RELOP_MACRO(<=)
01222 FAD_RELOP_MACRO(>=)
01223 FAD_RELOP_MACRO(<<=)
01224 FAD_RELOP_MACRO(>>=)
01225 FAD_RELOP_MACRO(&)
01226 FAD_RELOP_MACRO(|)
01227 
01228 #undef FAD_RELOP_MACRO
01229 
01230 namespace Sacado {
01231 
01232   namespace CacheFad {
01233 
01234     template <typename ExprT>
01235     inline bool operator ! (const Expr<ExprT>& expr) 
01236     {
01237       return ! expr.val();
01238     }
01239 
01240   } // namespace CacheFad
01241 
01242 } // namespace Sacado
01243 
01244 //-------------------------- I/O Operators -----------------------
01245 
01246 namespace Sacado {
01247 
01248   namespace CacheFad {
01249 
01250     template <typename ExprT>
01251     std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
01252       os << x.val() << " [";
01253       
01254       for (int i=0; i< x.size(); i++) {
01255         os << " " << x.dx(i);
01256       }
01257 
01258       os << " ]";
01259       return os;
01260     }
01261 
01262   } // namespace CacheFad
01263 
01264 } // namespace Sacado
01265 
01266 
01267 #endif // SACADO_CACHEFAD_OPS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 10:19:31 2011 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.6.3