| 
									
										
										
										
											2010-10-14 12:54: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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @file    VariableIndex.h | 
					
						
							|  |  |  |  * @brief    | 
					
						
							|  |  |  |  * @author  Richard Roberts | 
					
						
							|  |  |  |  * @created Sep 12, 2010 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <gtsam/base/types.h>
 | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  | #include <gtsam/base/FastList.h>
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | #include <gtsam/inference/Permutation.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							|  |  |  | #include <iostream>
 | 
					
						
							|  |  |  | #include <boost/shared_ptr.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  | #include <boost/foreach.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Inference; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * The VariableIndex class stores the information necessary to perform | 
					
						
							|  |  |  |  * elimination, including an index of factors involving each variable and | 
					
						
							|  |  |  |  * the structure of the intermediate joint factors that develop during | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |  * elimination.  This maps variables to collections of factor indices. | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | class VariableIndex { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   typedef boost::shared_ptr<VariableIndex> shared_ptr; | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |   typedef FastList<size_t> Factors; | 
					
						
							| 
									
										
										
										
											2010-10-23 02:11:15 +08:00
										 |  |  |   typedef Factors::iterator Factor_iterator; | 
					
						
							|  |  |  |   typedef Factors::const_iterator Factor_const_iterator; | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |   std::vector<Factors> indexUnpermuted_; | 
					
						
							|  |  |  |   Permuted<std::vector<Factors>, Factors&> index_; | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   size_t nFactors_; | 
					
						
							|  |  |  |   size_t nEntries_; // Sum of involved variable counts of each factor
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   VariableIndex() : index_(indexUnpermuted_), nFactors_(0), nEntries_(0) {} | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  |   template<class FactorGraph> VariableIndex(const FactorGraph& factorGraph, Index nVariables); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   template<class FactorGraph> VariableIndex(const FactorGraph& factorGraph); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |   Index size() const { return index_.size(); } | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   size_t nFactors() const { return nFactors_; } | 
					
						
							|  |  |  |   size_t nEntries() const { return nEntries_; } | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |   const Factors& operator[](Index variable) const { checkVar(variable); return index_[variable]; } | 
					
						
							|  |  |  |   Factors& operator[](Index variable) { checkVar(variable); return index_[variable]; } | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   void permute(const Permutation& permutation); | 
					
						
							|  |  |  |   template<class FactorGraph> void augment(const FactorGraph& factorGraph); | 
					
						
							|  |  |  |   void rebaseFactors(ptrdiff_t baseIndexChange); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |   bool equals(const VariableIndex& other, double tol=0.0) const; | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   void print(const std::string& str = "VariableIndex: ") const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |   VariableIndex(size_t nVars) : indexUnpermuted_(nVars), index_(indexUnpermuted_), nFactors_(0), nEntries_(0) {} | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |   void checkVar(Index variable) const { assert(variable < index_.size()); } | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  |   template<class FactorGraph> void fill(const FactorGraph& factorGraph); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |   Factor_iterator factorsBegin(Index variable) { checkVar(variable); return index_[variable].begin(); } | 
					
						
							|  |  |  |   Factor_const_iterator factorsBegin(Index variable) const { checkVar(variable); return index_[variable].begin(); } | 
					
						
							|  |  |  |   Factor_iterator factorsEnd(Index variable) { checkVar(variable); return index_[variable].end(); } | 
					
						
							|  |  |  |   Factor_const_iterator factorsEnd(Index variable) const { checkVar(variable); return index_[variable].end(); } | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  | template<class FactorGraph> | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  | void VariableIndex::fill(const FactorGraph& factorGraph) { | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Build index mapping from variable id to factor index
 | 
					
						
							|  |  |  |   for(size_t fi=0; fi<factorGraph.size(); ++fi) | 
					
						
							|  |  |  |     if(factorGraph[fi]) { | 
					
						
							|  |  |  |       BOOST_FOREACH(const Index key, factorGraph[fi]->keys()) { | 
					
						
							|  |  |  |         if(key < index_.size()) { | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |           index_[key].push_back(fi); | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  |           ++ nEntries_; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       ++ nFactors_; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | template<class FactorGraph> | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  | VariableIndex::VariableIndex(const FactorGraph& factorGraph) : | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     index_(indexUnpermuted_), nFactors_(0), nEntries_(0) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // If the factor graph is empty, return an empty index because inside this
 | 
					
						
							|  |  |  |   // if block we assume at least one factor.
 | 
					
						
							|  |  |  |   if(factorGraph.size() > 0) { | 
					
						
							|  |  |  |     // Find highest-numbered variable
 | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |     Index maxVar = 0; | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     BOOST_FOREACH(const typename FactorGraph::sharedFactor& factor, factorGraph) { | 
					
						
							|  |  |  |       if(factor) { | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |         BOOST_FOREACH(const Index key, factor->keys()) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |           if(key > maxVar) | 
					
						
							|  |  |  |             maxVar = key; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  |     // Allocate array
 | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     index_.container().resize(maxVar+1); | 
					
						
							|  |  |  |     index_.permutation() = Permutation::Identity(maxVar+1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  |     fill(factorGraph); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | template<class FactorGraph> | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  | VariableIndex::VariableIndex(const FactorGraph& factorGraph, Index nVariables) : | 
					
						
							| 
									
										
										
										
											2010-10-22 06:59:54 +08:00
										 |  |  |     indexUnpermuted_(nVariables), index_(indexUnpermuted_), nFactors_(0), nEntries_(0) { | 
					
						
							|  |  |  |   fill(factorGraph); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | template<class FactorGraph> | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  | void VariableIndex::augment(const FactorGraph& factorGraph) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |   // If the factor graph is empty, return an empty index because inside this
 | 
					
						
							|  |  |  |   // if block we assume at least one factor.
 | 
					
						
							|  |  |  |   if(factorGraph.size() > 0) { | 
					
						
							|  |  |  |     // Find highest-numbered variable
 | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |     Index maxVar = 0; | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     BOOST_FOREACH(const typename FactorGraph::sharedFactor& factor, factorGraph) { | 
					
						
							|  |  |  |       if(factor) { | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |         BOOST_FOREACH(const Index key, factor->keys()) { | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |           if(key > maxVar) | 
					
						
							|  |  |  |             maxVar = key; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Allocate index
 | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |     Index originalSize = index_.size(); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |     index_.container().resize(std::max(index_.size(), maxVar+1)); | 
					
						
							|  |  |  |     index_.permutation().resize(index_.container().size()); | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |     for(Index var=originalSize; var<index_.permutation().size(); ++var) | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |       index_.permutation()[var] = var; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Augment index mapping from variable id to factor index
 | 
					
						
							|  |  |  |     size_t orignFactors = nFactors_; | 
					
						
							|  |  |  |     for(size_t fi=0; fi<factorGraph.size(); ++fi) | 
					
						
							|  |  |  |       if(factorGraph[fi]) { | 
					
						
							| 
									
										
										
										
											2010-10-12 05:14:35 +08:00
										 |  |  |         BOOST_FOREACH(const Index key, factorGraph[fi]->keys()) { | 
					
						
							| 
									
										
										
										
											2010-10-23 02:02:55 +08:00
										 |  |  |           index_[key].push_back(orignFactors + fi); | 
					
						
							| 
									
										
										
										
											2010-10-09 06:04:47 +08:00
										 |  |  |           ++ nEntries_; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         ++ nFactors_; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |