More experiments

release/4.3a0
dellaert 2014-10-10 11:41:01 +02:00
parent 8e264f4289
commit 732ff54b83
2 changed files with 102 additions and 12 deletions

View File

@ -24,6 +24,13 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
// template meta-programming headers
#include <boost/mpl/vector.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/fold.hpp>
namespace gtsam { namespace gtsam {
template<typename T> template<typename T>
@ -380,31 +387,40 @@ public:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include <boost/mpl/list.hpp> // 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 /// Recursive Trace Class
template<class T, class LIST> template<class T, class LIST>
struct MakeTrace: public JacobianTrace<T> { struct MakeTrace: public JacobianTrace<T> {
typedef boost::mpl::front<LIST> A1;
static const size_t dimA = A1::dimension;
typedef Eigen::Matrix<double, T::dimension, A1::dimension> JacobianTA;
typedef Eigen::Matrix<double, 2, T::dimension> Jacobian2T;
typename JacobianTrace<A1>::Pointer trace1; typedef typename boost::mpl::front<LIST>::type A;
JacobianTA dTdA1;
// 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<double, m, n> JacobianTA;
typedef Eigen::Matrix<double, 2, m> Jacobian2T;
// declare trace that produces value A, and corresponding Jacobian
typename JacobianTrace<A>::Pointer trace;
JacobianTA dTdA;
/// Start the reverse AD process /// Start the reverse AD process
virtual void startReverseAD(JacobianMap& jacobians) const { virtual void startReverseAD(JacobianMap& jacobians) const {
Select<T::dimension, A1>::reverseAD(trace1, dTdA1, jacobians); Select<T::dimension, A>::reverseAD(trace, dTdA, jacobians);
} }
/// Given df/dT, multiply in dT/dA and continue reverse AD process /// Given df/dT, multiply in dT/dA and continue reverse AD process
virtual void reverseAD(const Matrix& dFdT, JacobianMap& jacobians) const { 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 /// Version specialized to 2-dimensional output
virtual void reverseAD2(const Jacobian2T& dFdT, virtual void reverseAD2(const Jacobian2T& dFdT,
JacobianMap& jacobians) const { JacobianMap& jacobians) const {
trace1.reverseAD2(dFdT * dTdA1, jacobians); trace.reverseAD2(dFdT * dTdA, jacobians);
} }
}; };
@ -460,8 +476,8 @@ public:
typename JacobianTrace<T>::Pointer& p) const { typename JacobianTrace<T>::Pointer& p) const {
Trace* trace = new Trace(); Trace* trace = new Trace();
p.setFunction(trace); p.setFunction(trace);
A1 a = this->expressionA1_->traceExecution(values, trace->trace1); A1 a = this->expressionA1_->traceExecution(values, trace->trace);
return function_(a, trace->dTdA1); return function_(a, trace->dTdA);
} }
}; };

View File

@ -318,6 +318,80 @@ TEST(ExpressionFactor, composeTernary) {
EXPECT( assert_equal(expected, *jf,1e-9)); EXPECT( assert_equal(expected, *jf,1e-9));
} }
/* ************************************************************************* */
namespace mpl = boost::mpl;
template<class TYPES>
struct ProtoTrace: public ProtoTrace<typename mpl::pop_front<TYPES>::type> {
typedef typename mpl::front<TYPES>::type A;
};
/// Recursive Trace Class, Base case
template<>
struct ProtoTrace<mpl::vector0<> > {
};
template<>
struct ProtoTrace<int> {
};
/// Recursive Trace Class, Primary Template
template<class A, class More>
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<double, m, n> JacobianTA;
typedef Eigen::Matrix<double, 2, m> Jacobian2T;
// declare trace that produces value A, and corresponding Jacobian
typename JacobianTrace<A>::Pointer trace;
JacobianTA dTdA;
};
typedef mpl::vector<Pose3, Point3, Cal3_S2> MyTypes;
template<class T> struct Incomplete;
#include<boost/mpl/empty_base.hpp>
#include<boost/mpl/placeholders.hpp>
#include<boost/mpl/reverse_fold.hpp>
namespace MPL = mpl::placeholders;
typedef mpl::reverse_fold<MyTypes, mpl::empty_base, store<MPL::_2, MPL::_1> >::type Generated;
Generated generated;
//Incomplete<Generated> incomplete;
#include <boost/mpl/assert.hpp>
typedef mpl::vector1<Point3> OneType;
typedef mpl::pop_front<OneType>::type Empty;
typedef mpl::pop_front<Empty>::type Bad;
//typedef ProtoTrace<OneType> UnaryTrace;
//BOOST_MPL_ASSERT((boost::is_same< UnaryTrace::A, Point3 >));
#include <boost/static_assert.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/assert.hpp>
//#include <boost/mpl/print.hpp>
BOOST_STATIC_ASSERT((mpl::plus<mpl::int_<2>,mpl::int_<3> >::type::value==5));
typedef mpl::vector0<> List0;
typedef ProtoTrace<int> Proto0;
//typedef ProtoTrace<mpl::vec/tor0<> > Proto0;
//typedef mpl::print<Proto0>::type Dbg;
//incomplete<ProtoTrace<List0> > proto0;
typedef struct {
} Expected0;
BOOST_MPL_ASSERT((boost::is_same< Expected0, Expected0 >));
//BOOST_MPL_ASSERT((boost::is_same< ProtoTrace<int>, ProtoTrace<List0> >));
/* ************************************************************************* */ /* ************************************************************************* */
int main() { int main() {
TestResult tr; TestResult tr;