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