SundanceADReal.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
00030 
00031 #ifndef SUNDANCE_ADREAL_H
00032 #define SUNDANCE_ADREAL_H
00033 
00034 
00035 #include "SundanceDefs.hpp"
00036 #include "SundancePoint.hpp"
00037 #include "SundanceStdMathFunctors.hpp"
00038 #include "Teuchos_RefCountPtr.hpp"
00039 
00040 namespace Sundance
00041 {
00042 /**
00043  * First-order automatic differentiation of a multivariable function.
00044  * @author Kevin Long
00045  */
00046 class ADReal
00047 {
00048 public:
00049   /** Create an ADReal with value and gradient = 0 */
00050   ADReal() : value_(0), gradient_(0.0, 0.0, 0.0){;}
00051   /** Create an ADReal object that varies linearly with
00052    * one coordinate direction  */
00053   ADReal(double value, int direction, int spatialDimension)
00054     : value_(value), gradient_()
00055     {
00056       if (spatialDimension==1) gradient_ = Point(0.0);
00057       if (spatialDimension==2) gradient_ = Point(0.0, 0.0);
00058       if (spatialDimension==3) gradient_ = Point(0.0, 0.0, 0.0);
00059       gradient_[direction] = 1.0;
00060     }
00061   /** Create a constant-valued ADReal object in a multidimensional space */
00062   ADReal(double value, int spatialDimension)
00063     : value_(value), gradient_()
00064     {
00065       if (spatialDimension==1) gradient_ = Point(0.0);
00066       if (spatialDimension==2) gradient_ = Point(0.0, 0.0);
00067       if (spatialDimension==3) gradient_ = Point(0.0, 0.0, 0.0);
00068     }
00069 
00070   /** Create an ADReal with the specified value and gradient */
00071   ADReal(double value, const Point& gradient)
00072     : value_(value), gradient_(gradient) {;}
00073 
00074   /** unary minus */
00075   ADReal operator-() const ;
00076   /** reflexive addition */
00077   ADReal& operator+=(const ADReal& other) ;
00078   /** reflexive subtraction */
00079   ADReal& operator-=(const ADReal& other) ;
00080   /** reflexive multiplication */
00081   ADReal& operator*=(const ADReal& other) ;
00082   /** reflexive division */
00083   ADReal& operator/=(const ADReal& other) ;
00084 
00085   /** reflexive scalar addition */
00086   ADReal& operator+=(const double& scalar) ;
00087   /** reflexive scalar subtraction */
00088   ADReal& operator-=(const double& scalar) ;
00089   /** reflexive scalar multiplication */
00090   ADReal& operator*=(const double& scalar) ;
00091   /** reflexive scalar division */
00092   ADReal& operator/=(const double& scalar) ;
00093 
00094   /** addition */
00095   ADReal operator+(const ADReal& other) const ;
00096   /** subtraction */
00097   ADReal operator-(const ADReal& other) const ;
00098   /** multiplication */
00099   ADReal operator*(const ADReal& other) const ;
00100   /** division */
00101   ADReal operator/(const ADReal& other) const ;
00102 
00103   /** scalar addition */
00104   ADReal operator+(const double& scalar) const ;
00105   /** scalar subtraction */
00106   ADReal operator-(const double& scalar) const ;
00107   /** scalar multiplication */
00108   ADReal operator*(const double& scalar) const ;
00109   /** scalar division */
00110   ADReal operator/(const double& scalar) const ;
00111 
00112   /** get the value */
00113   const double& value() const {return value_;}
00114   /** get the gradient */
00115   const Point& gradient() const {return gradient_;}
00116 
00117   void reciprocate() ;
00118 
00119   static double& totalFlops() {static double rtn = 0; return rtn;}
00120 
00121 
00122   static void addFlops(const double& flops) {totalFlops() += flops;}
00123 private:
00124   double value_;
00125   Point gradient_;
00126 };
00127 
00128 
00129 
00130 /** \relates ADReal */
00131 ADReal operator+(const double& scalar,
00132   const ADReal& a);
00133 /** \relates ADReal */
00134 ADReal operator-(const double& scalar,
00135   const ADReal& a);
00136 /** \relates ADReal */
00137 ADReal operator*(const double& scalar,
00138   const ADReal& a);
00139 /** \relates ADReal */
00140 ADReal operator/(const double& scalar,
00141   const ADReal& a);
00142 
00143 
00144 inline ADReal pow(const ADReal& x, const double& y)
00145 {
00146   Teuchos::RCP<UnaryFunctor> func = Teuchos::rcp(new PowerFunctor(y));
00147   double f;
00148   double df;
00149   double xVal = x.value();
00150   func->eval1(&xVal, 1, &f, &df);
00151   return ADReal(f, df*x.gradient());
00152 }
00153 
00154 #define SUNDANCE_AD_FUNCTOR(opName, functorName) \
00155   inline ADReal opName(const ADReal& x)\
00156   {\
00157     Teuchos::RCP<UnaryFunctor> func = Teuchos::rcp(new functorName());\
00158     double f;\
00159     double df;\
00160     double xVal = x.value();\
00161     func->eval1(&xVal, 1, &f, &df);\
00162     return ADReal(f, df*x.gradient());}
00163 
00164 
00165 SUNDANCE_AD_FUNCTOR(exp, StdExp)
00166 
00167   SUNDANCE_AD_FUNCTOR(log, StdLog)
00168 
00169   SUNDANCE_AD_FUNCTOR(sqrt, StdSqrt)
00170 
00171   SUNDANCE_AD_FUNCTOR(sin, StdSin)
00172 
00173   SUNDANCE_AD_FUNCTOR(cos, StdCos)
00174 
00175 
00176     
00177   }
00178 
00179 
00180 namespace std
00181 {
00182 inline ostream& operator<<(std::ostream& os, const Sundance::ADReal& x)
00183 {
00184   std::cerr << "AD[" << x.value() << ", grad="<< x.gradient() << "]";
00185   return os;
00186 }
00187 }
00188 
00189 
00190 
00191 #endif
00192 
00193 
00194 

Site Contact