Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

HybridJunctionTree

Open In Colab

A HybridJunctionTree is the hybrid equivalent of gtsam.GaussianJunctionTree. It represents an intermediate stage in multifrontal variable elimination on a HybridGaussianFactorGraph.

It is a tree structure where each node (a “cluster” or “clique”) contains:

  1. A set of frontal variables (those being eliminated at this node).

  2. A set of separator variables (those shared with the parent clique).

  3. The original factors from the HybridGaussianFactorGraph that involve only the frontal and separator variables of this clique and its descendants in the elimination tree.

Key differences:

  • vs. HybridEliminationTree: A junction tree node can eliminate multiple variables (frontals) at once, whereas an elimination tree node corresponds to a single variable elimination.

  • vs. HybridBayesTree: A junction tree node stores the original factors before elimination, while a Bayes tree node stores the result of eliminating those factors (a HybridConditional).

Like HybridEliminationTree, the HybridJunctionTree is primarily an internal data structure used by the eliminateMultifrontal process. Its structure directly informs the structure of the resulting HybridBayesTree. Direct manipulation in Python is uncommon.

import gtsam
import numpy as np

from gtsam import (
    HybridGaussianFactorGraph,
    Ordering,
    HybridEliminationTree,
    HybridJunctionTree,
    JacobianFactor,
    DecisionTreeFactor,
    HybridGaussianFactor,
)
from gtsam.symbol_shorthand import X, D

Creating a HybridJunctionTree

It is constructed from a HybridEliminationTree. The process typically involves:

  1. Create HybridGaussianFactorGraph.

  2. Determine an Ordering.

  3. Build the HybridEliminationTree.

  4. Build the HybridJunctionTree from the HybridEliminationTree.

This process is encapsulated within HybridGaussianFactorGraph.eliminateMultifrontal.

# --- Create a HybridGaussianFactorGraph (same as HBT/HET examples) ---
hgfg = HybridGaussianFactorGraph()
dk0 = (D(0), 2)
prior_d0 = DecisionTreeFactor([dk0], "0.6 0.4"); hgfg.add(prior_d0) # F0
prior_x0 = JacobianFactor(X(0), np.eye(1), np.zeros(1), gtsam.noiseModel.Isotropic.Sigma(1, 1.0)); hgfg.add(prior_x0) # F1
gf0 = JacobianFactor(X(1), np.eye(1), np.array([1.0]), gtsam.noiseModel.Isotropic.Sigma(1, 0.5))
gf1 = JacobianFactor(X(1), np.eye(1), np.array([5.0]), gtsam.noiseModel.Isotropic.Sigma(1, 1.0))
meas_x1_d0 = HybridGaussianFactor(dk0, [gf0, gf1]); hgfg.add(meas_x1_d0) # F2
odom_x0_x1 = JacobianFactor(X(0), -np.eye(1), X(1), np.eye(1), np.array([1.0]), gtsam.noiseModel.Isotropic.Sigma(1, np.sqrt(0.1))); hgfg.add(odom_x0_x1) # F3
print("Original HybridGaussianFactorGraph:")
hgfg.print()

# --- Ordering and Elimination Tree ---
ordering = gtsam.Ordering([X(0), X(1), D(0)])
print(f"\nElimination Ordering: {ordering}")
het = HybridEliminationTree(hgfg, ordering)
print("\nHybridEliminationTree:")
het.print()

# --- Construct the Junction Tree ---
hjt = HybridJunctionTree(het)
print("\nResulting HybridJunctionTree:")
# Printing shows cliques, separators, and the *original factor indices* stored within each clique.
hjt.print()
Original HybridGaussianFactorGraph:

size: 4
Factor 0
DiscreteFactor:
 f[ (d0,2), ]
 Choice(d0) 
 0 Leaf  0.6
 1 Leaf  0.4

Factor 1
GaussianFactor:

  A[x0] = [
	1
]
  b = [ 0 ]
  Noise model: unit (1) 

Factor 2
HybridGaussianFactor:
Hybrid [x1; d0]{
 Choice(d0) 
 0 Leaf :
  A[x1] = [
	1
]
  b = [ 1 ]
isotropic dim=1 sigma=0.5
scalar: 0

 1 Leaf :
  A[x1] = [
	1
]
  b = [ 5 ]
  Noise model: unit (1) 
scalar: 0

}

Factor 3
GaussianFactor:

  A[x0] = [
	-1
]
  A[x1] = [
	1
]
  b = [ 1 ]
isotropic dim=1 sigma=0.316228


Elimination Ordering: Position 0: x0, x1, d0


HybridEliminationTree:
-(d0)
- f[ (d0,2), ]
 Choice(d0) 
 0 Leaf  0.6
 1 Leaf  0.4
| -(x1)
| -
Hybrid [x1; d0]{
 Choice(d0) 
 0 Leaf :
  A[x1] = [
	1
]
  b = [ 1 ]
isotropic dim=1 sigma=0.5
scalar: 0

 1 Leaf :
  A[x1] = [
	1
]
  b = [ 5 ]
  Noise model: unit (1) 
scalar: 0

}
| | -(x0)
| | -
  A[x0] = [
	1
]
  b = [ 0 ]
  Noise model: unit (1) 
| | -
  A[x0] = [
	-1
]
  A[x1] = [
	1
]
  b = [ 1 ]
isotropic dim=1 sigma=0.316228

Resulting HybridJunctionTree:
- (4) d0 
| - (4) x1 
| | - (4) x0 

Elimination

The primary purpose of the junction tree is to structure the multifrontal elimination process, which ultimately yields a HybridBayesTree. The eliminate method of the junction tree performs this step, but it’s usually accessed via HybridGaussianFactorGraph.eliminateMultifrontal.