From 732ff54b83c72549fc92e4f43e006af9352a2f78 Mon Sep 17 00:00:00 2001 From: dellaert Date: Fri, 10 Oct 2014 11:41:01 +0200 Subject: [PATCH] More experiments --- gtsam_unstable/nonlinear/Expression-inl.h | 40 +++++++--- .../nonlinear/tests/testExpressionFactor.cpp | 74 +++++++++++++++++++ 2 files changed, 102 insertions(+), 12 deletions(-) diff --git a/gtsam_unstable/nonlinear/Expression-inl.h b/gtsam_unstable/nonlinear/Expression-inl.h index b7038fc4c..53f531149 100644 --- a/gtsam_unstable/nonlinear/Expression-inl.h +++ b/gtsam_unstable/nonlinear/Expression-inl.h @@ -24,6 +24,13 @@ #include #include +// template meta-programming headers +#include +#include +#include +#include +#include + namespace gtsam { template @@ -380,31 +387,40 @@ public: //----------------------------------------------------------------------------- -#include +// Abrahams, David; Gurtovoy, Aleksey (2004-12-10). +// C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost +// and Beyond (Kindle Location 1244). Pearson Education. /// Recursive Trace Class template struct MakeTrace: public JacobianTrace { - typedef boost::mpl::front A1; - static const size_t dimA = A1::dimension; - typedef Eigen::Matrix JacobianTA; - typedef Eigen::Matrix Jacobian2T; - typename JacobianTrace::Pointer trace1; - JacobianTA dTdA1; + typedef typename boost::mpl::front::type A; + + // define dimensions + static const size_t m = T::dimension; + static const size_t n = A::dimension; + + // define fixed size Jacobian matrix types + typedef Eigen::Matrix JacobianTA; + typedef Eigen::Matrix Jacobian2T; + + // declare trace that produces value A, and corresponding Jacobian + typename JacobianTrace::Pointer trace; + JacobianTA dTdA; /// Start the reverse AD process virtual void startReverseAD(JacobianMap& jacobians) const { - Select::reverseAD(trace1, dTdA1, jacobians); + Select::reverseAD(trace, dTdA, jacobians); } /// Given df/dT, multiply in dT/dA and continue reverse AD process virtual void reverseAD(const Matrix& dFdT, JacobianMap& jacobians) const { - trace1.reverseAD(dFdT * dTdA1, jacobians); + trace.reverseAD(dFdT * dTdA, jacobians); } /// Version specialized to 2-dimensional output virtual void reverseAD2(const Jacobian2T& dFdT, JacobianMap& jacobians) const { - trace1.reverseAD2(dFdT * dTdA1, jacobians); + trace.reverseAD2(dFdT * dTdA, jacobians); } }; @@ -460,8 +476,8 @@ public: typename JacobianTrace::Pointer& p) const { Trace* trace = new Trace(); p.setFunction(trace); - A1 a = this->expressionA1_->traceExecution(values, trace->trace1); - return function_(a, trace->dTdA1); + A1 a = this->expressionA1_->traceExecution(values, trace->trace); + return function_(a, trace->dTdA); } }; diff --git a/gtsam_unstable/nonlinear/tests/testExpressionFactor.cpp b/gtsam_unstable/nonlinear/tests/testExpressionFactor.cpp index 87da6fde9..163139543 100644 --- a/gtsam_unstable/nonlinear/tests/testExpressionFactor.cpp +++ b/gtsam_unstable/nonlinear/tests/testExpressionFactor.cpp @@ -318,6 +318,80 @@ TEST(ExpressionFactor, composeTernary) { EXPECT( assert_equal(expected, *jf,1e-9)); } +/* ************************************************************************* */ + +namespace mpl = boost::mpl; + +template +struct ProtoTrace: public ProtoTrace::type> { + + typedef typename mpl::front::type A; + +}; + +/// Recursive Trace Class, Base case +template<> +struct ProtoTrace > { +}; + +template<> +struct ProtoTrace { +}; + +/// Recursive Trace Class, Primary Template +template +struct store: More { + // define dimensions + static const size_t m = 3; + static const size_t n = A::dimension; + + // define fixed size Jacobian matrix types + typedef Eigen::Matrix JacobianTA; + typedef Eigen::Matrix Jacobian2T; + + // declare trace that produces value A, and corresponding Jacobian + typename JacobianTrace::Pointer trace; + JacobianTA dTdA; + +}; +typedef mpl::vector MyTypes; + +template struct Incomplete; + +#include +#include +#include +namespace MPL = mpl::placeholders; +typedef mpl::reverse_fold >::type Generated; +Generated generated; +//Incomplete incomplete; +#include + +typedef mpl::vector1 OneType; +typedef mpl::pop_front::type Empty; +typedef mpl::pop_front::type Bad; +//typedef ProtoTrace UnaryTrace; +//BOOST_MPL_ASSERT((boost::is_same< UnaryTrace::A, Point3 >)); + +#include +#include +#include +#include +//#include + +BOOST_STATIC_ASSERT((mpl::plus,mpl::int_<3> >::type::value==5)); + +typedef mpl::vector0<> List0; +typedef ProtoTrace Proto0; +//typedef ProtoTrace > Proto0; +//typedef mpl::print::type Dbg; +//incomplete > proto0; + +typedef struct { +} Expected0; +BOOST_MPL_ASSERT((boost::is_same< Expected0, Expected0 >)); +//BOOST_MPL_ASSERT((boost::is_same< ProtoTrace, ProtoTrace >)); + /* ************************************************************************* */ int main() { TestResult tr;