28#include <boost/optional.hpp>
29#include <boost/assign/list_of.hpp>
32using boost::assign::cref_list_of;
37 template<
class CLIQUE>
40 for (
const sharedClique& root : roots_) getCliqueData(root, &stats);
45 template <
class CLIQUE>
48 const auto conditional = clique->conditional();
49 stats->conditionalSizes.push_back(conditional->nrFrontals());
50 stats->separatorSizes.push_back(conditional->nrParents());
52 getCliqueData(c, stats);
57 template<
class CLIQUE>
61 count += root->numCachedSeparatorMarginals();
66 template<
class CLIQUE>
68 if (roots_.empty())
throw std::invalid_argument(
"the root of Bayes tree has not been initialized!");
69 std::ofstream of(s.c_str());
72 saveGraph(of, root, keyFormatter);
78 template<
class CLIQUE>
82 std::stringstream out;
84 std::string parent = out.str();
85 parent +=
"[label=\"";
87 for (
Key index : clique->conditional_->frontals()) {
88 if (!first) parent +=
",";
90 parent += indexFormatter(index);
93 if (clique->parent()) {
95 s << parentnum <<
"->" << num <<
"\n";
99 for (
Key sep : clique->conditional_->parents()) {
100 if (!first) parent +=
",";
102 parent += indexFormatter(sep);
110 saveGraph(s, c, indexFormatter, parentnum);
115 template<
class CLIQUE>
119 size += clique->treeSize();
124 template<
class CLIQUE>
126 for(
Key j: clique->conditional()->frontals())
128 if (parent_clique !=
nullptr) {
129 clique->parent_ = parent_clique;
130 parent_clique->children.push_back(clique);
132 roots_.push_back(clique);
138 template <
class FACTOR,
class CLIQUE>
139 struct _pushCliqueFunctor {
142 int operator()(
const boost::shared_ptr<CLIQUE>& clique,
int dummy) {
143 graph->push_back(clique->conditional_);
150 template <
class CLIQUE>
155 _pushCliqueFunctor<FactorType, CLIQUE> functor(graph);
160 template<
class CLIQUE>
167 template<
typename NODE>
168 boost::shared_ptr<NODE>
169 BayesTreeCloneForestVisitorPre(
const boost::shared_ptr<NODE>& node,
const boost::shared_ptr<NODE>& parentPointer)
172 boost::shared_ptr<NODE> clone = boost::make_shared<NODE>(*node);
173 clone->children.clear();
174 clone->parent_ = parentPointer;
175 parentPointer->children.push_back(clone);
181 template<
class CLIQUE>
184 boost::shared_ptr<Clique> rootContainer = boost::make_shared<Clique>();
186 for(
const sharedClique& root: rootContainer->children) {
187 root->parent_ =
typename Clique::weak_ptr();
194 template<
class CLIQUE>
196 std::cout << s <<
": cliques: " << size() <<
", variables: " << nodes_.size() << std::endl;
202 template<
class CLIQUE>
203 bool check_sharedCliques(
207 return v1.first == v2.first &&
208 ((!v1.second && !v2.second) || (v1.second && v2.second && v1.second->equals(*v2.second)));
212 template<
class CLIQUE>
214 return size()==other.
size() &&
215 std::equal(nodes_.begin(), nodes_.end(), other.
nodes_.begin(), &check_sharedCliques<CLIQUE>);
219 template<
class CLIQUE>
220 template<
class CONTAINER>
222 typename CONTAINER::const_iterator lowestOrderedParent = min_element(parents.begin(), parents.end());
223 assert(lowestOrderedParent != parents.end());
224 return *lowestOrderedParent;
228 template<
class CLIQUE>
231 for(
const Key& j: subtree->conditional()->frontals()) {
232 bool inserted = nodes_.insert(std::make_pair(j, subtree)).second;
233 assert(inserted); (void)inserted;
237 for(
const sharedClique& child: subtree->children) {
238 fillNodesIndex(child); }
242 template<
class CLIQUE>
244 roots_.push_back(subtree);
245 fillNodesIndex(subtree);
251 template<
class CLIQUE>
252 typename BayesTree<CLIQUE>::sharedConditional
255 gttic(BayesTree_marginalFactor);
261 FactorGraphType cliqueMarginal = clique->marginal2(function);
264 BayesNetType marginalBN = *cliqueMarginal.marginalMultifrontalBayesNet(
265 Ordering(cref_list_of<1,Key>(j)), function);
268 return marginalBN.front();
274 template<
class CLIQUE>
275 typename BayesTree<CLIQUE>::sharedFactorGraph
278 gttic(BayesTree_joint);
279 return boost::make_shared<FactorGraphType>(*jointBayesNet(j1, j2, function));
283 template<
class CLIQUE>
284 typename BayesTree<CLIQUE>::sharedBayesNet
287 gttic(BayesTree_jointBayesNet);
291 gttic(Lowest_common_ancestor);
312 while(p1 != path1.end() && p2 != path2.end() && *p1 == *p2) {
318 gttoc(Lowest_common_ancestor);
321 FactorGraphType p_BC1C2;
327 FactorGraphType p_B = B->marginal2(function);
331 gttic(Clique_shortcuts);
332 BayesNetType p_C1_Bred = C1->shortcut(B, function);
333 BayesNetType p_C2_Bred = C2->shortcut(B, function);
334 gttoc(Clique_shortcuts);
338 gttic(Full_root_factoring);
339 boost::shared_ptr<typename EliminationTraitsType::BayesTreeType> p_C1_B; {
341 KeySet C1_minus_B_set(C1->conditional()->beginParents(), C1->conditional()->endParents());
342 for(
const Key j: *B->conditional()) {
343 C1_minus_B_set.erase(j); }
344 C1_minus_B.assign(C1_minus_B_set.begin(), C1_minus_B_set.end());
347 sharedFactorGraph temp_remaining;
348 boost::tie(p_C1_B, temp_remaining) =
349 FactorGraphType(p_C1_Bred).eliminatePartialMultifrontal(
Ordering(C1_minus_B), function);
351 boost::shared_ptr<typename EliminationTraitsType::BayesTreeType> p_C2_B; {
353 KeySet C2_minus_B_set(C2->conditional()->beginParents(), C2->conditional()->endParents());
354 for(
const Key j: *B->conditional()) {
355 C2_minus_B_set.erase(j); }
356 C2_minus_B.assign(C2_minus_B_set.begin(), C2_minus_B_set.end());
359 sharedFactorGraph temp_remaining;
360 boost::tie(p_C2_B, temp_remaining) =
361 FactorGraphType(p_C2_Bred).eliminatePartialMultifrontal(
Ordering(C2_minus_B), function);
363 gttoc(Full_root_factoring);
365 gttic(Variable_joint);
370 p_BC1C2 += C1->conditional();
372 p_BC1C2 += C2->conditional();
373 gttoc(Variable_joint);
379 gttic(Disjoint_marginals);
380 p_BC1C2 += C1->marginal2(function);
381 p_BC1C2 += C2->marginal2(function);
382 gttoc(Disjoint_marginals);
386 return p_BC1C2.marginalMultifrontalBayesNet(
Ordering(cref_list_of<2,Key>(j1)(j2)), function);
390 template<
class CLIQUE>
398 template<
class CLIQUE>
401 root->deleteCachedShortcuts();
406 template<
class CLIQUE>
409 if (clique->isRoot()) {
410 typename Roots::iterator root = std::find(roots_.begin(), roots_.end(), clique);
411 if(root != roots_.end())
415 typename Roots::iterator child = std::find(parent->children.begin(), parent->children.end(), clique);
416 assert(child != parent->children.end());
417 parent->children.erase(child);
422 child->parent_ =
typename Clique::weak_ptr();
424 for(
Key j: clique->conditional()->frontals()) {
425 nodes_.unsafe_erase(j);
430 template <
class CLIQUE>
436 orphans->remove(clique);
439 this->removeClique(clique);
442 this->removePath(
typename Clique::shared_ptr(clique->parent_.lock()), bn,
447 orphans->insert(orphans->begin(), clique->children.begin(),
448 clique->children.end());
449 clique->children.clear();
451 bn->push_back(clique->conditional_);
457 template <
class CLIQUE>
462 for (
const Key& j : keys) {
465 typename Nodes::const_iterator node = nodes_.find(j);
466 if (node != nodes_.end()) {
468 this->removePath(node->second, bn, orphans);
474 for (
sharedClique& orphan : *orphans) orphan->deleteCachedShortcuts();
478 template<
class CLIQUE>
484 cliques.push_back(subtree);
487 if(!subtree->isRoot())
488 subtree->parent()->children.erase(std::find(
489 subtree->parent()->children.begin(), subtree->parent()->children.end(), subtree));
491 roots_.erase(std::find(roots_.begin(), roots_.end(), subtree));
494 for(
typename Cliques::iterator clique = cliques.begin(); clique != cliques.end(); ++clique)
498 cliques.push_back(child); }
501 (*clique)->deleteCachedShortcutsNonRecursive();
504 for(
Key j: (*clique)->conditional()->frontals()) {
505 nodes_.unsafe_erase(j); }
508 (*clique)->parent_.reset();
509 (*clique)->children.clear();
Bayes Tree is a tree of cliques of a Bayes Chain.
Variable ordering for the elimination algorithm.
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:86
bool equal(const T &obj1, const T &obj2, double tol)
Call equal on the object.
Definition: Testable.h:84
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:69
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
void DepthFirstForest(FOREST &forest, DATA &rootData, VISITOR_PRE &visitorPre, VISITOR_POST &visitorPost)
Traverse a forest depth-first with pre-order and post-order visits.
Definition: treeTraversal-inst.h:77
void PrintForest(const FOREST &forest, std::string str, const KeyFormatter &keyFormatter)
Print a tree, prefixing each line with str, and formatting keys using keyFormatter.
Definition: treeTraversal-inst.h:219
Definition: FastList.h:40
A factor graph is a bipartite graph with factor nodes connected to variable nodes.
Definition: FactorGraph.h:93
store all the sizes
Definition: BayesTree.h:48
Definition: BayesTree.h:67
Nodes nodes_
Map from indices to Clique.
Definition: BayesTree.h:100
void removeClique(sharedClique clique)
remove a clique: warning, can result in a forest
Definition: BayesTree-inst.h:407
sharedFactorGraph joint(Key j1, Key j2, const Eliminate &function=EliminationTraitsType::DefaultEliminate) const
return joint on two variables Limitation: can only calculate joint if cliques are disjoint or one of ...
Definition: BayesTree-inst.h:276
void fillNodesIndex(const sharedClique &subtree)
Fill the nodes index for a subtree.
Definition: BayesTree-inst.h:229
void addFactorsToGraph(FactorGraph< FactorType > *graph) const
Add all cliques in this BayesTree to the specified factor graph.
Definition: BayesTree-inst.h:151
bool equals(const This &other, double tol=1e-9) const
check equality
Definition: BayesTree-inst.h:213
void saveGraph(const std::string &s, const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Read only with side effects.
Definition: BayesTree-inst.h:67
This & operator=(const This &other)
Assignment operator.
Definition: BayesTree-inst.h:182
boost::shared_ptr< Clique > sharedClique
Shared pointer to a clique.
Definition: BayesTree.h:74
BayesTree()
Create an empty Bayes Tree.
Definition: BayesTree.h:109
void clear()
Remove all nodes.
Definition: BayesTree-inst.h:391
void addClique(const sharedClique &clique, const sharedClique &parent_clique=sharedClique())
add a clique (top down)
Definition: BayesTree-inst.h:125
sharedBayesNet jointBayesNet(Key j1, Key j2, const Eliminate &function=EliminationTraitsType::DefaultEliminate) const
return joint on two variables as a BayesNet Limitation: can only calculate joint if cliques are disjo...
Definition: BayesTree-inst.h:285
Key findParentClique(const CONTAINER &parents) const
Find parent clique of a conditional.
Definition: BayesTree-inst.h:221
size_t size() const
number of cliques
Definition: BayesTree-inst.h:116
void deleteCachedShortcuts()
Clear all shortcut caches - use before timing on marginal calculation to avoid residual cache data.
Definition: BayesTree-inst.h:399
void removePath(sharedClique clique, BayesNetType *bn, Cliques *orphans)
Remove path from clique to root and return that path as factors plus a list of orphaned subtree roots...
Definition: BayesTree-inst.h:431
sharedConditional marginalFactor(Key j, const Eliminate &function=EliminationTraitsType::DefaultEliminate) const
Return marginal on any variable.
Definition: BayesTree-inst.h:253
size_t numCachedSeparatorMarginals() const
Collect number of cliques with cached separator marginals.
Definition: BayesTree-inst.h:58
BayesTreeCliqueData getCliqueData() const
Gather data on all cliques.
Definition: BayesTree-inst.h:38
Cliques removeSubtree(const sharedClique &subtree)
Remove the requested subtree.
Definition: BayesTree-inst.h:479
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print
Definition: BayesTree-inst.h:195
void insertRoot(const sharedClique &subtree)
Insert a new subtree with known parent clique.
Definition: BayesTree-inst.h:243
void removeTop(const KeyVector &keys, BayesNetType *bn, Cliques *orphans)
Given a list of indices, turn "contaminated" part of the tree back into a factor graph.
Definition: BayesTree-inst.h:458
Definition: Ordering.h:34