gtsam  3.2.1
gtsam
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BayesTreeCliqueBase-inst.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 
17 #pragma once
18 
20 #include <gtsam/base/timing.h>
21 #include <boost/foreach.hpp>
22 
23 namespace gtsam {
24 
25  /* ************************************************************************* */
26  template<class DERIVED, class FACTORGRAPH>
28  const typename FactorGraphType::EliminationResult& eliminationResult)
29  {
30  conditional_ = eliminationResult.first;
31  }
32 
33  /* ************************************************************************* */
34  template<class DERIVED, class FACTORGRAPH>
36  const DERIVED& other, double tol) const
37  {
38  return (!conditional_ && !other.conditional())
39  || conditional_->equals(*other.conditional(), tol);
40  }
41 
42  /* ************************************************************************* */
43  template<class DERIVED, class FACTORGRAPH>
46  {
47  FastSet<Key> p_F_S_parents(this->conditional()->beginParents(), this->conditional()->endParents());
48  FastSet<Key> indicesB(B->conditional()->begin(), B->conditional()->end());
49  FastVector<Key> S_setminus_B;
50  std::set_difference(p_F_S_parents.begin(), p_F_S_parents.end(),
51  indicesB.begin(), indicesB.end(), back_inserter(S_setminus_B));
52  return S_setminus_B;
53  }
54 
55  /* ************************************************************************* */
56  template<class DERIVED, class FACTORGRAPH>
58  const derived_ptr& B, const FactorGraphType& p_Cp_B) const
59  {
60  gttic(shortcut_indices);
61  FastSet<Key> allKeys = p_Cp_B.keys();
62  FastSet<Key> indicesB(B->conditional()->begin(), B->conditional()->end());
63  FastVector<Key> S_setminus_B = separator_setminus_B(B);
64  FastVector<Key> keep;
65  // keep = S\B intersect allKeys (S_setminus_B is already sorted)
66  std::set_intersection(S_setminus_B.begin(), S_setminus_B.end(), //
67  allKeys.begin(), allKeys.end(), back_inserter(keep));
68  // keep += B intersect allKeys
69  std::set_intersection(indicesB.begin(), indicesB.end(), //
70  allKeys.begin(), allKeys.end(), back_inserter(keep));
71  return keep;
72  }
73 
74  /* ************************************************************************* */
75  template<class DERIVED, class FACTORGRAPH>
77  const std::string& s, const KeyFormatter& keyFormatter) const
78  {
79  conditional_->print(s, keyFormatter);
80  }
81 
82  /* ************************************************************************* */
83  template<class DERIVED, class FACTORGRAPH>
85  size_t size = 1;
86  BOOST_FOREACH(const derived_ptr& child, children)
87  size += child->treeSize();
88  return size;
89  }
90 
91  /* ************************************************************************* */
92  template<class DERIVED, class FACTORGRAPH>
94  {
95  if (!cachedSeparatorMarginal_)
96  return 0;
97 
98  size_t subtree_count = 1;
99  BOOST_FOREACH(const derived_ptr& child, children)
100  subtree_count += child->numCachedSeparatorMarginals();
101 
102  return subtree_count;
103  }
104 
105  /* ************************************************************************* */
106  // The shortcut density is a conditional P(S|R) of the separator of this
107  // clique on the root. We can compute it recursively from the parent shortcut
108  // P(Sp|R) as \int P(Fp|Sp) P(Sp|R), where Fp are the frontal nodes in p
109  /* ************************************************************************* */
110  template<class DERIVED, class FACTORGRAPH>
111  typename BayesTreeCliqueBase<DERIVED, FACTORGRAPH>::BayesNetType
112  BayesTreeCliqueBase<DERIVED, FACTORGRAPH>::shortcut(const derived_ptr& B, Eliminate function) const
113  {
114  gttic(BayesTreeCliqueBase_shortcut);
115  // We only calculate the shortcut when this clique is not B
116  // and when the S\B is not empty
117  FastVector<Key> S_setminus_B = separator_setminus_B(B);
118  if (!parent_.expired() /*(if we're not the root)*/ && !S_setminus_B.empty())
119  {
120  // Obtain P(Cp||B) = P(Fp|Sp) * P(Sp||B) as a factor graph
121  derived_ptr parent(parent_.lock());
122  gttoc(BayesTreeCliqueBase_shortcut);
123  FactorGraphType p_Cp_B(parent->shortcut(B, function)); // P(Sp||B)
124  gttic(BayesTreeCliqueBase_shortcut);
125  p_Cp_B += parent->conditional_; // P(Fp|Sp)
126 
127  // Determine the variables we want to keepSet, S union B
128  FastVector<Key> keep = shortcut_indices(B, p_Cp_B);
129 
130  // Marginalize out everything except S union B
131  boost::shared_ptr<FactorGraphType> p_S_B = p_Cp_B.marginal(keep, function);
132  return *p_S_B->eliminatePartialSequential(S_setminus_B, function).first;
133  }
134  else
135  {
136  return BayesNetType();
137  }
138  }
139 
140  /* ************************************************************************* */
141  // separator marginal, uses separator marginal of parent recursively
142  // P(C) = P(F|S) P(S)
143  /* ************************************************************************* */
144  template<class DERIVED, class FACTORGRAPH>
145  typename BayesTreeCliqueBase<DERIVED, FACTORGRAPH>::FactorGraphType
147  {
148  gttic(BayesTreeCliqueBase_separatorMarginal);
149  // Check if the Separator marginal was already calculated
150  if (!cachedSeparatorMarginal_)
151  {
152  gttic(BayesTreeCliqueBase_separatorMarginal_cachemiss);
153  // If this is the root, there is no separator
154  if (parent_.expired() /*(if we're the root)*/)
155  {
156  // we are root, return empty
157  FactorGraphType empty;
158  cachedSeparatorMarginal_ = empty;
159  }
160  else
161  {
162  // Obtain P(S) = \int P(Cp) = \int P(Fp|Sp) P(Sp)
163  // initialize P(Cp) with the parent separator marginal
164  derived_ptr parent(parent_.lock());
165  gttoc(BayesTreeCliqueBase_separatorMarginal_cachemiss); // Flatten recursion in timing outline
166  gttoc(BayesTreeCliqueBase_separatorMarginal);
167  FactorGraphType p_Cp(parent->separatorMarginal(function)); // P(Sp)
168  gttic(BayesTreeCliqueBase_separatorMarginal);
169  gttic(BayesTreeCliqueBase_separatorMarginal_cachemiss);
170  // now add the parent conditional
171  p_Cp += parent->conditional_; // P(Fp|Sp)
172 
173  // The variables we want to keepSet are exactly the ones in S
174  FastVector<Key> indicesS(this->conditional()->beginParents(), this->conditional()->endParents());
175  cachedSeparatorMarginal_ = *p_Cp.marginalMultifrontalBayesNet(Ordering(indicesS), boost::none, function);
176  }
177  }
178 
179  // return the shortcut P(S||B)
180  return *cachedSeparatorMarginal_; // return the cached version
181  }
182 
183  /* ************************************************************************* */
184  // marginal2, uses separator marginal of parent recursively
185  // P(C) = P(F|S) P(S)
186  /* ************************************************************************* */
187  template<class DERIVED, class FACTORGRAPH>
188  typename BayesTreeCliqueBase<DERIVED, FACTORGRAPH>::FactorGraphType
190  {
191  gttic(BayesTreeCliqueBase_marginal2);
192  // initialize with separator marginal P(S)
193  FactorGraphType p_C = this->separatorMarginal(function);
194  // add the conditional P(F|S)
195  p_C += boost::shared_ptr<FactorType>(this->conditional_);
196  return p_C;
197  }
198 
199  /* ************************************************************************* */
200  template<class DERIVED, class FACTORGRAPH>
202 
203  // When a shortcut is requested, all of the shortcuts between it and the
204  // root are also generated. So, if this clique's cached shortcut is set,
205  // recursively call over all child cliques. Otherwise, it is unnecessary.
206  if (cachedSeparatorMarginal_) {
207  BOOST_FOREACH(derived_ptr& child, children) {
208  child->deleteCachedShortcuts();
209  }
210 
211  //Delete CachedShortcut for this clique
212  cachedSeparatorMarginal_ = boost::none;
213  }
214 
215  }
216 
217 }
void setEliminationResult(const typename FactorGraphType::EliminationResult &eliminationResult)
Fill the elimination result produced during elimination.
Definition: BayesTreeCliqueBase-inst.h:27
void deleteCachedShortcuts()
This deletes the cached shortcuts of all cliques (subtree) below this clique.
Definition: BayesTreeCliqueBase-inst.h:201
FastVector< Key > shortcut_indices(const derived_ptr &B, const FactorGraphType &p_Cp_B) const
Determine variable indices to keep in recursive separator shortcut calculation The factor graph p_Cp_...
Definition: BayesTreeCliqueBase-inst.h:57
Timing utilities.
bool equals(const DERIVED &other, double tol=1e-9) const
check equality
Definition: BayesTreeCliqueBase-inst.h:35
Base class for cliques of a BayesTree.
size_t treeSize() const
The size of subtree rooted at this clique, i.e., nr of Cliques.
Definition: BayesTreeCliqueBase-inst.h:84
FastVector< Key > separator_setminus_B(const derived_ptr &B) const
Calculate set for shortcut calculations.
Definition: BayesTreeCliqueBase-inst.h:45
FactorGraphType marginal2(Eliminate function=EliminationTraitsType::DefaultEliminate) const
return the marginal P(C) of the clique, using marginal caching
Definition: BayesTreeCliqueBase-inst.h:189
size_t numCachedSeparatorMarginals() const
Collect number of cliques with cached separator marginals.
Definition: BayesTreeCliqueBase-inst.h:93
Definition: Ordering.h:30
FactorGraphType separatorMarginal(Eliminate function=EliminationTraitsType::DefaultEliminate) const
return the marginal P(S) on the separator
Definition: BayesTreeCliqueBase-inst.h:146
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print this node
Definition: BayesTreeCliqueBase-inst.h:76
boost::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: types.h:62
BayesNetType shortcut(const derived_ptr &root, Eliminate function=EliminationTraitsType::DefaultEliminate) const
return the conditional P(S|Root) on the separator given the root
Definition: BayesTreeCliqueBase-inst.h:112