gtsam
Loading...
Searching...
No Matches
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
16
17#pragma once
18
22#include <gtsam/base/timing.h>
23
24#include <vector>
25
26namespace gtsam {
27
28 /* ************************************************************************* */
29 template<class DERIVED, class FACTORGRAPH>
31 const typename FactorGraphType::EliminationResult& eliminationResult)
32 {
33 conditional_ = eliminationResult.first;
34 }
35
36 /* ************************************************************************* */
37 template<class DERIVED, class FACTORGRAPH>
39 const DERIVED& other, double tol) const
40 {
41 return (!conditional_ && !other.conditional())
42 || conditional_->equals(*other.conditional(), tol);
43 }
44
45 /* ************************************************************************* */
46 template<class DERIVED, class FACTORGRAPH>
49 {
50 KeySet p_F_S_parents(this->conditional()->beginParents(), this->conditional()->endParents());
51 KeySet indicesB(B->conditional()->begin(), B->conditional()->end());
52 KeyVector S_setminus_B;
53 std::set_difference(p_F_S_parents.begin(), p_F_S_parents.end(),
54 indicesB.begin(), indicesB.end(), std::back_inserter(S_setminus_B));
55 return S_setminus_B;
56 }
57
58 /* ************************************************************************* */
59 template<class DERIVED, class FACTORGRAPH>
61 const derived_ptr& B, const FactorGraphType& p_Cp_B) const
62 {
63 gttic(shortcut_indices);
64 KeySet allKeys = p_Cp_B.keys();
65 KeySet indicesB(B->conditional()->begin(), B->conditional()->end());
66 KeyVector S_setminus_B = separator_setminus_B(B);
67 KeyVector keep;
68 // keep = S\B intersect allKeys (S_setminus_B is already sorted)
69 std::set_intersection(S_setminus_B.begin(), S_setminus_B.end(), //
70 allKeys.begin(), allKeys.end(), std::back_inserter(keep));
71 // keep += B intersect allKeys
72 std::set_intersection(indicesB.begin(), indicesB.end(), //
73 allKeys.begin(), allKeys.end(), std::back_inserter(keep));
74 return keep;
75 }
76
77 /* ************************************************************************* */
78 template<class DERIVED, class FACTORGRAPH>
80 const std::string& s, const KeyFormatter& keyFormatter) const
81 {
82 conditional_->print(s, keyFormatter);
83 }
84
85 /* ************************************************************************* */
86 template<class DERIVED, class FACTORGRAPH>
88 size_t size = 1;
89 for(const derived_ptr& child: children)
90 size += child->treeSize();
91 return size;
92 }
93
94 /* ************************************************************************* */
95 template<class DERIVED, class FACTORGRAPH>
97 {
98 std::lock_guard<std::mutex> marginalLock(cachedSeparatorMarginalMutex_);
100 return 0;
101
102 size_t subtree_count = 1;
103 for(const derived_ptr& child: children)
104 subtree_count += child->numCachedSeparatorMarginals();
105
106 return subtree_count;
107 }
108
109 /* ************************************************************************* */
110 // The shortcut density is a conditional P(S|B) of the separator of this
111 // clique on the root or common ancestor B. We can compute it recursively from
112 // the parent shortcut P(Sp|B) as \int P(Fp|Sp) P(Sp|B), where Fp are the
113 // frontal nodes in the parent p, and Sp the separator of the parent.
114 /* *************************************************************************
115 */
116 template <class DERIVED, class FACTORGRAPH>
117 typename BayesTreeCliqueBase<DERIVED, FACTORGRAPH>::BayesNetType
119 const derived_ptr& B, Eliminate function) const {
120 gttic(BayesTreeCliqueBase_shortcut);
121 // We only calculate the shortcut when this clique is not B
122 // and when the S\B is not empty
123 KeyVector S_setminus_B = separator_setminus_B(B);
124 if (!parent_.expired() /*(if we're not the root)*/ && !S_setminus_B.empty())
125 {
126 // Obtain P(Cp||B) = P(Fp|Sp) * P(Sp||B) as a factor graph
127 derived_ptr parent(parent_.lock());
128 FactorGraphType p_Cp_B(parent->shortcut(B, function)); // P(Sp||B)
129 p_Cp_B.push_back(parent->conditional_); // P(Fp|Sp)
130
131 // Determine the variables we want to keep, S union B
132 KeyVector keep = shortcut_indices(B, p_Cp_B);
133
134 // Marginalize out everything except S union B
135 std::shared_ptr<FactorGraphType> p_S_B = p_Cp_B.marginal(keep, function);
136 return *p_S_B->eliminatePartialSequential(S_setminus_B, function).first;
137 }
138 else
139 {
140 return BayesNetType();
141 }
142 }
143
144 /* *********************************************************************** */
145 // Separator marginal, using cached separator marginals of ancestors
146 // Calculates P(S) = \int P(Cp) = \int P(Fp|Sp) P(Sp)
147 // if P(Sp) is not cached, it walks to the nearest cached ancestor.
148 // Here again, Fp and Sp are the frontal nodes and separator in the parent p.
149 /* *********************************************************************** */
150 template <class DERIVED, class FACTORGRAPH>
151 typename BayesTreeCliqueBase<DERIVED, FACTORGRAPH>::FactorGraphType
153 Eliminate function) const {
154 gttic(BayesTreeCliqueBase_separatorMarginal);
156 // Lock the leaf-to-root path, then fill uncached separator marginals from
157 // root to leaf. This preserves the recursive implementation's locking
158 // semantics without consuming stack space for deep Bayes-tree chains.
159 std::vector<const This*> path;
160 std::vector<derived_ptr> keepAlive;
161 std::vector<std::unique_lock<std::mutex>> locks;
162 const This* clique = this;
163 while (true) {
164 path.push_back(clique);
165 locks.emplace_back(clique->cachedSeparatorMarginalMutex_);
166 if (clique->cachedSeparatorMarginal_) {
167 break;
168 }
169
170 derived_ptr parent = clique->parent_.lock();
171 if (!parent) {
172 break;
173 }
174 keepAlive.push_back(parent);
175 clique = parent.get();
176 }
178 for (auto it = path.rbegin(); it != path.rend(); ++it) {
179 const This* clique = *it;
180 if (clique->cachedSeparatorMarginal_) {
181 continue;
182 }
184 derived_ptr parent = clique->parent_.lock();
185 if (!parent) {
186 FactorGraphType empty;
187 clique->cachedSeparatorMarginal_ = empty;
188 continue;
189 }
190
191 // Obtain P(S) = \int P(Cp) = \int P(Fp|Sp) P(Sp).
192 FactorGraphType p_Cp(*parent->cachedSeparatorMarginal_);
193 p_Cp.push_back(parent->conditional_);
194
195 // The variables we want to keep are exactly the ones in S.
196 KeyVector indicesS(clique->conditional()->beginParents(),
197 clique->conditional()->endParents());
198 auto separatorMarginal =
199 p_Cp.marginalMultifrontalBayesNet(Ordering(indicesS), function);
201 }
202
203 return *cachedSeparatorMarginal_;
204 }
205
206 /* *********************************************************************** */
207 // marginal2, uses separator marginal of parent
208 // P(C) = P(F|S) P(S)
209 /* *********************************************************************** */
210 template <class DERIVED, class FACTORGRAPH>
211 typename BayesTreeCliqueBase<DERIVED, FACTORGRAPH>::FactorGraphType
213 Eliminate function) const {
214 gttic(BayesTreeCliqueBase_marginal2);
215 // initialize with separator marginal P(S)
216 FactorGraphType p_C = this->separatorMarginal(function);
217 // add the conditional P(F|S)
218 p_C.push_back(std::shared_ptr<FactorType>(this->conditional_));
219 return p_C;
220 }
221
222 /* ************************************************************************* */
223 template<class DERIVED, class FACTORGRAPH>
225
226 // When a shortcut is requested, all of the shortcuts between it and the
227 // root are also generated. So, if this clique's cached shortcut is set,
228 // recursively call over all child cliques. Otherwise, it is unnecessary.
229
230 std::lock_guard<std::mutex> marginalLock(cachedSeparatorMarginalMutex_);
232 for(derived_ptr& child: children) {
233 child->deleteCachedShortcuts();
234 }
235
236 //Delete CachedShortcut for this clique
238 }
239
240 }
241
242}
Timing utilities.
Base class for cliques of a BayesTree.
Variable ordering for the elimination algorithm.
Factor Graph Base Class.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition Key.h:91
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition Key.h:35
Template to create a binary predicate.
Definition Testable.h:112
derived_ptr parent() const
Definition BayesTreeCliqueBase.h:161
size_t treeSize() const
The size of subtree rooted at this clique, i.e., nr of Cliques.
Definition BayesTreeCliqueBase-inst.h:87
std::mutex cachedSeparatorMarginalMutex_
This protects Cached seperator marginal P(S) from concurrent read/writes as many the functions which ...
Definition BayesTreeCliqueBase.h:109
FactorGraphType marginal2(Eliminate function=EliminationTraitsType::DefaultEliminate) const
return the marginal P(C) of the clique, using marginal caching
Definition BayesTreeCliqueBase-inst.h:212
bool equals(const DERIVED &other, double tol=1e-9) const
check equality
Definition BayesTreeCliqueBase-inst.h:38
FactorGraphType separatorMarginal(Eliminate function=EliminationTraitsType::DefaultEliminate) const
return the marginal P(S) on the separator
Definition BayesTreeCliqueBase-inst.h:152
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:118
void deleteCachedShortcuts()
This deletes the cached shortcuts of all cliques (subtree) below this clique.
Definition BayesTreeCliqueBase-inst.h:224
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:60
const sharedConditional & conditional() const
Access the conditional.
Definition BayesTreeCliqueBase.h:140
KeyVector separator_setminus_B(const derived_ptr &B) const
Calculate set for shortcut calculations.
Definition BayesTreeCliqueBase-inst.h:48
virtual void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print this node
Definition BayesTreeCliqueBase-inst.h:79
size_t numCachedSeparatorMarginals() const
Collect number of cliques with cached separator marginals.
Definition BayesTreeCliqueBase-inst.h:96
std::optional< FactorGraphType > cachedSeparatorMarginal_
This stores the Cached separator marginal P(S).
Definition BayesTreeCliqueBase.h:104
void setEliminationResult(const typename FactorGraphType::EliminationResult &eliminationResult)
Fill the elimination result produced during elimination.
Definition BayesTreeCliqueBase-inst.h:30
Definition Ordering.h:33