Charts !!!!
							parent
							
								
									9c97b1d8a0
								
							
						
					
					
						commit
						ed6a2b6eff
					
				|  | @ -355,27 +355,22 @@ template<typename T> | ||||||
| struct dimension: public std::integral_constant<int, T::dimension> { | struct dimension: public std::integral_constant<int, T::dimension> { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // TangentVector is Eigen::Matrix type in tangent space, can be Dynamic...
 | // Chart is a map from T -> vector, retract is its inverse
 | ||||||
| template<typename T> | template<typename T> | ||||||
| struct TangentVector { | struct DefaultChart { | ||||||
|   BOOST_STATIC_ASSERT(is_manifold<T>::value); |   BOOST_STATIC_ASSERT(is_manifold<T>::value); | ||||||
|   typedef Eigen::Matrix<double, dimension<T>::value, 1> type; |   typedef Eigen::Matrix<double, dimension<T>::value, 1> vector; | ||||||
| }; |   DefaultChart(const T& t) : | ||||||
| 
 |       t_(t) { | ||||||
| // default localCoordinates
 |  | ||||||
| template<typename T> |  | ||||||
| struct LocalCoordinates { |  | ||||||
|   typename TangentVector<T>::type operator()(const T& t1, const T& t2) { |  | ||||||
|     return t1.localCoordinates(t2); |  | ||||||
|   } |   } | ||||||
| }; |   vector apply(const T& other) { | ||||||
| 
 |     return t_.localCoordinates(other); | ||||||
| // default retract
 |  | ||||||
| template<typename T> |  | ||||||
| struct Retract { |  | ||||||
|   T operator()(const T& t, const typename TangentVector<T>::type& d) { |  | ||||||
|     return t.retract(d); |  | ||||||
|   } |   } | ||||||
|  |   T retract(const vector& d) { | ||||||
|  |     return t_.retract(d); | ||||||
|  |   } | ||||||
|  | private: | ||||||
|  |   T const & t_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Fixed size Eigen::Matrix type
 | // Fixed size Eigen::Matrix type
 | ||||||
|  | @ -384,28 +379,48 @@ template<int M, int N, int Options> | ||||||
| struct is_manifold<Eigen::Matrix<double, M, N, Options> > : public true_type { | struct is_manifold<Eigen::Matrix<double, M, N, Options> > : public true_type { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // TODO: Could be more sophisticated using Eigen traits and SFINAE?
 | ||||||
|  | 
 | ||||||
|  | template<int Options> | ||||||
|  | struct dimension<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Options> > : public integral_constant< | ||||||
|  |     size_t, Eigen::Dynamic> { | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template<int M, int Options> | ||||||
|  | struct dimension<Eigen::Matrix<double, M, Eigen::Dynamic, Options> > : public integral_constant< | ||||||
|  |     size_t, Eigen::Dynamic> { | ||||||
|  |   BOOST_STATIC_ASSERT(M!=Eigen::Dynamic); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template<int N, int Options> | ||||||
|  | struct dimension<Eigen::Matrix<double, Eigen::Dynamic, N, Options> > : public integral_constant< | ||||||
|  |     size_t, Eigen::Dynamic> { | ||||||
|  |   BOOST_STATIC_ASSERT(N!=Eigen::Dynamic); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| template<int M, int N, int Options> | template<int M, int N, int Options> | ||||||
| struct dimension<Eigen::Matrix<double, M, N, Options> > : public integral_constant< | struct dimension<Eigen::Matrix<double, M, N, Options> > : public integral_constant< | ||||||
|     size_t, M * N> { |     size_t, M * N> { | ||||||
|   BOOST_STATIC_ASSERT(M!=Eigen::Dynamic && N!=Eigen::Dynamic); |   BOOST_STATIC_ASSERT(M!=Eigen::Dynamic && N!=Eigen::Dynamic); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // Chart is a map from T -> vector, retract is its inverse
 | ||||||
| template<int M, int N, int Options> | template<int M, int N, int Options> | ||||||
| struct LocalCoordinates<Eigen::Matrix<double, M, N, Options> > { | struct DefaultChart<Eigen::Matrix<double, M, N, Options> > { | ||||||
|   typedef Eigen::Matrix<double, M, N, Options> T; |   typedef Eigen::Matrix<double, M, N, Options> T; | ||||||
|   typedef typename TangentVector<T>::type result_type; |   typedef Eigen::Matrix<double, dimension<T>::value, 1> vector; | ||||||
|   result_type operator()(const T& t1, const T& t2) { |   DefaultChart(const T& t) : | ||||||
|     T diff = t2 - t1; |       t_(t) { | ||||||
|     return result_type(Eigen::Map<result_type>(diff.data())); |  | ||||||
|   } |   } | ||||||
| }; |   vector apply(const T& other) { | ||||||
| 
 |     T diff = other - t_; | ||||||
| template<int M, int N, int Options> |     return Eigen::Map<vector>(diff.data()); | ||||||
| struct Retract<Eigen::Matrix<double, M, N, Options> > { |  | ||||||
|   typedef Eigen::Matrix<double, M, N, Options> T; |  | ||||||
|   T operator()(const T& t, const typename TangentVector<T>::type& d) { |  | ||||||
|     return t + Eigen::Map<const T>(d.data()); |  | ||||||
|   } |   } | ||||||
|  |   T retract(const vector& d) { | ||||||
|  |     return t_ + Eigen::Map<const T>(d.data()); | ||||||
|  |   } | ||||||
|  | private: | ||||||
|  |   T const & t_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Point2
 | // Point2
 | ||||||
|  | @ -431,16 +446,15 @@ TEST(Expression, dimension) { | ||||||
|   EXPECT_LONGS_EQUAL(8, dimension<Matrix24>::value); |   EXPECT_LONGS_EQUAL(8, dimension<Matrix24>::value); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // localCoordinates
 | // charts
 | ||||||
| TEST(Expression, localCoordinates) { | TEST(Expression, Charts) { | ||||||
|   EXPECT(LocalCoordinates<Point2>()(Point2(0,0),Point2(1,0))==Vector2(1,0)); |   DefaultChart<Point2> chart1(Point2(0, 0)); | ||||||
|   EXPECT(LocalCoordinates<Vector2>()(Vector2(0,0),Vector2(1,0))==Vector2(1,0)); |   EXPECT(chart1.apply(Point2(1,0))==Vector2(1,0)); | ||||||
| } |   EXPECT(chart1.retract(Vector2(1,0))==Point2(1,0)); | ||||||
| 
 | 
 | ||||||
| // retract
 |   DefaultChart<Vector2> chart2(Vector2(0, 0)); | ||||||
| TEST(Expression, retract) { |   EXPECT(chart2.apply(Vector2(1,0))==Vector2(1,0)); | ||||||
|   EXPECT(Retract<Point2>()(Point2(0,0),Vector2(1,0))==Point2(1,0)); |   EXPECT(chart2.retract(Vector2(1,0))==Vector2(1,0)); | ||||||
|   EXPECT(Retract<Vector2>()(Vector2(0,0),Vector2(1,0))==Vector2(1,0)); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ************************************************************************* */ | /* ************************************************************************* */ | ||||||
|  | @ -451,31 +465,35 @@ Matrix numericalDerivative(boost::function<Y(const X&)> h, const X& x, | ||||||
| 
 | 
 | ||||||
|   BOOST_STATIC_ASSERT(is_manifold<Y>::value); |   BOOST_STATIC_ASSERT(is_manifold<Y>::value); | ||||||
|   static const size_t M = dimension<Y>::value; |   static const size_t M = dimension<Y>::value; | ||||||
|   typedef typename TangentVector<Y>::type TangentY; |   typedef DefaultChart<Y> ChartY; | ||||||
|   LocalCoordinates<Y> localCoordinates; |   typedef typename ChartY::vector TangentY; | ||||||
| 
 | 
 | ||||||
|   BOOST_STATIC_ASSERT(is_manifold<X>::value); |   BOOST_STATIC_ASSERT(is_manifold<X>::value); | ||||||
|   static const size_t N = dimension<X>::value; |   static const size_t N = dimension<X>::value; | ||||||
|   typedef typename TangentVector<X>::type TangentX; |   typedef DefaultChart<X> ChartX; | ||||||
|   Retract<X> retract; |   typedef typename ChartX::vector TangentX; | ||||||
| 
 | 
 | ||||||
|   // get value at x
 |   // get chart at x
 | ||||||
|  |   ChartX chartX(x); | ||||||
|  | 
 | ||||||
|  |   // get value at x, and corresponding chart
 | ||||||
|   Y hx = h(x); |   Y hx = h(x); | ||||||
|  |   ChartY chartY(hx); | ||||||
| 
 | 
 | ||||||
|   // Prepare a tangent vector to perturb x with
 |   // Prepare a tangent vector to perturb x with
 | ||||||
|   TangentX d; |   TangentX dx; | ||||||
|   d.setZero(); |   dx.setZero(); | ||||||
| 
 | 
 | ||||||
|   // Fill in Jacobian H
 |   // Fill in Jacobian H
 | ||||||
|   Matrix H = zeros(M, N); |   Matrix H = zeros(M, N); | ||||||
|   double factor = 1.0 / (2.0 * delta); |   double factor = 1.0 / (2.0 * delta); | ||||||
|   for (size_t j = 0; j < N; j++) { |   for (size_t j = 0; j < N; j++) { | ||||||
|     d(j) = delta; |     dx(j) = delta; | ||||||
|     TangentY hxplus = localCoordinates(hx, h(retract(x, d))); |     TangentY dy1 = chartY.apply(h(chartX.retract(dx))); | ||||||
|     d(j) = -delta; |     dx(j) = -delta; | ||||||
|     TangentY hxmin = localCoordinates(hx, h(retract(x, d))); |     TangentY dy2 = chartY.apply(h(chartX.retract(dx))); | ||||||
|     H.block<M, 1>(0, j) << (hxplus - hxmin) * factor; |     H.block<M, 1>(0, j) << (dy1 - dy2) * factor; | ||||||
|     d(j) = 0; |     dx(j) = 0; | ||||||
|   } |   } | ||||||
|   return H; |   return H; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue