gtsam  4.0.0
gtsam
FactorGraph.h
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
21 // \callgraph
22 
23 #pragma once
24 
25 #include <boost/serialization/nvp.hpp>
26 #include <boost/assign/list_inserter.hpp>
27 #include <boost/bind.hpp>
28 #include <boost/make_shared.hpp>
29 #include <boost/utility/enable_if.hpp>
30 #include <boost/type_traits.hpp>
31 
32 #include <gtsam/base/Testable.h>
33 #include <gtsam/base/FastVector.h>
34 #include <gtsam/inference/Key.h>
35 
36 namespace gtsam {
37 
38  // Forward declarations
39  template<class CLIQUE> class BayesTree;
40 
42  template<class C>
44  {
45  C& obj;
46  public:
47  CRefCallPushBack(C& obj) : obj(obj) {}
48  template<typename A>
49  void operator()(const A& a) { obj.push_back(a); }
50  };
51 
53  template<class C>
55  {
56  C& obj;
57  public:
58  RefCallPushBack(C& obj) : obj(obj) {}
59  template<typename A>
60  void operator()(A& a) { obj.push_back(a); }
61  };
62 
64  template<class C>
66  {
67  C& obj;
68  public:
69  CRefCallAddCopy(C& obj) : obj(obj) {}
70  template<typename A>
71  void operator()(const A& a) { obj.addCopy(a); }
72  };
73 
79  template<class FACTOR>
80  class FactorGraph {
81 
82  public:
83  typedef FACTOR FactorType;
84  typedef boost::shared_ptr<FACTOR> sharedFactor;
85  typedef sharedFactor value_type;
86  typedef typename FastVector<sharedFactor>::iterator iterator;
87  typedef typename FastVector<sharedFactor>::const_iterator const_iterator;
88 
89  private:
90  typedef FactorGraph<FACTOR> This;
91  typedef boost::shared_ptr<This> shared_ptr;
92 
93  protected:
95  GTSAM_CONCEPT_TESTABLE_TYPE(FACTOR)
96 
97 
98  FastVector<sharedFactor> factors_;
99 
102 
105 
107  template<typename ITERATOR>
108  FactorGraph(ITERATOR firstFactor, ITERATOR lastFactor) { push_back(firstFactor, lastFactor); }
109 
111  template<class CONTAINER>
112  explicit FactorGraph(const CONTAINER& factors) { push_back(factors); }
113 
117 
118  // TODO: are these needed?
119 
121  // * @brief Constructor from a Bayes net
122  // * @param bayesNet the Bayes net to convert, type CONDITIONAL must yield compatible factor
123  // * @return a factor graph with all the conditionals, as factors
124  // */
125  //template<class CONDITIONAL>
126  //FactorGraph(const BayesNet<CONDITIONAL>& bayesNet);
127 
129  //template<class CONDITIONAL, class CLIQUE>
130  //FactorGraph(const BayesTree<CONDITIONAL, CLIQUE>& bayesTree);
131 
133  //template<class DERIVEDFACTOR>
134  //FactorGraph(const FactorGraph<DERIVEDFACTOR>& factors) {
135  // factors_.assign(factors.begin(), factors.end());
136  //}
137 
139 
140  public:
143 
148  void reserve(size_t size) { factors_.reserve(size); }
149 
150  // TODO: are these needed?
151 
153  template<class DERIVEDFACTOR>
154  typename boost::enable_if<boost::is_base_of<FactorType, DERIVEDFACTOR> >::type
155  push_back(boost::shared_ptr<DERIVEDFACTOR> factor) {
156  factors_.push_back(boost::shared_ptr<FACTOR>(factor)); }
157 
159  void push_back(const sharedFactor& factor) {
160  factors_.push_back(factor); }
161 
163  template<typename ITERATOR>
164  typename boost::enable_if<boost::is_base_of<FactorType, typename ITERATOR::value_type::element_type> >::type
165  push_back(ITERATOR firstFactor, ITERATOR lastFactor) {
166  factors_.insert(end(), firstFactor, lastFactor); }
167 
169  template<typename CONTAINER>
170  typename boost::enable_if<boost::is_base_of<FactorType, typename CONTAINER::value_type::element_type> >::type
171  push_back(const CONTAINER& container) {
172  push_back(container.begin(), container.end());
173  }
174 
177  template<class CLIQUE>
178  typename boost::enable_if<boost::is_base_of<This, typename CLIQUE::FactorGraphType> >::type
179  push_back(const BayesTree<CLIQUE>& bayesTree) {
180  bayesTree.addFactorsToGraph(*this);
181  }
182 
185  template<class DERIVEDFACTOR>
186  typename boost::enable_if<boost::is_base_of<FactorType, DERIVEDFACTOR> >::type
187  push_back(const DERIVEDFACTOR& factor) {
188  factors_.push_back(boost::make_shared<DERIVEDFACTOR>(factor));
189  }
190 
192  template<typename ITERATOR>
193  typename boost::enable_if<boost::is_base_of<FactorType, typename ITERATOR::value_type> >::type
194  push_back(ITERATOR firstFactor, ITERATOR lastFactor) {
195  for (ITERATOR f = firstFactor; f != lastFactor; ++f)
196  push_back(*f);
197  }
198 
200  template<typename CONTAINER>
201  typename boost::enable_if<boost::is_base_of<FactorType, typename CONTAINER::value_type> >::type
202  push_back(const CONTAINER& container) {
203  push_back(container.begin(), container.end());
204  }
205 
207  template<class DERIVEDFACTOR>
208  typename boost::enable_if<boost::is_base_of<FactorType, DERIVEDFACTOR>,
209  boost::assign::list_inserter<RefCallPushBack<This> > >::type
210  operator+=(boost::shared_ptr<DERIVEDFACTOR> factor) {
211  return boost::assign::make_list_inserter(RefCallPushBack<This>(*this))(factor);
212  }
213 
215  boost::assign::list_inserter<CRefCallPushBack<This> >
216  operator+=(const sharedFactor& factor) {
217  return boost::assign::make_list_inserter(CRefCallPushBack<This>(*this))(factor);
218  }
219 
221  template<class FACTOR_OR_CONTAINER>
222  boost::assign::list_inserter<CRefCallPushBack<This> >
223  operator+=(const FACTOR_OR_CONTAINER& factorOrContainer) {
224  return boost::assign::make_list_inserter(CRefCallPushBack<This>(*this))(factorOrContainer);
225  }
226 
228  template<class DERIVEDFACTOR>
229  typename boost::enable_if<boost::is_base_of<FactorType, DERIVEDFACTOR> >::type
230  add(boost::shared_ptr<DERIVEDFACTOR> factor) {
231  push_back(factor);
232  }
233 
235  void add(const sharedFactor& factor) {
236  push_back(factor);
237  }
238 
240  template<class FACTOR_OR_CONTAINER>
241  void add(const FACTOR_OR_CONTAINER& factorOrContainer) {
242  push_back(factorOrContainer);
243  }
244 
248 
250  void print(const std::string& s = "FactorGraph",
251  const KeyFormatter& formatter = DefaultKeyFormatter) const;
252 
254  bool equals(const This& fg, double tol = 1e-9) const;
256 
257  public:
260 
262  size_t size() const { return factors_.size(); }
263 
265  bool empty() const { return factors_.empty(); }
266 
270  const sharedFactor at(size_t i) const { return factors_.at(i); }
271 
275  sharedFactor& at(size_t i) { return factors_.at(i); }
276 
280  const sharedFactor operator[](size_t i) const { return at(i); }
281 
285  sharedFactor& operator[](size_t i) { return at(i); }
286 
288  const_iterator begin() const { return factors_.begin();}
289 
291  const_iterator end() const { return factors_.end(); }
292 
294  sharedFactor front() const { return factors_.front(); }
295 
297  sharedFactor back() const { return factors_.back(); }
298 
302 
304  iterator begin() { return factors_.begin();}
305 
307  iterator end() { return factors_.end(); }
308 
313  void resize(size_t size) { factors_.resize(size); }
314 
316  void remove(size_t i) { factors_[i].reset();}
317 
319  void replace(size_t index, sharedFactor factor) { at(index) = factor; }
320 
322  iterator erase(iterator item) { return factors_.erase(item); }
323 
325  iterator erase(iterator first, iterator last) { return factors_.erase(first, last); }
326 
330 
332  size_t nrFactors() const;
333 
335  KeySet keys() const;
336 
338  KeyVector keyVector() const;
339 
341  inline bool exists(size_t idx) const { return idx < size() && at(idx); }
342 
343  private:
344 
346  friend class boost::serialization::access;
347  template<class ARCHIVE>
348  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
349  ar & BOOST_SERIALIZATION_NVP(factors_);
350  }
351 
353 
354  }; // FactorGraph
355 
356 } // namespace gtsam
357 
358 #include <gtsam/inference/FactorGraph-inst.h>
void addFactorsToGraph(FactorGraph< FactorType > &graph) const
Add all cliques in this BayesTree to the specified factor graph.
Definition: BayesTree-inst.h:155
const sharedFactor operator[](size_t i) const
Get a specific factor by index (this does not check array bounds, as opposed to at() which does)...
Definition: FactorGraph.h:280
boost::enable_if< boost::is_base_of< FactorType, DERIVEDFACTOR > >::type add(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:230
sharedFactor & operator[](size_t i)
Get a specific factor by index (this does not check array bounds, as opposed to at() which does)...
Definition: FactorGraph.h:285
FactorGraph(ITERATOR firstFactor, ITERATOR lastFactor)
Constructor from iterator over factors (shared_ptr or plain objects)
Definition: FactorGraph.h:108
boost::enable_if< boost::is_base_of< FactorType, DERIVEDFACTOR >, boost::assign::list_inserter< RefCallPushBack< This > > >::type operator+=(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:210
bool exists(size_t idx) const
MATLAB interface utility: Checks whether a factor index idx exists in the graph and is a live pointer...
Definition: FactorGraph.h:341
void print(const Matrix &A, const string &s, ostream &stream)
print without optional string, must specify cout yourself
Definition: Matrix.cpp:140
sharedFactor back() const
Get the last factor.
Definition: FactorGraph.h:297
void push_back(const sharedFactor &factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:159
void replace(size_t index, sharedFactor factor)
replace a factor by index
Definition: FactorGraph.h:319
boost::enable_if< boost::is_base_of< FactorType, typename ITERATOR::value_type::element_type > >::type push_back(ITERATOR firstFactor, ITERATOR lastFactor)
push back many factors with an iterator over shared_ptr (factors are not copied)
Definition: FactorGraph.h:165
boost::enable_if< boost::is_base_of< FactorType, typename CONTAINER::value_type::element_type > >::type push_back(const CONTAINER &container)
push back many factors as shared_ptr&#39;s in a container (factors are not copied)
Definition: FactorGraph.h:171
sharedFactor front() const
Get the first factor.
Definition: FactorGraph.h:294
Definition: BayesTree.h:64
iterator end()
non-const STL-style end()
Definition: FactorGraph.h:307
boost::assign::list_inserter< CRefCallPushBack< This > > operator+=(const sharedFactor &factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:216
boost::enable_if< boost::is_base_of< FactorType, typename ITERATOR::value_type > >::type push_back(ITERATOR firstFactor, ITERATOR lastFactor)
push back many factors with an iterator over plain factors (factors are copied)
Definition: FactorGraph.h:194
Helper.
Definition: FactorGraph.h:43
Definition: FastVector.h:36
iterator begin()
non-const STL-style begin()
Definition: FactorGraph.h:304
void resize(size_t size)
Directly resize the number of factors in the graph.
Definition: FactorGraph.h:313
Template to create a binary predicate.
Definition: Testable.h:110
Helper.
Definition: FactorGraph.h:54
const_iterator end() const
Iterator to end of factors.
Definition: FactorGraph.h:291
bool empty() const
Check if the graph is empty (null factors set by remove() will cause this to return false)...
Definition: FactorGraph.h:265
void reserve(size_t size)
Reserve space for the specified number of factors if you know in advance how many there will be (work...
Definition: FactorGraph.h:148
boost::enable_if< boost::is_base_of< FactorType, DERIVEDFACTOR > >::type push_back(const DERIVEDFACTOR &factor)
Add a factor by value, will be copy-constructed (use push_back with a shared_ptr to avoid the copy)...
Definition: FactorGraph.h:187
void add(const FACTOR_OR_CONTAINER &factorOrContainer)
Add a factor or container of factors, including STL collections, BayesTrees, etc. ...
Definition: FactorGraph.h:241
boost::shared_ptr< FACTOR > sharedFactor
Shared pointer to a factor.
Definition: FactorGraph.h:84
boost::enable_if< boost::is_base_of< FactorType, DERIVEDFACTOR > >::type push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:155
Helper.
Definition: FactorGraph.h:65
FactorGraph(const CONTAINER &factors)
Construct from container of factors (shared_ptr or plain objects)
Definition: FactorGraph.h:112
const_iterator begin() const
Iterator to beginning of factors.
Definition: FactorGraph.h:288
A factor graph is a bipartite graph with factor nodes connected to variable nodes.
Definition: BayesTree.h:32
size_t size() const
return the number of factors (including any null factors set by remove() ).
Definition: FactorGraph.h:262
FACTOR FactorType
factor type
Definition: FactorGraph.h:83
sharedFactor & at(size_t i)
Get a specific factor by index (this checks array bounds and may throw an exception, as opposed to operator[] which does not).
Definition: FactorGraph.h:275
void add(const sharedFactor &factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:235
boost::enable_if< boost::is_base_of< This, typename CLIQUE::FactorGraphType > >::type push_back(const BayesTree< CLIQUE > &bayesTree)
push back a BayesTree as a collection of factors.
Definition: FactorGraph.h:179
boost::assign::list_inserter< CRefCallPushBack< This > > operator+=(const FACTOR_OR_CONTAINER &factorOrContainer)
Add a factor or container of factors, including STL collections, BayesTrees, etc. ...
Definition: FactorGraph.h:223
const sharedFactor at(size_t i) const
Get a specific factor by index (this checks array bounds and may throw an exception, as opposed to operator[] which does not).
Definition: FactorGraph.h:270
A thin wrapper around std::vector that uses boost&#39;s pool_allocator.
iterator erase(iterator first, iterator last)
Erase factors and rearrange other factors to take up the empty space.
Definition: FactorGraph.h:325
boost::enable_if< boost::is_base_of< FactorType, typename CONTAINER::value_type > >::type push_back(const CONTAINER &container)
push back many factors as non-pointer objects in a container (factors are copied) ...
Definition: FactorGraph.h:202
iterator erase(iterator item)
Erase factor and rearrange other factors to take up the empty space.
Definition: FactorGraph.h:322
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
boost::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: Key.h:33
Concept check for values that can be used in unit tests.