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

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