Skip to article frontmatterSkip to article content

JunctionTree

A JunctionTree is an intermediate data structure used in GTSAM’s multifrontal variable elimination. It is a ClusterTree where each node (cluster) corresponds to a clique in the chordal graph formed during elimination.

Key differences from related structures:

  • vs. EliminationTree: Junction tree nodes can represent the elimination of multiple variables simultaneously (a ‘frontal’ set), whereas elimination tree nodes typically represent single variable eliminations.
  • vs. BayesTree: A JunctionTree node contains the original factors associated with the variables being eliminated in that clique. A BayesTree node contains the result of eliminating those factors (i.e., a conditional density P(FrontalsSeparator)P(\text{Frontals} | \text{Separator})).

Like EliminationTree, direct manipulation of JunctionTree objects in Python is uncommon. It’s primarily an internal structure used by eliminateMultifrontal when producing a BayesTree.

Open In Colab

import gtsam
import numpy as np

# JunctionTree is templated, need concrete types
from gtsam import GaussianFactorGraph, Ordering, VariableIndex
from gtsam import symbol_shorthand

X = symbol_shorthand.X
L = symbol_shorthand.L

Creating a JunctionTree

A JunctionTree is typically constructed from an EliminationTree as part of the multifrontal elimination process. The direct constructor might not be exposed in Python, as it’s usually created internally.

# Create a graph (same as BayesTree example)
graph = GaussianFactorGraph()
model = gtsam.noiseModel.Isotropic.Sigma(1, 1.0)
graph.add(X(0), -np.eye(1), np.zeros(1), model)
graph.add(X(0), -np.eye(1), X(1), np.eye(1), np.zeros(1), model)
graph.add(X(1), -np.eye(1), X(2), np.eye(1), np.zeros(1), model)
graph.add(L(1), -np.eye(1), X(0), np.eye(1), np.zeros(1), model)
graph.add(L(1), -np.eye(1), X(1), np.eye(1), np.zeros(1), model)
graph.add(L(2), -np.eye(1), X(1), np.eye(1), np.zeros(1), model)
graph.add(L(2), -np.eye(1), X(2), np.eye(1), np.zeros(1), model)

ordering = Ordering.ColamdGaussianFactorGraph(graph)

# Perform multifrontal elimination, which uses a JunctionTree internally
bayes_tree, remaining_graph = graph.eliminatePartialMultifrontal(ordering)

# The resulting BayesTree reflects the structure of the intermediate JunctionTree
print("Resulting BayesTree (structure mirrors JunctionTree):")
bayes_tree.print()

# Accessing the JunctionTree directly isn't typical in Python workflows.
# Its structure is implicitly captured by the BayesTree cliques.
Resulting BayesTree (structure mirrors JunctionTree):
: cliques: 2, variables: 5
- p(x1 l2 x2 )
  R = [   1.61245 -0.620174 -0.620174 ]
      [         0   1.27098  -1.08941 ]
      [         0         0  0.654654 ]
  d = [ 0 0 0 ]
  mean: 3 elements
  l2: 0
  x1: 0
  x2: 0
  logNormalizationConstant: -2.46292
  No noise model
| - p(l1 x0  | x1)
  R = [   1.41421 -0.707107 ]
      [         0   1.58114 ]
  S[x1] = [ -0.707107 ]
          [ -0.948683 ]
  d = [ 0 0 ]
  logNormalizationConstant: -1.03316
  No noise model