More experiments
							parent
							
								
									8e264f4289
								
							
						
					
					
						commit
						732ff54b83
					
				|  | @ -24,6 +24,13 @@ | |||
| #include <boost/foreach.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 { | ||||
| 
 | ||||
| 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
 | ||||
| template<class T, class LIST> | ||||
| 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; | ||||
|   JacobianTA dTdA1; | ||||
|   typedef typename boost::mpl::front<LIST>::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<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
 | ||||
|   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
 | ||||
|   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<T>::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); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -318,6 +318,80 @@ TEST(ExpressionFactor, composeTernary) { | |||
|   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() { | ||||
|   TestResult tr; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue