28 #include <boost/optional.hpp> 29 #include <boost/assign/list_of.hpp> 32 using boost::assign::cref_list_of;
37 template<
class CLIQUE>
41 getCliqueData(data, root);
46 template<
class CLIQUE>
48 data.conditionalSizes.push_back(clique->conditional()->nrFrontals());
49 data.separatorSizes.push_back(clique->conditional()->nrParents());
51 getCliqueData(data, c);
56 template<
class CLIQUE>
60 count += root->numCachedSeparatorMarginals();
65 template<
class CLIQUE>
67 if (roots_.empty())
throw std::invalid_argument(
"the root of Bayes tree has not been initialized!");
68 std::ofstream of(s.c_str());
71 saveGraph(of, root, keyFormatter);
77 template<
class CLIQUE>
81 std::stringstream out;
83 std::string parent = out.str();
84 parent +=
"[label=\"";
86 for(
Key index: clique->conditional_->frontals()) {
87 if(!first) parent +=
","; first =
false;
88 parent += indexFormatter(index);
93 s << parentnum <<
"->" << num <<
"\n";
97 for(
Key sep: clique->conditional_->parents()) {
98 if(!first) parent +=
","; first =
false;
99 parent += indexFormatter(sep);
107 saveGraph(s, c, indexFormatter, parentnum);
112 template<
class CLIQUE>
116 size += clique->treeSize();
121 template<
class CLIQUE>
123 for(
Key j: clique->conditional()->frontals())
125 if (parent_clique != NULL) {
126 clique->parent_ = parent_clique;
127 parent_clique->children.push_back(clique);
129 roots_.push_back(clique);
136 template<
class FACTOR,
class CLIQUE>
142 template<
class FACTOR,
class CLIQUE>
143 struct _pushCliqueFunctor {
146 int operator()(
const boost::shared_ptr<CLIQUE>& clique,
int dummy) {
154 template<
class CLIQUE>
159 _pushCliqueFunctor<FactorType,CLIQUE> functor(graph);
165 template<
class CLIQUE>
172 template<
typename NODE>
173 boost::shared_ptr<NODE>
174 BayesTreeCloneForestVisitorPre(
const boost::shared_ptr<NODE>& node,
const boost::shared_ptr<NODE>& parentPointer)
177 boost::shared_ptr<NODE> clone = boost::make_shared<NODE>(*node);
178 clone->children.
clear();
179 clone->parent_ = parentPointer;
180 parentPointer->children.push_back(clone);
186 template<
class CLIQUE>
189 boost::shared_ptr<Clique> rootContainer = boost::make_shared<Clique>();
191 for(
const sharedClique& root: rootContainer->children) {
192 root->parent_ =
typename Clique::weak_ptr();
199 template<
class CLIQUE>
201 std::cout << s <<
": cliques: " << size() <<
", variables: " << nodes_.size() << std::endl;
207 template<
class CLIQUE>
208 bool check_sharedCliques(
212 return v1.first == v2.first &&
213 ((!v1.second && !v2.second) || (v1.second && v2.second && v1.second->equals(*v2.second)));
217 template<
class CLIQUE>
219 return size()==other.
size() &&
220 std::equal(nodes_.begin(), nodes_.end(), other.
nodes_.begin(), &check_sharedCliques<CLIQUE>);
224 template<
class CLIQUE>
225 template<
class CONTAINER>
227 typename CONTAINER::const_iterator lowestOrderedParent = min_element(parents.begin(), parents.end());
228 assert(lowestOrderedParent != parents.end());
229 return *lowestOrderedParent;
233 template<
class CLIQUE>
236 for(
const Key& j: subtree->conditional()->frontals()) {
237 bool inserted = nodes_.insert(std::make_pair(j, subtree)).second;
238 assert(inserted); (void)inserted;
242 for(
const sharedClique& child: subtree->children) {
243 fillNodesIndex(child); }
247 template<
class CLIQUE>
249 roots_.push_back(subtree);
250 fillNodesIndex(subtree);
256 template<
class CLIQUE>
257 typename BayesTree<CLIQUE>::sharedConditional
260 gttic(BayesTree_marginalFactor);
266 FactorGraphType cliqueMarginal = clique->marginal2(
function);
269 BayesNetType marginalBN = *cliqueMarginal.marginalMultifrontalBayesNet(
270 Ordering(cref_list_of<1,Key>(j)), boost::none,
function);
273 return marginalBN.front();
279 template<
class CLIQUE>
280 typename BayesTree<CLIQUE>::sharedFactorGraph
283 gttic(BayesTree_joint);
284 return boost::make_shared<FactorGraphType>(*jointBayesNet(j1, j2,
function));
288 template<
class CLIQUE>
289 typename BayesTree<CLIQUE>::sharedBayesNet
292 gttic(BayesTree_jointBayesNet);
296 gttic(Lowest_common_ancestor);
317 while(p1 != path1.end() && p2 != path2.end() && *p1 == *p2) {
323 gttoc(Lowest_common_ancestor);
326 FactorGraphType p_BC1C2;
332 FactorGraphType p_B = B->marginal2(
function);
336 gttic(Clique_shortcuts);
337 BayesNetType p_C1_Bred = C1->shortcut(B,
function);
338 BayesNetType p_C2_Bred = C2->shortcut(B,
function);
339 gttoc(Clique_shortcuts);
343 gttic(Full_root_factoring);
344 boost::shared_ptr<typename EliminationTraitsType::BayesTreeType> p_C1_B; {
346 KeySet C1_minus_B_set(C1->conditional()->beginParents(), C1->conditional()->endParents());
347 for(
const Key j: *B->conditional()) {
348 C1_minus_B_set.erase(j); }
349 C1_minus_B.assign(C1_minus_B_set.begin(), C1_minus_B_set.end());
352 sharedFactorGraph temp_remaining;
353 boost::tie(p_C1_B, temp_remaining) =
354 FactorGraphType(p_C1_Bred).eliminatePartialMultifrontal(
Ordering(C1_minus_B),
function);
356 boost::shared_ptr<typename EliminationTraitsType::BayesTreeType> p_C2_B; {
358 KeySet C2_minus_B_set(C2->conditional()->beginParents(), C2->conditional()->endParents());
359 for(
const Key j: *B->conditional()) {
360 C2_minus_B_set.erase(j); }
361 C2_minus_B.assign(C2_minus_B_set.begin(), C2_minus_B_set.end());
364 sharedFactorGraph temp_remaining;
365 boost::tie(p_C2_B, temp_remaining) =
366 FactorGraphType(p_C2_Bred).eliminatePartialMultifrontal(
Ordering(C2_minus_B),
function);
368 gttoc(Full_root_factoring);
370 gttic(Variable_joint);
375 p_BC1C2 += C1->conditional();
377 p_BC1C2 += C2->conditional();
378 gttoc(Variable_joint);
384 gttic(Disjoint_marginals);
385 p_BC1C2 += C1->marginal2(
function);
386 p_BC1C2 += C2->marginal2(
function);
387 gttoc(Disjoint_marginals);
391 return p_BC1C2.marginalMultifrontalBayesNet(
Ordering(cref_list_of<2,Key>(j1)(j2)), boost::none,
function);
395 template<
class CLIQUE>
403 template<
class CLIQUE>
406 root->deleteCachedShortcuts();
411 template<
class CLIQUE>
414 if (clique->isRoot()) {
415 typename Roots::iterator root = std::find(roots_.begin(), roots_.end(), clique);
416 if(root != roots_.end())
420 typename Roots::iterator child = std::find(parent->children.begin(), parent->children.end(), clique);
421 assert(child != parent->children.end());
422 parent->children.erase(child);
427 child->parent_ =
typename Clique::weak_ptr();
429 for(
Key j: clique->conditional()->frontals()) {
430 nodes_.unsafe_erase(j);
435 template<
class CLIQUE>
442 orphans.remove(clique);
445 this->removeClique(clique);
448 this->removePath(
typename Clique::shared_ptr(clique->parent_.lock()), bn, orphans);
451 orphans.insert(orphans.begin(), clique->children.begin(), clique->children.end());
452 clique->children.clear();
454 bn.push_back(clique->conditional_);
460 template<
class CLIQUE>
464 for(
const Key& j: keys)
468 typename Nodes::const_iterator node = nodes_.find(j);
469 if(node != nodes_.end()) {
471 this->removePath(node->second, bn, orphans);
478 orphan->deleteCachedShortcuts();
482 template<
class CLIQUE>
488 cliques.push_back(subtree);
491 if(!subtree->isRoot())
492 subtree->parent()->children.erase(std::find(
493 subtree->parent()->children.begin(), subtree->parent()->children.end(), subtree));
495 roots_.erase(std::find(roots_.begin(), roots_.end(), subtree));
498 for(
typename Cliques::iterator clique = cliques.begin(); clique != cliques.end(); ++clique)
502 cliques.push_back(child); }
505 (*clique)->deleteCachedShortcutsNonRecursive();
508 for(
Key j: (*clique)->conditional()->frontals()) {
509 nodes_.unsafe_erase(j); }
512 (*clique)->parent_.reset();
513 (*clique)->children.clear();
BayesTreeCliqueData getCliqueData() const
Gather data on all cliques.
Definition: BayesTree-inst.h:38
void addFactorsToGraph(FactorGraph< FactorType > &graph) const
Add all cliques in this BayesTree to the specified factor graph.
Definition: BayesTree-inst.h:155
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
size_t numCachedSeparatorMarginals() const
Collect number of cliques with cached separator marginals.
Definition: BayesTree-inst.h:57
void saveGraph(const std::string &s, const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Read only with side effects.
Definition: BayesTree-inst.h:66
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:436
Definition: FastList.h:38
Cliques removeSubtree(const sharedClique &subtree)
Remove the requested subtree.
Definition: BayesTree-inst.h:483
Key findParentClique(const CONTAINER &parents) const
Find parent clique of a conditional.
Definition: BayesTree-inst.h:226
Nodes nodes_
Map from indices to Clique.
Definition: BayesTree.h:95
boost::shared_ptr< Clique > sharedClique
Shared pointer to a clique.
Definition: BayesTree.h:72
Definition: BayesTree.h:64
Bayes Tree is a tree of cliques of a Bayes Chain.
void fillNodesIndex(const sharedClique &subtree)
Fill the nodes index for a subtree.
Definition: BayesTree-inst.h:234
void removeClique(sharedClique clique)
remove a clique: warning, can result in a forest
Definition: BayesTree-inst.h:412
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print
Definition: BayesTree-inst.h:200
bool equals(const This &other, double tol=1e-9) const
check equality
Definition: BayesTree-inst.h:218
void deleteCachedShortcuts()
Clear all shortcut caches - use before timing on marginal calculation to avoid residual cache data...
Definition: BayesTree-inst.h:404
void clear()
Remove all nodes.
Definition: BayesTree-inst.h:396
store all the sizes
Definition: BayesTree.h:46
void addClique(const sharedClique &clique, const sharedClique &parent_clique=sharedClique())
add a clique (top down)
Definition: BayesTree-inst.h:122
size_t size() const
number of cliques
Definition: BayesTree-inst.h:113
BayesTree()
Create an empty Bayes Tree.
Definition: BayesTree.h:107
This & operator=(const This &other)
Assignment operator.
Definition: BayesTree-inst.h:187
Definition: Ordering.h:33
void insertRoot(const sharedClique &subtree)
Insert a new subtree with known parent clique.
Definition: BayesTree-inst.h:248
bool equal(const T &obj1, const T &obj2, double tol)
Call equal on the object.
Definition: Testable.h:83
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:220
boost::enable_if< boost::is_base_of< FactorType, DERIVEDFACTOR > >::type push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:155
sharedConditional marginalFactor(Key j, const Eliminate &function=EliminationTraitsType::DefaultEliminate) const
Return marginal on any variable.
Definition: BayesTree-inst.h:258
A factor graph is a bipartite graph with factor nodes connected to variable nodes.
Definition: BayesTree.h:32
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:281
void removeTop(const FastVector< Key > &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:461
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:57
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
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
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:290