#pragma once #include namespace cgv { namespace math { /** interface class for multivariate function with two template arguments: - X defines the type of the independent variables and - T the type of range to which the function maps For example a function that maps from n double variables to an int would be declared as mfunc */ template class mfunc { public: /// points must have get_nr_independent_variables() components typedef cgv::math::vec pnt_type; /// vectors must have get_nr_independent_variables() components typedef cgv::math::vec vec_type; /// virtual destructor virtual ~mfunc() {} /// return the number of independent variables that are mapped by the function virtual unsigned get_nr_independent_variables() const = 0; /// interface for evaluation of the multivariate function virtual T evaluate(const pnt_type& p) const = 0; /** interface for evaluation of the gradient of the multivariate function. default implementation uses central differences to approximate the gradient, with an epsilon of 1e-5. */ virtual vec_type evaluate_gradient(const pnt_type& p) const { static X epsilon = (X)1e-5; static X inv_2_eps = (X)(0.5/epsilon); unsigned n = p.size(); vec_type g(n); pnt_type q(p); for (unsigned i=0; i class v2_func : public mfunc { public: /// returns 2 unsigned int get_nr_independent_variables() const { return 2; } }; /** specialization of a multivariate function to three independent variables, which only reimplements the method get_nr_independent_variables. */ template class v3_func : public mfunc { public: /// returns 3 unsigned int get_nr_independent_variables() const { return 3; } }; } }