gtsam/gtsam_unstable/linear/bayesTreeOperations.cpp

133 lines
4.7 KiB
C++

/**
* @file bayesTreeOperations.cpp
*
* @date Jun 22, 2012
* @author Alex Cunningham
*/
#include <gtsam_unstable/linear/bayesTreeOperations.h>
#include <boost/foreach.hpp>
using namespace std;
namespace gtsam {
/* ************************************************************************* */
std::set<Index> keysToIndices(const KeySet& keys, const OrderingOrdered& ordering) {
std::set<Index> result;
BOOST_FOREACH(const Key& key, keys)
result.insert(ordering[key]);
return result;
}
/* ************************************************************************* */
GaussianFactorGraphOrdered splitFactors(const GaussianFactorGraphOrdered& fullgraph) {
GaussianFactorGraphOrdered result;
BOOST_FOREACH(const GaussianFactorOrdered::shared_ptr& factor, fullgraph) {
GaussianFactorGraphOrdered split = splitFactor(factor);
result.push_back(split);
}
return result;
}
/* ************************************************************************* */
GaussianFactorGraphOrdered splitFactor(const GaussianFactorOrdered::shared_ptr& factor) {
GaussianFactorGraphOrdered result;
if (!factor) return result;
// Needs to be a jacobian factor - just pass along hessians
JacobianFactorOrdered::shared_ptr jf = boost::dynamic_pointer_cast<JacobianFactorOrdered>(factor);
if (!jf) {
result.push_back(factor);
return result;
}
// Loop over variables and strip off factors using split conditionals
// Assumes upper triangular structure
JacobianFactorOrdered::const_iterator rowIt, colIt;
const size_t totalRows = jf->rows();
size_t rowsRemaining = totalRows;
for (rowIt = jf->begin(); rowIt != jf->end() && rowsRemaining > 0; ++rowIt) {
// get dim of current variable
size_t varDim = jf->getDim(rowIt);
size_t startRow = totalRows - rowsRemaining;
size_t nrRows = std::min(rowsRemaining, varDim);
// Extract submatrices
std::vector<std::pair<Index, Matrix> > matrices;
for (colIt = rowIt; colIt != jf->end(); ++colIt) {
Index idx = *colIt;
const Matrix subA = jf->getA(colIt).middleRows(startRow, nrRows);
matrices.push_back(make_pair(idx, subA));
}
Vector subB = jf->getb().segment(startRow, nrRows);
Vector sigmas = jf->get_model()->sigmas().segment(startRow, nrRows);
SharedDiagonal model;
if (jf->get_model()->isConstrained())
model = noiseModel::Constrained::MixedSigmas(sigmas);
else
model = noiseModel::Diagonal::Sigmas(sigmas);
// extract matrices from each
// assemble into new JacobianFactor
result.add(matrices, subB, model);
rowsRemaining -= nrRows;
}
return result;
}
/* ************************************************************************* */
GaussianFactorGraphOrdered removePriors(const GaussianFactorGraphOrdered& fullgraph) {
GaussianFactorGraphOrdered result;
BOOST_FOREACH(const GaussianFactorOrdered::shared_ptr& factor, fullgraph) {
JacobianFactorOrdered::shared_ptr jf = boost::dynamic_pointer_cast<JacobianFactorOrdered>(factor);
if (factor && (!jf || jf->size() > 1))
result.push_back(factor);
}
return result;
}
/* ************************************************************************* */
void findCliques(const GaussianBayesTreeOrdered::sharedClique& current_clique,
std::set<GaussianConditionalOrdered::shared_ptr>& result) {
// Add the current clique
result.insert(current_clique->conditional());
// Add the parent if not root
if (!current_clique->isRoot())
findCliques(current_clique->parent(), result);
}
/* ************************************************************************* */
std::set<GaussianConditionalOrdered::shared_ptr> findAffectedCliqueConditionals(
const GaussianBayesTreeOrdered& bayesTree, const std::set<Index>& savedIndices) {
std::set<GaussianConditionalOrdered::shared_ptr> affected_cliques;
// FIXME: track previously found keys more efficiently
BOOST_FOREACH(const Index& index, savedIndices) {
GaussianBayesTreeOrdered::sharedClique clique = bayesTree.nodes()[index];
// add path back to root to affected set
findCliques(clique, affected_cliques);
}
return affected_cliques;
}
/* ************************************************************************* */
std::deque<GaussianBayesTreeOrdered::sharedClique>
findPathCliques(const GaussianBayesTreeOrdered::sharedClique& initial) {
std::deque<GaussianBayesTreeOrdered::sharedClique> result, parents;
if (initial->isRoot())
return result;
result.push_back(initial->parent());
parents = findPathCliques(initial->parent());
result.insert(result.end(), parents.begin(), parents.end());
return result;
}
/* ************************************************************************* */
} // \namespace gtsam