Sacado_Fad_Ops.hpp

Go to the documentation of this file.
00001 // $Id: Sacado_Fad_Ops.hpp,v 1.18.2.1 2009/03/05 20:35:26 etphipp Exp $ 
00002 // $Source: /space/CVS/Trilinos/packages/sacado/src/Sacado_Fad_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_FAD_OPS_HPP
00055 #define SACADO_FAD_OPS_HPP
00056 
00057 #include "Sacado_Fad_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,VALUE,DX,FASTACCESSDX)    \
00063 namespace Sacado {              \
00064   namespace Fad {             \
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   return VALUE;             \
00085       }                 \
00086                   \
00087       value_type dx(int i) const {          \
00088   return DX;              \
00089       }                 \
00090                   \
00091       value_type fastAccessDx(int i) const {        \
00092   return FASTACCESSDX;            \
00093       }                 \
00094                   \
00095     protected:                \
00096                   \
00097       const ExprT& expr;            \
00098     };                  \
00099                   \
00100     template <typename T>           \
00101     inline Expr< OP< Expr<T> > >          \
00102     OPNAME (const Expr<T>& expr)          \
00103     {                 \
00104       typedef OP< Expr<T> > expr_t;         \
00105                         \
00106       return Expr<expr_t>(expr);          \
00107     }                 \
00108   }                 \
00109 }
00110 
00111 FAD_UNARYOP_MACRO(operator+,
00112       UnaryPlusOp, 
00113       expr.val(),
00114       expr.dx(i),
00115       expr.fastAccessDx(i))
00116 FAD_UNARYOP_MACRO(operator-,
00117       UnaryMinusOp, 
00118       -expr.val(),
00119       -expr.dx(i),
00120       -expr.fastAccessDx(i))
00121 FAD_UNARYOP_MACRO(exp,
00122       ExpOp, 
00123       std::exp(expr.val()),
00124       std::exp(expr.val())*expr.dx(i),
00125       std::exp(expr.val())*expr.fastAccessDx(i))
00126 FAD_UNARYOP_MACRO(log,
00127       LogOp, 
00128       std::log(expr.val()),
00129       expr.dx(i)/expr.val(),
00130       expr.fastAccessDx(i)/expr.val())
00131 FAD_UNARYOP_MACRO(log10,
00132       Log10Op, 
00133       std::log10(expr.val()),
00134       expr.dx(i)/( std::log(value_type(10))*expr.val()),
00135       expr.fastAccessDx(i) / ( std::log(value_type(10))*expr.val()))
00136 FAD_UNARYOP_MACRO(sqrt,
00137       SqrtOp, 
00138       std::sqrt(expr.val()),
00139       expr.dx(i)/(value_type(2)* std::sqrt(expr.val())),
00140       expr.fastAccessDx(i)/(value_type(2)* std::sqrt(expr.val())))
00141 FAD_UNARYOP_MACRO(cos,
00142       CosOp, 
00143       std::cos(expr.val()),
00144       -expr.dx(i)* std::sin(expr.val()),
00145       -expr.fastAccessDx(i)* std::sin(expr.val()))
00146 FAD_UNARYOP_MACRO(sin,
00147       SinOp, 
00148       std::sin(expr.val()),
00149       expr.dx(i)* std::cos(expr.val()),
00150       expr.fastAccessDx(i)* std::cos(expr.val()))
00151 FAD_UNARYOP_MACRO(tan,
00152       TanOp, 
00153       std::tan(expr.val()),
00154       expr.dx(i)*
00155         (value_type(1)+ std::tan(expr.val())* std::tan(expr.val())),
00156       expr.fastAccessDx(i)*
00157         (value_type(1)+ std::tan(expr.val())* std::tan(expr.val())))
00158 FAD_UNARYOP_MACRO(acos,
00159       ACosOp, 
00160       std::acos(expr.val()),
00161       -expr.dx(i)/ std::sqrt(value_type(1)-expr.val()*expr.val()),
00162       -expr.fastAccessDx(i) /
00163         std::sqrt(value_type(1)-expr.val()*expr.val()))
00164 FAD_UNARYOP_MACRO(asin,
00165       ASinOp, 
00166       std::asin(expr.val()),
00167       expr.dx(i)/ std::sqrt(value_type(1)-expr.val()*expr.val()),
00168       expr.fastAccessDx(i) /
00169         std::sqrt(value_type(1)-expr.val()*expr.val()))
00170 FAD_UNARYOP_MACRO(atan,
00171       ATanOp, 
00172       std::atan(expr.val()),
00173       expr.dx(i)/(value_type(1)+expr.val()*expr.val()),
00174       expr.fastAccessDx(i)/(value_type(1)+expr.val()*expr.val()))
00175 FAD_UNARYOP_MACRO(cosh,
00176       CoshOp, 
00177       std::cosh(expr.val()),
00178       expr.dx(i)* std::sinh(expr.val()),
00179       expr.fastAccessDx(i)* std::sinh(expr.val()))
00180 FAD_UNARYOP_MACRO(sinh,
00181       SinhOp, 
00182       std::sinh(expr.val()),
00183       expr.dx(i)* std::cosh(expr.val()),
00184       expr.fastAccessDx(i)* std::cosh(expr.val()))
00185 FAD_UNARYOP_MACRO(tanh,
00186       TanhOp, 
00187       std::tanh(expr.val()),
00188       expr.dx(i)/( std::cosh(expr.val())* std::cosh(expr.val())),
00189       expr.fastAccessDx(i) / 
00190         ( std::cosh(expr.val())* std::cosh(expr.val())))
00191 FAD_UNARYOP_MACRO(acosh,
00192       ACoshOp, 
00193       acosh(expr.val()),
00194       expr.dx(i)/ std::sqrt((expr.val()-value_type(1)) * 
00195                (expr.val()+value_type(1))),
00196       expr.fastAccessDx(i)/ std::sqrt((expr.val()-value_type(1)) * 
00197              (expr.val()+value_type(1))))
00198 FAD_UNARYOP_MACRO(asinh,
00199       ASinhOp, 
00200       asinh(expr.val()),
00201       expr.dx(i)/ std::sqrt(value_type(1)+expr.val()*expr.val()),
00202       expr.fastAccessDx(i)/ std::sqrt(value_type(1)+
00203              expr.val()*expr.val()))
00204 FAD_UNARYOP_MACRO(atanh,
00205       ATanhOp, 
00206       atanh(expr.val()),
00207       expr.dx(i)/(value_type(1)-expr.val()*expr.val()),
00208       expr.fastAccessDx(i)/(value_type(1)-
00209              expr.val()*expr.val()))
00210 FAD_UNARYOP_MACRO(abs,
00211       AbsOp, 
00212       std::abs(expr.val()),
00213       expr.val() >= 0 ? value_type(+expr.dx(i)) : 
00214         value_type(-expr.dx(i)),
00215       expr.val() >= 0 ? value_type(+expr.fastAccessDx(i)) : 
00216         value_type(-expr.fastAccessDx(i)))
00217 FAD_UNARYOP_MACRO(fabs,
00218       FAbsOp, 
00219       std::fabs(expr.val()),
00220       expr.val() >= 0 ? value_type(+expr.dx(i)) : 
00221         value_type(-expr.dx(i)),
00222       expr.val() >= 0 ? value_type(+expr.fastAccessDx(i)) : 
00223         value_type(-expr.fastAccessDx(i)))
00224 
00225 #undef FAD_UNARYOP_MACRO
00226 
00227 #define FAD_BINARYOP_MACRO(OPNAME,OP,VALUE,DX,FASTACCESSDX,VAL_CONST_DX_1,VAL_CONST_DX_2,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
00228 namespace Sacado {              \
00229   namespace Fad {             \
00230                   \
00231     template <typename ExprT1, typename ExprT2>       \
00232     class OP {};              \
00233                   \
00234     template <typename T1, typename T2>         \
00235     class Expr< OP< Expr<T1>, Expr<T2> > > {        \
00236                   \
00237     public:               \
00238                   \
00239       typedef Expr<T1> ExprT1;            \
00240       typedef Expr<T2> ExprT2;            \
00241       typedef typename ExprT1::value_type value_type_1;     \
00242       typedef typename ExprT2::value_type value_type_2;     \
00243       typedef typename Sacado::Promote<value_type_1,      \
00244                value_type_2>::type value_type;  \
00245                   \
00246       Expr(const ExprT1& expr1_, const ExprT2& expr2_) :    \
00247   expr1(expr1_), expr2(expr2_) {}         \
00248                   \
00249       int size() const {            \
00250   int sz1 = expr1.size(), sz2 = expr2.size();     \
00251   return sz1 > sz2 ? sz1 : sz2;         \
00252       }                 \
00253                   \
00254       bool hasFastAccess() const {          \
00255   return expr1.hasFastAccess() && expr2.hasFastAccess();    \
00256       }                 \
00257                   \
00258       bool isPassive() const {            \
00259   return expr1.isPassive() && expr2.isPassive();      \
00260       }                 \
00261                   \
00262       const value_type val() const {          \
00263   return VALUE;             \
00264       }                 \
00265                   \
00266       const value_type dx(int i) const {        \
00267   return DX;              \
00268       }                 \
00269                   \
00270       const value_type fastAccessDx(int i) const {      \
00271   return FASTACCESSDX;            \
00272       }                 \
00273                         \
00274     protected:                \
00275                   \
00276       const ExprT1& expr1;            \
00277       const ExprT2& expr2;            \
00278                   \
00279     };                  \
00280                   \
00281     template <typename T1>            \
00282     class Expr< OP< Expr<T1>, typename Expr<T1>::value_type> > {  \
00283                   \
00284     public:               \
00285                   \
00286       typedef Expr<T1> ExprT1;            \
00287       typedef typename ExprT1::value_type value_type;     \
00288       typedef typename ExprT1::value_type ConstT;     \
00289                   \
00290       Expr(const ExprT1& expr1_, const ConstT& c_) :      \
00291   expr1(expr1_), c(c_) {}           \
00292                   \
00293       int size() const {            \
00294   return expr1.size();            \
00295       }                 \
00296                   \
00297       bool hasFastAccess() const {          \
00298   return expr1.hasFastAccess();         \
00299       }                 \
00300                   \
00301       bool isPassive() const {            \
00302   return expr1.isPassive();         \
00303       }                 \
00304                   \
00305       const value_type val() const {          \
00306   return VAL_CONST_DX_2;            \
00307       }                 \
00308                   \
00309       const value_type dx(int i) const {        \
00310   return CONST_DX_2;            \
00311       }                 \
00312                   \
00313       const value_type fastAccessDx(int i) const {      \
00314   return CONST_FASTACCESSDX_2;          \
00315       }                 \
00316                   \
00317     protected:                \
00318                   \
00319       const ExprT1& expr1;            \
00320       const ConstT& c;              \
00321     };                  \
00322                   \
00323     template <typename T2>            \
00324     class Expr< OP< typename Expr<T2>::value_type, Expr<T2> > > { \
00325                   \
00326     public:               \
00327                   \
00328       typedef Expr<T2> ExprT2;            \
00329       typedef typename ExprT2::value_type value_type;     \
00330       typedef typename ExprT2::value_type ConstT;     \
00331                   \
00332       Expr(const ConstT& c_, const ExprT2& expr2_) :      \
00333   c(c_), expr2(expr2_) {}           \
00334                   \
00335       int size() const {            \
00336   return expr2.size();            \
00337       }                 \
00338                   \
00339       bool hasFastAccess() const {          \
00340   return expr2.hasFastAccess();         \
00341       }                 \
00342                   \
00343       bool isPassive() const {            \
00344   return expr2.isPassive();         \
00345       }                 \
00346                   \
00347       const value_type val() const {          \
00348   return VAL_CONST_DX_1;            \
00349       }                 \
00350                   \
00351       const value_type dx(int i) const {        \
00352   return CONST_DX_1;            \
00353       }                 \
00354                   \
00355       const value_type fastAccessDx(int i) const {      \
00356   return CONST_FASTACCESSDX_1;          \
00357       }                 \
00358                         \
00359     protected:                \
00360                   \
00361       const ConstT& c;              \
00362       const ExprT2& expr2;            \
00363     };                  \
00364                   \
00365     template <typename T1, typename T2>         \
00366     inline Expr< OP< Expr<T1>, Expr<T2> > >       \
00367     OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2)   \
00368     {                 \
00369       typedef OP< Expr<T1>, Expr<T2> > expr_t;        \
00370                       \
00371       return Expr<expr_t>(expr1, expr2);        \
00372     }                 \
00373                   \
00374     template <typename T>           \
00375     inline Expr< OP< Expr<T>, Expr<T> > >       \
00376     OPNAME (const Expr<T>& expr1, const Expr<T>& expr2)     \
00377     {                 \
00378       typedef OP< Expr<T>, Expr<T> > expr_t;        \
00379                       \
00380       return Expr<expr_t>(expr1, expr2);        \
00381     }                 \
00382                   \
00383     template <typename T>           \
00384     inline Expr< OP< typename Expr<T>::value_type, Expr<T> > >    \
00385     OPNAME (const typename Expr<T>::value_type& c,      \
00386       const Expr<T>& expr)          \
00387     {                 \
00388       typedef typename Expr<T>::value_type ConstT;      \
00389       typedef OP< ConstT, Expr<T> > expr_t;       \
00390                   \
00391       return Expr<expr_t>(c, expr);         \
00392     }                 \
00393                   \
00394     template <typename T>           \
00395     inline Expr< OP< Expr<T>, typename Expr<T>::value_type > >    \
00396     OPNAME (const Expr<T>& expr,          \
00397       const typename Expr<T>::value_type& c)      \
00398     {                 \
00399       typedef typename Expr<T>::value_type ConstT;      \
00400       typedef OP< Expr<T>, ConstT > expr_t;       \
00401                   \
00402       return Expr<expr_t>(expr, c);         \
00403     }                 \
00404   }                 \
00405 }
00406 
00407 
00408 FAD_BINARYOP_MACRO(operator+,
00409        AdditionOp, 
00410        expr1.val() + expr2.val(),
00411        expr1.dx(i) + expr2.dx(i),
00412        expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
00413        c + expr2.val(),
00414        expr1.val() + c,
00415        expr2.dx(i),
00416        expr1.dx(i),
00417        expr2.fastAccessDx(i),
00418        expr1.fastAccessDx(i))
00419 FAD_BINARYOP_MACRO(operator-,
00420        SubtractionOp, 
00421        expr1.val() - expr2.val(),
00422        expr1.dx(i) - expr2.dx(i),
00423        expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
00424        c - expr2.val(),
00425        expr1.val() - c,
00426        -expr2.dx(i),
00427        expr1.dx(i),
00428        -expr2.fastAccessDx(i),
00429        expr1.fastAccessDx(i))
00430 FAD_BINARYOP_MACRO(operator*,
00431        MultiplicationOp, 
00432        expr1.val() * expr2.val(),
00433        expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val(),
00434        expr1.val()*expr2.fastAccessDx(i) + 
00435          expr1.fastAccessDx(i)*expr2.val(),
00436        c * expr2.val(),
00437        expr1.val() * c,
00438        c*expr2.dx(i),
00439        expr1.dx(i)*c,
00440        c*expr2.fastAccessDx(i),
00441        expr1.fastAccessDx(i)*c)
00442 FAD_BINARYOP_MACRO(operator/,
00443        DivisionOp, 
00444        expr1.val() / expr2.val(),
00445        (expr1.dx(i)*expr2.val() - expr2.dx(i)*expr1.val()) /
00446          (expr2.val()*expr2.val()),
00447        (expr1.fastAccessDx(i)*expr2.val() - 
00448           expr2.fastAccessDx(i)*expr1.val()) /
00449           (expr2.val()*expr2.val()),
00450        c / expr2.val(),
00451        expr1.val() / c,
00452        -expr2.dx(i)*c / (expr2.val()*expr2.val()),
00453        expr1.dx(i)/c,
00454        -expr2.fastAccessDx(i)*c / (expr2.val()*expr2.val()),
00455        expr1.fastAccessDx(i)/c)
00456 FAD_BINARYOP_MACRO(atan2,
00457        Atan2Op,
00458        std::atan2(expr1.val(), expr2.val()),
00459        (expr2.val()*expr1.dx(i) - expr1.val()*expr2.dx(i))/
00460       (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
00461        (expr2.val()*expr1.fastAccessDx(i) - expr1.val()*expr2.fastAccessDx(i))/
00462       (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
00463        std::atan2(c, expr2.val()),
00464        std::atan2(expr1.val(), c),
00465        (-c*expr2.dx(i)) / (c*c + expr2.val()*expr2.val()),
00466        (c*expr1.dx(i))/ (expr1.val()*expr1.val() + c*c),
00467        (-c*expr2.fastAccessDx(i))/ (c*c + expr2.val()*expr2.val()),
00468        (c*expr1.fastAccessDx(i))/ (expr1.val()*expr1.val() + c*c))
00469 FAD_BINARYOP_MACRO(pow,
00470        PowerOp,
00471        std::pow(expr1.val(), expr2.val()),
00472        (expr2.dx(i)*std::log(expr1.val())+expr2.val()*expr1.dx(i)/
00473         expr1.val())*std::pow(expr1.val(),expr2.val()),
00474        (expr2.fastAccessDx(i)*std::log(expr1.val())+
00475         expr2.val()*expr1.fastAccessDx(i)/
00476         expr1.val())*std::pow(expr1.val(),expr2.val()),
00477        std::pow(c, expr2.val()),
00478        std::pow(expr1.val(), c),
00479        expr2.dx(i)*std::log(c)*std::pow(c,expr2.val()),
00480        c*expr1.dx(i)/expr1.val()*std::pow(expr1.val(),c),
00481        expr2.fastAccessDx(i)*std::log(c)*std::pow(c,expr2.val()),
00482        c*expr1.fastAccessDx(i)/expr1.val()*std::pow(expr1.val(),c))
00483 FAD_BINARYOP_MACRO(max,
00484                    MaxOp,
00485                    std::max(expr1.val(), expr2.val()),
00486                    expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00487                    expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) : 
00488                                                 expr2.fastAccessDx(i),
00489        std::max(c, expr2.val()),
00490        std::max(expr1.val(), c),
00491                    c >= expr2.val() ? value_type(0) : expr2.dx(i),
00492                    expr1.val() >= c ? expr1.dx(i) : value_type(0),
00493                    c >= expr2.val() ? value_type(0) : expr2.fastAccessDx(i),
00494                    expr1.val() >= c ? expr1.fastAccessDx(i) : value_type(0))
00495 FAD_BINARYOP_MACRO(min,
00496                    MinOp,
00497                    std::min(expr1.val(), expr2.val()),
00498                    expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
00499                    expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) : 
00500                                                 expr2.fastAccessDx(i),
00501        std::min(c, expr2.val()),
00502        std::min(expr1.val(), c),
00503                    c <= expr2.val() ? value_type(0) : expr2.dx(i),
00504                    expr1.val() <= c ? expr1.dx(i) : value_type(0),
00505                    c <= expr2.val() ? value_type(0) : expr2.fastAccessDx(i),
00506                    expr1.val() <= c ? expr1.fastAccessDx(i) : value_type(0))
00507 
00508 #undef FAD_BINARYOP_MACRO
00509 
00510 //-------------------------- Relational Operators -----------------------
00511 
00512 #define FAD_RELOP_MACRO(OP)           \
00513 namespace Sacado {              \
00514   namespace Fad {             \
00515     template <typename ExprT1, typename ExprT2>       \
00516     inline bool               \
00517     operator OP (const Expr<ExprT1>& expr1,       \
00518      const Expr<ExprT2>& expr2)       \
00519     {                 \
00520       return expr1.val() OP expr2.val();        \
00521     }                 \
00522                   \
00523     template <typename ExprT2>            \
00524     inline bool               \
00525     operator OP (const typename Expr<ExprT2>::value_type& a,    \
00526      const Expr<ExprT2>& expr2)       \
00527     {                 \
00528       return a OP expr2.val();            \
00529     }                 \
00530                   \
00531     template <typename ExprT1>            \
00532     inline bool               \
00533     operator OP (const Expr<ExprT1>& expr1,       \
00534      const typename Expr<ExprT1>::value_type& b)    \
00535     {                 \
00536       return expr1.val() OP b;            \
00537     }                 \
00538   }                 \
00539 }
00540 
00541 FAD_RELOP_MACRO(==)
00542 FAD_RELOP_MACRO(!=)
00543 FAD_RELOP_MACRO(<)
00544 FAD_RELOP_MACRO(>)
00545 FAD_RELOP_MACRO(<=)
00546 FAD_RELOP_MACRO(>=)
00547 FAD_RELOP_MACRO(<<=)
00548 FAD_RELOP_MACRO(>>=)
00549 FAD_RELOP_MACRO(&)
00550 FAD_RELOP_MACRO(|)
00551 
00552 #undef FAD_RELOP_MACRO
00553 
00554 namespace Sacado {
00555 
00556   namespace Fad {
00557 
00558     template <typename ExprT>
00559     inline bool operator ! (const Expr<ExprT>& expr) 
00560     {
00561       return ! expr.val();
00562     }
00563 
00564   } // namespace Fad
00565 
00566 } // namespace Sacado
00567 
00568 //-------------------------- I/O Operators -----------------------
00569 
00570 namespace Sacado {
00571 
00572   namespace Fad {
00573 
00574     template <typename ExprT>
00575     std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
00576       os << x.val() << "  [";
00577       
00578       for (int i=0; i< x.size(); i++) {
00579   os << " " << x.dx(i);
00580       }
00581 
00582       os << " ]\n";
00583       return os;
00584     }
00585 
00586   } // namespace Fad
00587 
00588 } // namespace Sacado
00589 
00590 
00591 #endif // SACADO_FAD_OPS_HPP

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