29 std::cout << s <<
" (" << problemSize_ <<
")";
36 std::vector<size_t> nrFrontals;
37 nrFrontals.reserve(nrChildren());
38 for (
const sharedNode& child :
children)
39 nrFrontals.push_back(child->nrFrontals());
47 auto it = cache->find(
this);
48 if (it != cache->end())
return it->second;
52 for (
const auto& factor :
factors) {
53 if (!factor)
continue;
54 keys.insert(factor->begin(), factor->end());
57 KeySet childSeparators = child->separatorKeys(cache);
58 keys.insert(childSeparators.begin(), childSeparators.end());
65 auto result = cache->emplace(
this, std::move(keys));
66 return result.first->second;
76 cluster->orderedFrontalKeys.rend());
77 factors.push_back(cluster->factors);
78 children.insert(
children.end(), cluster->children.begin(), cluster->children.end());
80 problemSize_ = std::max(problemSize_, cluster->problemSize_);
86 const std::vector<bool>&
merge) {
93 const Children& selected) {
94 gttic(Cluster_mergeChildren);
96 if (selected.empty())
return;
99 for (
const auto& child : selected) {
101 selectedSet.insert(child.get());
104 if (selectedSet.empty())
return;
108 size_t nrFactors =
factors.size();
109 size_t nrNewChildren = 0;
111 if (child && selectedSet.count(child.get()) != 0) {
112 nrKeys += child->orderedFrontalKeys.size();
113 nrFactors += child->factors.size();
114 nrNewChildren += child->nrChildren();
121 auto oldChildren = this->children;
122 this->children.clear();
123 this->children.reserve(nrNewChildren);
126 for (
const sharedNode& child : oldChildren) {
127 if (child && selectedSet.count(child.get()) != 0) {
134 std::reverse(orderedFrontalKeys.begin(), orderedFrontalKeys.end());
138template <
class GRAPH>
140 const std::vector<bool>&
merge) {
145template <
class GRAPH>
147 const Children& selected) {
148 gttic(Cluster_mergeChildrenSiblings);
150 if (selected.empty())
return;
153 for (
const auto& child : selected) {
155 selectedSet.insert(child.get());
158 const size_t selectedCount = selectedSet.size();
160 if (selectedCount <= 1)
return;
162 auto oldChildren = this->children;
163 Children newChildren;
164 newChildren.reserve(oldChildren.size() - selectedCount + 1);
165 auto merged = std::make_shared<Cluster>();
166 bool inserted =
false;
169 if (child && selectedSet.count(child.get()) != 0) {
171 merged->merge(child);
174 newChildren.push_back(merged);
178 newChildren.push_back(child);
183 std::reverse(merged->orderedFrontalKeys.begin(),
184 merged->orderedFrontalKeys.end());
185 this->children.swap(newChildren);
189template <
class GRAPH>
192 const std::vector<bool>&
merge)
const {
193 assert(
merge.size() == this->children.size());
196 for (
size_t i = 0; i < children.size(); ++i) {
198 selected.push_back(children[i]);
205template <
class GRAPH>
217template <
class GRAPH>
218ClusterTree<GRAPH>::~ClusterTree() {
221 for (
auto&& root :
roots_) {
222 std::queue<sharedNode> bfs_queue;
225 bfs_queue.push(std::move(root));
229 while (!bfs_queue.empty()) {
231 auto node = std::move(bfs_queue.front());
235 for (
auto child : node->children) {
236 bfs_queue.push(std::move(child));
246template <
class GRAPH>
257template<
class CLUSTERTREE>
258struct EliminationData {
260 typedef typename CLUSTERTREE::sharedFactor sharedFactor;
261 typedef typename CLUSTERTREE::FactorType FactorType;
262 typedef typename CLUSTERTREE::FactorGraphType FactorGraphType;
263 typedef typename CLUSTERTREE::ConditionalType ConditionalType;
264 typedef typename CLUSTERTREE::BayesTreeType::Node BTNode;
266 EliminationData*
const parentData;
267 size_t myIndexInParent;
269 std::shared_ptr<BTNode> bayesTreeNode;
271 std::shared_ptr<std::mutex> writeLock;
274 EliminationData(EliminationData* _parentData,
size_t nChildren) :
275 parentData(_parentData), bayesTreeNode(std::make_shared<BTNode>())
277 , writeLock(std::make_shared<std::mutex>())
282 parentData->writeLock->lock();
284 myIndexInParent = parentData->childFactors.size();
285 parentData->childFactors.push_back(sharedFactor());
287 parentData->writeLock->unlock();
294 if (parentData->parentData)
295 bayesTreeNode->parent_ = parentData->bayesTreeNode;
296 parentData->bayesTreeNode->children.push_back(bayesTreeNode);
301 static EliminationData EliminationPreOrderVisitor(
302 const typename CLUSTERTREE::sharedNode& node,
303 EliminationData& parentData) {
305 EliminationData myData(&parentData, node->nrChildren());
306 myData.bayesTreeNode->problemSize_ = node->problemSize();
312 class EliminationPostOrderVisitor {
313 const typename CLUSTERTREE::Eliminate& eliminationFunction_;
314 typename CLUSTERTREE::BayesTreeType::Nodes& nodesIndex_;
318 EliminationPostOrderVisitor(
319 const typename CLUSTERTREE::Eliminate& eliminationFunction,
320 typename CLUSTERTREE::BayesTreeType::Nodes& nodesIndex) :
321 eliminationFunction_(eliminationFunction), nodesIndex_(nodesIndex) {
325 void operator()(
const typename CLUSTERTREE::sharedNode& node, EliminationData& myData) {
329 FactorGraphType gatheredFactors;
330 gatheredFactors.reserve(node->factors.size() + node->nrChildren());
331 gatheredFactors.push_back(node->factors);
332 gatheredFactors.push_back(myData.childFactors);
336 for (
const sharedFactor& factor: node->factors) {
339 myData.bayesTreeNode->children.push_back(asSubtree->clique);
340 asSubtree->clique->parent_ = myData.bayesTreeNode;
345 auto eliminationResult = eliminationFunction_(gatheredFactors, node->orderedFrontalKeys);
350 myData.bayesTreeNode->setEliminationResult(eliminationResult);
355 for (
const Key& j : myData.bayesTreeNode->conditional()->frontals()) {
357 nodesIndex_.insert({j, myData.bayesTreeNode});
359 nodesIndex_.emplace(j, myData.bayesTreeNode);
363 if (!eliminationResult.second->empty()) {
365 myData.parentData->writeLock->lock();
367 myData.parentData->childFactors[myData.myIndexInParent] = eliminationResult.second;
369 myData.parentData->writeLock->unlock();
377template<
class BAYESTREE,
class GRAPH>
384 remainingFactors_ = other.remainingFactors_;
390template <
class BAYESTREE,
class GRAPH>
391std::pair<std::shared_ptr<BAYESTREE>, std::shared_ptr<GRAPH> >
393 gttic(ClusterTree_eliminate);
397 std::shared_ptr<BayesTreeType> result = std::make_shared<BayesTreeType>();
400 Data rootsContainer(0, this->nrRoots());
402 typename Data::EliminationPostOrderVisitor visitorPost(function, result->nodes_);
410 result->roots_.insert(result->roots_.end(), rootsContainer.bayesTreeNode->children.begin(),
411 rootsContainer.bayesTreeNode->children.end());
414 std::shared_ptr<FactorGraphType> remaining = std::make_shared<FactorGraphType>();
415 remaining->reserve(remainingFactors_.size() + rootsContainer.childFactors.size());
416 remaining->push_back(remainingFactors_.begin(), remainingFactors_.end());
417 for (
const sharedFactor& factor : rootsContainer.childFactors) {
419 remaining->push_back(factor);
423 return {result, remaining};
Bayes Tree is a tree of cliques of a Bayes Chain.
Collects factorgraph fragments defined on variable clusters, arranged in a tree.
std::vector< T, typename internal::FastDefaultVectorAllocator< T >::type > FastVector
FastVector is a type alias to a std::vector with a custom memory allocator.
Definition FastVector.h:33
Global functions in a separate testing namespace.
Definition chartTesting.h:28
void PrintKeyVector(const KeyVector &keys, const string &s, const KeyFormatter &keyFormatter)
Utility function to print sets of keys with optional prefix.
Definition Key.cpp:84
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
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
FastVector< std::shared_ptr< typename FOREST::Node > > CloneForest(const FOREST &forest)
Clone a tree, copy-constructing new nodes (calling std::make_shared) and setting up child pointers fo...
Definition treeTraversal-inst.h:246
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:276
void DepthFirstForestParallel(FOREST &forest, DATA &rootData, VISITOR_PRE &visitorPre, VISITOR_POST &visitorPost, int problemSizeThreshold=10)
Traverse a forest depth-first with pre-order and post-order visits.
Definition treeTraversal-inst.h:181
FastSet is a thin wrapper around std::set that uses the boost fast_pool_allocator instead of the defa...
Definition FastSet.h:54
An object whose scope defines a block where TBB and OpenMP parallelism are mixed.
Definition types.h:87
EliminatableClusterTree< BAYESTREE, GRAPH > This
This class.
Definition ClusterTree.h:209
This & operator=(const This &other)
Assignment operator - makes a deep copy of the tree structure, but only pointers to factors are copie...
Definition ClusterTree-inst.h:378
EliminatableClusterTree(const This &other)
Copy constructor - makes a deep copy of the tree structure, but only pointers to factors are copied,...
Definition ClusterTree.h:228
std::shared_ptr< FactorType > sharedFactor
Shared pointer to a factor.
Definition ClusterTree.h:218
std::pair< std::shared_ptr< BayesTreeType >, std::shared_ptr< FactorGraphType > > eliminate(const Eliminate &function) const
Eliminate the factors to a Bayes tree and remaining factor graph.
Definition ClusterTree-inst.h:392
GRAPH::Eliminate Eliminate
Typedef for an eliminate subroutine.
Definition ClusterTree.h:216
Definition BayesTree.h:405
Definition ClusterTree-inst.h:258
This & operator=(const This &other)
Assignment operator - makes a deep copy of the tree structure, but only pointers to factors are copie...
Definition ClusterTree-inst.h:247
ClusterTree< GRAPH > This
This class.
Definition ClusterTree.h:30
FastVector< sharedNode > roots_
concept check
Definition ClusterTree.h:135
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Print the cluster tree.
Definition ClusterTree-inst.h:206
ClusterTree(const This &other)
Copy constructor - makes a deep copy of the tree structure, but only pointers to factors are copied,...
Definition ClusterTree.h:142
Children children
sub-trees
Definition ClusterTree.h:40
virtual void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
print this node
Definition ClusterTree-inst.h:27
void merge(const std::shared_ptr< Cluster > &cluster)
Merge in given cluster.
Definition ClusterTree-inst.h:73
KeySet separatorKeys(KeySetMap *cache=nullptr) const
Return the separator keys (subtree keys minus frontals), optionally cached.
Definition ClusterTree-inst.h:45
void mergeChildrenSiblings(const std::vector< bool > &merge)
Merge selected siblings into a new child cluster.
Definition ClusterTree-inst.h:139
Keys orderedFrontalKeys
Frontal keys of this node.
Definition ClusterTree.h:43
void mergeChildren(const std::vector< bool > &merge)
Merge all children for which bit is set into this node.
Definition ClusterTree-inst.h:85
std::vector< size_t > nrFrontalsOfChildren() const
Return a vector with nrFrontal keys for each child.
Definition ClusterTree-inst.h:35
FactorGraphType factors
Factors associated with this node.
Definition ClusterTree.h:45
void addChild(const std::shared_ptr< Cluster > &cluster)
Definition ClusterTree.h:73
Children childrenFromMask(const std::vector< bool > &merge) const
Convert a child-selection mask into the selected child pointers.
Definition ClusterTree-inst.h:191