70 lines
2.1 KiB
C
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; }
|
||
|
};
|
||
|
|
||
|
}
|
||
|
}
|