AutomaticDifferentiation/AutomaticDifferentiation_static.hpp

58 lines
1.9 KiB
C++
Raw Normal View History

#ifndef DEF_AUTOMATIC_DIFFERENTIATION_STATIC
#define DEF_AUTOMATIC_DIFFERENTIATION_STATIC
#undef __Dual_DualBase
#undef __Dual_VectorT
#undef __Dual_bdynamic
#define __Dual_DualBase DualS
#define __Dual_VectorT Eigen::Array<Scalar, N, 1>
#define __Dual_bdynamic 0
#include "AutomaticDifferentiation_base.hpp"
/// Function object to evaluate the derivative of a univariate function anywhere without explicitely using the dual numbers.
///
/// Here is an example of use :
///
/// template<typename T> fct(T x) { return exp(-x*x); }
///
/// Scalar x = 3.14;
/// auto gradFct = GradFunc1(fct, x); // x is only passed to the function so that the full type of GradFunc1 does not need to be written manually.
/// Scalar dfdx = gradFct(x); // Evaluation of the gradient of fct at x.
///
/// // Alternatively :
/// Scalar fx, dfdx;
/// gradFct.get_f_grad(x, fx, dfdx); // Evaluation of the gradient of fct at x.
template<typename Func, typename Scalar>
struct GradFunc1
{
Func f;
/// Constructor of the gradient function object. The second parameter IS NOT USED FOR THE COMPUTATION OF THE GRADIENT, but only as a convenience for the
/// automatic detection of the Scalar variable type.
GradFunc1(Func f_, Scalar) : f(f_) {}
// Function that returns the 1st derivative of the function f at x.
Scalar operator()(Scalar const& x)
{
// differentiate using the dual number and return the .b component.
DualS<Scalar, 1> X(x);
X.diff(0);
DualS<Scalar, 1> Y = f(X);
return Y.d(0);
}
/// Function that returns both the function value and the gradient of f at x. Use this preferably over separate calls to f and to gradf.
void get_f_grad(Scalar const& x, Scalar & fx, Scalar & gradfx)
{
// differentiate using the dual number and return the .b component.
DualS<Scalar, 1> X(x);
X.diff(0);
DualS<Scalar, 1> Y = f(X);
fx = Y.x();
gradfx = Y.d(0);
}
};
#endif