From 30b21503b336b5d773e628a00facbb4ba59615c7 Mon Sep 17 00:00:00 2001 From: Mike Bosse Date: Mon, 15 Dec 2014 16:11:28 +0100 Subject: [PATCH] fixed size matrices for numerical derivatives --- gtsam/base/Lie.h | 8 +-- gtsam/base/numericalDerivative.h | 91 +++++++++++++++++++------------- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/gtsam/base/Lie.h b/gtsam/base/Lie.h index 7a9d32249..7953bf511 100644 --- a/gtsam/base/Lie.h +++ b/gtsam/base/Lie.h @@ -147,11 +147,7 @@ T expm(const Vector& x, int K=7) { * the gtsam namespace to be more easily enforced as testable */ #define GTSAM_CONCEPT_LIE_INST(T) \ - template class gtsam::ManifoldConcept; \ - template class gtsam::GroupConcept; \ - template class gtsam::LieConcept; + template class gtsam::IsLieGroup; #define GTSAM_CONCEPT_LIE_TYPE(T) \ - typedef gtsam::ManifoldConcept _gtsam_ManifoldConcept_##T; \ - typedef gtsam::GroupConcept _gtsam_GroupConcept_##T; \ - typedef gtsam::LieConcept _gtsam_LieConcept_##T; + typedef gtsam::IsLieGroup _gtsam_LieConcept_##T; diff --git a/gtsam/base/numericalDerivative.h b/gtsam/base/numericalDerivative.h index 0a783037a..f159d43ff 100644 --- a/gtsam/base/numericalDerivative.h +++ b/gtsam/base/numericalDerivative.h @@ -59,13 +59,22 @@ namespace gtsam { * http://www.boost.org/doc/libs/release/libs/bind/bind.html */ + +// a quick helper struct to get the appropriate fixed sized matrix from two value types +namespace internal { +template +struct FixedSizeMatrix { + typedef Eigen::Matrix::dimension, traits_x::dimension> type; +}; +} + /** * Numerically compute gradient of scalar function * Class X is the input argument * The class X needs to have dim, expmap, logmap */ template -Vector numericalGradient(boost::function h, const X& x, +typename internal::FixedSizeMatrix::type numericalGradient(boost::function h, const X& x, double delta = 1e-5) { double factor = 1.0 / (2.0 * delta); @@ -103,12 +112,15 @@ Vector numericalGradient(boost::function h, const X& x, * Class X is the input argument * @return m*n Jacobian computed via central differencing */ + template // TODO Should compute fixed-size matrix -Matrix numericalDerivative11(boost::function h, const X& x, +typename internal::FixedSizeMatrix::type numericalDerivative11(boost::function h, const X& x, double delta = 1e-5) { using namespace traits; + typedef typename internal::FixedSizeMatrix::type Matrix; + BOOST_STATIC_ASSERT_MSG( (boost::is_base_of::structure_category>::value), "Template argument Y must be a manifold type."); typedef traits_x TraitsY; @@ -148,7 +160,7 @@ Matrix numericalDerivative11(boost::function h, const X& x, /** use a raw C++ function pointer */ template -Matrix numericalDerivative11(Y (*h)(const X&), const X& x, +typename internal::FixedSizeMatrix::type numericalDerivative11(Y (*h)(const X&), const X& x, double delta = 1e-5) { return numericalDerivative11(boost::bind(h, _1), x, delta); } @@ -162,7 +174,7 @@ Matrix numericalDerivative11(Y (*h)(const X&), const X& x, * @return m*n Jacobian computed via central differencing */ template -Matrix numericalDerivative21(const boost::function& h, +typename internal::FixedSizeMatrix::type numericalDerivative21(const boost::function& h, const X1& x1, const X2& x2, double delta = 1e-5) { BOOST_STATIC_ASSERT_MSG( (boost::is_base_of::structure_category>::value), "Template argument Y must be a manifold type."); @@ -173,7 +185,7 @@ Matrix numericalDerivative21(const boost::function& h, /** use a raw C++ function pointer */ template -inline Matrix numericalDerivative21(Y (*h)(const X1&, const X2&), const X1& x1, +typename internal::FixedSizeMatrix::type numericalDerivative21(Y (*h)(const X1&, const X2&), const X1& x1, const X2& x2, double delta = 1e-5) { return numericalDerivative21(boost::bind(h, _1, _2), x1, x2, delta); } @@ -187,7 +199,7 @@ inline Matrix numericalDerivative21(Y (*h)(const X1&, const X2&), const X1& x1, * @return m*n Jacobian computed via central differencing */ template -Matrix numericalDerivative22(boost::function h, +typename internal::FixedSizeMatrix::type numericalDerivative22(boost::function h, const X1& x1, const X2& x2, double delta = 1e-5) { BOOST_STATIC_ASSERT_MSG( (boost::is_base_of::structure_category>::value), "Template argument X1 must be a manifold type."); @@ -198,7 +210,7 @@ Matrix numericalDerivative22(boost::function h, /** use a raw C++ function pointer */ template -inline Matrix numericalDerivative22(Y (*h)(const X1&, const X2&), const X1& x1, +typename internal::FixedSizeMatrix::type numericalDerivative22(Y (*h)(const X1&, const X2&), const X1& x1, const X2& x2, double delta = 1e-5) { return numericalDerivative22(boost::bind(h, _1, _2), x1, x2, delta); } @@ -214,7 +226,7 @@ inline Matrix numericalDerivative22(Y (*h)(const X1&, const X2&), const X1& x1, * All classes Y,X1,X2,X3 need dim, expmap, logmap */ template -Matrix numericalDerivative31( +typename internal::FixedSizeMatrix::type numericalDerivative31( boost::function h, const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { BOOST_STATIC_ASSERT_MSG( (boost::is_base_of::structure_category>::value), @@ -225,7 +237,7 @@ Matrix numericalDerivative31( } template -inline Matrix numericalDerivative31(Y (*h)(const X1&, const X2&, const X3&), +typename internal::FixedSizeMatrix::type numericalDerivative31(Y (*h)(const X1&, const X2&, const X3&), const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalDerivative31(boost::bind(h, _1, _2, _3), x1, x2, x3, delta); @@ -242,7 +254,7 @@ inline Matrix numericalDerivative31(Y (*h)(const X1&, const X2&, const X3&), * All classes Y,X1,X2,X3 need dim, expmap, logmap */ template -Matrix numericalDerivative32( +typename internal::FixedSizeMatrix::type numericalDerivative32( boost::function h, const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { BOOST_STATIC_ASSERT_MSG( (boost::is_base_of::structure_category>::value), @@ -253,7 +265,7 @@ Matrix numericalDerivative32( } template -inline Matrix numericalDerivative32(Y (*h)(const X1&, const X2&, const X3&), +inline typename internal::FixedSizeMatrix::type numericalDerivative32(Y (*h)(const X1&, const X2&, const X3&), const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalDerivative32(boost::bind(h, _1, _2, _3), x1, x2, x3, delta); @@ -270,7 +282,7 @@ inline Matrix numericalDerivative32(Y (*h)(const X1&, const X2&, const X3&), * All classes Y,X1,X2,X3 need dim, expmap, logmap */ template -Matrix numericalDerivative33( +typename internal::FixedSizeMatrix::type numericalDerivative33( boost::function h, const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { BOOST_STATIC_ASSERT_MSG( (boost::is_base_of::structure_category>::value), @@ -281,7 +293,7 @@ Matrix numericalDerivative33( } template -inline Matrix numericalDerivative33(Y (*h)(const X1&, const X2&, const X3&), +inline typename internal::FixedSizeMatrix::type numericalDerivative33(Y (*h)(const X1&, const X2&, const X3&), const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalDerivative33(boost::bind(h, _1, _2, _3), x1, x2, x3, delta); @@ -296,7 +308,7 @@ inline Matrix numericalDerivative33(Y (*h)(const X1&, const X2&, const X3&), * @return n*n Hessian matrix computed via central differencing */ template -inline Matrix numericalHessian(boost::function f, const X& x, +inline typename internal::FixedSizeMatrix::type numericalHessian(boost::function f, const X& x, double delta = 1e-5) { BOOST_STATIC_ASSERT_MSG( (boost::is_base_of::structure_category>::value), "Template argument X must be a manifold type."); @@ -309,7 +321,7 @@ inline Matrix numericalHessian(boost::function f, const X& x, } template -inline Matrix numericalHessian(double (*f)(const X&), const X& x, double delta = +inline typename internal::FixedSizeMatrix::type numericalHessian(double (*f)(const X&), const X& x, double delta = 1e-5) { return numericalHessian(boost::function(f), x, delta); } @@ -323,6 +335,8 @@ class G_x1 { X1 x1_; double delta_; public: + typedef typename internal::FixedSizeMatrix::type Vector; + G_x1(const boost::function& f, const X1& x1, double delta) : f_(f), x1_(x1), delta_(delta) { @@ -333,9 +347,10 @@ public: }; template -inline Matrix numericalHessian212( +inline typename internal::FixedSizeMatrix::type numericalHessian212( boost::function f, const X1& x1, const X2& x2, double delta = 1e-5) { + typedef typename internal::FixedSizeMatrix::type Vector; G_x1 g_x1(f, x1, delta); return numericalDerivative11( boost::function( @@ -343,17 +358,19 @@ inline Matrix numericalHessian212( } template -inline Matrix numericalHessian212(double (*f)(const X1&, const X2&), +inline typename internal::FixedSizeMatrix::type numericalHessian212(double (*f)(const X1&, const X2&), const X1& x1, const X2& x2, double delta = 1e-5) { return numericalHessian212(boost::function(f), x1, x2, delta); } template -inline Matrix numericalHessian211( +inline typename internal::FixedSizeMatrix::type numericalHessian211( boost::function f, const X1& x1, const X2& x2, double delta = 1e-5) { + typedef typename internal::FixedSizeMatrix::type Vector; + Vector (*numGrad)(boost::function, const X1&, double) = &numericalGradient; boost::function f2(boost::bind(f, _1, x2)); @@ -364,17 +381,17 @@ inline Matrix numericalHessian211( } template -inline Matrix numericalHessian211(double (*f)(const X1&, const X2&), +inline typename internal::FixedSizeMatrix::type numericalHessian211(double (*f)(const X1&, const X2&), const X1& x1, const X2& x2, double delta = 1e-5) { return numericalHessian211(boost::function(f), x1, x2, delta); } template -inline Matrix numericalHessian222( +inline typename internal::FixedSizeMatrix::type numericalHessian222( boost::function f, const X1& x1, const X2& x2, double delta = 1e-5) { - + typedef typename internal::FixedSizeMatrix::type Vector; Vector (*numGrad)(boost::function, const X2&, double) = &numericalGradient; boost::function f2(boost::bind(f, x1, _1)); @@ -385,7 +402,7 @@ inline Matrix numericalHessian222( } template -inline Matrix numericalHessian222(double (*f)(const X1&, const X2&), +inline typename internal::FixedSizeMatrix::type numericalHessian222(double (*f)(const X1&, const X2&), const X1& x1, const X2& x2, double delta = 1e-5) { return numericalHessian222(boost::function(f), x1, x2, delta); @@ -396,10 +413,10 @@ inline Matrix numericalHessian222(double (*f)(const X1&, const X2&), */ /* **************************************************************** */ template -inline Matrix numericalHessian311( +inline typename internal::FixedSizeMatrix::type numericalHessian311( boost::function f, const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { - + typedef typename internal::FixedSizeMatrix::type Vector; Vector (*numGrad)(boost::function, const X1&, double) = &numericalGradient; boost::function f2(boost::bind(f, _1, x2, x3)); @@ -410,7 +427,7 @@ inline Matrix numericalHessian311( } template -inline Matrix numericalHessian311(double (*f)(const X1&, const X2&, const X3&), +inline typename internal::FixedSizeMatrix::type numericalHessian311(double (*f)(const X1&, const X2&, const X3&), const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalHessian311( boost::function(f), x1, x2, x3, @@ -419,10 +436,10 @@ inline Matrix numericalHessian311(double (*f)(const X1&, const X2&, const X3&), /* **************************************************************** */ template -inline Matrix numericalHessian322( +inline typename internal::FixedSizeMatrix::type numericalHessian322( boost::function f, const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { - + typedef typename internal::FixedSizeMatrix::type Vector; Vector (*numGrad)(boost::function, const X2&, double) = &numericalGradient; boost::function f2(boost::bind(f, x1, _1, x3)); @@ -433,7 +450,7 @@ inline Matrix numericalHessian322( } template -inline Matrix numericalHessian322(double (*f)(const X1&, const X2&, const X3&), +inline typename internal::FixedSizeMatrix::type numericalHessian322(double (*f)(const X1&, const X2&, const X3&), const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalHessian322( boost::function(f), x1, x2, x3, @@ -442,10 +459,10 @@ inline Matrix numericalHessian322(double (*f)(const X1&, const X2&, const X3&), /* **************************************************************** */ template -inline Matrix numericalHessian333( +inline typename internal::FixedSizeMatrix::type numericalHessian333( boost::function f, const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { - + typedef typename internal::FixedSizeMatrix::type Vector; Vector (*numGrad)(boost::function, const X3&, double) = &numericalGradient; boost::function f2(boost::bind(f, x1, x2, _1)); @@ -456,7 +473,7 @@ inline Matrix numericalHessian333( } template -inline Matrix numericalHessian333(double (*f)(const X1&, const X2&, const X3&), +inline typename internal::FixedSizeMatrix::type numericalHessian333(double (*f)(const X1&, const X2&, const X3&), const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalHessian333( boost::function(f), x1, x2, x3, @@ -465,7 +482,7 @@ inline Matrix numericalHessian333(double (*f)(const X1&, const X2&, const X3&), /* **************************************************************** */ template -inline Matrix numericalHessian312( +inline typename internal::FixedSizeMatrix::type numericalHessian312( boost::function f, const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalHessian212( @@ -474,7 +491,7 @@ inline Matrix numericalHessian312( } template -inline Matrix numericalHessian313( +inline typename internal::FixedSizeMatrix::type numericalHessian313( boost::function f, const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalHessian212( @@ -483,7 +500,7 @@ inline Matrix numericalHessian313( } template -inline Matrix numericalHessian323( +inline typename internal::FixedSizeMatrix::type numericalHessian323( boost::function f, const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalHessian212( @@ -493,7 +510,7 @@ inline Matrix numericalHessian323( /* **************************************************************** */ template -inline Matrix numericalHessian312(double (*f)(const X1&, const X2&, const X3&), +inline typename internal::FixedSizeMatrix::type numericalHessian312(double (*f)(const X1&, const X2&, const X3&), const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalHessian312( boost::function(f), x1, x2, x3, @@ -501,7 +518,7 @@ inline Matrix numericalHessian312(double (*f)(const X1&, const X2&, const X3&), } template -inline Matrix numericalHessian313(double (*f)(const X1&, const X2&, const X3&), +inline typename internal::FixedSizeMatrix::type numericalHessian313(double (*f)(const X1&, const X2&, const X3&), const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalHessian313( boost::function(f), x1, x2, x3, @@ -509,7 +526,7 @@ inline Matrix numericalHessian313(double (*f)(const X1&, const X2&, const X3&), } template -inline Matrix numericalHessian323(double (*f)(const X1&, const X2&, const X3&), +inline typename internal::FixedSizeMatrix::type numericalHessian323(double (*f)(const X1&, const X2&, const X3&), const X1& x1, const X2& x2, const X3& x3, double delta = 1e-5) { return numericalHessian323( boost::function(f), x1, x2, x3,