More experiments
parent
8e264f4289
commit
732ff54b83
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue