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