00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #ifndef SUNDANCE_STDMATHFUNCTORS_H
00032 #define SUNDANCE_STDMATHFUNCTORS_H
00033 
00034 #include "SundanceDefs.hpp"
00035 #include "PlayaExceptions.hpp"
00036 #include "SundanceUnaryFunctor.hpp"
00037 #ifdef _MSC_VER
00038 # include "winmath.h"
00039 #endif
00040 
00041 
00042 namespace Sundance
00043 {
00044   using namespace Teuchos;
00045 
00046 
00047   class PowerFunctor : public UnaryFunctor
00048   {
00049   public:
00050 
00051     PowerFunctor(const double& p);
00052     
00053  
00054     virtual void eval1(const double* const x, 
00055               int nx, 
00056               double* f, 
00057               double* df) const ;
00058  
00059     virtual void eval0(const double* const x, int nx, double* f) const ;
00060 
00061 
00062     virtual void eval2(const double* const x, 
00063                       int nx, 
00064                       double* f, 
00065                       double* df_dx,
00066                       double* d2f_dxx) const ;
00067 
00068 
00069     virtual void eval3(const double* const x, 
00070                       int nx, 
00071                       double* f, 
00072                       double* df_dx,
00073                       double* d2f_dxx,
00074                       double* d3f_dxxx) const ;
00075 
00076     static RCP<FunctorDomain> powerDomain(const double& p);
00077 
00078   protected:
00079     bool acceptX(int diffOrder, const double& x) const
00080     {
00081       if (powerIsInteger_)
00082   {
00083     return p_>=0.0 || x!=0.0;
00084   }
00085       else
00086   {
00087     if (x<0.0) return false; 
00088     if (x==0.0) return (p_ > diffOrder);
00089   }
00090       return true;      
00091     }
00092   private:
00093     double p_;
00094     bool powerIsInteger_;
00095   };
00096 
00097 
00098   
00099   
00100 
00101   SUNDANCE_UNARY_FUNCTOR(reciprocal, StdReciprocal, "reciprocal function", 
00102                          NonzeroDomain(), 1.0/x[i], -f[i]*f[i], -2.0*df[i]/x[i])
00103 
00104     SUNDANCE_UNARY_FUNCTOR(fabs, StdFabs, "absolute value", UnboundedDomain(), ::fabs(x[i]), ((x[i]>=0.0) ? x[i] : -x[i]), 0.0)
00105 
00106   SUNDANCE_UNARY_FUNCTOR(sign, StdSign, "sign function", UnboundedDomain(), 
00107                          ((x[i]>0.0) ? 1.0 : ( (x[i]<0.0) ? -1.0 : 0.0)), 
00108                          0.0, 0.0)
00109 
00110     SUNDANCE_UNARY_FUNCTOR3(exp, StdExp, "exponential function", UnboundedDomain(), ::exp(x[i]), f[i], f[i], f[i])
00111 
00112     SUNDANCE_UNARY_FUNCTOR3(log, StdLog, "logarithm", PositiveDomain(), ::log(x[i]), 1.0/x[i], -df[i]*df[i], -2.0*d2f[i]*df[i])
00113 
00114   SUNDANCE_UNARY_FUNCTOR(sqrt, StdSqrt, "square root", PositiveDomain(), ::sqrt(x[i]), 0.5/f[i], -0.5*df[i]/x[i])
00115 
00116     SUNDANCE_UNARY_FUNCTOR3(sin, StdSin, "sine function", UnboundedDomain(), ::sin(x[i]), ::cos(x[i]), -f[i], -df[i])
00117 
00118     SUNDANCE_UNARY_FUNCTOR3(cos, StdCos, "cosine function", UnboundedDomain(), ::cos(x[i]), -::sin(x[i]), -f[i], -df[i])
00119 
00120   SUNDANCE_UNARY_FUNCTOR(tan, StdTan, "tangent function", UnboundedDomain(),
00121                          ::tan(x[i]), 1.0 + f[i]*f[i], 2.0*f[i]*df[i])
00122 
00123   SUNDANCE_UNARY_FUNCTOR(asin, StdASin, "inverse sine", 
00124                          BoundedDomain(-1.0, 1.0),
00125                          ::asin(x[i]), 1.0/::sqrt(1.0-x[i]*x[i]),
00126                          x[i]*df[i]*df[i]*df[i])
00127 
00128   SUNDANCE_UNARY_FUNCTOR(acos, StdACos, "inverse cosine",
00129                          BoundedDomain(-1.0, 1.0), 
00130                          ::acos(x[i]), -1.0/::sqrt(1.0-x[i]*x[i]),
00131                          x[i]*df[i]*df[i]*df[i])
00132 
00133   SUNDANCE_UNARY_FUNCTOR(atan, StdATan, "inverse tangent", 
00134                          UnboundedDomain(),
00135                          ::atan(x[i]), 1.0/(1.0 + x[i]*x[i]),
00136                          -2.0*x[i]*df[i]*df[i])
00137 
00138   SUNDANCE_UNARY_FUNCTOR(sinh, StdSinh, "hyperbolic sine",
00139                          UnboundedDomain(),
00140                          ::sinh(x[i]), ::cosh(x[i]), f[i])
00141 
00142   SUNDANCE_UNARY_FUNCTOR(cosh, StdCosh, "hyperbolic cosine",
00143                          UnboundedDomain(),
00144                          ::cosh(x[i]), ::sinh(x[i]), f[i])
00145 
00146   SUNDANCE_UNARY_FUNCTOR(tanh, StdTanh, "hyperbolic tangent",
00147                          UnboundedDomain(),
00148                          ::tanh(x[i]), 1.0 - f[i]*f[i], -2.0*f[i]*df[i])
00149 
00150   SUNDANCE_UNARY_FUNCTOR(asinh, StdASinh, "inverse hyperbolic sine",
00151                          UnboundedDomain(),
00152                          ::asinh(x[i]), 1.0/::sqrt(1.0 + x[i]*x[i]),
00153                          -x[i]*df[i]*df[i]*df[i])
00154 
00155   SUNDANCE_UNARY_FUNCTOR(acosh, StdACosh, "inverse hyperbolic cosine",
00156                          LowerBoundedDomain(1.0),
00157                          ::acosh(x[i]), 1.0/::sqrt(x[i]*x[i]-1.0),
00158                          -x[i]*df[i]*df[i]*df[i])
00159 
00160   SUNDANCE_UNARY_FUNCTOR(atanh, StdATanh, "inverse hyperbolic tangent",
00161                          BoundedDomain(-1.0, 1.0), 
00162                          ::atanh(x[i]), 1.0/(1.0 - x[i]*x[i]),
00163                          2.0*x[i]*df[i]*df[i])
00164 
00165 
00166 }
00167 
00168                   
00169 
00170 #endif