22 #include <boost/function.hpp>
24 #pragma GCC diagnostic push
25 #pragma GCC diagnostic ignored "-Wunused-variable"
27 #include <boost/bind.hpp>
29 #pragma GCC diagnostic pop
62 inline LieVector makeLieVectorD(
double d) {
return LieVector((Vector) (Vector(1) << d)); }
71 double factor = 1.0/(2.0*
delta);
72 const size_t n = x.dim();
74 for (
size_t j=0;j<n;j++) {
75 d(j) +=
delta;
double hxplus = h(x.retract(d));
76 d(j) -= 2*
delta;
double hxmin = h(x.retract(d));
77 d(j) +=
delta; g(j) = (hxplus-hxmin)*factor;
84 return numericalGradient<X>(boost::bind(h, _1), x,
delta);
97 template<
class Y,
class X>
100 double factor = 1.0/(2.0*
delta);
101 const size_t m = hx.dim(), n = x.dim();
103 Matrix H =
zeros(m,n);
104 for (
size_t j=0;j<n;j++) {
105 d(j) +=
delta; Vector hxplus = hx.localCoordinates(h(x.retract(d)));
106 d(j) -= 2*
delta; Vector hxmin = hx.localCoordinates(h(x.retract(d)));
108 H.col(j) << (hxplus-hxmin)*factor;
114 template<
class Y,
class X>
116 return numericalDerivative11<Y,X>(boost::bind(h, _1), x,
delta);
127 return numericalDerivative11<LieVector, X>(boost::bind(makeLieVectorD, boost::bind(h, _1)), x,
delta);
133 return numericalDerivative11<LieVector, X>(boost::bind(
makeLieVector, boost::bind(h, _1)), x,
delta);
138 return numericalDerivative11<LieVector, X>(boost::bind(
makeLieVector, boost::bind(h, _1)), x,
delta);
150 template<
class Y,
class X1,
class X2>
152 const X1& x1,
const X2& x2,
double delta=1e-5) {
154 double factor = 1.0/(2.0*
delta);
155 const size_t m = hx.dim(), n = x1.dim();
157 Matrix H =
zeros(m,n);
158 for (
size_t j=0;j<n;j++) {
159 d(j) +=
delta; Vector hxplus = hx.localCoordinates(h(x1.retract(d),x2));
160 d(j) -= 2*
delta; Vector hxmin = hx.localCoordinates(h(x1.retract(d),x2));
162 H.col(j) << (hxplus-hxmin)*factor;
168 template<
class Y,
class X1,
class X2>
170 const X1& x1,
const X2& x2,
double delta=1e-5) {
171 return numericalDerivative21<Y,X1,X2>(boost::bind(h, _1, _2), x1, x2,
delta);
175 template<
class X1,
class X2>
177 const X1& x1,
const X2& x2,
double delta=1e-5) {
178 return numericalDerivative21<LieVector,X1,X2>(
179 boost::bind(makeLieVectorD, boost::bind(h, _1, _2)), x1, x2,
delta);
182 template<
class X1,
class X2>
184 const X1& x1,
const X2& x2,
double delta=1e-5) {
185 return numericalDerivative21<LieVector,X1,X2>(
186 boost::bind(makeLieVectorD, boost::bind(h, _1, _2)), x1, x2,
delta);
190 template<
class X1,
class X2>
192 const X1& x1,
const X2& x2,
double delta=1e-5) {
193 return numericalDerivative21<LieVector,X1,X2>(
197 template<
class X1,
class X2>
199 const X1& x1,
const X2& x2,
double delta=1e-5) {
200 return numericalDerivative21<LieVector,X1,X2>(
213 template<
class Y,
class X1,
class X2>
215 (boost::function<Y(
const X1&,
const X2&)> h,
216 const X1& x1,
const X2& x2,
double delta=1e-5) {
218 double factor = 1.0/(2.0*
delta);
219 const size_t m = hx.dim(), n = x2.dim();
221 Matrix H =
zeros(m,n);
222 for (
size_t j=0;j<n;j++) {
223 d(j) +=
delta; Vector hxplus = hx.localCoordinates(h(x1,x2.retract(d)));
224 d(j) -= 2*
delta; Vector hxmin = hx.localCoordinates(h(x1,x2.retract(d)));
226 H.col(j) << (hxplus-hxmin)*factor;
232 template<
class Y,
class X1,
class X2>
234 (Y (*h)(
const X1&,
const X2&),
const X1& x1,
const X2& x2,
double delta=1e-5) {
235 return numericalDerivative22<Y,X1,X2>(boost::bind(h, _1, _2), x1, x2,
delta);
239 template<
class X1,
class X2>
241 const X1& x1,
const X2& x2,
double delta=1e-5) {
242 return numericalDerivative22<LieVector,X1,X2>(
243 boost::bind(makeLieVectorD, boost::bind(h, _1, _2)), x1, x2,
delta);
246 template<
class X1,
class X2>
248 const X1& x1,
const X2& x2,
double delta=1e-5) {
249 return numericalDerivative22<LieVector,X1,X2>(
250 boost::bind(makeLieVectorD, boost::bind(h, _1, _2)), x1, x2,
delta);
254 template<
class X1,
class X2>
256 const X1& x1,
const X2& x2,
double delta=1e-5) {
257 return numericalDerivative22<LieVector,X1,X2>(
261 template<
class X1,
class X2>
263 const X1& x1,
const X2& x2,
double delta=1e-5) {
264 return numericalDerivative22<LieVector,X1,X2>(
278 template<
class Y,
class X1,
class X2,
class X3>
280 (boost::function<Y(
const X1&,
const X2&,
const X3&)> h,
281 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5)
284 double factor = 1.0/(2.0*
delta);
285 const size_t m = hx.dim(), n = x1.dim();
287 Matrix H =
zeros(m,n);
288 for (
size_t j=0;j<n;j++) {
289 d(j) +=
delta; Vector hxplus = hx.localCoordinates(h(x1.retract(d),x2,x3));
290 d(j) -= 2*
delta; Vector hxmin = hx.localCoordinates(h(x1.retract(d),x2,x3));
292 H.col(j) << (hxplus-hxmin)*factor;
296 template<
class Y,
class X1,
class X2,
class X3>
298 (Y (*h)(
const X1&,
const X2&,
const X3&),
299 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
300 return numericalDerivative31<Y,X1,X2, X3>(boost::bind(h, _1, _2, _3), x1, x2, x3,
delta);
304 template<
class X1,
class X2,
class X3>
306 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
307 return numericalDerivative31<LieVector,X1,X2,X3>(
308 boost::bind(makeLieVectorD, boost::bind(h, _1, _2, _3)), x1, x2, x3,
delta);
311 template<
class X1,
class X2,
class X3>
313 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
314 return numericalDerivative31<LieVector,X1,X2,X3>(
315 boost::bind(makeLieVectorD, boost::bind(h, _1, _2, _3)), x1, x2, x3,
delta);
319 template<
class X1,
class X2,
class X3>
321 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
322 return numericalDerivative31<LieVector,X1,X2,X3>(
326 template<
class X1,
class X2,
class X3>
328 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
329 return numericalDerivative31<LieVector,X1,X2,X3>(
343 template<
class Y,
class X1,
class X2,
class X3>
345 (boost::function<Y(
const X1&,
const X2&,
const X3&)> h,
346 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5)
349 double factor = 1.0/(2.0*
delta);
350 const size_t m = hx.dim(), n = x2.dim();
352 Matrix H =
zeros(m,n);
353 for (
size_t j=0;j<n;j++) {
354 d(j) +=
delta; Vector hxplus = hx.localCoordinates(h(x1, x2.retract(d),x3));
355 d(j) -= 2*
delta; Vector hxmin = hx.localCoordinates(h(x1, x2.retract(d),x3));
357 H.col(j) << (hxplus-hxmin)*factor;
361 template<
class Y,
class X1,
class X2,
class X3>
363 (Y (*h)(
const X1&,
const X2&,
const X3&),
364 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
365 return numericalDerivative32<Y,X1,X2, X3>(boost::bind(h, _1, _2, _3), x1, x2, x3,
delta);
369 template<
class X1,
class X2,
class X3>
371 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
372 return numericalDerivative32<LieVector,X1,X2,X3>(
373 boost::bind(makeLieVectorD, boost::bind(h, _1, _2, _3)), x1, x2, x3,
delta);
376 template<
class X1,
class X2,
class X3>
378 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
379 return numericalDerivative32<LieVector,X1,X2,X3>(
380 boost::bind(makeLieVectorD, boost::bind(h, _1, _2, _3)), x1, x2, x3,
delta);
384 template<
class X1,
class X2,
class X3>
386 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
387 return numericalDerivative32<LieVector,X1,X2,X3>(
391 template<
class X1,
class X2,
class X3>
393 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
394 return numericalDerivative32<LieVector,X1,X2,X3>(
408 template<
class Y,
class X1,
class X2,
class X3>
410 (boost::function<Y(
const X1&,
const X2&,
const X3&)> h,
411 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5)
414 double factor = 1.0/(2.0*
delta);
415 const size_t m = hx.dim(), n = x3.dim();
417 Matrix H =
zeros(m,n);
418 for (
size_t j=0;j<n;j++) {
419 d(j) +=
delta; Vector hxplus = hx.localCoordinates(h(x1, x2, x3.retract(d)));
420 d(j) -= 2*
delta; Vector hxmin = hx.localCoordinates(h(x1, x2, x3.retract(d)));
422 H.col(j) << (hxplus-hxmin)*factor;
426 template<
class Y,
class X1,
class X2,
class X3>
428 (Y (*h)(
const X1&,
const X2&,
const X3&),
429 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
430 return numericalDerivative33<Y,X1,X2, X3>(boost::bind(h, _1, _2, _3), x1, x2, x3,
delta);
434 template<
class X1,
class X2,
class X3>
436 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
437 return numericalDerivative33<LieVector,X1,X2,X3>(
438 boost::bind(makeLieVectorD, boost::bind(h, _1, _2, _3)), x1, x2, x3,
delta);
441 template<
class X1,
class X2,
class X3>
443 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
444 return numericalDerivative33<LieVector,X1,X2,X3>(
445 boost::bind(makeLieVectorD, boost::bind(h, _1, _2, _3)), x1, x2, x3,
delta);
449 template<
class X1,
class X2,
class X3>
451 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
452 return numericalDerivative33<LieVector,X1,X2,X3>(
456 template<
class X1,
class X2,
class X3>
458 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
459 return numericalDerivative33<LieVector,X1,X2,X3>(
473 return numericalDerivative11<X>(boost::function<Vector(const X&)>(boost::bind(
474 static_cast<Vector (*)(boost::function<double(const X&)>,
const X&,
double)
>(&numericalGradient<X>),
487 template<
class X1,
class X2>
489 const boost::function<double(const X1&, const X2&)>& f_;
493 G_x1(
const boost::function<
double(
const X1&,
const X2&)>& f,
const X1& x1,
double delta) : f_(f), x1_(x1), delta_(delta) {}
494 Vector operator()(
const X2& x2) {
495 return numericalGradient<X1>(boost::function<double (const X1&)>(boost::bind(f_, _1, x2)), x1_, delta_);
499 template<
class X1,
class X2>
500 inline Matrix numericalHessian212(boost::function<
double(
const X1&,
const X2&)> f,
const X1& x1,
const X2& x2,
double delta=1e-5) {
502 return numericalDerivative11<X2>(boost::function<Vector (const X2&)>(boost::bind<Vector>(boost::ref(g_x1), _1)), x2,
delta);
506 template<
class X1,
class X2>
507 inline Matrix numericalHessian212(
double (*f)(
const X1&,
const X2&),
const X1& x1,
const X2& x2,
double delta=1e-5) {
508 return numericalHessian212(boost::function<
double (
const X1&,
const X2&)>(f), x1, x2,
delta);
512 template<
class X1,
class X2>
513 inline Matrix numericalHessian211(boost::function<
double(
const X1&,
const X2&)> f,
const X1& x1,
const X2& x2,
double delta=1e-5) {
515 Vector (*numGrad)(boost::function<double(const X1&)>,
const X1&, double) = &numericalGradient<X1>;
516 boost::function<double (const X1&)> f2(boost::bind(f, _1, x2));
518 return numericalDerivative11<X1>(boost::function<Vector (const X1&)>(boost::bind(numGrad, f2, _1,
delta)), x1,
delta);
522 template<
class X1,
class X2>
523 inline Matrix numericalHessian211(
double (*f)(
const X1&,
const X2&),
const X1& x1,
const X2& x2,
double delta=1e-5) {
524 return numericalHessian211(boost::function<
double (
const X1&,
const X2&)>(f), x1, x2,
delta);
528 template<
class X1,
class X2>
529 inline Matrix numericalHessian222(boost::function<
double(
const X1&,
const X2&)> f,
const X1& x1,
const X2& x2,
double delta=1e-5) {
531 Vector (*numGrad)(boost::function<double(const X2&)>,
const X2&, double) = &numericalGradient<X2>;
532 boost::function<double (const X2&)> f2(boost::bind(f, x1, _1));
534 return numericalDerivative11<X2>(boost::function<Vector (const X2&)>(boost::bind(numGrad, f2, _1,
delta)), x2,
delta);
538 template<
class X1,
class X2>
539 inline Matrix numericalHessian222(
double (*f)(
const X1&,
const X2&),
const X1& x1,
const X2& x2,
double delta=1e-5) {
540 return numericalHessian222(boost::function<
double (
const X1&,
const X2&)>(f), x1, x2,
delta);
547 template<
class X1,
class X2,
class X3>
549 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
551 Vector (*numGrad)(boost::function<double(const X1&)>,
const X1&, double) = &numericalGradient<X1>;
552 boost::function<double (const X1&)> f2(boost::bind(f, _1, x2, x3));
554 return numericalDerivative11<X1>(boost::function<Vector (const X1&)>(boost::bind(numGrad, f2, _1,
delta)), x1,
delta);
557 template<
class X1,
class X2,
class X3>
558 inline Matrix
numericalHessian311(
double (*f)(
const X1&,
const X2&,
const X3&),
const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
563 template<
class X1,
class X2,
class X3>
564 inline Matrix numericalHessian322(boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
565 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
567 Vector (*numGrad)(boost::function<double(const X2&)>,
const X2&, double) = &numericalGradient<X2>;
568 boost::function<double (const X2&)> f2(boost::bind(f, x1, _1, x3));
570 return numericalDerivative11<X2>(boost::function<Vector (const X2&)>(boost::bind(numGrad, f2, _1,
delta)), x2,
delta);
573 template<
class X1,
class X2,
class X3>
574 inline Matrix numericalHessian322(
double (*f)(
const X1&,
const X2&,
const X3&),
const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
575 return numericalHessian322(boost::function<
double (
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
delta);
579 template<
class X1,
class X2,
class X3>
580 inline Matrix numericalHessian333(boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
581 const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
583 Vector (*numGrad)(boost::function<double(const X3&)>,
const X3&, double) = &numericalGradient<X3>;
584 boost::function<double (const X3&)> f2(boost::bind(f, x1, x2, _1));
586 return numericalDerivative11<X3>(boost::function<Vector (const X3&)>(boost::bind(numGrad, f2, _1,
delta)), x3,
delta);
589 template<
class X1,
class X2,
class X3>
590 inline Matrix numericalHessian333(
double (*f)(
const X1&,
const X2&,
const X3&),
const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
591 return numericalHessian333(boost::function<
double (
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
delta);
595 template<
class X1,
class X2,
class X3>
596 inline Matrix numericalHessian312(boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
597 return numericalHessian212<X1,X2>(boost::function<double (const X1&, const X2&)>(boost::bind(f, _1, _2, x3)), x1, x2,
delta );
600 template<
class X1,
class X2,
class X3>
601 inline Matrix numericalHessian313(boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
602 return numericalHessian212<X1,X3>(boost::function<double (const X1&, const X3&)>(boost::bind(f, _1, x2, _2)), x1, x3,
delta );
605 template<
class X1,
class X2,
class X3>
606 inline Matrix numericalHessian323(boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
607 return numericalHessian212<X2,X3>(boost::function<double (const X2&, const X3&)>(boost::bind(f, x1, _1, _2)), x2, x3,
delta );
611 template<
class X1,
class X2,
class X3>
612 inline Matrix numericalHessian312(
double (*f)(
const X1&,
const X2&,
const X3&),
const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
613 return numericalHessian312(boost::function<
double (
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
delta);
616 template<
class X1,
class X2,
class X3>
617 inline Matrix numericalHessian313(
double (*f)(
const X1&,
const X2&,
const X3&),
const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
618 return numericalHessian313(boost::function<
double (
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
delta);
621 template<
class X1,
class X2,
class X3>
622 inline Matrix numericalHessian323(
double (*f)(
const X1&,
const X2&,
const X3&),
const X1& x1,
const X2& x2,
const X3& x3,
double delta=1e-5) {
623 return numericalHessian323(boost::function<
double (
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
delta);
Matrix numericalDerivative22(boost::function< Y(const X1 &, const X2 &)> h, const X1 &x1, const X2 &x2, double delta=1e-5)
Compute numerical derivative in argument 2 of binary function.
Definition: numericalDerivative.h:215
Matrix numericalDerivative21(boost::function< Y(const X1 &, const X2 &)> h, const X1 &x1, const X2 &x2, double delta=1e-5)
Compute numerical derivative in argument 1 of binary function.
Definition: numericalDerivative.h:151
Helper class that computes the derivative of f w.r.t.
Definition: numericalDerivative.h:488
Matrix numericalHessian(boost::function< double(const X &)> f, const X &x, double delta=1e-5)
Compute numerical Hessian matrix.
Definition: numericalDerivative.h:472
Matrix numericalHessian311(boost::function< double(const X1 &, const X2 &, const X3 &)> f, const X1 &x1, const X2 &x2, const X3 &x3, double delta=1e-5)
Numerical Hessian for tenary functions.
Definition: numericalDerivative.h:548
Vector numericalGradient(boost::function< double(const X &)> h, const X &x, double delta=1e-5)
Numerically compute gradient of scalar function Class X is the input argument The class X needs to ha...
Definition: numericalDerivative.h:70
bool zero(const Vector &v)
check if all zero
Definition: Vector.cpp:39
A wrapper around vector providing Lie compatibility.
Matrix numericalDerivative33(boost::function< Y(const X1 &, const X2 &, const X3 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, double delta=1e-5)
Compute numerical derivative in argument 3 of ternary function.
Definition: numericalDerivative.h:410
typedef and functions to augment Eigen's MatrixXd
Matrix numericalDerivative32(boost::function< Y(const X1 &, const X2 &, const X3 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, double delta=1e-5)
Compute numerical derivative in argument 2 of ternary function.
Definition: numericalDerivative.h:345
LieVector makeLieVector(const Vector &v)
global functions for converting to a LieVector for use with numericalDerivative
Definition: numericalDerivative.h:61
LieVector is a wrapper around vector to allow it to be a Lie type.
Definition: LieVector.h:29
Vector delta(size_t n, size_t i, double value)
Create basis vector of dimension n, with a constant in spot i.
Definition: Vector.cpp:53
Matrix zeros(size_t m, size_t n)
Creates an zeros matrix, with matlab-like syntax.
Definition: Matrix.cpp:40
Matrix numericalDerivative11(boost::function< Y(const X &)> h, const X &x, double delta=1e-5)
Compute numerical derivative in argument 1 of unary function.
Definition: numericalDerivative.h:98
Matrix numericalDerivative31(boost::function< Y(const X1 &, const X2 &, const X3 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, double delta=1e-5)
Compute numerical derivative in argument 1 of ternary function.
Definition: numericalDerivative.h:280