21 #include <boost/function.hpp> 23 #pragma GCC diagnostic push 24 #pragma GCC diagnostic ignored "-Wunused-variable" 26 #include <boost/bind.hpp> 28 #pragma GCC diagnostic pop 63 template<
class Y,
class X=
double>
75 typename internal::FixedSizeMatrix<X>::type
numericalGradient(boost::function<
double(
const X&)> h,
const X& x,
76 double delta = 1e-5) {
77 double factor = 1.0 / (2.0 * delta);
79 BOOST_STATIC_ASSERT_MSG(
81 "Template argument X must be a manifold type.");
83 BOOST_STATIC_ASSERT_MSG(N>0,
"Template argument X must be fixed-size type.");
91 Eigen::Matrix<double,N,1> g; g.setZero();
92 for (
int j = 0; j < N; j++) {
98 g(j) = (hxplus - hxmin) * factor;
114 template<
class Y,
class X>
117 double delta = 1e-5) {
119 typedef typename internal::FixedSizeMatrix<Y,X>::type Matrix;
122 "Template argument Y must be a manifold type.");
124 typedef typename TraitsY::TangentVector TangentY;
127 "Template argument X must be a manifold type.");
129 BOOST_STATIC_ASSERT_MSG(N>0,
"Template argument X must be fixed-size type.");
131 typedef typename TraitsX::TangentVector TangentX;
137 const TangentY zeroY = TraitsY::Local(hx, hx);
138 const size_t m = zeroY.size();
145 Matrix H = Matrix::Zero(m, N);
146 const double factor = 1.0 / (2.0 * delta);
147 for (
int j = 0; j < N; j++) {
149 const TangentY dy1 = TraitsY::Local(hx, h(TraitsX::Retract(x, dx)));
151 const TangentY dy2 = TraitsY::Local(hx, h(TraitsX::Retract(x, dx)));
153 H.col(j) << (dy1 - dy2) * factor;
159 template<
class Y,
class X>
161 double delta = 1e-5) {
162 return numericalDerivative11<Y, X>(boost::bind(h, _1), x, delta);
173 template<
class Y,
class X1,
class X2>
174 typename internal::FixedSizeMatrix<Y,X1>::type
numericalDerivative21(
const boost::function<Y(
const X1&,
const X2&)>& h,
175 const X1& x1,
const X2& x2,
double delta = 1e-5) {
177 "Template argument Y must be a manifold type.");
179 "Template argument X1 must be a manifold type.");
180 return numericalDerivative11<Y, X1>(boost::bind(h, _1, x2), x1, delta);
184 template<
class Y,
class X1,
class X2>
186 const X2& x2,
double delta = 1e-5) {
187 return numericalDerivative21<Y, X1, X2>(boost::bind(h, _1, _2), x1, x2, delta);
198 template<
class Y,
class X1,
class X2>
200 const X1& x1,
const X2& x2,
double delta = 1e-5) {
204 "Template argument X2 must be a manifold type.");
205 return numericalDerivative11<Y, X2>(boost::bind(h, x1, _1), x2, delta);
209 template<
class Y,
class X1,
class X2>
211 const X2& x2,
double delta = 1e-5) {
212 return numericalDerivative22<Y, X1, X2>(boost::bind(h, _1, _2), x1, x2, delta);
225 template<
class Y,
class X1,
class X2,
class X3>
227 boost::function<Y(
const X1&,
const X2&,
const X3&)> h,
const X1& x1,
228 const X2& x2,
const X3& x3,
double delta = 1e-5) {
230 "Template argument Y must be a manifold type.");
232 "Template argument X1 must be a manifold type.");
233 return numericalDerivative11<Y, X1>(boost::bind(h, _1, x2, x3), x1, delta);
236 template<
class Y,
class X1,
class X2,
class X3>
237 typename internal::FixedSizeMatrix<Y,X1>::type
numericalDerivative31(Y (*h)(
const X1&,
const X2&,
const X3&),
238 const X1& x1,
const X2& x2,
const X3& x3,
double delta = 1e-5) {
239 return numericalDerivative31<Y, X1, X2, X3>(boost::bind(h, _1, _2, _3), x1,
253 template<
class Y,
class X1,
class X2,
class X3>
255 boost::function<Y(
const X1&,
const X2&,
const X3&)> h,
const X1& x1,
256 const X2& x2,
const X3& x3,
double delta = 1e-5) {
258 "Template argument Y must be a manifold type.");
260 "Template argument X2 must be a manifold type.");
261 return numericalDerivative11<Y, X2>(boost::bind(h, x1, _1, x3), x2, delta);
264 template<
class Y,
class X1,
class X2,
class X3>
265 inline typename internal::FixedSizeMatrix<Y,X2>::type
numericalDerivative32(Y (*h)(
const X1&,
const X2&,
const X3&),
266 const X1& x1,
const X2& x2,
const X3& x3,
double delta = 1e-5) {
267 return numericalDerivative32<Y, X1, X2, X3>(boost::bind(h, _1, _2, _3), x1,
281 template<
class Y,
class X1,
class X2,
class X3>
283 boost::function<Y(
const X1&,
const X2&,
const X3&)> h,
const X1& x1,
284 const X2& x2,
const X3& x3,
double delta = 1e-5) {
286 "Template argument Y must be a manifold type.");
288 "Template argument X3 must be a manifold type.");
289 return numericalDerivative11<Y, X3>(boost::bind(h, x1, x2, _1), x3, delta);
292 template<
class Y,
class X1,
class X2,
class X3>
293 inline typename internal::FixedSizeMatrix<Y,X3>::type
numericalDerivative33(Y (*h)(
const X1&,
const X2&,
const X3&),
294 const X1& x1,
const X2& x2,
const X3& x3,
double delta = 1e-5) {
295 return numericalDerivative33<Y, X1, X2, X3>(boost::bind(h, _1, _2, _3), x1,
309 template<
class Y,
class X1,
class X2,
class X3,
class X4>
311 boost::function<Y(
const X1&,
const X2&,
const X3&,
const X4&)> h,
const X1& x1,
312 const X2& x2,
const X3& x3,
const X4& x4,
double delta = 1e-5) {
314 "Template argument Y must be a manifold type.");
316 "Template argument X1 must be a manifold type.");
317 return numericalDerivative11<Y, X1>(boost::bind(h, _1, x2, x3, x4), x1, delta);
330 template<
class Y,
class X1,
class X2,
class X3,
class X4>
332 boost::function<Y(
const X1&,
const X2&,
const X3&,
const X4&)> h,
const X1& x1,
333 const X2& x2,
const X3& x3,
const X4& x4,
double delta = 1e-5) {
335 "Template argument Y must be a manifold type.");
337 "Template argument X2 must be a manifold type.");
338 return numericalDerivative11<Y, X2>(boost::bind(h, x1, _1, x3, x4), x2, delta);
351 template<
class Y,
class X1,
class X2,
class X3,
class X4>
353 boost::function<Y(
const X1&,
const X2&,
const X3&,
const X4&)> h,
const X1& x1,
354 const X2& x2,
const X3& x3,
const X4& x4,
double delta = 1e-5) {
356 "Template argument Y must be a manifold type.");
358 "Template argument X3 must be a manifold type.");
359 return numericalDerivative11<Y, X3>(boost::bind(h, x1, x2, _1, x4), x3, delta);
372 template<
class Y,
class X1,
class X2,
class X3,
class X4>
374 boost::function<Y(
const X1&,
const X2&,
const X3&,
const X4&)> h,
const X1& x1,
375 const X2& x2,
const X3& x3,
const X4& x4,
double delta = 1e-5) {
377 "Template argument Y must be a manifold type.");
379 "Template argument X4 must be a manifold type.");
380 return numericalDerivative11<Y, X4>(boost::bind(h, x1, x2, x3, _1), x4, delta);
392 inline typename internal::FixedSizeMatrix<X,X>::type
numericalHessian(boost::function<
double(
const X&)> f,
const X& x,
393 double delta = 1e-5) {
395 "Template argument X must be a manifold type.");
396 typedef Eigen::Matrix<double, traits<X>::dimension, 1> VectorD;
397 typedef boost::function<double(const X&)> F;
398 typedef boost::function<VectorD(F, const X&, double)> G;
399 G ng =
static_cast<G
>(numericalGradient<X> );
400 return numericalDerivative11<VectorD, X>(boost::bind(ng, f, _1, delta), x,
405 inline typename internal::FixedSizeMatrix<X,X>::type
numericalHessian(
double (*f)(
const X&),
const X& x,
double delta =
413 template<
class X1,
class X2>
415 const boost::function<double(const X1&, const X2&)>& f_;
419 typedef typename internal::FixedSizeMatrix<X1>::type Vector;
421 G_x1(
const boost::function<
double(
const X1&,
const X2&)>& f,
const X1& x1,
423 f_(f), x1_(x1), delta_(delta) {
425 Vector operator()(
const X2& x2) {
426 return numericalGradient<X1>(boost::bind(f_, _1, x2), x1_, delta_);
430 template<
class X1,
class X2>
431 inline typename internal::FixedSizeMatrix<X1,X2>::type numericalHessian212(
432 boost::function<
double(
const X1&,
const X2&)> f,
const X1& x1,
const X2& x2,
433 double delta = 1e-5) {
434 typedef typename internal::FixedSizeMatrix<X1>::type Vector;
436 return numericalDerivative11<Vector, X2>(
437 boost::function<Vector(const X2&)>(
438 boost::bind<Vector>(boost::ref(g_x1), _1)), x2, delta);
441 template<
class X1,
class X2>
442 inline typename internal::FixedSizeMatrix<X1,X2>::type numericalHessian212(
double (*f)(
const X1&,
const X2&),
443 const X1& x1,
const X2& x2,
double delta = 1e-5) {
444 return numericalHessian212(boost::function<
double(
const X1&,
const X2&)>(f),
448 template<
class X1,
class X2>
449 inline typename internal::FixedSizeMatrix<X1,X1>::type numericalHessian211(
450 boost::function<
double(
const X1&,
const X2&)> f,
const X1& x1,
const X2& x2,
451 double delta = 1e-5) {
453 typedef typename internal::FixedSizeMatrix<X1>::type Vector;
455 Vector (*numGrad)(boost::function<double(const X1&)>,
const X1&,
456 double) = &numericalGradient<X1>;
457 boost::function<double(const X1&)> f2(boost::bind(f, _1, x2));
459 return numericalDerivative11<Vector, X1>(
460 boost::function<Vector(const X1&)>(boost::bind(numGrad, f2, _1, delta)),
464 template<
class X1,
class X2>
465 inline typename internal::FixedSizeMatrix<X1,X1>::type numericalHessian211(
double (*f)(
const X1&,
const X2&),
466 const X1& x1,
const X2& x2,
double delta = 1e-5) {
467 return numericalHessian211(boost::function<
double(
const X1&,
const X2&)>(f),
471 template<
class X1,
class X2>
472 inline typename internal::FixedSizeMatrix<X2,X2>::type numericalHessian222(
473 boost::function<
double(
const X1&,
const X2&)> f,
const X1& x1,
const X2& x2,
474 double delta = 1e-5) {
475 typedef typename internal::FixedSizeMatrix<X2>::type Vector;
476 Vector (*numGrad)(boost::function<double(const X2&)>,
const X2&,
477 double) = &numericalGradient<X2>;
478 boost::function<double(const X2&)> f2(boost::bind(f, x1, _1));
480 return numericalDerivative11<Vector, X2>(
481 boost::function<Vector(const X2&)>(boost::bind(numGrad, f2, _1, delta)),
485 template<
class X1,
class X2>
486 inline typename internal::FixedSizeMatrix<X2,X2>::type numericalHessian222(
double (*f)(
const X1&,
const X2&),
487 const X1& x1,
const X2& x2,
double delta = 1e-5) {
488 return numericalHessian222(boost::function<
double(
const X1&,
const X2&)>(f),
496 template<
class X1,
class X2,
class X3>
498 boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
const X1& x1,
499 const X2& x2,
const X3& x3,
double delta = 1e-5) {
500 typedef typename internal::FixedSizeMatrix<X1>::type Vector;
501 Vector (*numGrad)(boost::function<double(const X1&)>,
const X1&,
502 double) = &numericalGradient<X1>;
503 boost::function<double(const X1&)> f2(boost::bind(f, _1, x2, x3));
505 return numericalDerivative11<Vector, X1>(
506 boost::function<Vector(const X1&)>(boost::bind(numGrad, f2, _1, delta)),
510 template<
class X1,
class X2,
class X3>
511 inline typename internal::FixedSizeMatrix<X1,X1>::type
numericalHessian311(
double (*f)(
const X1&,
const X2&,
const X3&),
512 const X1& x1,
const X2& x2,
const X3& x3,
double delta = 1e-5) {
514 boost::function<
double(
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
519 template<
class X1,
class X2,
class X3>
520 inline typename internal::FixedSizeMatrix<X2,X2>::type numericalHessian322(
521 boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
const X1& x1,
522 const X2& x2,
const X3& x3,
double delta = 1e-5) {
523 typedef typename internal::FixedSizeMatrix<X2>::type Vector;
524 Vector (*numGrad)(boost::function<double(const X2&)>,
const X2&,
525 double) = &numericalGradient<X2>;
526 boost::function<double(const X2&)> f2(boost::bind(f, x1, _1, x3));
528 return numericalDerivative11<Vector, X2>(
529 boost::function<Vector(const X2&)>(boost::bind(numGrad, f2, _1, delta)),
533 template<
class X1,
class X2,
class X3>
534 inline typename internal::FixedSizeMatrix<X2,X2>::type numericalHessian322(
double (*f)(
const X1&,
const X2&,
const X3&),
535 const X1& x1,
const X2& x2,
const X3& x3,
double delta = 1e-5) {
536 return numericalHessian322(
537 boost::function<
double(
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
542 template<
class X1,
class X2,
class X3>
543 inline typename internal::FixedSizeMatrix<X3,X3>::type numericalHessian333(
544 boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
const X1& x1,
545 const X2& x2,
const X3& x3,
double delta = 1e-5) {
546 typedef typename internal::FixedSizeMatrix<X3>::type Vector;
547 Vector (*numGrad)(boost::function<double(const X3&)>,
const X3&,
548 double) = &numericalGradient<X3>;
549 boost::function<double(const X3&)> f2(boost::bind(f, x1, x2, _1));
551 return numericalDerivative11<Vector, X3>(
552 boost::function<Vector(const X3&)>(boost::bind(numGrad, f2, _1, delta)),
556 template<
class X1,
class X2,
class X3>
557 inline typename internal::FixedSizeMatrix<X3,X3>::type numericalHessian333(
double (*f)(
const X1&,
const X2&,
const X3&),
558 const X1& x1,
const X2& x2,
const X3& x3,
double delta = 1e-5) {
559 return numericalHessian333(
560 boost::function<
double(
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
565 template<
class X1,
class X2,
class X3>
566 inline typename internal::FixedSizeMatrix<X1,X2>::type numericalHessian312(
567 boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
const X1& x1,
568 const X2& x2,
const X3& x3,
double delta = 1e-5) {
569 return numericalHessian212<X1, X2>(
570 boost::function<double(const X1&, const X2&)>(boost::bind(f, _1, _2, x3)),
574 template<
class X1,
class X2,
class X3>
575 inline typename internal::FixedSizeMatrix<X1,X3>::type numericalHessian313(
576 boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
const X1& x1,
577 const X2& x2,
const X3& x3,
double delta = 1e-5) {
578 return numericalHessian212<X1, X3>(
579 boost::function<double(const X1&, const X3&)>(boost::bind(f, _1, x2, _2)),
583 template<
class X1,
class X2,
class X3>
584 inline typename internal::FixedSizeMatrix<X2,X3>::type numericalHessian323(
585 boost::function<
double(
const X1&,
const X2&,
const X3&)> f,
const X1& x1,
586 const X2& x2,
const X3& x3,
double delta = 1e-5) {
587 return numericalHessian212<X2, X3>(
588 boost::function<double(const X2&, const X3&)>(boost::bind(f, x1, _1, _2)),
593 template<
class X1,
class X2,
class X3>
594 inline typename internal::FixedSizeMatrix<X1,X2>::type numericalHessian312(
double (*f)(
const X1&,
const X2&,
const X3&),
595 const X1& x1,
const X2& x2,
const X3& x3,
double delta = 1e-5) {
596 return numericalHessian312(
597 boost::function<
double(
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
601 template<
class X1,
class X2,
class X3>
602 inline typename internal::FixedSizeMatrix<X1,X3>::type numericalHessian313(
double (*f)(
const X1&,
const X2&,
const X3&),
603 const X1& x1,
const X2& x2,
const X3& x3,
double delta = 1e-5) {
604 return numericalHessian313(
605 boost::function<
double(
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
609 template<
class X1,
class X2,
class X3>
610 inline typename internal::FixedSizeMatrix<X2,X3>::type numericalHessian323(
double (*f)(
const X1&,
const X2&,
const X3&),
611 const X1& x1,
const X2& x2,
const X3& x3,
double delta = 1e-5) {
612 return numericalHessian323(
613 boost::function<
double(
const X1&,
const X2&,
const X3&)>(f), x1, x2, x3,
internal::FixedSizeMatrix< X >::type 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:75
internal::FixedSizeMatrix< Y, X1 >::type numericalDerivative21(const 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:174
Base class and basic functions for Lie types.
Helper class that computes the derivative of f w.r.t.
Definition: numericalDerivative.h:414
A non-templated config holding any types of Manifold-group elements.
internal::FixedSizeMatrix< X, X >::type numericalHessian(boost::function< double(const X &)> f, const X &x, double delta=1e-5)
Compute numerical Hessian matrix.
Definition: numericalDerivative.h:392
internal::FixedSizeMatrix< X1, X1 >::type 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:497
tag to assert a type is a manifold
Definition: Manifold.h:33
internal::FixedSizeMatrix< Y, X2 >::type 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:199
internal::FixedSizeMatrix< Y, X3 >::type 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:282
internal::FixedSizeMatrix< Y, X3 >::type numericalDerivative43(boost::function< Y(const X1 &, const X2 &, const X3 &, const X4 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4, double delta=1e-5)
Compute numerical derivative in argument 3 of 4-argument function.
Definition: numericalDerivative.h:352
Definition: numericalDerivative.h:64
internal::FixedSizeMatrix< Y, X >::type numericalDerivative11(boost::function< Y(const X &)> h, const X &x, double delta=1e-5)
New-style numerical derivatives using manifold_traits.
Definition: numericalDerivative.h:116
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition: concepts.h:30
internal::FixedSizeMatrix< Y, X2 >::type numericalDerivative42(boost::function< Y(const X1 &, const X2 &, const X3 &, const X4 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4, double delta=1e-5)
Compute numerical derivative in argument 2 of 4-argument function.
Definition: numericalDerivative.h:331
internal::FixedSizeMatrix< Y, X4 >::type numericalDerivative44(boost::function< Y(const X1 &, const X2 &, const X3 &, const X4 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4, double delta=1e-5)
Compute numerical derivative in argument 4 of 4-argument function.
Definition: numericalDerivative.h:373
internal::FixedSizeMatrix< Y, X1 >::type 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:226
internal::FixedSizeMatrix< Y, X2 >::type 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:254
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
internal::FixedSizeMatrix< Y, X1 >::type numericalDerivative41(boost::function< Y(const X1 &, const X2 &, const X3 &, const X4 &)> h, const X1 &x1, const X2 &x2, const X3 &x3, const X4 &x4, double delta=1e-5)
Compute numerical derivative in argument 1 of 4-argument function.
Definition: numericalDerivative.h:310