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 +=
",";
89 parent += indexFormatter(index);
92 if (clique->parent()) {
94 s << parentnum <<
"->" << num <<
"\n";
98 for (
Key sep : clique->conditional_->parents()) {
99 if (!first) parent +=
",";
101 parent += indexFormatter(sep);
109 saveGraph(s, c, indexFormatter, parentnum);
114 template<
class CLIQUE>
118 size += clique->treeSize();
123 template<
class CLIQUE>
125 for(
Key j: clique->conditional()->frontals())
127 if (parent_clique != NULL) {
128 clique->parent_ = parent_clique;
129 parent_clique->children.push_back(clique);
131 roots_.push_back(clique);
138 template<
class FACTOR,
class CLIQUE>
144 template<
class FACTOR,
class CLIQUE>
145 struct _pushCliqueFunctor {
146 _pushCliqueFunctor(FactorGraph<FACTOR>& graph_) : graph(graph_) {}
147 FactorGraph<FACTOR>& graph;
148 int operator()(
const boost::shared_ptr<CLIQUE>& clique,
int dummy) {
149 graph.push_back(clique->conditional_);
156 template<
class CLIQUE>
161 _pushCliqueFunctor<FactorType,CLIQUE> functor(graph);
167 template<
class CLIQUE>
174 template<
typename NODE>
175 boost::shared_ptr<NODE>
176 BayesTreeCloneForestVisitorPre(
const boost::shared_ptr<NODE>& node,
const boost::shared_ptr<NODE>& parentPointer)
179 boost::shared_ptr<NODE> clone = boost::make_shared<NODE>(*node);
180 clone->children.clear();
181 clone->parent_ = parentPointer;
182 parentPointer->children.push_back(clone);
188 template<
class CLIQUE>
191 boost::shared_ptr<Clique> rootContainer = boost::make_shared<Clique>();
193 for(
const sharedClique& root: rootContainer->children) {
194 root->parent_ =
typename Clique::weak_ptr();
201 template<
class CLIQUE>
203 std::cout << s <<
": cliques: " << size() <<
", variables: " << nodes_.size() << std::endl;
209 template<
class CLIQUE>
210 bool check_sharedCliques(
214 return v1.first == v2.first &&
215 ((!v1.second && !v2.second) || (v1.second && v2.second && v1.second->equals(*v2.second)));
219 template<
class CLIQUE>
221 return size()==other.
size() &&
222 std::equal(nodes_.begin(), nodes_.end(), other.
nodes_.begin(), &check_sharedCliques<CLIQUE>);
226 template<
class CLIQUE>
227 template<
class CONTAINER>
229 typename CONTAINER::const_iterator lowestOrderedParent = min_element(parents.begin(), parents.end());
230 assert(lowestOrderedParent != parents.end());
231 return *lowestOrderedParent;
235 template<
class CLIQUE>
238 for(
const Key& j: subtree->conditional()->frontals()) {
239 bool inserted = nodes_.insert(std::make_pair(j, subtree)).second;
240 assert(inserted); (void)inserted;
245 fillNodesIndex(child); }
249 template<
class CLIQUE>
251 roots_.push_back(subtree);
252 fillNodesIndex(subtree);
258 template<
class CLIQUE>
259 typename BayesTree<CLIQUE>::sharedConditional
262 gttic(BayesTree_marginalFactor);
268 FactorGraphType cliqueMarginal = clique->marginal2(
function);
271 BayesNetType marginalBN = *cliqueMarginal.marginalMultifrontalBayesNet(
272 Ordering(cref_list_of<1,Key>(j)), boost::none,
function);
275 return marginalBN.front();
281 template<
class CLIQUE>
282 typename BayesTree<CLIQUE>::sharedFactorGraph
285 gttic(BayesTree_joint);
286 return boost::make_shared<FactorGraphType>(*jointBayesNet(j1, j2,
function));
290 template<
class CLIQUE>
291 typename BayesTree<CLIQUE>::sharedBayesNet
294 gttic(BayesTree_jointBayesNet);
298 gttic(Lowest_common_ancestor);
319 while(p1 != path1.end() && p2 != path2.end() && *p1 == *p2) {
325 gttoc(Lowest_common_ancestor);
328 FactorGraphType p_BC1C2;
334 FactorGraphType p_B = B->marginal2(
function);
338 gttic(Clique_shortcuts);
339 BayesNetType p_C1_Bred = C1->shortcut(B,
function);
340 BayesNetType p_C2_Bred = C2->shortcut(B,
function);
341 gttoc(Clique_shortcuts);
345 gttic(Full_root_factoring);
346 boost::shared_ptr<typename EliminationTraitsType::BayesTreeType> p_C1_B; {
348 KeySet C1_minus_B_set(C1->conditional()->beginParents(), C1->conditional()->endParents());
349 for(
const Key j: *B->conditional()) {
350 C1_minus_B_set.erase(j); }
351 C1_minus_B.assign(C1_minus_B_set.begin(), C1_minus_B_set.end());
354 sharedFactorGraph temp_remaining;
355 boost::tie(p_C1_B, temp_remaining) =
356 FactorGraphType(p_C1_Bred).eliminatePartialMultifrontal(
Ordering(C1_minus_B),
function);
358 boost::shared_ptr<typename EliminationTraitsType::BayesTreeType> p_C2_B; {
360 KeySet C2_minus_B_set(C2->conditional()->beginParents(), C2->conditional()->endParents());
361 for(
const Key j: *B->conditional()) {
362 C2_minus_B_set.erase(j); }
363 C2_minus_B.assign(C2_minus_B_set.begin(), C2_minus_B_set.end());
366 sharedFactorGraph temp_remaining;
367 boost::tie(p_C2_B, temp_remaining) =
368 FactorGraphType(p_C2_Bred).eliminatePartialMultifrontal(
Ordering(C2_minus_B),
function);
370 gttoc(Full_root_factoring);
372 gttic(Variable_joint);
377 p_BC1C2 += C1->conditional();
379 p_BC1C2 += C2->conditional();
380 gttoc(Variable_joint);
386 gttic(Disjoint_marginals);
387 p_BC1C2 += C1->marginal2(
function);
388 p_BC1C2 += C2->marginal2(
function);
389 gttoc(Disjoint_marginals);
393 return p_BC1C2.marginalMultifrontalBayesNet(
Ordering(cref_list_of<2,Key>(j1)(j2)), boost::none,
function);
397 template<
class CLIQUE>
405 template<
class CLIQUE>
408 root->deleteCachedShortcuts();
413 template<
class CLIQUE>
416 if (clique->isRoot()) {
417 typename Roots::iterator root = std::find(roots_.begin(), roots_.end(), clique);
418 if(root != roots_.end())
422 typename Roots::iterator child = std::find(parent->children.begin(), parent->children.end(), clique);
423 assert(child != parent->children.end());
424 parent->children.erase(child);
429 child->parent_ =
typename Clique::weak_ptr();
431 for(
Key j: clique->conditional()->frontals()) {
432 nodes_.unsafe_erase(j);
437 template<
class CLIQUE>
444 orphans.remove(clique);
447 this->removeClique(clique);
450 this->removePath(
typename Clique::shared_ptr(clique->parent_.lock()), bn, orphans);
453 orphans.insert(orphans.begin(), clique->children.begin(), clique->children.end());
454 clique->children.clear();
456 bn.push_back(clique->conditional_);
462 template<
class CLIQUE>
466 for(
const Key& j: keys)
470 typename Nodes::const_iterator node = nodes_.find(j);
471 if(node != nodes_.end()) {
473 this->removePath(node->second, bn, orphans);
480 orphan->deleteCachedShortcuts();
484 template<
class CLIQUE>
490 cliques.push_back(subtree);
493 if(!subtree->isRoot())
494 subtree->parent()->children.erase(std::find(
495 subtree->parent()->children.begin(), subtree->parent()->children.end(), subtree));
497 roots_.erase(std::find(roots_.begin(), roots_.end(), subtree));
500 for(
typename Cliques::iterator clique = cliques.begin(); clique != cliques.end(); ++clique)
504 cliques.push_back(child); }
507 (*clique)->deleteCachedShortcutsNonRecursive();
510 for(
Key j: (*clique)->conditional()->frontals()) {
511 nodes_.unsafe_erase(j); }
514 (*clique)->parent_.reset();
515 (*clique)->children.clear();
size_t numCachedSeparatorMarginals() const
Collect number of cliques with cached separator marginals.
Definition: BayesTree-inst.h:57
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
sharedConditional marginalFactor(Key j, const Eliminate &function=EliminationTraitsType::DefaultEliminate) const
Return marginal on any variable.
Definition: BayesTree-inst.h:260
void clear()
Remove all nodes.
Definition: BayesTree-inst.h:398
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:57
boost::shared_ptr< Clique > sharedClique
Shared pointer to a clique.
Definition: BayesTree.h:72
void saveGraph(const std::string &s, const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Read only with side effects.
Definition: BayesTree-inst.h:66
Variable ordering for the elimination algorithm.
void addFactorsToGraph(FactorGraph< FactorType > &graph) const
Add all cliques in this BayesTree to the specified factor graph.
Definition: BayesTree-inst.h:157
bool equals(const This &other, double tol=1e-9) const
check equality
Definition: BayesTree-inst.h:220
void removeClique(sharedClique clique)
remove a clique: warning, can result in a forest
Definition: BayesTree-inst.h:414
void addClique(const sharedClique &clique, const sharedClique &parent_clique=sharedClique())
add a clique (top down)
Definition: BayesTree-inst.h:124
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:438
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
Definition: FastList.h:38
Key findParentClique(const CONTAINER &parents) const
Find parent clique of a conditional.
Definition: BayesTree-inst.h:228
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:283
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:56
store all the sizes
Definition: BayesTree.h:46
A factor graph is a bipartite graph with factor nodes connected to variable nodes.
Definition: BayesTree.h:32
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
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:292
This & operator=(const This &other)
Assignment operator.
Definition: BayesTree-inst.h:189
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:463
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
bool equal(const T &obj1, const T &obj2, double tol)
Call equal on the object.
Definition: Testable.h:83
size_t size() const
number of cliques
Definition: BayesTree-inst.h:115
Nodes nodes_
Map from indices to Clique.
Definition: BayesTree.h:95
void deleteCachedShortcuts()
Clear all shortcut caches - use before timing on marginal calculation to avoid residual cache data.
Definition: BayesTree-inst.h:406
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:485
void fillNodesIndex(const sharedClique &subtree)
Fill the nodes index for a subtree.
Definition: BayesTree-inst.h:236
void insertRoot(const sharedClique &subtree)
Insert a new subtree with known parent clique.
Definition: BayesTree-inst.h:250
Bayes Tree is a tree of cliques of a Bayes Chain.
Definition: Ordering.h:34
BayesTree()
Create an empty Bayes Tree.
Definition: BayesTree.h:107
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print
Definition: BayesTree-inst.h:202
std::enable_if< std::is_base_of< FactorType, DERIVEDFACTOR >::value >::type push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:159