21 #ifndef RFFGEN_CMATH_POW_HH 
   22 #define RFFGEN_CMATH_POW_HH 
   25 #include "../Util/base.hh" 
   26 #include "../Util/chainer.hh" 
   27 #include "../Util/exceptions.hh" 
   42     template <
int div
idend, 
int divisor=1>
 
   43     struct Pow : 
Base , Chainer< Pow<dividend,divisor> >
 
   45       using Chainer< Pow<dividend,divisor> >::operator ();
 
   56 #ifdef RFFGEN_ENABLE_EXCEPTIONS 
   57         if( k < 3 &&  x == 0 ) 
throw OutOfDomainException(
"Pow<" + std::to_string(dividend) + 
"," + std::to_string(divisor) + 
">" , 
"]-inf,inf[ \\ {0}",x,__FILE__,__LINE__);
 
   59         xk = x * (xk1 = x * (xk2 = x * ( xk3 = ::pow(x,k-3)) ) );
 
   63       double d0() const noexcept
 
   70       double d1(
double dx = 1.)
 const 
   76       template < 
int = -1 , 
int = -1 >
 
   77       double d2(
double dx = 1., 
double dy = 1.)
 const 
   79         return k * (k-1) * xk2 * dx * dy;
 
   83       template < 
int = -1 , 
int = -1 , 
int = -1 >
 
   84       double d3(
double dx = 1., 
double dy = 1., 
double dz = 1.)
 const 
   86         return k * (k-1) * (k-2) * xk3 * dx * dy * dz;
 
   90       const double k = 
static_cast<double>(dividend)/divisor;
 
   91       double xk, xk1, xk2, xk3;
 
   98     template <
int div
idend, 
int divisor=1>
 
  113     struct Pow<2,1> : 
Base, Chainer< Pow<2,1> >
 
  115       using Chainer< Pow<2,1> >::operator ();
 
  117       explicit Pow(
double x_=0) { 
update(x_); }
 
  119       void update(
const double& x_)
 
  126       double d0() const noexcept
 
  132       template < 
int = -1 >
 
  133       double d1(
double dx=1.)
 const 
  139       template < 
int = -1 , 
int = -1 >
 
  140       double d2(
double dx=1, 
double dy=1)
 const 
  146       double x = 0., x2 = 0.;
 
  150     struct Pow<3,1> : Base , Chainer< Pow<3,1> >
 
  152       using Chainer< Pow<3,1> >::operator ();
 
  154       explicit Pow(
double x_=0) { 
update(x_); }
 
  164       double d0() const noexcept
 
  170       template < 
int = -1 >
 
  171       double d1(
double dx=1)
 const 
  177       template < 
int = -1 , 
int = -1 >
 
  178       double d2(
double dx=1, 
double dy=1)
 const 
  180         return 6 * x * dx * dy;
 
  183       template < 
int = -1 , 
int = -1 , 
int = -1 >
 
  184       double d3(
double dx=1,
double dy=1,
double dz=1)
 const 
  190       double x = 0., x2 = 0., x3 = 0.;
 
  199     struct Pow<-1,1> : Base , Chainer< Pow<-1,1> >
 
  201       using Chainer< 
Pow<-1,1> >::operator ();
 
  207 #ifdef RFFGEN_ENABLE_EXCEPTIONS 
  208         if( x == 0 ) 
throw OutOfDomainException(
"Pow<-1,1>",
"]-inf,inf[ \\ {0}",x,__FILE__,__LINE__);
 
  211         x_inv2 = x_inv*x_inv;
 
  215       double d0() const noexcept
 
  221       template < 
int = -1 >
 
  222       double d1(
double dx = 1.)
 const 
  224         return -1 * x_inv2 * dx;
 
  228       template < 
int = -1 , 
int = -1 >
 
  229       double d2(
double dx = 1., 
double dy = 1.)
 const 
  231         return 2 * x_inv2 * x_inv * dx * dy;
 
  235       template < 
int = -1 , 
int = -1 , 
int = -1 >
 
  236       double d3(
double dx = 1., 
double dy = 1., 
double dz = 1.)
 const 
  238         return -6 * x_inv2 * x_inv2 * dx * dy * dz;
 
  242       double x_inv = 1., x_inv2 = 1.;
 
  246     struct Pow<1,2> : Base, Chainer< Pow<1,2> >
 
  248       using Chainer< Pow<1,2> >::operator ();
 
  259 #ifdef RFFGEN_ENABLE_EXCEPTIONS 
  260         if( x < 0 ) 
throw OutOfDomainException(
"Pow<1,2>",
"[0,inf[",x,__FILE__,__LINE__);
 
  267       double d0() const noexcept
 
  273       template < 
int = -1 >
 
  274       double d1(
double dx = 1.)
 const 
  276         return 0.5 / sqrt_x * dx;
 
  280       template < 
int = -1 , 
int = -1 >
 
  281       double d2(
double dx = 1., 
double dy = 1.)
 const 
  283         return -0.25 / (x_*sqrt_x) * dx * dy;
 
  287       template < 
int = -1 , 
int = -1 , 
int = -1 >
 
  288       double d3(
double dx = 1., 
double dy = 1., 
double dz = 1.)
 const 
  290         return 0.375 / (x_*x_*sqrt_x) * dx * dy * dz;
 
  294       double x_ = 0., sqrt_x = 1.;
 
  302     struct Pow<-1,3> : Base , Chainer< Pow<-1,3> >
 
  304       using Chainer< 
Pow<-1,3> >::operator ();
 
  315 #ifdef RFFGEN_ENABLE_EXCEPTIONS 
  316         if( x < 0 ) 
throw OutOfDomainException(
"Pow<1,3>",
"[0,inf[",x,__FILE__,__LINE__);
 
  329       double d0() const noexcept { 
return d0val; }
 
  332       template < 
int = -1 >
 
  333       double d1(
double dt=1)
 const { 
return d1val*dt; }
 
  336       template < 
int = -1 , 
int = -1 >
 
  337       double d2(
double dt0=1, 
double dt1=1)
 const { 
return d2val*dt0*dt1; }
 
  340       template < 
int = -1 , 
int = -1 , 
int = -1 >
 
  341       double d3(
double dt0=1, 
double dt1=1, 
double dt2=1)
 const { 
return d3val*dt0*dt1*dt2; }
 
  344       double d0val = 0, d1val = 0, d2val = 0, d3val = 0;
 
  353     struct Pow<-2,3> : Base , Chainer< Pow<-2,3> >
 
  355       using Chainer< 
Pow<-2,3> >::operator ();
 
  366 #ifdef RFFGEN_ENABLE_EXCEPTIONS 
  367         if( x < 0 ) 
throw OutOfDomainException(
"Pow<2,3>",
"[0,inf[",x,__FILE__,__LINE__);
 
  381       double d0() const noexcept { 
return d0val; }
 
  384       template < 
int = -1 >
 
  385       double d1(
double dt=1)
 const { 
return d1val*dt; }
 
  388       template < 
int = -1 , 
int = -1 >
 
  389       double d2(
double dt0=1, 
double dt1=1)
 const { 
return d2val*dt0*dt1; }
 
  392       template < 
int = -1 , 
int = -1 , 
int = -1 >
 
  393       double d3(
double dt0=1, 
double dt1=1, 
double dt2=1)
 const { 
return d3val*dt0*dt1*dt2; }
 
  396       double d0val = 0, d1val = 0, d2val = 0, d3val = 0;
 
  424     template <class Function, class = std::enable_if_t<std::is_base_of<Base,Function>::value> >
 
  425     auto sqrt(
const Function& f)
 
  434     template <class Function, class = std::enable_if_t<std::is_base_of<Base,Function>::value> >
 
  435     auto cbrt(
const Function& f)
 
  444     template <class Function, class = std::enable_if_t<std::is_base_of<Base,Function>::value> >
 
  445     auto cbrt2(
const Function& f)
 
  454     template <
int dividend, 
int divisor,
 
  456               class = std::enable_if_t<std::is_base_of<Base,Function>::value> >
 
  457     auto pow(
const Function& f)
 
  459       return Pow<dividend,divisor>()(f);
 
  464 #endif // RFFGEN_CMATH_POW_HH 
Pow< 2, 3 > Cbrt2
Third root squared including first three derivatives (based on sqrt(double) in <cmath>). 
Definition: pow.hh:418
Base class for functions satisfying FunctionConcept. Required for enabling the operators in generate...
Definition: base.hh:27
double d2(double dx=1., double dy=1.) const 
Second (directinal) derivative. 
Definition: pow.hh:77
Power function with rational exponent  including first three derivatives. 
Definition: pow.hh:43
double d0() const noexcept
Function value. 
Definition: pow.hh:63
auto power()
Definition: pow.hh:99
Exception for scalar function arguments that are outside the domain of the function. 
Definition: exceptions.hh:40
Pow(double x=1)
Constructor. 
Definition: pow.hh:51
Pow< 1, 3 > Cbrt
Third root including first three derivatives (based on sqrt(double) in <cmath>). 
Definition: pow.hh:412
double d3(double dx=1., double dy=1., double dz=1.) const 
Third (directional) derivative. 
Definition: pow.hh:84
void update(double x)
Reset point of evaluation. 
Definition: pow.hh:54
Pow< 1, 2 > Sqrt
Square root including first three derivatives (based on sqrt(double) in <cmath>). ...
Definition: pow.hh:406
double d1(double dx=1.) const 
First (directional) derivative. 
Definition: pow.hh:70