Working on ISAM
							parent
							
								
									735c7a8650
								
							
						
					
					
						commit
						60d5feb5cf
					
				|  | @ -31,6 +31,7 @@ namespace gtsam { | |||
|   // Forward declarations
 | ||||
|   template<class FACTOR> class FactorGraph; | ||||
| 
 | ||||
|   /* ************************************************************************* */ | ||||
|   /**
 | ||||
|    * Bayes tree | ||||
|    * @tparam CONDITIONAL The type of the conditional densities, i.e. the type of node in the underlying Bayes chain, | ||||
|  | @ -256,4 +257,23 @@ namespace gtsam { | |||
| 
 | ||||
|   }; // BayesTree
 | ||||
| 
 | ||||
|   /* ************************************************************************* */ | ||||
|   template<class CLIQUE> | ||||
|   class BayesTreeOrphanWrapper : public CLIQUE::FactorType | ||||
|   { | ||||
|   public: | ||||
|     typedef CLIQUE CliqueType; | ||||
|     typedef typename CLIQUE::FactorType Base; | ||||
| 
 | ||||
|     boost::shared_ptr<CliqueType> clique; | ||||
| 
 | ||||
|     BayesTreeOrphanWrapper(const boost::shared_ptr<CliqueType>& clique) : | ||||
|       clique(clique) | ||||
|     { | ||||
|       // Store parent keys in our base type factor so that eliminating those parent keys will pull
 | ||||
|       // this subtree into the elimination.
 | ||||
|       keys_.assign(clique->conditional()->beginParents(), clique->conditional()->endParents()); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
| } /// namespace gtsam
 | ||||
|  |  | |||
|  | @ -0,0 +1,63 @@ | |||
| /* ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  * 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    ISAM-inl.h | ||||
|  * @brief   Incremental update functionality (iSAM) for BayesTree. | ||||
|  * @author  Michael Kaess | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <gtsam/inference/ISAM.h> | ||||
| 
 | ||||
| namespace gtsam { | ||||
| 
 | ||||
|   /* ************************************************************************* */ | ||||
|   template<class BAYESTREE> | ||||
|   void ISAM<BAYESTREE>::update_internal(const FactorGraphType& newFactors, Cliques& orphans, const Eliminate& function) | ||||
|   { | ||||
|     // Remove the contaminated part of the Bayes tree
 | ||||
|     // Throw exception if disconnected
 | ||||
|     BayesNetType bn; | ||||
|     if (!this->empty()) { | ||||
|       const FastSet<Key> newFactorKeys = newFactors.keys(); | ||||
|       this->removeTop(std::vector<Key>(newFactorKeys.begin(), newFactorKeys.end()), bn, orphans); | ||||
|       if (bn.empty()) | ||||
|         throw std::runtime_error( | ||||
|             "ISAM::update_internal(): no variables in common between existing Bayes tree and incoming factors!"); | ||||
|     } | ||||
| 
 | ||||
|     // Add the removed top and the new factors
 | ||||
|     FactorGraphType factors; | ||||
|     factors += bn; | ||||
|     factors += newFactors; | ||||
| 
 | ||||
|     // Add the orphaned subtrees
 | ||||
|     BOOST_FOREACH(const sharedClique& orphan, orphans) | ||||
|       factors += boost::make_shared<BayesTreeOrphanWrapper<Clique> >(orphan); | ||||
| 
 | ||||
|     // eliminate into a Bayes net
 | ||||
|     Base bayesTree = *factors.eliminateMultifrontal(boost::none, function); | ||||
|     this->roots_.insert(this->roots_.end(), bayesTree.roots().begin(), bayesTree.roots().end()); | ||||
|     this->nodes_.insert(bayesTree.nodes().begin(), bayesTree.nodes().end()); | ||||
|   } | ||||
| 
 | ||||
|   /* ************************************************************************* */ | ||||
|   template<class BAYESTREE> | ||||
|   void ISAM<BAYESTREE>::update(const FactorGraphType& newFactors, const Eliminate& function) | ||||
|   { | ||||
|     Cliques orphans; | ||||
|     this->update_internal(newFactors, orphans, function); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| /// namespace gtsam
 | ||||
|  | @ -0,0 +1,69 @@ | |||
| /* ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  * 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    ISAM.h | ||||
|  * @brief   Incremental update functionality (iSAM) for BayesTree. | ||||
|  * @author  Michael Kaess | ||||
|  */ | ||||
| 
 | ||||
| // \callgraph
 | ||||
| #pragma once | ||||
| 
 | ||||
| namespace gtsam { | ||||
| 
 | ||||
|   /**
 | ||||
|    * A Bayes tree with an update methods that implements the iSAM algorithm. | ||||
|    * Given a set of new factors, it re-eliminates the invalidated part of the tree. | ||||
|    * \nosubgrouping | ||||
|    */ | ||||
|   template<class BAYESTREE> | ||||
|   class ISAM: public BAYESTREE | ||||
|   { | ||||
|   private: | ||||
| 
 | ||||
|     typedef BAYESTREE Base; | ||||
|     typedef typename Base::FactorGraphType FactorGraphType; | ||||
|     typedef typename Base::Cliques Cliques; | ||||
|     typedef typename Base::Eliminate Eliminate; | ||||
|     typedef typename Base::EliminationTraits EliminationTraits; | ||||
| 
 | ||||
|   public: | ||||
| 
 | ||||
|     /// @name Standard Constructors
 | ||||
|     /// @{
 | ||||
| 
 | ||||
|     /** Create an empty Bayes Tree */ | ||||
|     ISAM() {} | ||||
| 
 | ||||
|     /** Copy constructor */ | ||||
|     ISAM(const Base& bayesTree) : Base(bayesTree) {} | ||||
| 
 | ||||
|     /// @}
 | ||||
|     /// @name Advanced Interface Interface
 | ||||
|     /// @{
 | ||||
| 
 | ||||
|     /**
 | ||||
|      * update the Bayes tree with a set of new factors, typically derived from measurements | ||||
|      * @param newFactors is a factor graph that contains the new factors | ||||
|      * @param function an elimination routine | ||||
|      */ | ||||
|     void update(const FactorGraphType& newFactors, const Eliminate& function = EliminationTraits::DefaultEliminate); | ||||
| 
 | ||||
|     /** update_internal provides access to list of orphans for drawing purposes */ | ||||
|     void update_internal(const FactorGraphType& newFactors, Cliques& orphans, | ||||
|       const Eliminate& function = EliminationTraits::DefaultEliminate); | ||||
| 
 | ||||
|     /// @}
 | ||||
| 
 | ||||
|   }; | ||||
| 
 | ||||
| }/// namespace gtsam
 | ||||
|  | @ -177,8 +177,18 @@ namespace gtsam { | |||
|       // Gather factors
 | ||||
|       FactorGraphType gatheredFactors; | ||||
|       gatheredFactors.reserve(node->factors.size() + node->children.size()); | ||||
|       gatheredFactors.push_back(node->factors.begin(), node->factors.end()); | ||||
|       gatheredFactors.push_back(myData.childFactors.begin(), myData.childFactors.end()); | ||||
|       gatheredFactors += node->factors; | ||||
|       gatheredFactors += myData.childFactors; | ||||
| 
 | ||||
|       // Check for Bayes tree orphan subtrees, and add them to our children
 | ||||
|       BOOST_FOREACH(const sharedFactor& f, node->factors) | ||||
|       { | ||||
|         if(const BayesTreeOrphanWrapper<BTNode>* asSubtree = dynamic_cast<const BayesTreeOrphanWrapper<BTNode>*>(f.get())) | ||||
|         { | ||||
|           myData.bayesTreeNode->children.push_back(asSubtree->clique); | ||||
|           asSubtree->clique->parent_ = myData.bayesTreeNode; | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       // Do dense elimination step
 | ||||
|       std::pair<boost::shared_ptr<ConditionalType>, boost::shared_ptr<FactorType> > eliminationResult = | ||||
|  |  | |||
|  | @ -0,0 +1,31 @@ | |||
| /* ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  * 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 SymbolicISAM.cpp | ||||
|  * @date July 29, 2013 | ||||
|  * @author Frank Dellaert | ||||
|  * @author Richard Roberts | ||||
|  */ | ||||
| 
 | ||||
| #include <gtsam/symbolic/SymbolicISAM.h> | ||||
| #include <gtsam/inference/ISAM-inst.h> | ||||
| 
 | ||||
| namespace gtsam { | ||||
| 
 | ||||
|   /* ************************************************************************* */ | ||||
|   SymbolicISAM::SymbolicISAM() {} | ||||
| 
 | ||||
|   /* ************************************************************************* */ | ||||
|   SymbolicISAM::SymbolicISAM(const SymbolicBayesTree& bayesTree) : | ||||
|     Base(bayesTree) {} | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,46 @@ | |||
| /* ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  * 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 SymbolicISAM.h | ||||
|  * @date July 29, 2013 | ||||
|  * @author Frank Dellaert | ||||
|  * @author Richard Roberts | ||||
|  */ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <gtsam/symbolic/SymbolicBayesTree.h> | ||||
| #include <gtsam/inference/ISAM.h> | ||||
| 
 | ||||
| namespace gtsam { | ||||
| 
 | ||||
|   class GTSAM_EXPORT SymbolicISAM : public ISAM<SymbolicBayesTree> | ||||
|   { | ||||
|   public: | ||||
|     typedef ISAM<SymbolicBayesTree> Base; | ||||
|     typedef SymbolicISAM This; | ||||
|     typedef boost::shared_ptr<This> shared_ptr; | ||||
| 
 | ||||
|     /// @name Standard Constructors
 | ||||
|     /// @{
 | ||||
| 
 | ||||
|     /** Create an empty Bayes Tree */ | ||||
|     SymbolicISAM(); | ||||
| 
 | ||||
|     /** Copy constructor */ | ||||
|     SymbolicISAM(const SymbolicBayesTree& bayesTree); | ||||
| 
 | ||||
|     /// @}
 | ||||
| 
 | ||||
|   }; | ||||
| 
 | ||||
| } | ||||
|  | @ -341,6 +341,28 @@ TEST( BayesTreeOrdered, removeTop4 ) | |||
|   EXPECT(orphans.empty()); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| TEST( BayesTreeOrdered, removeTop5 ) | ||||
| { | ||||
|   // Remove top called with variables that are not in the Bayes tree
 | ||||
|   SymbolicFactorGraph graph = list_of | ||||
|     (SymbolicFactor(L(5))) | ||||
|     (SymbolicFactor(X(4), L(5))) | ||||
|     (SymbolicFactor(X(2), X(4))) | ||||
|     (SymbolicFactor(X(3), X(2))); | ||||
|   SymbolicBayesTree bayesTree = *graph.eliminateMultifrontal( | ||||
|     Ordering(list_of (X(3)) (X(2)) (X(4)) (L(5)) )); | ||||
| 
 | ||||
|   // Remove nonexistant
 | ||||
|   SymbolicBayesNet bn; | ||||
|   SymbolicBayesTree::Cliques orphans; | ||||
|   bayesTree.removeTop(list_of(X(10)), bn, orphans); | ||||
| 
 | ||||
|   SymbolicBayesNet expectedBn; | ||||
|   EXPECT(assert_equal(expectedBn, bn)); | ||||
|   EXPECT(orphans.empty()); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| TEST( SymbolicBayesTree, thinTree ) { | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,132 @@ | |||
| /* ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  * 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    testISAM.cpp | ||||
|  * @brief   Unit tests for ISAM | ||||
|  * @author  Michael Kaess | ||||
|  */ | ||||
| 
 | ||||
| #include <boost/foreach.hpp> | ||||
| #include <boost/assign/std/list.hpp> // for operator += | ||||
| using namespace boost::assign; | ||||
| 
 | ||||
| #include <CppUnitLite/TestHarness.h> | ||||
| 
 | ||||
| #include <gtsam/symbolic/SymbolicISAM.h> | ||||
| #include <gtsam/symbolic/tests/symbolicExampleGraphs.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace gtsam; | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| // Some numbers that should be consistent among all smoother tests
 | ||||
| 
 | ||||
| //static double sigmax1 = 0.786153, sigmax2 = 0.687131 ,sigmax3 = 0.671512,
 | ||||
| //sigmax4 = 0.669534, sigmax5 = sigmax3,, sigmax7 = sigmax1, sigmax6 = sigmax2;
 | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| 
 | ||||
| //// SLAM example from RSS sqrtSAM paper
 | ||||
| //SymbolicConditional::shared_ptr x3(new SymbolicConditional("x3")),
 | ||||
| //    x2(new SymbolicConditional("x2","x3")),
 | ||||
| //    x1(new SymbolicConditional("x1","x2","x3")),
 | ||||
| //    l1(new SymbolicConditional("l1","x1","x2")),
 | ||||
| //    l2(new SymbolicConditional("l2","x1","x3"));
 | ||||
| //
 | ||||
| //// ISAM for sqrtSAM example
 | ||||
| //SymbolicISAM createSlamSymbolicISAM(){
 | ||||
| //  // Create using insert
 | ||||
| //  SymbolicISAM bayesTree_slam;
 | ||||
| //  bayesTree_slam.insert(x3);
 | ||||
| //  bayesTree_slam.insert(x2);
 | ||||
| //  bayesTree_slam.insert(x1);
 | ||||
| //  bayesTree_slam.insert(l2);
 | ||||
| //  bayesTree_slam.insert(l1);
 | ||||
| //  return bayesTree_slam;
 | ||||
| //}
 | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| 
 | ||||
| //// Conditionals for ASIA example from the tutorial with A and D evidence
 | ||||
| //SymbolicConditional::shared_ptr
 | ||||
| //  B(new SymbolicConditional("B")),
 | ||||
| //  L(new SymbolicConditional("L", "B")),
 | ||||
| //  E(new SymbolicConditional("E", "B", "L")),
 | ||||
| //  S(new SymbolicConditional("S", "L", "B")),
 | ||||
| //  T(new SymbolicConditional("T", "E", "L")),
 | ||||
| //  X(new SymbolicConditional("X", "E"));
 | ||||
| //
 | ||||
| //// ISAM for Asia example
 | ||||
| //SymbolicISAM createAsiaSymbolicISAM() {
 | ||||
| //  SymbolicISAM bayesTree;
 | ||||
| //  bayesTree.insert(B);
 | ||||
| //  bayesTree.insert(L);
 | ||||
| //  bayesTree.insert(E);
 | ||||
| //  bayesTree.insert(S);
 | ||||
| //  bayesTree.insert(T);
 | ||||
| //  bayesTree.insert(X);
 | ||||
| //  return bayesTree;
 | ||||
| //}
 | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| TEST( SymbolicISAM, iSAM ) | ||||
| { | ||||
|   // Now we modify the Bayes tree by inserting a new factor over B and S
 | ||||
| 
 | ||||
|   SymbolicFactorGraph fullGraph; | ||||
|   fullGraph += asiaGraph; | ||||
|   fullGraph += SymbolicFactor(_B_, _S_); | ||||
| 
 | ||||
|   // This ordering is chosen to match the one chosen by COLAMD during the ISAM update
 | ||||
|   SymbolicBayesTree expected = *fullGraph.eliminateMultifrontal(Ordering(list_of(_X_)(_B_)(_S_)(_E_)(_L_)(_T_))); | ||||
| 
 | ||||
|   // Add factor on B and S
 | ||||
|   SymbolicISAM actual = *asiaGraph.eliminateMultifrontal(); | ||||
| 
 | ||||
|   // Check whether the same
 | ||||
|   EXPECT(assert_equal(expected, (const SymbolicBayesTree&)actual)); | ||||
| } | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| //TEST( ISAM, iSAM_slam )
 | ||||
| //{
 | ||||
| //  // Create using insert
 | ||||
| //  SymbolicISAM bayesTree_slam = createSlamSymbolicISAM();
 | ||||
| //
 | ||||
| //  //New conditionals for the expected Bayes tree
 | ||||
| //  SymbolicConditional::shared_ptr
 | ||||
| //      l1_(new SymbolicConditional("l1","x1","x2","x3"));
 | ||||
| //
 | ||||
| //  // Create expected Bayes tree
 | ||||
| //  SymbolicISAM expected_slam;
 | ||||
| //  expected_slam.insert(x3);
 | ||||
| //  expected_slam.insert(x2);
 | ||||
| //  expected_slam.insert(x1);
 | ||||
| //  expected_slam.insert(l1_);
 | ||||
| //  expected_slam.insert(l2);
 | ||||
| //
 | ||||
| //
 | ||||
| //  // create new factors to be inserted
 | ||||
| //  SymbolicFactorGraph factorGraph_slam;
 | ||||
| //  factorGraph_slam.push_factor("x3","l1");
 | ||||
| //  factorGraph_slam.push_factor("x3");
 | ||||
| //
 | ||||
| //  // do incremental inference
 | ||||
| //  bayesTree_slam.update(factorGraph_slam);
 | ||||
| //
 | ||||
| //  // Check whether the same
 | ||||
| //  CHECK(assert_equal(expected_slam,bayesTree_slam));
 | ||||
| //}
 | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| int main() { TestResult tr; return TestRegistry::runAllTests(tr);} | ||||
| /* ************************************************************************* */ | ||||
		Loading…
	
		Reference in New Issue