/* ---------------------------------------------------------------------------- * 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 namespace gtsam { // Forward declarations template class BayesTree; class VariableIndex; /** * A factor graph is a bipartite graph with factor nodes connected to variable nodes. * In this class, however, only factor nodes are kept around. * \nosubgrouping */ template class FactorGraph { public: typedef FACTOR FactorType; ///< factor type typedef typename FACTOR::KeyType KeyType; ///< type of Keys we use to index variables with typedef boost::shared_ptr sharedFactor; ///< Shared pointer to a factor typedef boost::shared_ptr sharedConditional; ///< Shared pointer to a conditional typedef FactorGraph This; ///< Typedef for this class typedef boost::shared_ptr shared_ptr; ///< Shared pointer for this class typedef typename std::vector::iterator iterator; typedef typename std::vector::const_iterator const_iterator; /** typedef for elimination result */ typedef std::pair EliminationResult; /** typedef for an eliminate subroutine */ typedef boost::function Eliminate; protected: /** concept check, makes sure FACTOR defines print and equals */ GTSAM_CONCEPT_TESTABLE_TYPE(FACTOR) /** Collection of factors */ std::vector factors_; public: /// @name Standard Constructor /// @{ /** Default constructor */ FactorGraph() {} /// @} /// @name Advanced Constructors /// @{ /** * @brief Constructor from a Bayes net * @param bayesNet the Bayes net to convert, type CONDITIONAL must yield compatible factor * @return a factor graph with all the conditionals, as factors */ template FactorGraph(const BayesNet& bayesNet); /** convert from Bayes tree */ template FactorGraph(const BayesTree& bayesTree); /** convert from a derived type */ template FactorGraph(const FactorGraph& factors) { factors_.assign(factors.begin(), factors.end()); } /// @} /// @name Adding Factors /// @{ /** * Reserve space for the specified number of factors if you know in * advance how many there will be (works like std::vector::reserve). */ void reserve(size_t size) { factors_.reserve(size); } /** Add a factor */ template void push_back(const boost::shared_ptr& factor) { factors_.push_back(boost::shared_ptr(factor)); } /** push back many factors */ void push_back(const This& factors) { factors_.insert(end(), factors.begin(), factors.end()); } /** push back many factors with an iterator */ template void push_back(ITERATOR firstFactor, ITERATOR lastFactor) { factors_.insert(end(), firstFactor, lastFactor); } /** * @brief Add a vector of derived factors * @param factors to add */ template void push_back(const std::vector >& factors) { factors_.insert(end(), factors.begin(), factors.end()); } /// @} /// @name Testable /// @{ /** print out graph */ void print(const std::string& s = "FactorGraph", const IndexFormatter& formatter = DefaultIndexFormatter) const; /** Check equality */ bool equals(const This& fg, double tol = 1e-9) const; /// @} /// @name Standard Interface /// @{ /** return the number of factors and NULLS */ size_t size() const { return factors_.size();} /** Simple check for an empty graph - faster than comparing size() to zero */ bool empty() const { return factors_.empty(); } /** const cast to the underlying vector of factors */ operator const std::vector&() const { return factors_; } /** Get a specific factor by index */ const sharedFactor at(size_t i) const { assert(i > eliminateFrontals(size_t nFrontals, const Eliminate& eliminate) const; /** Factor the factor graph into a conditional and a remaining factor graph. * Given the factor graph \f$ f(X) \f$, and \c variables to factorize out * \f$ V \f$, this function factorizes into \f$ f(X) = f(V;Y)f(Y) \f$, where * \f$ Y := X\V \f$ are the remaining variables. If \f$ f(X) = p(X) \f$ is * a probability density or likelihood, the factorization produces a * conditional probability density and a marginal \f$ p(X) = p(V|Y)p(Y) \f$. * * For efficiency, this function treats the variables to eliminate * \c variables as fully-connected, so produces a dense (fully-connected) * conditional on all of the variables in \c variables, instead of a sparse * BayesNet. If the variables are not fully-connected, it is more efficient * to sequentially factorize multiple times. */ std::pair > eliminate( const std::vector& variables, const Eliminate& eliminateFcn, boost::optional variableIndex = boost::none) const; /** Eliminate a single variable, by calling FactorGraph::eliminate. */ std::pair > eliminateOne( KeyType variable, const Eliminate& eliminateFcn, boost::optional variableIndex = boost::none) const { std::vector variables(1, variable); return eliminate(variables, eliminateFcn, variableIndex); } /// @} /// @name Modifying Factor Graphs (imperative, discouraged) /// @{ /** non-const STL-style begin() */ iterator begin() { return factors_.begin();} /** non-const STL-style end() */ iterator end() { return factors_.end(); } /** resize the factor graph. TODO: effects? */ void resize(size_t size) { factors_.resize(size); } /** delete factor without re-arranging indexes by inserting a NULL pointer */ inline void remove(size_t i) { factors_[i].reset();} /** replace a factor by index */ void replace(size_t index, sharedFactor factor); /// @} /// @name Advanced Interface /// @{ /** return the number valid factors */ size_t nrFactors() const; /** Potentially very slow function to return all keys involved */ std::set keys() const; private: /** Serialization function */ friend class boost::serialization::access; template void serialize(ARCHIVE & ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(factors_); } /// @} }; // FactorGraph /** Create a combined joint factor (new style for EliminationTree). */ template typename DERIVEDFACTOR::shared_ptr Combine(const FactorGraph& factors, const FastMap >& variableSlots); /** * static function that combines two factor graphs * @param fg1 Linear factor graph * @param fg2 Linear factor graph * @return a new combined factor graph */ template FACTORGRAPH combine(const FACTORGRAPH& fg1, const FACTORGRAPH& fg2); } // namespace gtsam #include