9#include <kernel/analytic/function.hpp> 
   22      struct AutoDeriveGradWrapper
 
   24        template<
typename Po
int_, 
typename FuncEval_, 
typename AutoDer_>
 
   25        static typename AutoDer_::GradientType wrap(
const Point_& point, FuncEval_& func_eval, AutoDer_&)
 
   27          return func_eval.gradient(point);
 
   32      struct AutoDeriveGradWrapper<false>
 
   34        template<
typename Po
int_, 
typename FuncEval_, 
typename AutoDer_>
 
   35        static typename AutoDer_::GradientType wrap(
const Point_& point, FuncEval_&, AutoDer_& auto_der)
 
   37          return auto_der.extrapol_grad(point);
 
   42      struct AutoDeriveHessWrapper
 
   44        template<
typename Po
int_, 
typename FuncEval_, 
typename AutoDer_>
 
   45        static typename AutoDer_::HessianType wrap(
const Point_& point, FuncEval_& func_eval, AutoDer_&)
 
   47          return func_eval.hessian(point);
 
   52      struct AutoDeriveHessWrapper<false>
 
   54        template<
typename Po
int_, 
typename FuncEval_, 
typename AutoDer_>
 
   55        static typename AutoDer_::HessianType wrap(
const Point_& point, FuncEval_&, AutoDer_& auto_der)
 
   57          return auto_der.extrapol_hess(point);
 
   89    template<
typename Function_, 
typename DataType_ = Real>
 
   95      static_assert(Function_::can_value, 
"function cannot compute values");
 
  110      template<
typename Traits_>
 
  161          return Intern::AutoDeriveGradWrapper<Function_::can_grad>::wrap(point, 
_func_eval, *
this);
 
  169          return Intern::AutoDeriveHessWrapper<Function_::can_hess>::wrap(point, 
_func_eval, *
this);
 
  190          const std::size_t n(
_grad.size()-1);
 
  191          DataType def(Math::huge<DataType>());
 
  192          for(std::size_t i(0); i < n; ++i)
 
  201            for(std::size_t k(i); k > std::size_t(0); --k)
 
  212              return _grad.front();
 
  224          return _grad.front();
 
  245          const std::size_t n(
_hess.size()-1);
 
  246          DataType def(Math::huge<DataType>());
 
  247          for(std::size_t i(0); i < n; ++i)
 
  256            for(std::size_t k(i); k > std::size_t(0); --k)
 
  267              return _hess.front();
 
  279          return _hess.front();
 
  283        template<
int n_, 
int s_>
 
  287          return (x - y).norm_euclid_sqr();
 
  290        template<
int m_, 
int n_, 
int sm_, 
int sn_>
 
  295          return (x - y).norm_hessian_sqr();
 
  298        template<
int l_, 
int m_, 
int n_, 
int sl_, 
int sm_, 
int sn_>
 
  304          for(
int i(0); i < l_; ++i)
 
  306            for(
int j(0); j < m_; ++j)
 
  308              for(
int k(0); k < n_; ++k)
 
  319        static void _set_grad_quot(Tiny::Vector<DataType, domain_dim, sn_>& x, 
int i, 
const DataType& vr, 
const DataType& vl, 
const DataType denom)
 
  321          x[i] = denom * (vr - vl);
 
  325        template<
int img_dim_, 
int sm_, 
int sn_>
 
  326        static void _set_grad_quot(Tiny::Matrix<DataType, img_dim_, domain_dim, sm_, sn_>& x, 
int i, 
const ValueType& vr, 
const ValueType& vl, 
const DataType denom)
 
  328          for(
int k(0); k < img_dim_; ++k)
 
  329            x[k][i] = denom * (vr[k] - vl[k]);
 
  354            _set_grad_quot(x, i, vr, vl, denom);
 
  362        template<
int sm_, 
int sn_>
 
  365          x[i][i] = denom * (vr + vl - 
DataType(2)*vc);
 
  369        template<
int sm_, 
int sn_>
 
  370        static void _set_hess_quot(
Tiny::Matrix<DataType, domain_dim, domain_dim, sm_, sn_>& x, 
int i, 
int j, 
const ValueType& vne, 
const ValueType& vsw, 
const ValueType& vnw, 
const ValueType& vse, 
const DataType denom)
 
  372          x[i][j] = x[j][i] = denom * ((vne + vsw) - (vnw + vse));
 
  376        template<
int image_dim_, 
int sl_, 
int sm_, 
int sn_>
 
  377        static void _set_hess_quot(
Tiny::Tensor3<DataType, image_dim_, domain_dim, domain_dim, sl_, sm_, sn_>& x, 
int i, 
const ValueType& vr, 
const ValueType& vl,  
const ValueType& vc, 
const DataType denom)
 
  379          for(
int k(0); k < image_dim_; ++k)
 
  380            x[k][i][i] = denom * (vr[k] + vl[k] - 
DataType(2)*vc[k]);
 
  384        template<
int image_dim_, 
int sl_, 
int sm_, 
int sn_>
 
  385        static void _set_hess_quot(Tiny::Tensor3<DataType, image_dim_, domain_dim, domain_dim, sl_, sm_, sn_>& x, 
int i, 
int j, 
const ValueType& vne, 
const ValueType& vsw, 
const ValueType& vnw, 
const ValueType& vse, 
const DataType denom)
 
  387          for(
int k(0); k < image_dim_; ++k)
 
  388            x[k][i][j] = x[k][j][i] = denom * ((vne[k] + vsw[k]) - (vnw[k] + vse[k]));
 
  397          ValueType vc, vr, vl, vne, vnw, vse, vsw;
 
  417            _set_hess_quot(x, i, vr, vl, vc, denom1);
 
  447              _set_hess_quot(x, i, j, vne, vsw, vnw, vse, denom2);
 
  482      template<
typename... Args_>
 
  484        Function_(std::forward<Args_>(args)...),
 
  507        XASSERTM(initial_h > Math::eps<DataType_>(), 
"Initial h is too small or non-positive!");
 
  508        XASSERTM(max_steps > 0, 
"Invalid maximum extrapolation steps!");
 
  528        XASSERTM(initial_h > Math::eps<DataType_>(), 
"Initial h is too small or non-positive!");
 
  529        XASSERTM(max_steps > 0, 
"Invalid maximum extrapolation steps!");
 
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
static constexpr int domain_dim
get our dimension
Traits_::ValueType ValueType
value type
const DataType _init_grad_h
initial h for gradient extrapolation
std::vector< HessianType > _hess
our hessian extrapolation table
std::vector< GradientType > _grad
our gradient extrapolation table
const DataType _init_hess_h
initial h for hessian extrapolation
Traits_::HessianType HessianType
hessian type
void _eval_grad_quot(GradientType &x, PointType &v, const DataType h)
evaluates the first-order difference quotients
Traits_::GradientType GradientType
gradient type
void _eval_hess_quot(HessianType &x, PointType &v, const DataType h)
evaluates the second-order difference quotients
Traits_::DataType DataType
coefficient data type
Evaluator(const AutoDerive &function)
mandatory CTOR
HessianType extrapol_hess(const PointType &point)
Computes the hessian by a Richardson extrapolation scheme.
Traits_::PointType PointType
evaluation point type
GradientType extrapol_grad(const PointType &point)
Computes the gradient by a Richardson extrapolation scheme.
Function_::template Evaluator< Traits_ > _func_eval
the original function's evaluator
Auto-Derive function wrapper class template.
static constexpr bool can_grad
we provide function gradients
DataType_ _init_grad_h
initial h for gradient extrapolation
AutoDerive(Args_ &&... args)
Standard constructor.
void config_grad_extrapol(DataType_ initial_h, int max_steps)
Configures the Gradient extrapolation scheme.
static constexpr bool can_hess
we provide function hessiants
static constexpr int domain_dim
the input function must support value computation
DataType_ _init_hess_h
initial h for hessian extrapolation
Function_::ImageType ImageType
specify our image type
int _max_grad_steps
maximum number of gradient extrapolation steps
void config_hess_extrapol(DataType_ initial_h, int max_steps)
Configures the Hessian extrapolation scheme.
int _max_hess_steps
maximum number of hessian extrapolation steps
static constexpr bool can_value
our base class provides function values
Analytic Function Evaluator base-class template.
Tiny Matrix class template.
Tiny Tensor3 class template.
Tiny Vector class template.
T_ sqr(T_ x)
Returns the square of a value.
@ value
specifies whether the space should supply basis function values