SundanceStdMathFunctors.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_STDMATHFUNCTORS_H
00043 #define SUNDANCE_STDMATHFUNCTORS_H
00044 
00045 #include "SundanceDefs.hpp"
00046 #include "PlayaExceptions.hpp"
00047 #include "SundanceUnaryFunctor.hpp"
00048 #ifdef _MSC_VER
00049 # include "winmath.h"
00050 #endif
00051 
00052 
00053 namespace Sundance
00054 {
00055   using namespace Teuchos;
00056 
00057   /** */
00058   class PowerFunctor : public UnaryFunctor
00059   {
00060   public:
00061     /** */
00062     PowerFunctor(const double& p);
00063     
00064     /** Evaluate power function and deriv at an array of values */ 
00065     virtual void eval1(const double* const x, 
00066               int nx, 
00067               double* f, 
00068               double* df) const ;
00069     /** Evaluate power function at an array of values */ 
00070     virtual void eval0(const double* const x, int nx, double* f) const ;
00071 
00072     /** Evaluate power function and first two derivs at an array of values */
00073     virtual void eval2(const double* const x, 
00074                       int nx, 
00075                       double* f, 
00076                       double* df_dx,
00077                       double* d2f_dxx) const ;
00078 
00079     /** Evaluate power function and first three derivs at an array of values */
00080     virtual void eval3(const double* const x, 
00081                       int nx, 
00082                       double* f, 
00083                       double* df_dx,
00084                       double* d2f_dxx,
00085                       double* d3f_dxxx) const ;
00086 
00087     static RCP<FunctorDomain> powerDomain(const double& p);
00088 
00089   protected:
00090     bool acceptX(int diffOrder, const double& x) const
00091     {
00092       if (powerIsInteger_)
00093   {
00094     return p_>=0.0 || x!=0.0;
00095   }
00096       else
00097   {
00098     if (x<0.0) return false; 
00099     if (x==0.0) return (p_ > diffOrder);
00100   }
00101       return true;      
00102     }
00103   private:
00104     double p_;
00105     bool powerIsInteger_;
00106   };
00107 
00108 
00109   
00110   
00111 
00112   SUNDANCE_UNARY_FUNCTOR(reciprocal, StdReciprocal, "reciprocal function", 
00113                          NonzeroDomain(), 1.0/x[i], -f[i]*f[i], -2.0*df[i]/x[i])
00114 
00115     SUNDANCE_UNARY_FUNCTOR(fabs, StdFabs, "absolute value", UnboundedDomain(), ::fabs(x[i]), ((x[i]>=0.0) ? x[i] : -x[i]), 0.0)
00116 
00117   SUNDANCE_UNARY_FUNCTOR(sign, StdSign, "sign function", UnboundedDomain(), 
00118                          ((x[i]>0.0) ? 1.0 : ( (x[i]<0.0) ? -1.0 : 0.0)), 
00119                          0.0, 0.0)
00120 
00121     SUNDANCE_UNARY_FUNCTOR3(exp, StdExp, "exponential function", UnboundedDomain(), ::exp(x[i]), f[i], f[i], f[i])
00122 
00123     SUNDANCE_UNARY_FUNCTOR3(log, StdLog, "logarithm", PositiveDomain(), ::log(x[i]), 1.0/x[i], -df[i]*df[i], -2.0*d2f[i]*df[i])
00124 
00125   SUNDANCE_UNARY_FUNCTOR(sqrt, StdSqrt, "square root", PositiveDomain(), ::sqrt(x[i]), 0.5/f[i], -0.5*df[i]/x[i])
00126 
00127     SUNDANCE_UNARY_FUNCTOR3(sin, StdSin, "sine function", UnboundedDomain(), ::sin(x[i]), ::cos(x[i]), -f[i], -df[i])
00128 
00129     SUNDANCE_UNARY_FUNCTOR3(cos, StdCos, "cosine function", UnboundedDomain(), ::cos(x[i]), -::sin(x[i]), -f[i], -df[i])
00130 
00131   SUNDANCE_UNARY_FUNCTOR(tan, StdTan, "tangent function", UnboundedDomain(),
00132                          ::tan(x[i]), 1.0 + f[i]*f[i], 2.0*f[i]*df[i])
00133 
00134   SUNDANCE_UNARY_FUNCTOR(asin, StdASin, "inverse sine", 
00135                          BoundedDomain(-1.0, 1.0),
00136                          ::asin(x[i]), 1.0/::sqrt(1.0-x[i]*x[i]),
00137                          x[i]*df[i]*df[i]*df[i])
00138 
00139   SUNDANCE_UNARY_FUNCTOR(acos, StdACos, "inverse cosine",
00140                          BoundedDomain(-1.0, 1.0), 
00141                          ::acos(x[i]), -1.0/::sqrt(1.0-x[i]*x[i]),
00142                          x[i]*df[i]*df[i]*df[i])
00143 
00144   SUNDANCE_UNARY_FUNCTOR(atan, StdATan, "inverse tangent", 
00145                          UnboundedDomain(),
00146                          ::atan(x[i]), 1.0/(1.0 + x[i]*x[i]),
00147                          -2.0*x[i]*df[i]*df[i])
00148 
00149   SUNDANCE_UNARY_FUNCTOR(sinh, StdSinh, "hyperbolic sine",
00150                          UnboundedDomain(),
00151                          ::sinh(x[i]), ::cosh(x[i]), f[i])
00152 
00153   SUNDANCE_UNARY_FUNCTOR(cosh, StdCosh, "hyperbolic cosine",
00154                          UnboundedDomain(),
00155                          ::cosh(x[i]), ::sinh(x[i]), f[i])
00156 
00157   SUNDANCE_UNARY_FUNCTOR(tanh, StdTanh, "hyperbolic tangent",
00158                          UnboundedDomain(),
00159                          ::tanh(x[i]), 1.0 - f[i]*f[i], -2.0*f[i]*df[i])
00160 
00161   SUNDANCE_UNARY_FUNCTOR(asinh, StdASinh, "inverse hyperbolic sine",
00162                          UnboundedDomain(),
00163                          ::asinh(x[i]), 1.0/::sqrt(1.0 + x[i]*x[i]),
00164                          -x[i]*df[i]*df[i]*df[i])
00165 
00166   SUNDANCE_UNARY_FUNCTOR(acosh, StdACosh, "inverse hyperbolic cosine",
00167                          LowerBoundedDomain(1.0),
00168                          ::acosh(x[i]), 1.0/::sqrt(x[i]*x[i]-1.0),
00169                          -x[i]*df[i]*df[i]*df[i])
00170 
00171   SUNDANCE_UNARY_FUNCTOR(atanh, StdATanh, "inverse hyperbolic tangent",
00172                          BoundedDomain(-1.0, 1.0), 
00173                          ::atanh(x[i]), 1.0/(1.0 - x[i]*x[i]),
00174                          2.0*x[i]*df[i]*df[i])
00175 
00176 
00177 }
00178 
00179                   
00180 
00181 #endif

Site Contact