| 
									
										
										
										
											2013-06-06 23:36:38 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation, | 
					
						
							|  |  |  |  * Atlanta, Georgia 30332-0415 | 
					
						
							|  |  |  |  * All Rights Reserved | 
					
						
							|  |  |  |  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * See LICENSE for the license information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @file    EliminateableFactorGraph.h | 
					
						
							|  |  |  |  * @brief   Variable elimination algorithms for factor graphs | 
					
						
							|  |  |  |  * @author  Richard Roberts | 
					
						
							|  |  |  |  * @date    Apr 21, 2013 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam/inference/EliminateableFactorGraph.h>
 | 
					
						
							|  |  |  | #include <gtsam/inference/inferenceExceptions.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:43 +08:00
										 |  |  |   template<class FACTOR, class FACTORGRAPH, class CONDITIONAL, | 
					
						
							|  |  |  |   class BAYESNET, class ELIMINATIONTREE, class BAYESTREE, class JUNCTIONTREE> | 
					
						
							|  |  |  |   boost::shared_ptr<BAYESNET> | 
					
						
							|  |  |  |     EliminateableFactorGraph<FACTOR, FACTORGRAPH, CONDITIONAL, BAYESNET, ELIMINATIONTREE, BAYESTREE, JUNCTIONTREE>:: | 
					
						
							|  |  |  |     eliminateSequential( | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:55 +08:00
										 |  |  |     const Eliminate& function, OptionalOrdering ordering, OptionalVariableIndex variableIndex) const | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:38 +08:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:55 +08:00
										 |  |  |     if(ordering && variableIndex) { | 
					
						
							|  |  |  |       // Do elimination
 | 
					
						
							| 
									
										
										
										
											2013-06-18 05:16:06 +08:00
										 |  |  |       std::pair<boost::shared_ptr<BAYESNET>, boost::shared_ptr<FACTORGRAPH> > result | 
					
						
							|  |  |  |         = ELIMINATIONTREE(asDerived(), *variableIndex, *ordering).eliminate(function); | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:55 +08:00
										 |  |  |       // If any factors are remaining, the ordering was incomplete
 | 
					
						
							|  |  |  |       if(!result.second->empty()) | 
					
						
							|  |  |  |         throw InconsistentEliminationRequested(); | 
					
						
							|  |  |  |       // Return the Bayes net
 | 
					
						
							|  |  |  |       return result.first; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if(!variableIndex) { | 
					
						
							|  |  |  |       // If no VariableIndex provided, compute one and call this function again IMPORTANT: we check
 | 
					
						
							|  |  |  |       // for no variable index first so that it's always computed if we need to call COLAMD because
 | 
					
						
							|  |  |  |       // no Ordering is provided.
 | 
					
						
							|  |  |  |       return eliminateSequential(function, ordering, VariableIndexUnordered(asDerived())); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else /*if(!ordering)*/ { | 
					
						
							|  |  |  |       // If no Ordering provided, compute one and call this function again.  We are guaranteed to
 | 
					
						
							|  |  |  |       // have a VariableIndex already here because we computed one if needed in the previous 'else'
 | 
					
						
							|  |  |  |       // block.
 | 
					
						
							|  |  |  |       return eliminateSequential(function, OrderingUnordered::COLAMD(*variableIndex)); | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:38 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:43 +08:00
										 |  |  |   template<class FACTOR, class FACTORGRAPH, class CONDITIONAL, | 
					
						
							|  |  |  |   class BAYESNET, class ELIMINATIONTREE, class BAYESTREE, class JUNCTIONTREE> | 
					
						
							| 
									
										
										
										
											2013-06-18 05:16:06 +08:00
										 |  |  |     boost::shared_ptr<BAYESTREE> | 
					
						
							|  |  |  |     EliminateableFactorGraph<FACTOR, FACTORGRAPH, CONDITIONAL, BAYESNET, ELIMINATIONTREE, BAYESTREE, JUNCTIONTREE> | 
					
						
							|  |  |  |     ::eliminateMultifrontal(const Eliminate& function, OptionalOrdering ordering, OptionalVariableIndex variableIndex) const | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:38 +08:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:55 +08:00
										 |  |  |     if(ordering && variableIndex) { | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:38 +08:00
										 |  |  |       // Do elimination with given ordering
 | 
					
						
							| 
									
										
										
										
											2013-06-18 05:16:06 +08:00
										 |  |  |       std::pair<boost::shared_ptr<BAYESTREE>, boost::shared_ptr<FACTORGRAPH> > result | 
					
						
							|  |  |  |         = JUNCTIONTREE(ELIMINATIONTREE(asDerived(), *variableIndex, *ordering)).eliminate(function); | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:55 +08:00
										 |  |  |       // If any factors are remaining, the ordering was incomplete
 | 
					
						
							|  |  |  |       if(!result.second->empty()) | 
					
						
							|  |  |  |         throw InconsistentEliminationRequested(); | 
					
						
							|  |  |  |       // Return the Bayes tree
 | 
					
						
							|  |  |  |       return result.first; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if(!variableIndex) { | 
					
						
							|  |  |  |       // If no VariableIndex provided, compute one and call this function again IMPORTANT: we check
 | 
					
						
							|  |  |  |       // for no variable index first so that it's always computed if we need to call COLAMD because
 | 
					
						
							|  |  |  |       // no Ordering is provided.
 | 
					
						
							|  |  |  |       return eliminateMultifrontal(function, ordering, VariableIndexUnordered(asDerived())); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else /*if(!ordering)*/ { | 
					
						
							|  |  |  |       // If no Ordering provided, compute one and call this function again.  We are guaranteed to
 | 
					
						
							|  |  |  |       // have a VariableIndex already here because we computed one if needed in the previous 'else'
 | 
					
						
							|  |  |  |       // block.
 | 
					
						
							|  |  |  |       return eliminateMultifrontal(function, OrderingUnordered::COLAMD(*variableIndex)); | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:38 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-18 05:16:06 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   template<class FACTOR, class FACTORGRAPH, class CONDITIONAL, | 
					
						
							|  |  |  |   class BAYESNET, class ELIMINATIONTREE, class BAYESTREE, class JUNCTIONTREE> | 
					
						
							|  |  |  |     std::pair<boost::shared_ptr<BAYESNET>, boost::shared_ptr<FACTORGRAPH> > | 
					
						
							|  |  |  |     EliminateableFactorGraph<FACTOR, FACTORGRAPH, CONDITIONAL, BAYESNET, ELIMINATIONTREE, BAYESTREE, JUNCTIONTREE> | 
					
						
							|  |  |  |     ::eliminatePartialSequential(const Eliminate& function, const OrderingUnordered& ordering, | 
					
						
							|  |  |  |     OptionalVariableIndex variableIndex = boost::none) const | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if(variableIndex) { | 
					
						
							|  |  |  |       // Do elimination
 | 
					
						
							|  |  |  |       return ELIMINATIONTREE(asDerived(), *variableIndex, ordering).eliminate(function); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       // If no variable index is provided, compute one and call this function again
 | 
					
						
							|  |  |  |       return eliminatePartialSequential(function, ordering, VariableIndexUnordered(asDerived())); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   template<class FACTOR, class FACTORGRAPH, class CONDITIONAL, | 
					
						
							|  |  |  |   class BAYESNET, class ELIMINATIONTREE, class BAYESTREE, class JUNCTIONTREE> | 
					
						
							|  |  |  |     std::pair<boost::shared_ptr<BAYESTREE>, boost::shared_ptr<FACTORGRAPH> > | 
					
						
							|  |  |  |     EliminateableFactorGraph<FACTOR, FACTORGRAPH, CONDITIONAL, BAYESNET, ELIMINATIONTREE, BAYESTREE, JUNCTIONTREE> | 
					
						
							|  |  |  |     ::eliminatePartialMultifrontal(const Eliminate& function, const OrderingUnordered& ordering, | 
					
						
							|  |  |  |     OptionalVariableIndex variableIndex = boost::none) const | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if(variableIndex) { | 
					
						
							|  |  |  |       // Do elimination
 | 
					
						
							|  |  |  |       return JUNCTIONTREE(ELIMINATIONTREE(asDerived(), *variableIndex, ordering)).eliminate(function); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       // If no variable index is provided, compute one and call this function again
 | 
					
						
							|  |  |  |       return eliminatePartialMultifrontal(function, ordering, VariableIndexUnordered(asDerived())); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-06 23:36:38 +08:00
										 |  |  | } |