255 lines
6.9 KiB
C++
255 lines
6.9 KiB
C++
/**
|
|
* @file ClusterTree.h
|
|
* @date Oct 8, 2013
|
|
* @author Kai Ni
|
|
* @author Richard Roberts
|
|
* @author Frank Dellaert
|
|
* @brief Collects factorgraph fragments defined on variable clusters, arranged in a tree
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <gtsam/base/Testable.h>
|
|
#include <gtsam/base/FastVector.h>
|
|
#include <gtsam/inference/Ordering.h>
|
|
|
|
namespace gtsam {
|
|
|
|
/**
|
|
* A cluster-tree is associated with a factor graph and is defined as in Koller-Friedman:
|
|
* each node k represents a subset \f$ C_k \sub X \f$, and the tree is family preserving, in that
|
|
* each factor \f$ f_i \f$ is associated with a single cluster and \f$ scope(f_i) \sub C_k \f$.
|
|
* \nosubgrouping
|
|
*/
|
|
template <class GRAPH>
|
|
class ClusterTree {
|
|
public:
|
|
typedef GRAPH FactorGraphType; ///< The factor graph type
|
|
typedef ClusterTree<GRAPH> This; ///< This class
|
|
typedef std::shared_ptr<This> shared_ptr; ///< Shared pointer to this class
|
|
|
|
typedef typename GRAPH::FactorType FactorType; ///< The type of factors
|
|
typedef std::shared_ptr<FactorType> sharedFactor; ///< Shared pointer to a factor
|
|
|
|
/// A Cluster is just a collection of factors
|
|
// TODO(frank): re-factor JunctionTree so we can make members private
|
|
struct Cluster {
|
|
typedef FastVector<std::shared_ptr<Cluster> > Children;
|
|
Children children; ///< sub-trees
|
|
|
|
typedef Ordering Keys;
|
|
Keys orderedFrontalKeys; ///< Frontal keys of this node
|
|
|
|
FactorGraphType factors; ///< Factors associated with this node
|
|
|
|
int problemSize_;
|
|
|
|
Cluster() : problemSize_(0) {}
|
|
|
|
virtual ~Cluster() {}
|
|
|
|
const Cluster& operator[](size_t i) const {
|
|
return *(children[i]);
|
|
}
|
|
|
|
/// Construct from factors associated with a single key
|
|
template <class CONTAINER>
|
|
Cluster(Key key, const CONTAINER& factorsToAdd)
|
|
: problemSize_(0) {
|
|
addFactors(key, factorsToAdd);
|
|
}
|
|
|
|
/// Add factors associated with a single key
|
|
template <class CONTAINER>
|
|
void addFactors(Key key, const CONTAINER& factorsToAdd) {
|
|
orderedFrontalKeys.push_back(key);
|
|
factors.push_back(factorsToAdd);
|
|
problemSize_ += factors.size();
|
|
}
|
|
|
|
/// Add a child cluster
|
|
void addChild(const std::shared_ptr<Cluster>& cluster) {
|
|
children.push_back(cluster);
|
|
problemSize_ = std::max(problemSize_, cluster->problemSize_);
|
|
}
|
|
|
|
size_t nrChildren() const {
|
|
return children.size();
|
|
}
|
|
|
|
size_t nrFactors() const {
|
|
return factors.size();
|
|
}
|
|
|
|
size_t nrFrontals() const {
|
|
return orderedFrontalKeys.size();
|
|
}
|
|
|
|
int problemSize() const {
|
|
return problemSize_;
|
|
}
|
|
|
|
/// print this node
|
|
virtual void print(const std::string& s = "",
|
|
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const;
|
|
|
|
/// Return a vector with nrFrontal keys for each child
|
|
std::vector<size_t> nrFrontalsOfChildren() const;
|
|
|
|
/// Merge in given cluster
|
|
void merge(const std::shared_ptr<Cluster>& cluster);
|
|
|
|
/// Merge all children for which bit is set into this node
|
|
void mergeChildren(const std::vector<bool>& merge);
|
|
};
|
|
|
|
typedef std::shared_ptr<Cluster> sharedCluster; ///< Shared pointer to Cluster
|
|
|
|
// Define Node=Cluster for compatibility with tree traversal functions
|
|
typedef Cluster Node;
|
|
typedef sharedCluster sharedNode;
|
|
|
|
/** concept check */
|
|
GTSAM_CONCEPT_TESTABLE_TYPE(FactorType)
|
|
|
|
protected:
|
|
FastVector<sharedNode> roots_;
|
|
|
|
/// @name Standard Constructors
|
|
/// @{
|
|
|
|
/** Copy constructor - makes a deep copy of the tree structure, but only pointers to factors are
|
|
* copied, factors are not cloned. */
|
|
ClusterTree(const This& other) {
|
|
*this = other;
|
|
}
|
|
|
|
/// @}
|
|
|
|
public:
|
|
|
|
/// Default constructor
|
|
ClusterTree() {}
|
|
|
|
/// @name Testable
|
|
/// @{
|
|
|
|
/** Print the cluster tree */
|
|
void print(const std::string& s = "",
|
|
const KeyFormatter& keyFormatter = DefaultKeyFormatter) const;
|
|
|
|
/// @}
|
|
/// @name Advanced Interface
|
|
/// @{
|
|
|
|
void addRoot(const std::shared_ptr<Cluster>& cluster) {
|
|
roots_.push_back(cluster);
|
|
}
|
|
|
|
void addChildrenAsRoots(const std::shared_ptr<Cluster>& cluster) {
|
|
for (auto child : cluster->children)
|
|
this->addRoot(child);
|
|
}
|
|
|
|
size_t nrRoots() const {
|
|
return roots_.size();
|
|
}
|
|
|
|
/** Return the set of roots (one for a tree, multiple for a forest) */
|
|
const FastVector<sharedNode>& roots() const {
|
|
return roots_;
|
|
}
|
|
|
|
const Cluster& operator[](size_t i) const {
|
|
return *(roots_[i]);
|
|
}
|
|
|
|
/// @}
|
|
|
|
~ClusterTree();
|
|
|
|
protected:
|
|
/// @name Details
|
|
/// @{
|
|
|
|
/// Assignment operator - makes a deep copy of the tree structure, but only pointers to factors
|
|
/// are copied, factors are not cloned.
|
|
This& operator=(const This& other);
|
|
|
|
/// @}
|
|
};
|
|
|
|
/**
|
|
* A cluster-tree that eliminates to a Bayes tree.
|
|
*/
|
|
template <class BAYESTREE, class GRAPH>
|
|
class EliminatableClusterTree : public ClusterTree<GRAPH> {
|
|
public:
|
|
typedef BAYESTREE BayesTreeType; ///< The BayesTree type produced by elimination
|
|
typedef GRAPH FactorGraphType; ///< The factor graph type
|
|
typedef EliminatableClusterTree<BAYESTREE, GRAPH> This; ///< This class
|
|
typedef std::shared_ptr<This> shared_ptr; ///< Shared pointer to this class
|
|
|
|
typedef typename BAYESTREE::ConditionalType ConditionalType; ///< The type of conditionals
|
|
typedef std::shared_ptr<ConditionalType>
|
|
sharedConditional; ///< Shared pointer to a conditional
|
|
|
|
typedef typename GRAPH::Eliminate Eliminate; ///< Typedef for an eliminate subroutine
|
|
typedef typename GRAPH::FactorType FactorType; ///< The type of factors
|
|
typedef std::shared_ptr<FactorType> sharedFactor; ///< Shared pointer to a factor
|
|
|
|
protected:
|
|
FastVector<sharedFactor> remainingFactors_;
|
|
|
|
/// @name Standard Constructors
|
|
/// @{
|
|
|
|
/** Copy constructor - makes a deep copy of the tree structure, but only pointers to factors are
|
|
* copied, factors are not cloned. */
|
|
EliminatableClusterTree(const This& other) : ClusterTree<GRAPH>(other) {
|
|
*this = other;
|
|
}
|
|
|
|
/// @}
|
|
|
|
public:
|
|
/// @name Standard Interface
|
|
/// @{
|
|
|
|
/** Eliminate the factors to a Bayes tree and remaining factor graph
|
|
* @param function The function to use to eliminate, see the namespace functions
|
|
* in GaussianFactorGraph.h
|
|
* @return The Bayes tree and factor graph resulting from elimination
|
|
*/
|
|
std::pair<std::shared_ptr<BayesTreeType>, std::shared_ptr<FactorGraphType> > eliminate(
|
|
const Eliminate& function) const;
|
|
|
|
/// @}
|
|
|
|
/// @name Advanced Interface
|
|
/// @{
|
|
|
|
/** Return the remaining factors that are not pulled into elimination */
|
|
const FastVector<sharedFactor>& remainingFactors() const {
|
|
return remainingFactors_;
|
|
}
|
|
|
|
/// @}
|
|
|
|
protected:
|
|
/// @name Details
|
|
/// @{
|
|
|
|
/// Assignment operator - makes a deep copy of the tree structure, but only pointers to factors
|
|
/// are copied, factors are not cloned.
|
|
This& operator=(const This& other);
|
|
|
|
/// Default constructor to be used in derived classes
|
|
EliminatableClusterTree() {}
|
|
|
|
/// @}
|
|
};
|
|
}
|
|
|
|
#include <gtsam/inference/ClusterTree-inst.h>
|