85 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
		
		
			
		
	
	
			85 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
|  | /**
 | ||
|  |  * @file    GenericSequentialSolver.cpp | ||
|  |  * @brief    | ||
|  |  * @author  Richard Roberts | ||
|  |  * @created Oct 21, 2010 | ||
|  |  */ | ||
|  | 
 | ||
|  | #pragma once
 | ||
|  | 
 | ||
|  | #include <gtsam/inference/GenericSequentialSolver.h>
 | ||
|  | #include <gtsam/inference/Factor-inl.h>
 | ||
|  | #include <gtsam/inference/EliminationTree-inl.h>
 | ||
|  | #include <gtsam/inference/BayesNet-inl.h>
 | ||
|  | #include <gtsam/inference/inference-inl.h>
 | ||
|  | 
 | ||
|  | #include <boost/foreach.hpp>
 | ||
|  | 
 | ||
|  | namespace gtsam { | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | template<class FACTOR> | ||
|  | GenericSequentialSolver<FACTOR>::GenericSequentialSolver(const FactorGraph<FACTOR>& factorGraph) : | ||
|  |     structure_(factorGraph), | ||
|  |     eliminationTree_(EliminationTree<FACTOR>::Create(factorGraph, structure_)) { | ||
|  |   factors_.push_back(factorGraph); | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | template<class FACTOR> | ||
|  | typename BayesNet<typename FACTOR::Conditional>::shared_ptr GenericSequentialSolver<FACTOR>::eliminate() const { | ||
|  |   return eliminationTree_->eliminate(); | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | template<class FACTOR> | ||
|  | typename FactorGraph<FACTOR>::shared_ptr GenericSequentialSolver<FACTOR>::joint(const std::vector<Index>& js) const { | ||
|  | 
 | ||
|  |   // Compute a COLAMD permutation with the marginal variable constrained to the end.
 | ||
|  |   Permutation::shared_ptr permutation(Inference::PermutationCOLAMD(structure_, js)); | ||
|  |   Permutation::shared_ptr permutationInverse(permutation->inverse()); | ||
|  | 
 | ||
|  |   // Permute the factors - NOTE that this permutes the original factors, not
 | ||
|  |   // copies.  Other parts of the code may hold shared_ptr's to these factors so
 | ||
|  |   // we must undo the permutation before returning.
 | ||
|  |   BOOST_FOREACH(const typename FACTOR::shared_ptr& factor, factors_) { | ||
|  |     if(factor) | ||
|  |       factor->permuteWithInverse(*permutationInverse); | ||
|  |   } | ||
|  | 
 | ||
|  |   // Eliminate all variables
 | ||
|  |   typename BayesNet<typename FACTOR::Conditional>::shared_ptr bayesNet( | ||
|  |       EliminationTree<FACTOR>::Create(factors_)->eliminate()); | ||
|  | 
 | ||
|  |   // Undo the permuation on the original factors and on the structure.
 | ||
|  |   BOOST_FOREACH(const typename FACTOR::shared_ptr& factor, factors_) { | ||
|  |     if(factor) | ||
|  |       factor->permuteWithInverse(*permutation); | ||
|  |   } | ||
|  | 
 | ||
|  |   // Take the joint marginal from the Bayes net.
 | ||
|  |   typename FactorGraph<FACTOR>::shared_ptr joint(new FactorGraph<FACTOR>); | ||
|  |   joint->reserve(js.size()); | ||
|  |   typename BayesNet<typename FACTOR::Conditional>::const_reverse_iterator conditional = bayesNet->rbegin(); | ||
|  |   for(size_t i = 0; i < js.size(); ++i) { | ||
|  |     joint->push_back(typename FACTOR::shared_ptr(new FACTOR(**(conditional++)))); } | ||
|  | 
 | ||
|  |   // Undo the permutation on the eliminated joint marginal factors
 | ||
|  |   BOOST_FOREACH(const typename FACTOR::shared_ptr& factor, *joint) { | ||
|  |     factor->permuteWithInverse(*permutation); } | ||
|  | 
 | ||
|  |   return joint; | ||
|  | } | ||
|  | 
 | ||
|  | /* ************************************************************************* */ | ||
|  | template<class FACTOR> | ||
|  | typename FACTOR::shared_ptr GenericSequentialSolver<FACTOR>::marginal(Index j) const { | ||
|  |   // Create a container for the one variable index
 | ||
|  |   vector<Index> js(1); js[0] = j; | ||
|  | 
 | ||
|  |   // Call joint and return the only factor in the factor graph it returns
 | ||
|  |   return (*this->joint(js))[0]; | ||
|  | } | ||
|  | 
 | ||
|  | } |