Sacado_ELRFad_Expression.hpp

Go to the documentation of this file.
00001 // $Id: Sacado_ELRFad_Expression.hpp,v 1.1.2.2 2007/09/18 18:42:13 rabartl Exp $ 
00002 // $Source: /space/CVS/Trilinos/packages/sacado/src/Sacado_ELRFad_Expression.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_ELRFAD_EXPRESSION_HPP
00055 #define SACADO_ELRFAD_EXPRESSION_HPP
00056 
00057 #include "Sacado_Traits.hpp"
00058 
00059 namespace Sacado {
00060 
00061   namespace ELRFad {
00062 
00064 
00068     template <typename A, typename B> struct ExprPromote {};
00069 
00071     template <typename A> struct ExprPromote<A,A> {
00072       typedef A type;
00073     };
00074 
00076 
00080     template <typename ExprT> 
00081     class Expr {
00082 
00083     public:
00084 
00086       typedef typename ExprT::value_type value_type;
00087 
00089       typedef typename ExprT::base_expr_type base_expr_type;
00090 
00092       static const int num_args = ExprT::num_args;
00093 
00095       explicit Expr(const ExprT& expr) : expr_(expr) {}
00096 
00098       int size() const {return expr_.size();}
00099 
00101       value_type val() const { return expr_.val();}
00102 
00104       void computePartials(const value_type& bar, 
00105          value_type partials[]) const { 
00106   expr_.computePartials(bar, partials); }
00107 
00109       void getTangents(int i, value_type dots[]) const { 
00110   expr_.getTangents(i, dots); }
00111 
00113       template <int Arg>
00114       value_type getTangent(int i) const {
00115   return expr_.template getTangent<Arg>(i);
00116       }
00117 
00119       template <int Arg>
00120       bool isActive() const { return expr_.template isActive<Arg>(); }
00121       
00122     protected:
00123 
00125       Expr() {}
00126 
00128       ExprT expr_;
00129 
00130     }; // class Expr
00131 
00133 
00136     template <typename ConstT> 
00137     class ConstExpr {
00138 
00139     public:
00140 
00142       typedef ConstT value_type;
00143 
00145       typedef ConstT base_expr_type;
00146 
00148       static const int num_args = 0;
00149 
00151       ConstExpr(const ConstT& constant) : constant_(constant) {}
00152 
00154       int size() const { return 0; }
00155 
00157       value_type val() const { return constant_; }
00158 
00160       void computePartials(const value_type& bar, 
00161          value_type partials[]) const {}
00162 
00164       void getTangents(int i, value_type dots[]) const {}
00165 
00167       template <int Arg>
00168       value_type getTangent(int i) const { return 0.0; }
00169 
00171       template <int Arg>
00172       bool isActive() const { return false; }
00173 
00174     protected:
00175       
00177       const ConstT& constant_;
00178 
00179     }; // class ConstExpr
00180 
00182 
00188     template <typename ExprT, template<typename> class Op> 
00189     class UnaryExpr {
00190 
00191     public:
00192 
00194       typedef typename ExprT::value_type value_type;
00195 
00197       typedef typename ExprT::base_expr_type base_expr_type;
00198 
00200       typedef Op<ExprT> OpT;
00201 
00203       static const int num_args = ExprT::num_args;
00204 
00206       UnaryExpr(const ExprT& expr) : expr_(expr) {}
00207 
00209       int size() const { return expr_.size(); }
00210 
00212       value_type val() const { return OpT::computeValue(expr_); }
00213 
00215       void computePartials(const value_type& bar, 
00216          value_type partials[]) const { 
00217   expr_.computePartials(OpT::computeAdjoint(bar, expr_), partials); }
00218 
00220       void getTangents(int i, value_type dots[]) const { 
00221   expr_.getTangents(i, dots); }
00222 
00224       template <int Arg>
00225       value_type getTangent(int i) const {
00226   return expr_.template getTangent<Arg>(i);
00227       }
00228 
00230       template <int Arg>
00231       bool isActive() const { return expr_.template isActive<Arg>(); }
00232 
00233     protected:
00234       
00236       const ExprT& expr_;
00237 
00238     }; // class UnaryExpr
00239 
00240     // The Sun compiler has difficulty with class partial specialization and
00241     // template templates, which the original BinaryExpr classes below use.
00242     // However the only significant difference between the specializations
00243     // of BinaryExpr for constant arguments is removing the reference
00244     // for the corresponding data member.  The type functions below allow
00245     // us to do this without specializing BinaryExpr.  We could also 
00246     // remove the template templates, but that drastically increases
00247     // compile times due to the increased length of template argument lists.
00248     template <typename T> struct ExprConstRef {
00249       typedef const T& type;
00250     };
00251     template <typename T> struct ExprConstRef< ConstExpr<T> > {
00252       typedef const ConstExpr<T> type;
00253     };
00254 
00256 
00263     template <typename ExprT1, typename ExprT2, 
00264         template<typename,typename> class Op> 
00265     class BinaryExpr {
00266     
00267     public:
00268 
00270       typedef typename ExprT1::value_type value_type_1;
00271 
00273       typedef typename ExprT2::value_type value_type_2;
00274 
00276       typedef typename Sacado::Promote<value_type_1,
00277                value_type_2>::type value_type;
00278 
00280       typedef typename ExprT1::base_expr_type base_expr_type_1;
00281 
00283       typedef typename ExprT2::base_expr_type base_expr_type_2;
00284 
00286       typedef typename ExprPromote<base_expr_type_1,
00287            base_expr_type_2>::type base_expr_type;
00288 
00290       static const int num_args1 = ExprT1::num_args;
00291 
00293       static const int num_args2 = ExprT2::num_args;
00294 
00296       static const int num_args = num_args1 + num_args2;
00297 
00298       typedef Op<ExprT1,ExprT2> OpT;
00299 
00301       BinaryExpr(const ExprT1& expr1, const ExprT2& expr2) : 
00302   expr1_(expr1), expr2_(expr2) {}
00303 
00305       int size() const {
00306   int sz1 = expr1_.size(), sz2 = expr2_.size(); 
00307   return sz1 > sz2 ? sz1 : sz2;
00308       }
00309 
00311       void computePartials(const value_type& bar, 
00312          value_type partials[]) const { 
00313   if (num_args1 > 0)
00314     expr1_.computePartials(OpT::computeLeftAdjoint(bar, expr1_, expr2_), 
00315          partials);
00316   if (num_args2 > 0)
00317     expr2_.computePartials(OpT::computeRightAdjoint(bar, expr1_, expr2_),
00318          partials+num_args1);
00319       }
00320 
00322       void getTangents(int i, value_type dots[]) const { 
00323   expr1_.getTangents(i, dots); 
00324   expr2_.getTangents(i, dots+num_args1); }
00325 
00327       value_type val() const { 
00328   return OpT::computeValue(expr1_,expr2_); }
00329 
00331       template <int Arg>
00332       value_type getTangent(int i) const {
00333   if (Arg < num_args1)
00334     return expr1_.template getTangent<Arg>(i);
00335   else
00336     return expr2_.template getTangent<Arg-num_args1>(i);
00337       }
00338 
00340       template <int Arg>
00341       bool isActive() const { 
00342   if (Arg < num_args1)
00343     return expr1_.template isActive<Arg>(); 
00344   else
00345     return expr2_.template isActive<Arg-num_args1>();
00346       }
00347 
00348     protected:
00349       
00351       typename ExprConstRef<ExprT1>::type expr1_;
00352 
00354       typename ExprConstRef<ExprT2>::type expr2_;
00355 
00356     }; // class BinaryExpr
00357 
00358   } // namespace ELRFad
00359 
00360 } // namespace Sacado
00361 
00362 #endif // SACADO_ELRFAD_EXPRESSION_HPP

Generated on Tue Oct 20 12:55:04 2009 for Sacado Package Browser (Single Doxygen Collection) by doxygen 1.4.7