- 3.0.2 core module.
DerivativesNumDiff.h
Go to the documentation of this file.
1 /**********************************************************************************************************************
2 This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich.
3 Licensed under the BSD-2 license (see LICENSE file in main directory)
4 **********************************************************************************************************************/
5 
6 #pragma once
7 
8 
9 namespace ct {
10 namespace core {
11 
13 
26 template <int IN_DIM, int OUT_DIM>
27 class DerivativesNumDiff : public Derivatives<IN_DIM, OUT_DIM, double>
28 {
29 public:
30  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
31 
32  typedef Eigen::Matrix<double, IN_DIM, 1> IN_TYPE;
33  typedef Eigen::Matrix<double, OUT_DIM, 1> OUT_TYPE;
34  typedef Eigen::Matrix<double, OUT_DIM, IN_DIM> JAC_TYPE;
35  typedef Eigen::Matrix<double, IN_DIM, IN_DIM> HES_TYPE;
36 
37  typedef std::function<OUT_TYPE(const IN_TYPE&)> Function;
38 
40 
49  DerivativesNumDiff(Function& f, bool doubleSidedDerivative = false)
50  : f_(f), doubleSidedDerivative_(doubleSidedDerivative)
51  {
52  eps_ = sqrt(Eigen::NumTraits<double>::epsilon());
53  }
54 
56  : f_(arg.f_), doubleSidedDerivative_(arg.doubleSidedDerivative_), eps_(arg.eps_)
57  {
58  }
59 
61  virtual ~DerivativesNumDiff() {}
63  DerivativesNumDiff* clone() const override { return new DerivativesNumDiff<IN_DIM, OUT_DIM>(*this); }
64  virtual OUT_TYPE forwardZero(const Eigen::VectorXd& x) override { return f_(x); }
66 
70  virtual JAC_TYPE jacobian(const Eigen::VectorXd& x) override
71  {
72  JAC_TYPE jac;
73  OUT_TYPE y_ref;
74 
75  if (!doubleSidedDerivative_)
76  {
77  y_ref = f_(x);
78  }
79 
80  for (size_t i = 0; i < x.rows(); ++i)
81  {
82  // inspired from http://en.wikipedia.org/wiki/Numerical_differentiation#Practical_considerations_using_floating_point_arithmetic
83  double h = eps_ * std::max(std::abs(x(i)), 1.0);
84  volatile double x_ph = x(i) + h;
85  double dxp = x_ph - x(i);
86 
87  IN_TYPE x_perturbed = x;
88  x_perturbed(i) = x_ph;
89 
90  // get evaluation of f(x,u)
91  OUT_TYPE y_perturbed = f_(x_perturbed);
92 
93  if (doubleSidedDerivative_)
94  {
95  volatile double x_mh = x(i) - h;
96  double dxm = x(i) - x_mh;
97 
98  x_perturbed = x;
99  x_perturbed(i) = x_mh;
100  OUT_TYPE y_perturbed_low = f_(x_perturbed);
101 
102  jac.template col(i) = (y_perturbed - y_perturbed_low) / (dxp + dxm);
103  }
104  else
105  {
106  jac.template col(i) = (y_perturbed - y_ref) / dxp;
107  }
108  }
109 
110  return jac;
111  }
112 
113 private:
114  std::function<OUT_TYPE(const IN_TYPE&)> f_;
115 
116  bool doubleSidedDerivative_;
117  double eps_;
118 };
119 }
120 }
virtual OUT_TYPE forwardZero(const Eigen::VectorXd &x) override
Evaluates the method itself.
Definition: DerivativesNumDiff.h:64
DerivativesNumDiff(Function &f, bool doubleSidedDerivative=false)
default constructor
Definition: DerivativesNumDiff.h:49
virtual JAC_TYPE jacobian(const Eigen::VectorXd &x) override
evaluate Derivatives at a given point
Definition: DerivativesNumDiff.h:70
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef Eigen::Matrix< double, IN_DIM, 1 > IN_TYPE
function input vector type
Definition: DerivativesNumDiff.h:32
Eigen::Matrix< double, OUT_DIM, 1 > OUT_TYPE
function output vector type
Definition: DerivativesNumDiff.h:33
Eigen::Matrix< double, OUT_DIM, IN_DIM > JAC_TYPE
Definition: DerivativesNumDiff.h:34
Derivatives using Num-Diff Codegeneration.
Definition: DerivativesNumDiff.h:27
General interface class for a Derivatives.
Definition: Derivatives.h:24
for i
std::function< OUT_TYPE(const IN_TYPE &)> Function
function tpye
Definition: DerivativesNumDiff.h:37
DerivativesNumDiff * clone() const override
deep cloning
Definition: DerivativesNumDiff.h:63
virtual ~DerivativesNumDiff()
default destructor
Definition: DerivativesNumDiff.h:61
Eigen::Matrix< double, IN_DIM, IN_DIM > HES_TYPE
Definition: DerivativesNumDiff.h:35
DerivativesNumDiff(const DerivativesNumDiff &arg)
Definition: DerivativesNumDiff.h:55