| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file FusionTupleConfig.h | 
					
						
							|  |  |  |  * @brief Experimental tuple config using boost.Fusion | 
					
						
							|  |  |  |  * @author Alex Cunningham | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/fusion/container/set.hpp>
 | 
					
						
							|  |  |  | #include <boost/fusion/include/make_set.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | #include <boost/fusion/include/as_vector.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | #include <boost/fusion/include/at_key.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | #include <boost/fusion/include/has_key.hpp>
 | 
					
						
							|  |  |  | #include <boost/fusion/include/zip.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-08-16 05:35:03 +08:00
										 |  |  | #include <boost/fusion/include/all.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | #include <boost/fusion/algorithm/iteration.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | #include <gtsam/base/Testable.h>
 | 
					
						
							|  |  |  | #include <gtsam/nonlinear/LieConfig.h>
 | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * This config uses a real tuple to store types | 
					
						
							|  |  |  |  * The template parameter should be a boost fusion structure, like | 
					
						
							|  |  |  |  * set<Config1, Config2> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | template<class Configs> | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | class FusionTupleConfig : public Testable<FusionTupleConfig<Configs> >{ | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	/** useful types */ | 
					
						
							|  |  |  | 	typedef Configs BaseTuple; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  | 	/** the underlying tuple storing everything */ | 
					
						
							|  |  |  | 	Configs base_tuple_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | private: | 
					
						
							|  |  |  |   /** helper structs to make use of fusion algorithms */ | 
					
						
							|  |  |  |   struct size_helper  { | 
					
						
							|  |  |  |     typedef size_t result_type; | 
					
						
							|  |  |  |       template<typename T> | 
					
						
							|  |  |  |       size_t operator()(const T& t, const size_t& s) const { | 
					
						
							|  |  |  |           return s + t.size(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct dim_helper { | 
					
						
							|  |  |  |       typedef size_t result_type; | 
					
						
							|  |  |  |       template<typename T> | 
					
						
							|  |  |  |       size_t operator()(const T& t, const size_t& s) const { | 
					
						
							|  |  |  |           return s + t.dim(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct zero_helper  { | 
					
						
							|  |  |  |       typedef VectorConfig result_type; | 
					
						
							|  |  |  |       template<typename T> | 
					
						
							|  |  |  |       result_type operator()(const T& t, const result_type& s) const { | 
					
						
							|  |  |  |         result_type new_s(s); | 
					
						
							|  |  |  |         new_s.insert(t.zero()); | 
					
						
							|  |  |  |           return new_s; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct update_helper { | 
					
						
							|  |  |  |     typedef Configs result_type; | 
					
						
							|  |  |  |       template<typename T> | 
					
						
							|  |  |  |       result_type operator()(const T& t, const result_type& s) const { | 
					
						
							|  |  |  |         result_type new_s(s); | 
					
						
							|  |  |  |         boost::fusion::at_key<T>(new_s).update(t); | 
					
						
							|  |  |  |           return new_s; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct expmap_helper { | 
					
						
							|  |  |  |       typedef FusionTupleConfig<Configs> result_type; | 
					
						
							|  |  |  |       VectorConfig delta; | 
					
						
							|  |  |  |       expmap_helper(const VectorConfig& d) : delta(d) {} | 
					
						
							|  |  |  |       template<typename T> | 
					
						
							|  |  |  |       result_type operator()(const T& t, const result_type& s) const { | 
					
						
							|  |  |  |         result_type new_s(s); | 
					
						
							|  |  |  |         boost::fusion::at_key<T>(new_s.base_tuple_) = T(gtsam::expmap(t, delta)); | 
					
						
							|  |  |  |           return new_s; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct logmap_helper { | 
					
						
							|  |  |  |     typedef VectorConfig result_type; | 
					
						
							|  |  |  |       template<typename T> | 
					
						
							|  |  |  |       result_type operator()(const T& t, const result_type& s) const { | 
					
						
							|  |  |  |         result_type new_s(s); | 
					
						
							|  |  |  |         new_s.insert(gtsam::logmap(boost::fusion::at_c<0>(t), boost::fusion::at_c<1>(t))); | 
					
						
							|  |  |  |           return new_s; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct empty_helper { | 
					
						
							|  |  |  |       template<typename T> | 
					
						
							|  |  |  |       bool operator()(T t) const { | 
					
						
							|  |  |  |           return t.empty(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct print_helper { | 
					
						
							|  |  |  |       template<typename T> | 
					
						
							|  |  |  |       void operator()(T t) const { | 
					
						
							|  |  |  |           t.print(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct equals_helper { | 
					
						
							|  |  |  |     double tol; | 
					
						
							|  |  |  |     equals_helper(double t) : tol(t) {} | 
					
						
							|  |  |  |       template<typename T> | 
					
						
							|  |  |  |       bool operator()(T t) const { | 
					
						
							|  |  |  |           return boost::fusion::at_c<0>(t).equals(boost::fusion::at_c<1>(t), tol); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** two separate function objects for arbitrary copy construction */ | 
					
						
							|  |  |  |   template<typename Ret, typename Config> | 
					
						
							|  |  |  |   struct assign_inner { | 
					
						
							|  |  |  |     typedef Ret result_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Config config; | 
					
						
							|  |  |  |     assign_inner(const Config& cfg) : config(cfg) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<typename T> | 
					
						
							|  |  |  |     result_type operator()(const T& t, const result_type& s) const { | 
					
						
							|  |  |  |       result_type new_s(s); | 
					
						
							|  |  |  |       T new_cfg(config); | 
					
						
							|  |  |  |       if (!new_cfg.empty()) boost::fusion::at_key<T>(new_s) = new_cfg; | 
					
						
							|  |  |  |       return new_s; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template<typename Ret> | 
					
						
							|  |  |  |   struct assign_outer { | 
					
						
							|  |  |  |     typedef Ret result_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<typename T> // T is the config from the "other" config
 | 
					
						
							|  |  |  |     Ret operator()(const T& t, const Ret& s) const { | 
					
						
							|  |  |  |       assign_inner<Ret, T> helper(t); | 
					
						
							|  |  |  |       return boost::fusion::fold(s, s, helper); // loop over the "self" config
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | public: | 
					
						
							|  |  |  | 	/** create an empty config */ | 
					
						
							|  |  |  | 	FusionTupleConfig() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** copy constructor */ | 
					
						
							|  |  |  | 	FusionTupleConfig(const FusionTupleConfig<Configs>& other) : base_tuple_(other.base_tuple_) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** direct initialization of the underlying structure */ | 
					
						
							|  |  |  | 	FusionTupleConfig(const Configs& cfg_set) : base_tuple_(cfg_set) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-14 03:51:04 +08:00
										 |  |  | 	/** initialization from arbitrary other configs */ | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 	template<class Configs2> | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | 	FusionTupleConfig(const FusionTupleConfig<Configs2>& other) | 
					
						
							| 
									
										
										
										
											2010-08-14 03:51:04 +08:00
										 |  |  | 		: base_tuple_(boost::fusion::fold(other.base_tuple(), Configs(), assign_outer<Configs>())) | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual ~FusionTupleConfig() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** insertion  */ | 
					
						
							|  |  |  | 	template <class Key, class Value> | 
					
						
							|  |  |  | 	void insert(const Key& j, const Value& x) { | 
					
						
							| 
									
										
										
										
											2010-08-24 03:44:17 +08:00
										 |  |  | 		config_<LieConfig<Key> >().insert(j,x); | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** insert a full config at a time */ | 
					
						
							|  |  |  | 	template<class Config> | 
					
						
							|  |  |  | 	void insertSub(const Config& config) { | 
					
						
							|  |  |  | 		config_<Config>().insert(config); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * Update function for whole configs - this will change existing values | 
					
						
							|  |  |  | 	 * @param config is a config to add | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	void update(const FusionTupleConfig<Configs>& config) { | 
					
						
							|  |  |  | 		base_tuple_ = boost::fusion::accumulate( | 
					
						
							|  |  |  | 				config.base_tuple_,	base_tuple_, | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | 				update_helper()); | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * Update function for whole subconfigs - this will change existing values | 
					
						
							|  |  |  | 	 * @param config is a config to add | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	template<class Config> | 
					
						
							|  |  |  | 	void update(const Config& config) { | 
					
						
							|  |  |  | 		config_<Config>().update(config); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * Update function for single key/value pairs - will change existing values | 
					
						
							|  |  |  | 	 * @param key is the variable identifier | 
					
						
							|  |  |  | 	 * @param value is the variable value to update | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	template<class Key, class Value> | 
					
						
							|  |  |  | 	void update(const Key& key, const Value& value) { | 
					
						
							| 
									
										
										
										
											2010-08-24 03:44:17 +08:00
										 |  |  | 		config_<LieConfig<Key> >().update(key,value); | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** check if a given element exists */ | 
					
						
							|  |  |  | 	template<class Key> | 
					
						
							|  |  |  | 	bool exists(const Key& j) const { | 
					
						
							| 
									
										
										
										
											2010-08-24 03:44:17 +08:00
										 |  |  | 		return config<LieConfig<Key> >().exists(j); | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-16 05:35:03 +08:00
										 |  |  | 	/** a variant of exists */ | 
					
						
							|  |  |  | 	template<class Key> | 
					
						
							|  |  |  | 	boost::optional<typename Key::Value_t> exists_(const Key& j)  const { | 
					
						
							| 
									
										
										
										
											2010-08-24 03:44:17 +08:00
										 |  |  | 		return config<LieConfig<Key> >().exists_(j); | 
					
						
							| 
									
										
										
										
											2010-08-16 05:35:03 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 	/** retrieve a point */ | 
					
						
							|  |  |  | 	template<class Key> | 
					
						
							|  |  |  | 	const typename Key::Value_t & at(const Key& j) const { | 
					
						
							| 
									
										
										
										
											2010-08-24 03:44:17 +08:00
										 |  |  | 		return config<LieConfig<Key> >().at(j); | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	/** access operator */ | 
					
						
							|  |  |  | 	template<class Key> | 
					
						
							|  |  |  | 	const typename Key::Value_t & operator[](const Key& j) const { return at<Key>(j); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** retrieve a reference to a full subconfig */ | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 	template<class Config> | 
					
						
							|  |  |  | 	const Config & config() const { | 
					
						
							|  |  |  | 		return boost::fusion::at_key<Config>(base_tuple_); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** size of the config - sum all sizes from subconfigs */ | 
					
						
							|  |  |  | 	size_t size() const { | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 		return boost::fusion::accumulate(base_tuple_, 0, | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | 				size_helper()); | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** combined dimension of the subconfigs */ | 
					
						
							|  |  |  | 	size_t dim() const { | 
					
						
							|  |  |  | 		return boost::fusion::accumulate(base_tuple_, 0, | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | 				dim_helper()); | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | 	/** number of configs in the config */ | 
					
						
							|  |  |  | 	size_t nrConfigs() const { | 
					
						
							|  |  |  | 		return boost::fusion::size(base_tuple_); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	/** erases a specific key */ | 
					
						
							|  |  |  | 	template<class Key> | 
					
						
							|  |  |  | 	void erase(const Key& j) { | 
					
						
							| 
									
										
										
										
											2010-08-24 03:44:17 +08:00
										 |  |  | 		config_<LieConfig<Key> >().erase(j); | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** clears the config */ | 
					
						
							|  |  |  | 	void clear() { | 
					
						
							|  |  |  | 		base_tuple_ = Configs(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 	/** returns true if the config is empty */ | 
					
						
							|  |  |  | 	bool empty() const { | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 		return boost::fusion::all(base_tuple_, | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | 				empty_helper()); | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | 	/** print */ | 
					
						
							|  |  |  | 	void print(const std::string& s="") const { | 
					
						
							|  |  |  | 		std::cout << "FusionTupleConfig " << s << ":" << std::endl; | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | 		boost::fusion::for_each(base_tuple_, print_helper()); | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** equals */ | 
					
						
							|  |  |  | 	bool equals(const FusionTupleConfig<Configs>& other, double tol=1e-9) const { | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | 		equals_helper helper(tol); | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | 		return boost::fusion::all( | 
					
						
							| 
									
										
										
										
											2010-08-16 05:35:03 +08:00
										 |  |  | 				boost::fusion::zip(base_tuple_,other.base_tuple_), helper); | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	/** zero: create VectorConfig of appropriate structure */ | 
					
						
							|  |  |  | 	VectorConfig zero() const { | 
					
						
							|  |  |  | 		return boost::fusion::accumulate(base_tuple_, VectorConfig(), | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | 				zero_helper()); | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FusionTupleConfig<Configs> expmap(const VectorConfig& delta) const { | 
					
						
							|  |  |  | 		return boost::fusion::accumulate(base_tuple_, base_tuple_, | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | 				expmap_helper(delta)); | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	VectorConfig logmap(const FusionTupleConfig<Configs>& cp) const { | 
					
						
							|  |  |  | 		return boost::fusion::accumulate(boost::fusion::zip(base_tuple_, cp.base_tuple_), | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | 				VectorConfig(), logmap_helper()); | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/**
 | 
					
						
							|  |  |  | 	 * direct access to the underlying fusion set - don't use this normally | 
					
						
							|  |  |  | 	 * TODO: make this a friend function or similar | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2010-08-14 03:51:04 +08:00
										 |  |  | 	const BaseTuple & base_tuple() const { return base_tuple_; } | 
					
						
							| 
									
										
										
										
											2010-08-13 22:55:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | private: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** retrieve a non-const reference to a full subconfig */ | 
					
						
							|  |  |  | 	template<class Config> | 
					
						
							|  |  |  | 	Config & config_() { | 
					
						
							|  |  |  | 		return boost::fusion::at_key<Config>(base_tuple_); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** Serialization function */ | 
					
						
							|  |  |  | 	friend class boost::serialization::access; | 
					
						
							|  |  |  | 	template<class Archive> | 
					
						
							|  |  |  | 	void serialize(Archive & ar, const unsigned int version) { | 
					
						
							|  |  |  | 		ar & BOOST_SERIALIZATION_NVP(base_tuple_); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-15 05:15:45 +08:00
										 |  |  | /** Exmap static functions */ | 
					
						
							|  |  |  | template<class Configs> | 
					
						
							|  |  |  | inline FusionTupleConfig<Configs> expmap(const FusionTupleConfig<Configs>& c, const VectorConfig& delta) { | 
					
						
							|  |  |  | 	  return c.expmap(delta); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** logmap static functions */ | 
					
						
							|  |  |  | template<class Configs> | 
					
						
							|  |  |  | inline VectorConfig logmap(const FusionTupleConfig<Configs>& c0, const FusionTupleConfig<Configs>& cp) { | 
					
						
							|  |  |  | 	  return c0.logmap(cp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-16 05:35:03 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Easy-to-use versions of FusionTupleConfig | 
					
						
							|  |  |  |  * These versions provide a simpler interface more like | 
					
						
							|  |  |  |  * the existing TupleConfig.  Each version has a number, and | 
					
						
							|  |  |  |  * takes explicit template arguments for config types. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | template<class C1> | 
					
						
							|  |  |  | struct FusionTupleConfig1 : public FusionTupleConfig<boost::fusion::set<C1> > { | 
					
						
							|  |  |  | 	typedef FusionTupleConfig<boost::fusion::set<C1> > Base; | 
					
						
							|  |  |  | 	typedef FusionTupleConfig1<C1> This; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	typedef C1 Config1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FusionTupleConfig1() {} | 
					
						
							| 
									
										
										
										
											2010-08-17 03:19:50 +08:00
										 |  |  | 	FusionTupleConfig1(const Base& c) : Base(c) {} | 
					
						
							| 
									
										
										
										
											2010-08-16 05:35:03 +08:00
										 |  |  | 	FusionTupleConfig1(const C1& c1) : Base(boost::fusion::make_set(c1)) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const Config1& first() const { return boost::fusion::at_key<C1>(this->base_tuple_); } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class C1, class C2> | 
					
						
							|  |  |  | struct FusionTupleConfig2 : public FusionTupleConfig<boost::fusion::set<C1, C2> > { | 
					
						
							|  |  |  | 	typedef FusionTupleConfig<boost::fusion::set<C1, C2> > Base; | 
					
						
							|  |  |  | 	typedef FusionTupleConfig2<C1,C2> This; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	typedef C1 Config1; | 
					
						
							|  |  |  | 	typedef C2 Config2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FusionTupleConfig2() {} | 
					
						
							| 
									
										
										
										
											2010-08-17 03:19:50 +08:00
										 |  |  | 	FusionTupleConfig2(const Base& c) : Base(c) {} | 
					
						
							| 
									
										
										
										
											2010-08-16 05:35:03 +08:00
										 |  |  | 	FusionTupleConfig2(const C1& c1, const C2& c2) : Base(boost::fusion::make_set(c1, c2)) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const Config1& first()  const { return boost::fusion::at_key<C1>(this->base_tuple_); } | 
					
						
							|  |  |  | 	const Config2& second() const { return boost::fusion::at_key<C2>(this->base_tuple_); } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<class C1, class C2, class C3> | 
					
						
							|  |  |  | struct FusionTupleConfig3 : public FusionTupleConfig<boost::fusion::set<C1, C2, C3> > { | 
					
						
							|  |  |  | 	typedef FusionTupleConfig<boost::fusion::set<C1, C2, C3> > Base; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	typedef C1 Config1; | 
					
						
							|  |  |  | 	typedef C2 Config2; | 
					
						
							|  |  |  | 	typedef C3 Config3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FusionTupleConfig3() {} | 
					
						
							| 
									
										
										
										
											2010-08-17 03:19:50 +08:00
										 |  |  | 	FusionTupleConfig3(const Base& c) : Base(c) {} | 
					
						
							| 
									
										
										
										
											2010-08-16 05:35:03 +08:00
										 |  |  | 	FusionTupleConfig3(const C1& c1, const C2& c2, const C3& c3) | 
					
						
							|  |  |  | 		: Base(boost::fusion::make_set(c1, c2, c3)) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const Config1& first()  const { return boost::fusion::at_key<C1>(this->base_tuple_); } | 
					
						
							|  |  |  | 	const Config2& second() const { return boost::fusion::at_key<C2>(this->base_tuple_); } | 
					
						
							|  |  |  | 	const Config3& third()  const { return boost::fusion::at_key<C3>(this->base_tuple_); } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 23:23:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | } // \namespace gtsam
 | 
					
						
							|  |  |  | 
 |