| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file    ISAM2-inl.h | 
					
						
							| 
									
										
										
										
											2009-12-30 12:27:14 +08:00
										 |  |  |  * @brief   Incremental update functionality (ISAM2) for BayesTree, with fluid relinearization. | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  |  * @author  Michael Kaess | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/foreach.hpp>
 | 
					
						
							|  |  |  | #include <boost/assign/std/list.hpp> // for operator +=
 | 
					
						
							|  |  |  | using namespace boost::assign; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-03 12:57:35 +08:00
										 |  |  | #include <set>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-16 09:16:59 +08:00
										 |  |  | #include "NonlinearFactorGraph-inl.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | #include "GaussianFactor.h"
 | 
					
						
							|  |  |  | #include "VectorConfig.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Conditional.h"
 | 
					
						
							|  |  |  | #include "BayesTree-inl.h"
 | 
					
						
							|  |  |  | #include "ISAM2.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	using namespace std; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 	// from inference-inl.h - need to additionally return the newly created factor for caching
 | 
					
						
							| 
									
										
										
										
											2010-01-18 16:05:33 +08:00
										 |  |  | 	boost::shared_ptr<GaussianConditional> _eliminateOne(FactorGraph<GaussianFactor>& graph, CachedFactors& cached, const Symbol& key) { | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// combine the factors of all nodes connected to the variable to be eliminated
 | 
					
						
							|  |  |  | 		// if no factors are connected to key, returns an empty factor
 | 
					
						
							|  |  |  | 		boost::shared_ptr<GaussianFactor> joint_factor = removeAndCombineFactors(graph,key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// eliminate that joint factor
 | 
					
						
							|  |  |  | 		boost::shared_ptr<GaussianFactor> factor; | 
					
						
							|  |  |  | 		boost::shared_ptr<GaussianConditional> conditional; | 
					
						
							|  |  |  | 		boost::tie(conditional, factor) = joint_factor->eliminate(key); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-20 09:24:32 +08:00
										 |  |  | 		// ADDED: remember the intermediate result to be able to later restart computation in the middle
 | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 		cached[key] = factor; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// add new factor on separator back into the graph
 | 
					
						
							|  |  |  | 		if (!factor->empty()) graph.push_back(factor); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// return the conditional Gaussian
 | 
					
						
							|  |  |  | 		return conditional; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// from GaussianFactorGraph.cpp, see _eliminateOne above
 | 
					
						
							| 
									
										
										
										
											2010-01-18 16:05:33 +08:00
										 |  |  | 	GaussianBayesNet _eliminate(FactorGraph<GaussianFactor>& graph, CachedFactors& cached, const Ordering& ordering) { | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 		GaussianBayesNet chordalBayesNet; // empty
 | 
					
						
							| 
									
										
										
										
											2010-01-18 12:53:17 +08:00
										 |  |  | 		BOOST_FOREACH(const Symbol& key, ordering) { | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 			GaussianConditional::shared_ptr cg = _eliminateOne(graph, cached, key); | 
					
						
							|  |  |  | 			chordalBayesNet.push_back(cg); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return chordalBayesNet; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 16:05:33 +08:00
										 |  |  | 	GaussianBayesNet _eliminate_const(const FactorGraph<GaussianFactor>& graph, CachedFactors& cached, const Ordering& ordering) { | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 		// make a copy that can be modified locally
 | 
					
						
							|  |  |  | 		FactorGraph<GaussianFactor> graph_ignored = graph; | 
					
						
							|  |  |  | 		return _eliminate(graph_ignored, cached, ordering); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 	/** Create an empty Bayes Tree */ | 
					
						
							|  |  |  | 	template<class Conditional, class Config> | 
					
						
							|  |  |  | 	ISAM2<Conditional, Config>::ISAM2() : BayesTree<Conditional>() {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-30 12:27:14 +08:00
										 |  |  | 	/** Create a Bayes Tree from a nonlinear factor graph */ | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 	template<class Conditional, class Config> | 
					
						
							| 
									
										
										
										
											2009-12-31 13:35:08 +08:00
										 |  |  | 	ISAM2<Conditional, Config>::ISAM2(const NonlinearFactorGraph<Config>& nlfg, const Ordering& ordering, const Config& config) | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 	: BayesTree<Conditional>(nlfg.linearize(config)->eliminate(ordering)), theta_(config), thetaFuture_(config), nonlinearFactors_(nlfg) { | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 		// todo: repeats calculation above, just to set "cached"
 | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 		// De-referencing shared pointer can be quite expensive because creates temporary
 | 
					
						
							|  |  |  | 		_eliminate_const(*nlfg.linearize(config), cached_, ordering); | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-20 14:49:19 +08:00
										 |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	template<class Conditional, class Config> | 
					
						
							| 
									
										
										
										
											2010-01-23 02:29:27 +08:00
										 |  |  | 	list<int>	ISAM2<Conditional, Config>::getAffectedFactors(const list<Symbol>& keys) const { | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 	  FactorGraph<NonlinearFactor<Config> > allAffected; | 
					
						
							| 
									
										
										
										
											2010-01-20 14:49:19 +08:00
										 |  |  | 		list<int> indices; | 
					
						
							|  |  |  | 		BOOST_FOREACH(const Symbol& key, keys) { | 
					
						
							|  |  |  | 			const list<int> l = nonlinearFactors_.factors(key); | 
					
						
							|  |  |  | 			indices.insert(indices.begin(), l.begin(), l.end()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		indices.sort(); | 
					
						
							|  |  |  | 		indices.unique(); | 
					
						
							| 
									
										
										
										
											2010-01-23 02:29:27 +08:00
										 |  |  | 		return indices; | 
					
						
							| 
									
										
										
										
											2010-01-20 14:49:19 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 	/* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-01-18 12:32:45 +08:00
										 |  |  | 	// retrieve all factors that ONLY contain the affected variables
 | 
					
						
							|  |  |  | 	// (note that the remaining stuff is summarized in the cached factors)
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 	template<class Conditional, class Config> | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 	boost::shared_ptr<GaussianFactorGraph> ISAM2<Conditional, Config>::relinearizeAffectedFactors | 
					
						
							|  |  |  | 	(const set<Symbol>& affectedKeys) const { | 
					
						
							| 
									
										
										
										
											2010-01-20 14:49:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		list<Symbol> affectedKeysList; // todo: shouldn't have to convert back to list...
 | 
					
						
							|  |  |  | 		affectedKeysList.insert(affectedKeysList.begin(), affectedKeys.begin(), affectedKeys.end()); | 
					
						
							| 
									
										
										
										
											2010-01-23 02:29:27 +08:00
										 |  |  | 		list<int> candidates = getAffectedFactors(affectedKeysList); | 
					
						
							| 
									
										
										
										
											2010-01-18 12:53:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 		NonlinearFactorGraph<Config> nonlinearAffectedFactors; | 
					
						
							| 
									
										
										
										
											2010-01-18 12:53:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 02:29:27 +08:00
										 |  |  | 		BOOST_FOREACH(int idx, candidates) { | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 			bool inside = true; | 
					
						
							| 
									
										
										
										
											2010-01-23 02:29:27 +08:00
										 |  |  | 			BOOST_FOREACH(const Symbol& key, nonlinearFactors_[idx]->keys()) { | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 				if (affectedKeys.find(key) == affectedKeys.end()) { | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 					inside = false; | 
					
						
							| 
									
										
										
										
											2010-01-20 14:49:19 +08:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if (inside) | 
					
						
							| 
									
										
										
										
											2010-01-23 02:29:27 +08:00
										 |  |  | 				nonlinearAffectedFactors.push_back(nonlinearFactors_[idx]); | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-18 12:53:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 		// TODO: temporary might be expensive, return shared pointer ?
 | 
					
						
							| 
									
										
										
										
											2010-01-22 04:15:52 +08:00
										 |  |  | 		return nonlinearAffectedFactors.linearize(theta_); | 
					
						
							| 
									
										
										
										
											2010-01-18 12:32:45 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 12:32:45 +08:00
										 |  |  | 	/* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-01-18 12:53:17 +08:00
										 |  |  | 	// find intermediate (linearized) factors from cache that are passed into the affected area
 | 
					
						
							| 
									
										
										
										
											2010-01-18 12:32:45 +08:00
										 |  |  | 	template<class Conditional, class Config> | 
					
						
							|  |  |  | 	FactorGraph<GaussianFactor> ISAM2<Conditional, Config>::getCachedBoundaryFactors(Cliques& orphans) { | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 		FactorGraph<GaussianFactor> cachedBoundary; | 
					
						
							| 
									
										
										
										
											2010-01-18 12:53:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 		BOOST_FOREACH(sharedClique orphan, orphans) { | 
					
						
							| 
									
										
										
										
											2010-01-20 14:49:19 +08:00
										 |  |  | 			// find the last variable that was eliminated
 | 
					
						
							|  |  |  | 			const Symbol& key = orphan->ordering().back(); | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 			// retrieve the cached factor and add to boundary
 | 
					
						
							| 
									
										
										
										
											2010-01-18 16:05:33 +08:00
										 |  |  | 			cachedBoundary.push_back(cached_[key]); | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-18 12:53:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 		return cachedBoundary; | 
					
						
							| 
									
										
										
										
											2010-01-18 12:32:45 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 12:32:45 +08:00
										 |  |  | 	/* ************************************************************************* */ | 
					
						
							|  |  |  | 	template<class Conditional, class Config> | 
					
						
							|  |  |  | 	void ISAM2<Conditional, Config>::update_internal(const NonlinearFactorGraph<Config>& newFactors, | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 			const Config& newTheta, Cliques& orphans, double wildfire_threshold, double relinearize_threshold, bool relinearize) { | 
					
						
							| 
									
										
										
										
											2010-01-22 00:09:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		//		marked_ = nonlinearFactors_.keys(); // debug only ////////////
 | 
					
						
							| 
									
										
										
										
											2010-01-22 00:09:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 		// only relinearize if requested in previous step AND necessary (ie. at least one variable changes)
 | 
					
						
							|  |  |  | 		relinearize = true; // todo - switched off
 | 
					
						
							|  |  |  | 		bool relinFromLast = true; //marked_.size() > 0;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		//// 1 - relinearize selected variables
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 		if (relinFromLast) { | 
					
						
							|  |  |  | 			theta_ = expmap(theta_, deltaMarked_); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		//// 2 - Add new factors (for later relinearization)
 | 
					
						
							| 
									
										
										
										
											2010-01-22 00:09:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 		nonlinearFactors_.push_back(newFactors); | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		//// 3 - Initialize new variables
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		theta_.insert(newTheta); | 
					
						
							|  |  |  | 		thetaFuture_.insert(newTheta); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		//// 4 - Mark affected variables as invalid
 | 
					
						
							| 
									
										
										
										
											2010-01-22 01:41:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 04:15:52 +08:00
										 |  |  | 		// todo - not in lyx yet: relin requires more than just removing the cliques corresponding to the variables!!!
 | 
					
						
							|  |  |  | 		// It's about factors!!!
 | 
					
						
							| 
									
										
										
										
											2010-01-22 01:41:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 		if (relinFromLast) { | 
					
						
							|  |  |  | 			// mark variables that have to be removed as invalid (removeFATtop)
 | 
					
						
							|  |  |  | 			// basically calculate all the keys contained in the factors that contain any of the keys...
 | 
					
						
							|  |  |  | 			// the goal is to relinearize all variables directly affected by new factors
 | 
					
						
							|  |  |  | 			list<int> allAffected = getAffectedFactors(marked_); | 
					
						
							|  |  |  | 			set<Symbol> accumulate; | 
					
						
							|  |  |  | 			BOOST_FOREACH(int idx, allAffected) { | 
					
						
							|  |  |  | 				list<Symbol> tmp = nonlinearFactors_[idx]->keys(); | 
					
						
							|  |  |  | 				accumulate.insert(tmp.begin(), tmp.end()); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			marked_.clear(); | 
					
						
							|  |  |  | 			marked_.insert(marked_.begin(), accumulate.begin(), accumulate.end()); | 
					
						
							|  |  |  | 		} // else: marked_ is empty anyways
 | 
					
						
							| 
									
										
										
										
											2010-01-22 01:41:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 		// also mark variables that are affected by new factors as invalid
 | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 		const list<Symbol> newKeys = newFactors.keys(); | 
					
						
							|  |  |  | 		marked_.insert(marked_.begin(), newKeys.begin(), newKeys.end()); | 
					
						
							|  |  |  | 		// eliminate duplicates
 | 
					
						
							|  |  |  | 		marked_.sort(); | 
					
						
							|  |  |  | 		marked_.unique(); | 
					
						
							| 
									
										
										
										
											2010-01-19 09:18:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		//// 5 - removeTop invalidate all cliques involving marked variables
 | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 09:18:28 +08:00
										 |  |  | 		// remove affected factors
 | 
					
						
							| 
									
										
										
										
											2010-01-21 08:38:22 +08:00
										 |  |  | 		BayesNet<GaussianConditional> affectedBayesNet; | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 		this->removeTop(marked_, affectedBayesNet, orphans); | 
					
						
							| 
									
										
										
										
											2010-01-18 12:32:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		//// 6 - find factors connected to affected variables
 | 
					
						
							|  |  |  | 		//// 7 - linearize
 | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 		boost::shared_ptr<GaussianFactorGraph> factors; | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 		if (relinFromLast) { | 
					
						
							|  |  |  | 			// ordering provides all keys in conditionals, there cannot be others because path to root included
 | 
					
						
							|  |  |  | 			set<Symbol> affectedKeys; | 
					
						
							|  |  |  | 			list<Symbol> tmp = affectedBayesNet.ordering(); | 
					
						
							|  |  |  | 			affectedKeys.insert(tmp.begin(), tmp.end()); | 
					
						
							| 
									
										
										
										
											2010-01-19 08:15:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 			// todo - remerge in keys of new factors
 | 
					
						
							|  |  |  | 			affectedKeys.insert(newKeys.begin(), newKeys.end()); | 
					
						
							| 
									
										
										
										
											2010-01-20 09:24:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 09:53:04 +08:00
										 |  |  | 			// Save number of affected variables
 | 
					
						
							|  |  |  | 			lastAffectedVariableCount = affectedKeys.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 			factors = relinearizeAffectedFactors(affectedKeys); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 09:53:04 +08:00
										 |  |  | 			// Save number of affected factors
 | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 			lastAffectedFactorCount = factors->size(); | 
					
						
							| 
									
										
										
										
											2010-01-23 09:53:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 			// add the cached intermediate results from the boundary of the orphans ...
 | 
					
						
							|  |  |  | 			FactorGraph<GaussianFactor> cachedBoundary = getCachedBoundaryFactors(orphans); | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 			factors->push_back(cachedBoundary); | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			// reuse the old factors
 | 
					
						
							|  |  |  | 			FactorGraph<GaussianFactor> tmp(affectedBayesNet); | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 			factors.reset(new GaussianFactorGraph); | 
					
						
							|  |  |  | 			factors->push_back(tmp); | 
					
						
							|  |  |  | 			factors->push_back(*newFactors.linearize(theta_)); // avoid temporary ?
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-18 12:32:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		//// 8 - eliminate and add orphans back in
 | 
					
						
							| 
									
										
										
										
											2010-01-03 12:57:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 		// create an ordering for the new and contaminated factors
 | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 		Ordering ordering = factors->getOrdering(); | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// eliminate into a Bayes net
 | 
					
						
							| 
									
										
										
										
											2010-02-22 05:17:47 +08:00
										 |  |  | 		BayesNet<Conditional> bayesNet = _eliminate(*factors, cached_, ordering); | 
					
						
							| 
									
										
										
										
											2010-01-03 12:57:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 10:27:26 +08:00
										 |  |  | 		// Create Index from ordering
 | 
					
						
							|  |  |  | 		IndexTable<Symbol> index(ordering); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 		// insert conditionals back in, straight into the topless bayesTree
 | 
					
						
							|  |  |  | 		typename BayesNet<Conditional>::const_reverse_iterator rit; | 
					
						
							| 
									
										
										
										
											2010-01-22 10:27:26 +08:00
										 |  |  | 		for ( rit=bayesNet.rbegin(); rit != bayesNet.rend(); ++rit ) | 
					
						
							|  |  |  | 			this->insert(*rit, index); | 
					
						
							| 
									
										
										
										
											2010-01-20 09:24:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 09:53:04 +08:00
										 |  |  | 		// Save number of affectedCliques
 | 
					
						
							|  |  |  | 		lastAffectedCliqueCount = this->size(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 		// add orphans to the bottom of the new tree
 | 
					
						
							|  |  |  | 		BOOST_FOREACH(sharedClique orphan, orphans) { | 
					
						
							| 
									
										
										
										
											2010-01-22 10:27:26 +08:00
										 |  |  | 			Symbol parentRepresentative = findParentClique(orphan->separator_, index); | 
					
						
							|  |  |  | 			sharedClique parent = (*this)[parentRepresentative]; | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 			parent->children_ += orphan; | 
					
						
							|  |  |  | 			orphan->parent_ = parent; // set new parent!
 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-18 12:32:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		//// 9 - update solution
 | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		delta_ = optimize2(*this, wildfire_threshold); | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		//// 10 - mark variables, if significant change
 | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		marked_.clear(); | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 		deltaMarked_ = VectorConfig(); // clear
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 		if (relinearize) { // decides about next step!!!
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (VectorConfig::const_iterator it = delta_.begin(); it!=delta_.end(); it++) { | 
					
						
							|  |  |  | 				Symbol key = it->first; | 
					
						
							|  |  |  | 				Vector v = it->second; | 
					
						
							|  |  |  | 				if (max(abs(v)) >= relinearize_threshold) { | 
					
						
							|  |  |  | 					marked_.push_back(key); | 
					
						
							|  |  |  | 					deltaMarked_.insert(key, v); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 			// not part of the formal algorithm, but needed to allow initialization of new variables outside by the user
 | 
					
						
							|  |  |  | 			thetaFuture_ = expmap(thetaFuture_, deltaMarked_); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	template<class Conditional, class Config> | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 	void ISAM2<Conditional, Config>::update( | 
					
						
							| 
									
										
										
										
											2010-01-22 14:28:12 +08:00
										 |  |  | 			const NonlinearFactorGraph<Config>& newFactors, const Config& newTheta, | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 			double wildfire_threshold, double relinearize_threshold, bool relinearize) { | 
					
						
							| 
									
										
										
										
											2010-01-17 14:06:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 		Cliques orphans; | 
					
						
							| 
									
										
										
										
											2010-01-23 08:21:34 +08:00
										 |  |  | 		this->update_internal(newFactors, newTheta, orphans, wildfire_threshold, relinearize_threshold, relinearize); | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-29 13:57:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /// namespace gtsam
 |