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 <gtsam/base/Testable.h>
26 #include <gtsam/base/FastVector.h>
27 #include <gtsam/inference/Key.h>
28 
29 #include <Eigen/Core> // for Eigen::aligned_allocator
30 
31 #include <boost/serialization/nvp.hpp>
32 #include <boost/serialization/vector.hpp>
33 #include <boost/assign/list_inserter.hpp>
34 #include <boost/bind.hpp>
35 #include <boost/make_shared.hpp>
36 
37 #include <type_traits>
38 #include <utility>
39 
40 namespace gtsam {
41 
42  // Forward declarations
43  template<class CLIQUE> class BayesTree;
44 
46  template<class C>
48  {
49  C& obj;
50  public:
51  CRefCallPushBack(C& obj) : obj(obj) {}
52  template<typename A>
53  void operator()(const A& a) { obj.push_back(a); }
54  };
55 
57  template<class C>
59  {
60  C& obj;
61  public:
62  RefCallPushBack(C& obj) : obj(obj) {}
63  template<typename A>
64  void operator()(A& a) { obj.push_back(a); }
65  };
66 
68  template<class C>
70  {
71  C& obj;
72  public:
73  CRefCallAddCopy(C& obj) : obj(obj) {}
74  template<typename A>
75  void operator()(const A& a) { obj.addCopy(a); }
76  };
77 
83  template<class FACTOR>
84  class FactorGraph {
85 
86  public:
87  typedef FACTOR FactorType;
88  typedef boost::shared_ptr<FACTOR> sharedFactor;
89  typedef sharedFactor value_type;
90  typedef typename FastVector<sharedFactor>::iterator iterator;
91  typedef typename FastVector<sharedFactor>::const_iterator const_iterator;
92 
93  private:
94  typedef FactorGraph<FACTOR> This;
95  typedef boost::shared_ptr<This> shared_ptr;
96 
97  protected:
99  GTSAM_CONCEPT_TESTABLE_TYPE(FACTOR)
100 
101 
102  FastVector<sharedFactor> factors_;
103 
106 
109 
111  template<typename ITERATOR>
112  FactorGraph(ITERATOR firstFactor, ITERATOR lastFactor) { push_back(firstFactor, lastFactor); }
113 
115  template<class CONTAINER>
116  explicit FactorGraph(const CONTAINER& factors) { push_back(factors); }
117 
121 
122  // TODO: are these needed?
123 
125  // * @brief Constructor from a Bayes net
126  // * @param bayesNet the Bayes net to convert, type CONDITIONAL must yield compatible factor
127  // * @return a factor graph with all the conditionals, as factors
128  // */
129  //template<class CONDITIONAL>
130  //FactorGraph(const BayesNet<CONDITIONAL>& bayesNet);
131 
133  //template<class CONDITIONAL, class CLIQUE>
134  //FactorGraph(const BayesTree<CONDITIONAL, CLIQUE>& bayesTree);
135 
137  //template<class DERIVEDFACTOR>
138  //FactorGraph(const FactorGraph<DERIVEDFACTOR>& factors) {
139  // factors_.assign(factors.begin(), factors.end());
140  //}
141 
143 
144  public:
147 
152  void reserve(size_t size) { factors_.reserve(size); }
153 
154  // TODO: are these needed?
155 
157  template<class DERIVEDFACTOR>
158  typename std::enable_if<std::is_base_of<FactorType, DERIVEDFACTOR>::value>::type
159  push_back(boost::shared_ptr<DERIVEDFACTOR> factor) {
160  factors_.push_back(boost::shared_ptr<FACTOR>(factor)); }
161 
163  void push_back(const sharedFactor& factor) {
164  factors_.push_back(factor); }
165 
167  template<class DERIVEDFACTOR, class... Args>
168  typename std::enable_if<std::is_base_of<FactorType, DERIVEDFACTOR>::value>::type
169  emplace_shared(Args&&... args) {
170  factors_.push_back(boost::allocate_shared<DERIVEDFACTOR>(Eigen::aligned_allocator<DERIVEDFACTOR>(), std::forward<Args>(args)...));
171  }
172 
174  template<typename ITERATOR>
175  typename std::enable_if<std::is_base_of<FactorType, typename ITERATOR::value_type::element_type>::value>::type
176  push_back(ITERATOR firstFactor, ITERATOR lastFactor) {
177  factors_.insert(end(), firstFactor, lastFactor); }
178 
180  template<typename CONTAINER>
181  typename std::enable_if<std::is_base_of<FactorType, typename CONTAINER::value_type::element_type>::value>::type
182  push_back(const CONTAINER& container) {
183  push_back(container.begin(), container.end());
184  }
185 
188  template<class CLIQUE>
189  typename std::enable_if<std::is_base_of<This, typename CLIQUE::FactorGraphType>::value>::type
190  push_back(const BayesTree<CLIQUE>& bayesTree) {
191  bayesTree.addFactorsToGraph(*this);
192  }
193 
194 //#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V4
197  template<class DERIVEDFACTOR>
198  typename std::enable_if<std::is_base_of<FactorType, DERIVEDFACTOR>::value>::type
199  push_back(const DERIVEDFACTOR& factor) {
200  factors_.push_back(boost::allocate_shared<DERIVEDFACTOR>(Eigen::aligned_allocator<DERIVEDFACTOR>(), factor));
201  }
202 //#endif
203 
205  template<typename ITERATOR>
206  typename std::enable_if<std::is_base_of<FactorType, typename ITERATOR::value_type>::value>::type
207  push_back(ITERATOR firstFactor, ITERATOR lastFactor) {
208  for (ITERATOR f = firstFactor; f != lastFactor; ++f)
209  push_back(*f);
210  }
211 
213  template<typename CONTAINER>
214  typename std::enable_if<std::is_base_of<FactorType, typename CONTAINER::value_type>::value>::type
215  push_back(const CONTAINER& container) {
216  push_back(container.begin(), container.end());
217  }
218 
220  template<class DERIVEDFACTOR>
221  typename std::enable_if<std::is_base_of<FactorType, DERIVEDFACTOR>::value,
222  boost::assign::list_inserter<RefCallPushBack<This> > >::type
223  operator+=(boost::shared_ptr<DERIVEDFACTOR> factor) {
224  return boost::assign::make_list_inserter(RefCallPushBack<This>(*this))(factor);
225  }
226 
228  boost::assign::list_inserter<CRefCallPushBack<This> >
229  operator+=(const sharedFactor& factor) {
230  return boost::assign::make_list_inserter(CRefCallPushBack<This>(*this))(factor);
231  }
232 
234  template<class FACTOR_OR_CONTAINER>
235  boost::assign::list_inserter<CRefCallPushBack<This> >
236  operator+=(const FACTOR_OR_CONTAINER& factorOrContainer) {
237  return boost::assign::make_list_inserter(CRefCallPushBack<This>(*this))(factorOrContainer);
238  }
239 
241  template<class DERIVEDFACTOR>
242  typename std::enable_if<std::is_base_of<FactorType, DERIVEDFACTOR>::value>::type
243  add(boost::shared_ptr<DERIVEDFACTOR> factor) {
244  push_back(factor);
245  }
246 
248  void add(const sharedFactor& factor) {
249  push_back(factor);
250  }
251 
253  template<class FACTOR_OR_CONTAINER>
254  void add(const FACTOR_OR_CONTAINER& factorOrContainer) {
255  push_back(factorOrContainer);
256  }
257 
261 
263  void print(const std::string& s = "FactorGraph",
264  const KeyFormatter& formatter = DefaultKeyFormatter) const;
265 
267  bool equals(const This& fg, double tol = 1e-9) const;
269 
270  public:
273 
275  size_t size() const { return factors_.size(); }
276 
278  bool empty() const { return factors_.empty(); }
279 
283  const sharedFactor at(size_t i) const { return factors_.at(i); }
284 
288  sharedFactor& at(size_t i) { return factors_.at(i); }
289 
293  const sharedFactor operator[](size_t i) const { return at(i); }
294 
298  sharedFactor& operator[](size_t i) { return at(i); }
299 
301  const_iterator begin() const { return factors_.begin();}
302 
304  const_iterator end() const { return factors_.end(); }
305 
307  sharedFactor front() const { return factors_.front(); }
308 
310  sharedFactor back() const { return factors_.back(); }
311 
315 
317  iterator begin() { return factors_.begin();}
318 
320  iterator end() { return factors_.end(); }
321 
326  void resize(size_t size) { factors_.resize(size); }
327 
329  void remove(size_t i) { factors_[i].reset();}
330 
332  void replace(size_t index, sharedFactor factor) { at(index) = factor; }
333 
335  iterator erase(iterator item) { return factors_.erase(item); }
336 
338  iterator erase(iterator first, iterator last) { return factors_.erase(first, last); }
339 
343 
345  size_t nrFactors() const;
346 
348  KeySet keys() const;
349 
351  KeyVector keyVector() const;
352 
354  inline bool exists(size_t idx) const { return idx < size() && at(idx); }
355 
356  private:
357 
359  friend class boost::serialization::access;
360  template<class ARCHIVE>
361  void serialize(ARCHIVE & ar, const unsigned int /*version*/) {
362  ar & BOOST_SERIALIZATION_NVP(factors_);
363  }
364 
366 
367  }; // FactorGraph
368 
369 } // namespace gtsam
370 
371 #include <gtsam/inference/FactorGraph-inst.h>
void print(const std::string &s="FactorGraph", const KeyFormatter &formatter=DefaultKeyFormatter) const
print out graph
Definition: FactorGraph-inst.h:36
boost::assign::list_inserter< CRefCallPushBack< This > > operator+=(const sharedFactor &factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:229
std::enable_if< std::is_base_of< FactorType, typename ITERATOR::value_type >::value >::type push_back(ITERATOR firstFactor, ITERATOR lastFactor)
push back many factors with an iterator over plain factors (factors are copied)
Definition: FactorGraph.h:207
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:354
A thin wrapper around std::vector that uses a custom allocator.
iterator end()
non-const STL-style end()
Definition: FactorGraph.h:320
void resize(size_t size)
Directly resize the number of factors in the graph.
Definition: FactorGraph.h:326
std::enable_if< std::is_base_of< This, typename CLIQUE::FactorGraphType >::value >::type push_back(const BayesTree< CLIQUE > &bayesTree)
push back a BayesTree as a collection of factors.
Definition: FactorGraph.h:190
sharedFactor back() const
Get the last factor.
Definition: FactorGraph.h:310
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:236
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:298
void replace(size_t index, sharedFactor factor)
replace a factor by index
Definition: FactorGraph.h:332
sharedFactor front() const
Get the first factor.
Definition: FactorGraph.h:307
void addFactorsToGraph(FactorGraph< FactorType > &graph) const
Add all cliques in this BayesTree to the specified factor graph.
Definition: BayesTree-inst.h:157
bool empty() const
Check if the graph is empty (null factors set by remove() will cause this to return false).
Definition: FactorGraph.h:278
FactorGraph(ITERATOR firstFactor, ITERATOR lastFactor)
Constructor from iterator over factors (shared_ptr or plain objects)
Definition: FactorGraph.h:112
Definition: BayesTree.h:64
std::enable_if< std::is_base_of< FactorType, DERIVEDFACTOR >::value >::type emplace_shared(Args &&... args)
Emplace a factor.
Definition: FactorGraph.h:169
KeyVector keyVector() const
Potentially slow function to return all keys involved, sorted, as a vector.
Definition: FactorGraph-inst.h:86
const_iterator begin() const
Iterator to beginning of factors.
Definition: FactorGraph.h:301
Helper.
Definition: FactorGraph.h:58
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
FACTOR FactorType
factor type
Definition: FactorGraph.h:87
Helper.
Definition: FactorGraph.h:47
FactorGraph(const CONTAINER &factors)
Construct from container of factors (shared_ptr or plain objects)
Definition: FactorGraph.h:116
size_t nrFactors() const
return the number of non-null factors
Definition: FactorGraph-inst.h:66
void remove(size_t i)
delete factor without re-arranging indexes by inserting a NULL pointer
Definition: FactorGraph.h:329
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:56
A factor graph is a bipartite graph with factor nodes connected to variable nodes.
Definition: BayesTree.h:32
boost::shared_ptr< FACTOR > sharedFactor
Shared pointer to a factor.
Definition: FactorGraph.h:88
bool equals(const This &fg, double tol=1e-9) const
Check equality.
Definition: FactorGraph-inst.h:49
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:152
void add(const sharedFactor &factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:248
iterator erase(iterator item)
Erase factor and rearrange other factors to take up the empty space.
Definition: FactorGraph.h:335
Helper.
Definition: FactorGraph.h:69
FastVector< sharedFactor > factors_
concept check, makes sure FACTOR defines print and equals
Definition: FactorGraph.h:102
std::enable_if< std::is_base_of< FactorType, DERIVEDFACTOR >::value >::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:199
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:293
const_iterator end() const
Iterator to end of factors.
Definition: FactorGraph.h:304
std::enable_if< std::is_base_of< FactorType, typename ITERATOR::value_type::element_type >::value >::type push_back(ITERATOR firstFactor, ITERATOR lastFactor)
push back many factors with an iterator over shared_ptr (factors are not copied)
Definition: FactorGraph.h:176
sharedFactor & at(size_t i)
Get a specific factor by index (this checks array bounds and may throw an exception,...
Definition: FactorGraph.h:288
KeySet keys() const
Potentially slow function to return all keys involved, sorted, as a set.
Definition: FactorGraph-inst.h:75
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
std::enable_if< std::is_base_of< FactorType, typename CONTAINER::value_type::element_type >::value >::type push_back(const CONTAINER &container)
push back many factors as shared_ptr's in a container (factors are not copied)
Definition: FactorGraph.h:182
Concept check for values that can be used in unit tests.
const sharedFactor at(size_t i) const
Get a specific factor by index (this checks array bounds and may throw an exception,...
Definition: FactorGraph.h:283
void push_back(const sharedFactor &factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:163
std::enable_if< std::is_base_of< FactorType, DERIVEDFACTOR >::value, boost::assign::list_inserter< RefCallPushBack< This > > >::type operator+=(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:223
std::enable_if< std::is_base_of< FactorType, DERIVEDFACTOR >::value >::type add(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:243
iterator begin()
non-const STL-style begin()
Definition: FactorGraph.h:317
std::enable_if< std::is_base_of< FactorType, typename CONTAINER::value_type >::value >::type push_back(const CONTAINER &container)
push back many factors as non-pointer objects in a container (factors are copied)
Definition: FactorGraph.h:215
void add(const FACTOR_OR_CONTAINER &factorOrContainer)
Add a factor or container of factors, including STL collections, BayesTrees, etc.
Definition: FactorGraph.h:254
iterator erase(iterator first, iterator last)
Erase factors and rearrange other factors to take up the empty space.
Definition: FactorGraph.h:338
std::enable_if< std::is_base_of< FactorType, DERIVEDFACTOR >::value >::type push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:159
size_t size() const
return the number of factors (including any null factors set by remove() ).
Definition: FactorGraph.h:275