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