/* ---------------------------------------------------------------------------- * 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 FactorGraph.h * @brief Factor Graph Base Class * @author Carlos Nieto * @author Christian Potthast * @author Michael Kaess */ // \callgraph #pragma once #include #include #include #include #include #include #include #include namespace gtsam { /** * A factor graph is a bipartite graph with factor nodes connected to variable nodes. * In this class, however, only factor nodes are kept around. * * Templated on the type of factors and values structure. */ template class FactorGraph: public Testable > { public: typedef FACTOR Factor; typedef boost::shared_ptr > shared_ptr; typedef typename boost::shared_ptr sharedFactor; typedef typename std::vector::iterator iterator; typedef typename std::vector::const_iterator const_iterator; protected: /** Collection of factors */ std::vector factors_; public: /** ------------------ Creating Factor Graphs ---------------------------- */ /** Default constructor */ FactorGraph() {} /** convert from Bayes net */ template FactorGraph(const BayesNet& bayesNet); /** convert from a derived type */ template FactorGraph(const FactorGraph& factorGraph); /** Add a factor */ template void push_back(const boost::shared_ptr& factor); /** push back many factors */ void push_back(const FactorGraph& factors); /** push back many factors with an iterator */ template void push_back(ITERATOR firstFactor, ITERATOR lastFactor); /** ------------------ Querying Factor Graphs ---------------------------- */ /** print out graph */ void print(const std::string& s = "FactorGraph") const; /** Check equality */ bool equals(const FactorGraph& fg, double tol = 1e-9) const; /** const cast to the underlying vector of factors */ operator const std::vector&() const { return factors_; } /** STL begin and end, so we can use BOOST_FOREACH */ const_iterator begin() const { return factors_.begin();} const_iterator end() const { return factors_.end(); } /** Get a specific factor by index */ sharedFactor operator[](size_t i) const { assert(i void serialize(ARCHIVE & ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(factors_); } }; // FactorGraph /** * static function that combines two factor graphs * @param const &fg1 Linear factor graph * @param const &fg2 Linear factor graph * @return a new combined factor graph */ template FACTORGRAPH combine(const FACTORGRAPH& fg1, const FACTORGRAPH& fg2); /** * These functions are defined here because they are templated on an * additional parameter. Putting them in the -inl.h file would mean these * would have to be explicitly instantiated for any possible derived factor * type. */ /* ************************************************************************* */ template template FactorGraph::FactorGraph(const FactorGraph& factorGraph) { factors_.reserve(factorGraph.size()); BOOST_FOREACH(const typename DERIVEDFACTOR::shared_ptr& factor, factorGraph) { if(factor) this->push_back(factor); else this->push_back(sharedFactor()); } } /* ************************************************************************* */ template template FactorGraph::FactorGraph(const BayesNet& bayesNet) { factors_.reserve(bayesNet.size()); BOOST_FOREACH(const typename CONDITIONAL::shared_ptr& cond, bayesNet) { this->push_back(sharedFactor(new FACTOR(*cond))); } } /* ************************************************************************* */ template template inline void FactorGraph::push_back(const boost::shared_ptr& factor) { #ifndef NDEBUG factors_.push_back(boost::dynamic_pointer_cast(factor)); // add the actual factor #else factors_.push_back(boost::static_pointer_cast(factor)); #endif } /* ************************************************************************* */ template template void FactorGraph::push_back(ITERATOR firstFactor, ITERATOR lastFactor) { ITERATOR factor = firstFactor; while(factor != lastFactor) this->push_back(*(factor++)); } } // namespace gtsam