SundanceADReal.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #ifndef SUNDANCE_ADREAL_H
00043 #define SUNDANCE_ADREAL_H
00044 
00045 
00046 #include "SundanceDefs.hpp"
00047 #include "SundancePoint.hpp"
00048 #include "SundanceStdMathFunctors.hpp"
00049 #include "Teuchos_RefCountPtr.hpp"
00050 
00051 namespace Sundance
00052 {
00053 /**
00054  * First-order automatic differentiation of a multivariable function.
00055  * @author Kevin Long
00056  */
00057 class ADReal
00058 {
00059 public:
00060   /** Create an ADReal with value and gradient = 0 */
00061   ADReal() : value_(0), gradient_(0.0, 0.0, 0.0){;}
00062   /** Create an ADReal object that varies linearly with
00063    * one coordinate direction  */
00064   ADReal(double value, int direction, int spatialDimension)
00065     : value_(value), gradient_()
00066     {
00067       if (spatialDimension==1) gradient_ = Point(0.0);
00068       if (spatialDimension==2) gradient_ = Point(0.0, 0.0);
00069       if (spatialDimension==3) gradient_ = Point(0.0, 0.0, 0.0);
00070       gradient_[direction] = 1.0;
00071     }
00072   /** Create a constant-valued ADReal object in a multidimensional space */
00073   ADReal(double value, int spatialDimension)
00074     : value_(value), gradient_()
00075     {
00076       if (spatialDimension==1) gradient_ = Point(0.0);
00077       if (spatialDimension==2) gradient_ = Point(0.0, 0.0);
00078       if (spatialDimension==3) gradient_ = Point(0.0, 0.0, 0.0);
00079     }
00080 
00081   /** Create an ADReal with the specified value and gradient */
00082   ADReal(double value, const Point& gradient)
00083     : value_(value), gradient_(gradient) {;}
00084 
00085   /** unary minus */
00086   ADReal operator-() const ;
00087   /** reflexive addition */
00088   ADReal& operator+=(const ADReal& other) ;
00089   /** reflexive subtraction */
00090   ADReal& operator-=(const ADReal& other) ;
00091   /** reflexive multiplication */
00092   ADReal& operator*=(const ADReal& other) ;
00093   /** reflexive division */
00094   ADReal& operator/=(const ADReal& other) ;
00095 
00096   /** reflexive scalar addition */
00097   ADReal& operator+=(const double& scalar) ;
00098   /** reflexive scalar subtraction */
00099   ADReal& operator-=(const double& scalar) ;
00100   /** reflexive scalar multiplication */
00101   ADReal& operator*=(const double& scalar) ;
00102   /** reflexive scalar division */
00103   ADReal& operator/=(const double& scalar) ;
00104 
00105   /** addition */
00106   ADReal operator+(const ADReal& other) const ;
00107   /** subtraction */
00108   ADReal operator-(const ADReal& other) const ;
00109   /** multiplication */
00110   ADReal operator*(const ADReal& other) const ;
00111   /** division */
00112   ADReal operator/(const ADReal& other) const ;
00113 
00114   /** scalar addition */
00115   ADReal operator+(const double& scalar) const ;
00116   /** scalar subtraction */
00117   ADReal operator-(const double& scalar) const ;
00118   /** scalar multiplication */
00119   ADReal operator*(const double& scalar) const ;
00120   /** scalar division */
00121   ADReal operator/(const double& scalar) const ;
00122 
00123   /** get the value */
00124   const double& value() const {return value_;}
00125   /** get the gradient */
00126   const Point& gradient() const {return gradient_;}
00127 
00128   void reciprocate() ;
00129 
00130   static double& totalFlops() {static double rtn = 0; return rtn;}
00131 
00132 
00133   static void addFlops(const double& flops) {totalFlops() += flops;}
00134 private:
00135   double value_;
00136   Point gradient_;
00137 };
00138 
00139 
00140 
00141 /** \relates ADReal */
00142 ADReal operator+(const double& scalar,
00143   const ADReal& a);
00144 /** \relates ADReal */
00145 ADReal operator-(const double& scalar,
00146   const ADReal& a);
00147 /** \relates ADReal */
00148 ADReal operator*(const double& scalar,
00149   const ADReal& a);
00150 /** \relates ADReal */
00151 ADReal operator/(const double& scalar,
00152   const ADReal& a);
00153 
00154 
00155 inline ADReal pow(const ADReal& x, const double& y)
00156 {
00157   Teuchos::RCP<UnaryFunctor> func = Teuchos::rcp(new PowerFunctor(y));
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 #define SUNDANCE_AD_FUNCTOR(opName, functorName) \
00166   inline ADReal opName(const ADReal& x)\
00167   {\
00168     Teuchos::RCP<UnaryFunctor> func = Teuchos::rcp(new functorName());\
00169     double f;\
00170     double df;\
00171     double xVal = x.value();\
00172     func->eval1(&xVal, 1, &f, &df);\
00173     return ADReal(f, df*x.gradient());}
00174 
00175 
00176 SUNDANCE_AD_FUNCTOR(exp, StdExp)
00177 
00178   SUNDANCE_AD_FUNCTOR(log, StdLog)
00179 
00180   SUNDANCE_AD_FUNCTOR(sqrt, StdSqrt)
00181 
00182   SUNDANCE_AD_FUNCTOR(sin, StdSin)
00183 
00184   SUNDANCE_AD_FUNCTOR(cos, StdCos)
00185 
00186 
00187     
00188   }
00189 
00190 
00191 namespace std
00192 {
00193 inline ostream& operator<<(std::ostream& os, const Sundance::ADReal& x)
00194 {
00195   std::cerr << "AD[" << x.value() << ", grad="<< x.gradient() << "]";
00196   return os;
00197 }
00198 }
00199 
00200 
00201 
00202 #endif
00203 
00204 
00205 

Site Contact