CGII/framework/include/cgv/math/mfunc.h
2018-05-17 15:50:03 +02:00

70 lines
2.1 KiB
C++

#pragma once
#include <cgv/math/vec.h>
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<double,int>
*/
template <typename X, typename T>
class mfunc
{
public:
/// points must have get_nr_independent_variables() components
typedef cgv::math::vec<X> pnt_type;
/// vectors must have get_nr_independent_variables() components
typedef cgv::math::vec<X> 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<n; ++i) {
q(i) += epsilon;
g(i) = evaluate(q);
q(i) = p(i)-epsilon;
g(i) -= evaluate(q);
g(i) *= inv_2_eps;
q(i) = p(i);
}
return g;
}
};
/** specialization of a multivariate function to two independent variables,
which only reimplements the method get_nr_independent_variables. */
template <typename X, typename T>
class v2_func : public mfunc<X,T>
{
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 <typename X, typename T>
class v3_func : public mfunc<X,T>
{
public:
/// returns 3
unsigned int get_nr_independent_variables() const { return 3; }
};
}
}