diff --git a/gtsam/linear/SubgraphPreconditioner.cpp b/gtsam/linear/SubgraphPreconditioner.cpp index c75bcd4e2..39f5a65cd 100644 --- a/gtsam/linear/SubgraphPreconditioner.cpp +++ b/gtsam/linear/SubgraphPreconditioner.cpp @@ -397,23 +397,30 @@ Subgraph::shared_ptr SubgraphBuilder::operator() (const GaussianFactorGraph &gfg const SubgraphBuilderParameters &p = parameters_; const Ordering inverse_ordering = Ordering::Natural(gfg); const FastMap forward_ordering = inverse_ordering.invert(); - const size_t n = inverse_ordering.size(), t = n * p.complexity_ ; + const size_t n = inverse_ordering.size(), m = gfg.size(); - vector w = weights(gfg); - const vector tree = buildTree(gfg, forward_ordering, w); + // Make sure the subgraph preconditioner does not include more than half of + // the edges beyond the spanning tree, or we might as well solve the whole thing. + size_t numExtraEdges = n * p.complexity_; + const size_t numRemaining = m - (n - 1); + numExtraEdges = std::min(numExtraEdges, numRemaining/2); - /* sanity check */ + // Calculate weights + vector weights = this->weights(gfg); + + // Build spanning tree. + const vector tree = buildTree(gfg, forward_ordering, weights); if ( tree.size() != n-1 ) { throw std::runtime_error("SubgraphBuilder::operator() tree.size() != n-1 failed "); } - /* down weight the tree edges to zero */ + // Downweight the tree edges to zero. for ( const size_t id: tree ) { - w[id] = 0.0; + weights[id] = 0.0; } /* decide how many edges to augment */ - vector offTree = sample(w, t); + vector offTree = sample(weights, numExtraEdges); vector subgraph = unary(gfg); subgraph.insert(subgraph.end(), tree.begin(), tree.end());