23#include <unordered_map>
24#include <unordered_set>
29#include "gtsam/dllexport.h"
38template <
typename BayesTree>
68 static std::unordered_set<Key>
72 const bool debug = ISDEBUG(
"BayesTreeMarginalizationHelper");
74 std::unordered_set<const Clique*> additionalCliques =
77 std::unordered_set<Key> additionalKeys;
78 for (
const Clique* clique : additionalCliques) {
83 std::cout <<
"BayesTreeMarginalizationHelper: Additional keys to re-eliminate: ";
84 for (
const Key& key : additionalKeys) {
87 std::cout << std::endl;
90 return additionalKeys;
99 static std::unordered_set<const Clique*>
103 std::unordered_set<const Clique*> additionalCliques;
104 std::unordered_set<Key> marginalizableKeySet(
105 marginalizableKeys.begin(), marginalizableKeys.end());
109 for (
const Clique* clique :
111 if (additionalCliques.count(clique)) {
120 additionalCliques.insert(clique);
127 return additionalCliques;
139 const std::unordered_set<Key>& keysOfInterest) {
140 std::unordered_set<const Clique*> cliques;
141 const auto& nodes = bayesTree.
nodes();
142 for (
const Key& key : keysOfInterest) {
147 const auto node = nodes.find(key);
148 if (node == nodes.end()) {
153 throw std::out_of_range(
155 "' has no clique in the Bayes tree.");
157 cliques.insert(node->second.get());
166 std::unordered_map<const Clique*, bool> wholeMarginalizableCliques;
167 std::unordered_map<const Clique*, bool> wholeMarginalizableSubtrees;
176 const Clique* clique,
177 const std::unordered_set<Key>& marginalizableKeys,
179 auto it = cache->wholeMarginalizableCliques.find(clique);
180 if (it != cache->wholeMarginalizableCliques.end()) {
184 for (
Key key : clique->conditional()->frontals()) {
185 if (!marginalizableKeys.count(key)) {
190 cache->wholeMarginalizableCliques.insert({clique, ret});
201 const Clique* subtree,
202 const std::unordered_set<Key>& marginalizableKeys,
204 auto it = cache->wholeMarginalizableSubtrees.find(subtree);
205 if (it != cache->wholeMarginalizableSubtrees.end()) {
210 for (
const sharedClique& child : subtree->children) {
219 cache->wholeMarginalizableSubtrees.insert({subtree, ret});
233 const Clique* clique,
234 const std::unordered_set<Key>& marginalizableKeys,
236 bool hasNonMarginalizableAhead =
false;
239 for (
Key key : clique->conditional()->frontals()) {
240 if (marginalizableKeys.count(key)) {
243 if (hasNonMarginalizableAhead) {
249 for (
const sharedClique& child : clique->children) {
256 hasNonMarginalizableAhead =
true;
270 const Clique* rootClique,
271 const std::unordered_set<Key>& marginalizableKeys,
272 std::unordered_set<const Clique*>* additionalCliques,
274 std::vector<const Clique*> dependentChildren;
275 dependentChildren.reserve(rootClique->children.size());
276 for (
const sharedClique& child : rootClique->children) {
277 if (additionalCliques->count(child.get())) {
284 dependentChildren.push_back(child.get());
288 dependentChildren, marginalizableKeys, additionalCliques, cache);
295 const std::vector<const Clique*>& dependentChildren,
296 const std::unordered_set<Key>& marginalizableKeys,
297 std::unordered_set<const Clique*>* additionalCliques,
299 std::deque<const Clique*> descendants(
300 dependentChildren.begin(), dependentChildren.end());
301 while (!descendants.empty()) {
302 const Clique* descendant = descendants.front();
303 descendants.pop_front();
309 additionalCliques->insert(descendant);
312 for (
const sharedClique& child : descendant->children) {
313 if (additionalCliques->count(child.get())) {
317 descendants.push_back(child.get());
331 const Clique* clique,
332 std::unordered_set<Key>* additionalKeys) {
333 for (
Key key : clique->conditional()->frontals()) {
334 additionalKeys->insert(key);
346 const Clique* clique,
Key key) {
347 auto& conditional = clique->conditional();
348 if (std::find(conditional->beginParents(),
349 conditional->endParents(), key)
350 != conditional->endParents()) {
361 const Clique* clique,
const std::unordered_set<Key>& keys) {
362 auto& conditional = clique->conditional();
363 for (
auto it = conditional->beginParents();
364 it != conditional->endParents(); ++it) {
365 if (keys.count(*it)) {
Base class for cliques of a BayesTree.
Bayes Tree is a tree of cliques of a Bayes Chain.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
KeyFormatter DefaultKeyFormatter
Assign default key formatter.
Definition Key.cpp:30
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition Key.h:91
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
Bayes tree.
Definition BayesTree.h:77
std::shared_ptr< Clique > sharedClique
Shared pointer to a clique.
Definition BayesTree.h:84
const Nodes & nodes() const
Return nodes.
Definition BayesTree.h:157
CLIQUE Clique
The clique type, normally BayesTreeClique.
Definition BayesTree.h:83
This class provides helper functions for marginalizing variables from a Bayes Tree.
Definition BayesTreeMarginalizationHelper.h:39
static bool hasDependency(const Clique *clique, Key key)
Check if the clique depends on the given key.
Definition BayesTreeMarginalizationHelper.h:345
static std::unordered_set< const Clique * > gatherAdditionalCliquesToReEliminate(const BayesTree &bayesTree, const KeyVector &marginalizableKeys)
This function identifies cliques that need to be re-eliminated before performing marginalization.
Definition BayesTreeMarginalizationHelper.h:100
static bool hasDependency(const Clique *clique, const std::unordered_set< Key > &keys)
Check if the clique depends on any of the given keys.
Definition BayesTreeMarginalizationHelper.h:360
static std::unordered_set< Key > gatherAdditionalKeysToReEliminate(const BayesTree &bayesTree, const KeyVector &marginalizableKeys)
This function identifies variables that need to be re-eliminated before performing marginalization.
Definition BayesTreeMarginalizationHelper.h:69
static bool isWholeSubtreeMarginalizable(const Clique *subtree, const std::unordered_set< Key > &marginalizableKeys, CachedSearch *cache)
Check if all variables in the subtree are marginalizable.
Definition BayesTreeMarginalizationHelper.h:200
static void gatherDependentCliques(const Clique *rootClique, const std::unordered_set< Key > &marginalizableKeys, std::unordered_set< const Clique * > *additionalCliques, CachedSearch *cache)
Gather all dependent nodes that lie on a path from the root clique to a clique containing a non-margi...
Definition BayesTreeMarginalizationHelper.h:269
static void gatherDependentCliquesFromChildren(const std::vector< const Clique * > &dependentChildren, const std::unordered_set< Key > &marginalizableKeys, std::unordered_set< const Clique * > *additionalCliques, CachedSearch *cache)
A helper function for the above gatherDependentCliques().
Definition BayesTreeMarginalizationHelper.h:294
static void addCliqueToKeySet(const Clique *clique, std::unordered_set< Key > *additionalKeys)
Add all frontal variables from a clique to a key set.
Definition BayesTreeMarginalizationHelper.h:330
static std::unordered_set< const Clique * > getCliquesContainingKeys(const BayesTree &bayesTree, const std::unordered_set< Key > &keysOfInterest)
Gather the cliques containing any of the given keys.
Definition BayesTreeMarginalizationHelper.h:137
static bool needsReelimination(const Clique *clique, const std::unordered_set< Key > &marginalizableKeys, CachedSearch *cache)
Check if a clique contains variables that need reelimination due to elimination ordering conflicts.
Definition BayesTreeMarginalizationHelper.h:232
static bool isWholeCliqueMarginalizable(const Clique *clique, const std::unordered_set< Key > &marginalizableKeys, CachedSearch *cache)
Check if all variables in the clique are marginalizable.
Definition BayesTreeMarginalizationHelper.h:175
A struct to cache the results of the below two functions.
Definition BayesTreeMarginalizationHelper.h:165