Factor Graphs API
This page describes the public API for building, updating, and inspecting factor graph structures.
Construction and Updates
FactorGraph.factorGraph — Function
factorGraph(
variables::AbstractVector{GaussianVariable}, factors::AbstractVector{GaussianFactor};
root = nothing
)
factorGraph(
variables::AbstractVector{DiscreteVariable}, factors::AbstractVector{DiscreteFactor};
root = nothing
)Construct a Gaussian or discrete factor graph from variable and factor nodes.
Arguments
variables: Variable nodes.factors: Factor nodes.
Keywords
root: Optional root variable for returning aTreeFactorGraph.
Returns
A GaussianFactorGraph or DiscreteFactorGraph, or a TreeFactorGraph view when root is provided.
Example
x1 = GaussianVariable(:x1, 1)
f1 = GaussianFactor(:x1, 0.0, 1.0, 0.1; label = "f1")
graph = factorGraph([x1], [f1])FactorGraph.treeFactorGraph — Function
treeFactorGraph(graph::GaussianFactorGraph; root = nothing)Create a tree-oriented factor graph view rooted at root.
Arguments
graph: Gaussian factor graph.
Keywords
root: Optional root variable ID or label. If omitted, the first variable is used.
Returns
A TreeFactorGraph view that shares the original graph.
Notes
The graph must be connected and must have exactly nodes - 1 edges. The returned tree view shares the original graph data.
Example
x1 = GaussianVariable(:x1, 1)
x2 = GaussianVariable(:x2, 1)
f1 = GaussianFactor(:x1, 0.0, 1.0, 0.1; label = "f1")
f2 = GaussianFactor(:x1, :x2, 0.0, [1.0 -1.0], 0.2; label = "f2")
graph = factorGraph([x1, x2], [f1, f2])
tree = treeFactorGraph(graph; root = :x1)Gaussian Models
FactorGraph.addVariable! — Method
addVariable!(
graph::GaussianFactorGraph, variable::GaussianVariable
)
addVariable!(
graph::GaussianFactorGraph, id::VariableId, dimension::Int;
label = string(id), components = 1:dimension, mean = nothing, covariance = nothing
)Add a continuous Gaussian variable to an existing Gaussian factor graph.
Arguments
graph: Gaussian factor graph to mutate.variable: Gaussian variable node to add.id: Variable ID.dimension: Dimension of the continuous state vector.
Keywords
label: Variable label.components: Component references for entries of the continuous state vector.mean: Optional initial mean.covariance: Optional initial covariance.
Returns
The added GaussianVariable.
Notes
This is intended for incremental graph construction with factorGraph. Calling this graph-only method changes the graph topology and makes existing inference objects for this graph stale. For warm-start inference, use the method that also receives an inference object.
GaussianVariable IDs and labels must remain unique.
Example
graph = GaussianFactorGraph()
addVariable!(graph, GaussianVariable(:x1, 1; label = "x1"))
addVariable!(graph, :x2, 2; label = "x2", components = [:position, :velocity])FactorGraph.addFactor! — Method
addFactor!(
graph::GaussianFactorGraph, factor::GaussianFactor
)
addFactor!(
graph::GaussianFactorGraph,
variable::Union{VariableRef, GaussianVariable}..., mean, coefficient, covariance;
label = "", initialize = false
)Add a Gaussian factor node to an existing Gaussian factor graph.
Arguments
graph: Gaussian factor graph to mutate.factor: Factor node to add.variable...: Connected variable references or Gaussian variable nodes for constructor-style insertion.mean: Observed or target value.coefficient: Linear coefficient matrix.covariance: Factor covariance.
Keywords
label: Factor label.initialize: Whether a unary factor initializes the connected variable belief.
Returns
The added GaussianFactor.
Notes
The new Gaussian factor is validated against the graph's existing variables, assigned the next Gaussian factor ID, inserted into graph.factors, and connected by new edges. Existing variables are not modified, but their adjacency lists receive the new edge IDs.
If label is omitted, the Gaussian factor is named fN, where N is the assigned Gaussian factor ID. Explicit labels are kept unchanged. Gaussian factor labels must remain unique.
Calling this graph-only method does not resize existing inference objects. Create a fresh moment, canonical, or Gaussian minsum inference object before running message passing on the updated graph, or call addFactor!(graph, inference, factorData) to extend an existing inference object as a warm start.
Example
x1 = GaussianVariable(:x1, 1)
x2 = GaussianVariable(:x2, 1)
graph = GaussianFactorGraph([x1, x2], GaussianFactor[])
addFactor!(graph, GaussianFactor(:x1, 0.5, 1.0, 0.1))
addFactor!(graph, :x1, :x2, [0.4, -0.2], [1.0 0.5; -0.4 1.2], [0.3, 0.25])FactorGraph.updateFactor! — Method
updateFactor!(
graph::GaussianFactorGraph, factor::FactorRef;
mean = nothing, coefficient = nothing, covariance = nothing, initialize = nothing
)Update a Gaussian factor node's mean, coefficient, covariance, and/or initialization flag without changing graph topology or factor dimensions.
Arguments
graph: Gaussian factor graph to mutate.factor: Factor index or label.
Keywords
mean: Replacement observed or target value.coefficient: Replacement coefficient matrix.covariance: Replacement covariance.initialize: Replacement initialization flag; omitted keeps the current flag.
Returns
The updated GaussianFactor.
Notes
Use mean for the observed or target value stored in the Gaussian factor. Use coefficient to replace the Gaussian factor coefficient matrix.
The update keeps the existing connected variables, ID, and label. If initialize is omitted, the existing initialization flag is kept. The updated mean length, coefficient matrix size, and covariance matrix size must match the old Gaussian factor. Dimensions, positive definiteness, and initializing unary Gaussian factor conflicts are validated before the graph is modified, so a failed update leaves the old Gaussian factor unchanged.
Example
x1 = GaussianVariable(:x1, 1)
f1 = GaussianFactor(:x1, 0.25, 1.0, 0.15; label = "f1", initialize = true)
graph = GaussianFactorGraph([x1], [f1])
updateFactor!(graph, "f1"; mean = 0.6, covariance = 0.2)Discrete Models
FactorGraph.addVariable! — Method
addVariable!(
graph::DiscreteFactorGraph, variable::DiscreteVariable
)
addVariable!(
graph::DiscreteFactorGraph, id::VariableId, cardinality::Int;
label = string(id), states = 1:cardinality, probability = nothing
)Add a finite-state discrete variable to an existing discrete factor graph.
Arguments
graph: Discrete factor graph to mutate.variable: Discrete variable node to add.id: Variable ID.cardinality: Number of states.
Keywords
label: Variable label.states: State references for entries of the finite state set.probability: Optional initial probability vector.
Returns
The added DiscreteVariable.
Notes
This graph-only method changes topology and makes existing inference objects stale. For warm-start inference, use the method that also receives an inference object.
Discrete variable IDs and labels must remain unique.
Example
graph = DiscreteFactorGraph()
addVariable!(graph, DiscreteVariable(:x1, 2; label = "x1", states = [:off, :on]))
addVariable!(graph, :x2, 2; label = "x2", states = [:low, :high])FactorGraph.addFactor! — Method
addFactor!(
graph::DiscreteFactorGraph, factorData::DiscreteFactor
)
addFactor!(
graph::DiscreteFactorGraph, variable::Union{VariableRef, DiscreteVariable}..., table;
label = "", initialize = false
)Add a discrete factor node to an existing discrete factor graph.
Arguments
graph: Discrete factor graph to mutate.factorData: Factor node to add.variable...: Connected variable references or discrete variable nodes.table: Nonnegative factor table.
Keywords
label: Factor label.initialize: Whether a unary factor initializes the connected variable belief.
Returns
The added DiscreteFactor.
Notes
The new discrete factor is validated against the graph's existing variables, assigned the next discrete factor ID, inserted into graph.factors, and connected by new edges.
Calling this graph-only method changes topology and makes existing inference objects stale. For warm-start inference, use the method that also receives an inference object.
If label is omitted, the discrete factor is named fN, where N is the assigned discrete factor ID. Explicit labels are kept unchanged. Discrete factor labels must remain unique.
Example
x1 = DiscreteVariable(:x1, 2; label = "x1", states = [:off, :on])
graph = DiscreteFactorGraph([x1], DiscreteFactor[])
addFactor!(graph, DiscreteFactor(:x1, [0.8, 0.2]; label = "f1"))FactorGraph.updateFactor! — Method
updateFactor!(
graph::DiscreteFactorGraph, factor::FactorRef;
table = nothing, initialize = nothing
)Update a discrete factor table and/or initialization flag without changing graph topology or table dimensions.
Arguments
graph: Discrete factor graph to mutate.factor: Factor index or label.
Keywords
table: Replacement table.initialize: Replacement initialization flag; omitted keeps the current flag.
Returns
The updated DiscreteFactor.
Notes
The connected variables stay fixed. The replacement table must have the same dimensions as the current table. This method does not change graph topology, so existing inference objects are not stale, but use the inference-aware updateFactor! method when a running inference state should also update an initializing unary factor.
Example
x1 = DiscreteVariable(:x1, 2; label = "x1", states = [:off, :on])
f1 = DiscreteFactor(:x1, [0.8, 0.2]; label = "f1")
graph = DiscreteFactorGraph([x1], [f1])
updateFactor!(graph, "f1"; table = [0.6, 0.4])Graph Lookup
FactorGraph.variableIndex — Function
variableIndex(graph::GaussianFactorGraph, variable::VariableRef)Resolve a variable reference to its internal one-based variable index.
Arguments
graph: Gaussian factor graph used to resolvevariable.variable: Variable ID or label.
Returns
The one-based internal variable index.
Example
x1 = GaussianVariable(:x1, 1; label = "state")
graph = factorGraph([x1], GaussianFactor[])
variableIndex(graph, "state")FactorGraph.variableDimension — Function
variableDimension(graph::GaussianFactorGraph, variable::VariableRef)Return the continuous state-vector dimension of a Gaussian variable.
Arguments
graph: Gaussian factor graph used to resolvevariable.variable: Variable ID or label.
Returns
The variable dimension.
Example
x1 = GaussianVariable(:x1, 2; components = [:position, :velocity])
graph = GaussianFactorGraph([x1], GaussianFactor[])
variableDimension(graph, :x1)FactorGraph.factorIndex — Function
factorIndex(graph::GaussianFactorGraph, factor::FactorRef)Resolve a factor reference to its internal one-based factor index.
Arguments
graph: Gaussian factor graph used to resolvefactor.factor: Factor index or label.
Returns
The one-based internal factor index.
Example
x1 = GaussianVariable(:x1, 1)
f1 = GaussianFactor(:x1, 0.0, 1.0, 0.1; label = "f1")
graph = factorGraph([x1], [f1])
factorIndex(graph, "f1")FactorGraph.edgeIndex — Function
edgeIndex(graph::AbstractFactorGraph; variable::VariableRef, factor::FactorRef)Return the edge ID connecting variable and factor.
Arguments
graph: Gaussian or discrete factor graph.
Keywords
variable: Variable ID or label.factor: Factor index or label.
Returns
The one-based edge ID.
Notes
Throws an error if the selected variable and factor are not connected.
Example
x1 = DiscreteVariable(:x1, 2)
f1 = DiscreteFactor(:x1, [0.8, 0.2]; label = "f1")
graph = factorGraph([x1], [f1])
edgeIndex(graph; variable = :x1, factor = "f1")FactorGraph.edgeIndices — Function
edgeIndices(graph::AbstractFactorGraph; variable = nothing, factor = nothing)Return edge IDs connected to a variable, a factor, or their specific pair.
Arguments
graph: Gaussian or discrete factor graph.
Keywords
variable: Optional variable ID or label.factor: Optional factor index or label.
Returns
A vector of edge IDs.
Notes
Exactly one of variable or factor selects all adjacent edges for that node. Passing both selects the single edge between them.
Example
x1 = DiscreteVariable(:x1, 2)
f1 = DiscreteFactor(:x1, [0.8, 0.2]; label = "f1")
graph = factorGraph([x1], [f1])
edgeIndices(graph; variable = :x1)Gaussian Models
FactorGraph.componentIndex — Function
componentIndex(graph::GaussianFactorGraph, variable::VariableRef, component::ComponentRef)Resolve a Gaussian component reference to its one-based index within a variable.
Arguments
graph: Gaussian factor graph used to resolvevariable.variable: Variable ID or label.component: Component reference.
Returns
The one-based component index.
Example
x1 = GaussianVariable(:x1, 2; label = "state", components = [:position, :velocity])
graph = GaussianFactorGraph([x1], GaussianFactor[])
componentIndex(graph, :x1, :velocity)FactorGraph.componentValue — Function
componentValue(graph::GaussianFactorGraph, variable::VariableRef, index::Int)Return the component reference stored at a one-based index.
Arguments
graph: Gaussian factor graph used to resolvevariable.variable: Variable ID or label.index: One-based component index.
Returns
The component reference at index.
Example
x1 = GaussianVariable(:x1, 2; label = "state", components = [:position, :velocity])
graph = GaussianFactorGraph([x1], GaussianFactor[])
componentValue(graph, :x1, 1)FactorGraph.coefficientBlock — Function
coefficientBlock(graph::GaussianFactorGraph; factor::FactorRef, variable::VariableRef)Return the coefficient submatrix for one variable connected to a Gaussian factor.
Arguments
graph: Gaussian factor graph.
Keywords
factor: Factor index or label.variable: Variable ID or label.
Returns
The coefficient block for the selected variable.
Notes
This is useful when inspecting a Gaussian factor connected to multiple variables. The returned block uses the same row dimension as GaussianFactor.coefficient and the column dimension of the selected variable.
Example
x1 = GaussianVariable(:x1, 1)
x2 = GaussianVariable(:x2, 1)
f1 = GaussianFactor(:x1, :x2, 0.0, [1.0 -1.0], 0.2; label = "f1")
graph = factorGraph([x1, x2], [f1])
coefficientBlock(graph; factor = "f1", variable = :x2)FactorGraph.coefficientBlocks — Function
coefficientBlocks(graph::GaussianFactorGraph, factor::FactorRef)Return coefficient submatrices for all variables connected to a Gaussian factor.
Arguments
graph: Gaussian factor graph.factor: Factor index or label.
Returns
The blocks in the same order as the factor's variables field.
Example
x1 = GaussianVariable(:x1, 1)
x2 = GaussianVariable(:x2, 1)
f1 = GaussianFactor(:x1, :x2, 0.0, [1.0 -1.0], 0.2; label = "f1")
graph = factorGraph([x1, x2], [f1])
coefficientBlocks(graph, "f1")Discrete Models
FactorGraph.stateIndex — Function
stateIndex(graph::DiscreteFactorGraph, variable::VariableRef, state::StateRef)Resolve a discrete state reference to its one-based index within a variable.
Arguments
graph: Discrete factor graph used to resolvevariable.variable: Variable ID or label.state: State reference.
Returns
The one-based state index.
Example
x1 = DiscreteVariable(:x1, 2; label = "x1", states = [:off, :on])
f1 = DiscreteFactor(:x1, [0.8, 0.2]; label = "f1")
graph = factorGraph([x1], [f1])
stateIndex(graph, :x1, :on)FactorGraph.stateValue — Function
stateValue(graph::DiscreteFactorGraph, variable::VariableRef, index::Int)Return the state reference stored at a one-based index.
Arguments
graph: Discrete factor graph used to resolvevariable.variable: Variable ID or label.index: One-based state index.
Returns
The state reference at index.
Example
x1 = DiscreteVariable(:x1, 2; label = "x1", states = [:off, :on])
f1 = DiscreteFactor(:x1, [0.8, 0.2]; label = "f1")
graph = factorGraph([x1], [f1])
stateValue(graph, :x1, 2)FactorGraph.factorAxis — Function
factorAxis(graph::DiscreteFactorGraph; factor::FactorRef, variable::VariableRef)Return the table axis for one variable connected to a discrete factor.
Arguments
graph: Discrete factor graph.
Keywords
factor: Factor index or label.variable: Variable ID or label.
Returns
The one-based table axis for the selected variable.
Notes
Discrete factor table axes follow the same order as the factor's variables field. This helper is useful when inspecting a discrete factor connected to multiple variables.
Example
x1 = DiscreteVariable(:x1, 2; label = "x1", states = [:off, :on])
x2 = DiscreteVariable(:x2, 2; label = "x2", states = [:low, :high])
f1 = DiscreteFactor(:x1, :x2, [1.0 0.2; 0.1 0.9]; label = "f1")
graph = factorGraph([x1, x2], [f1])
factorAxis(graph; factor = "f1", variable = :x2)FactorGraph.factorAxes — Function
factorAxes(graph::DiscreteFactorGraph, factor::FactorRef)Return table axes for all variables connected to a discrete factor.
Arguments
graph: Discrete factor graph.factor: Factor index or label.
Returns
The axes in the same order as the factor's variables field.
Example
x1 = DiscreteVariable(:x1, 2; label = "x1", states = [:off, :on])
x2 = DiscreteVariable(:x2, 2; label = "x2", states = [:low, :high])
f1 = DiscreteFactor(:x1, :x2, [1.0 0.2; 0.1 0.9]; label = "f1")
graph = factorGraph([x1, x2], [f1])
factorAxes(graph, "f1")Graph Figures
FactorGraph.graphFigure — Function
graphFigure(graph::AbstractFactorGraph; kwargs...)Return an SVG visualization of a factor graph.
Arguments
graph: Factor graph or tree view to draw.
Keywords
Canvas options control the size, padding, and displayed scale of the SVG:
canvas = NamedTuple(): Override canvas options. Supported keys are:width: Minimum SVG canvas width. Ifnothing, fit the graph tightly withpadding.height: Minimum SVG canvas height. Ifnothing, fit the graph tightly withpadding.padding: Minimum padding around the drawn graph.zoom: Scale the displayed SVG size while preserving the same view box.
Layout options control graph orientation, spacing, and edge geometry:
layout = NamedTuple(): Override layout options. Supported keys are:orientation: Use:horizontalor:verticallayout.rowSpacing: Vertical spacing between node rows. May be a scalar or a tuple/vector of per-gap spacings; the last per-gap value is reused.columnSpacing: Horizontal spacing between node columns. May be a scalar or a tuple/vector of per-gap spacings; the last per-gap value is reused.curvedEdges: Draw edges as cubic curves instead of straight lines.
Node options control the size of variable and factor nodes:
node = NamedTuple(): Override node options. Supported keys are:variableRadius: Default variable node radius.factorSize: Default factor node size.
Label options control label placement, visibility, and font size:
label = NamedTuple(): Override label options. Supported keys are:placement: Place labels:outsidenodes or:insidenodes.outsideGap: Gap between a node and its outside label.showVariables: Draw variable labels.showFactors: Draw factor labels.showTooltips: Add SVG hover tooltips for variables, factors, and edges.showEdgeIds: Draw edge ID labels next to edges.tooltipDetail: Tooltip detail level::summaryor:full.fontSize: Label font size in SVG user units.
View options control which part of a factor graph or tree view is drawn:
view = NamedTuple(): Override view options. Supported keys are:variables: Variable IDs or labels used as the focus.factors: Factor IDs or labels used as the focus.hops: Nonnegative number of bipartite graph hops from focused variables and factors, or:allto expand through the connected component.
Style options control default graph colors and stroke widths:
style = NamedTuple(): Override default SVG styles. Supported keys are:backgroundFill: SVG background fill color.variableFill: Variable node fill color.variableStroke: Variable node stroke color.variableStrokeWidth: Variable node stroke width.factorFill: Factor node fill color.factorStroke: Factor node stroke color.factorStrokeWidth: Factor node stroke width.edgeStroke: Edge stroke color.edgeStrokeWidth: Edge stroke width.edgeOpacity: Edge stroke opacity.labelFill: Label text fill color.
Highlight options control highlighted variables, factors, and edges:
highlight = NamedTuple[]: Highlight entries. Supported entry selectors are:(variable = x1, ...): Highlight a variable node.(factor = f1, ...): Highlight a factor node.(edge = 1, ...): Highlight an edge by edge ID or edge object.(variable = x1, factor = f1, ...): Highlight the edge connecting a variable and factor.
Supported style keys are:
stroke: Node or edge stroke color.fill: Node fill color. Applies only to variable and factor entries.strokeWidth: Stroke width for the selected variable, factor, or edge.incidentEdges: Whether a variable or factor entry highlights incident edges. Defaults totrue.edgeStroke: Incident edge stroke color for variable and factor entries.edgeStrokeWidth: Incident edge stroke width for variable and factor entries. Defaults tostrokeWidth.
Returns
An SVG document as a String.
Notes
For a general factor graph, horizontal layout draws unary factors on the left, variables in the middle, and multi-variable factors on the right. Vertical layout draws unary factors above variables and multi-variable factors below variables.
For a TreeFactorGraph, the layout uses graph depth. In horizontal tree layout, columnSpacing separates depth levels and rowSpacing separates nodes within a level. In vertical tree layout, rowSpacing separates depth levels and columnSpacing separates nodes within a level.
Example
variables = [
GaussianVariable(:x1, 1; label = "x1"),
GaussianVariable(:x2, 1; label = "x2")
]
factors = [
GaussianFactor(:x1, 0.0, 1.0, 1.0; label = "prior"),
GaussianFactor(:x1, :x2, 0.0, [1.0 -1.0], 1.0; label = "link")
]
graph = factorGraph(variables, factors)
svg = graphFigure(
graph;
highlight = [(variable = :x1, stroke = "#16a34a", fill = "#dcfce7", strokeWidth = 4)]
)graphFigure(graph::AbstractFactorGraph, inference::AbstractInference; kwargs...)Return an SVG visualization of graph with diagnostics from an existing inference object.
Arguments
graph: Factor graph to draw.inference: Existing inference object used for diagnostic values.
Keywords
Inference options control diagnostic overlays without running inference:
residual = nothing: Shade message residuals. Use:all, a positive integer count, or a fraction in(0, 1].variance = nothing: Shade Gaussian sum-product marginal variances. Use:all, a positive integer count, or a fraction in(0, 1].
Variable tooltips include current marginal values when available.
All graph-only graphFigure keywords are also supported.
Example
inference = moment(graph)
graphFigure(
graph,
inference;
residual = 4,
variance = :all
)FactorGraph.saveGraphFigure — Function
saveGraphFigure(path::AbstractString, graph::AbstractFactorGraph; kwargs...)Write a dependency-free SVG visualization of a factor graph to path.
Arguments
path: Output SVG file path.graph: Factor graph or tree view to draw.
Keywords
All keyword arguments are forwarded to graphFigure.
Returns
The written path.
Notes
The output is an SVG document. Parent directories must already exist.
Example
saveGraphFigure(
"graph.svg",
graph;
layout = (orientation = :vertical,),
label = (placement = :inside,)
)saveGraphFigure(path::AbstractString,
graph::AbstractFactorGraph,
inference::AbstractInference;
kwargs...
)Write an SVG visualization of graph with diagnostics from an existing inference object to path.
This method forwards keyword arguments to graphFigure(graph, inference; ...).
saveGraphFigure(
path::AbstractString,
tree::TreeFactorGraph,
inference::AbstractInference;
kwargs...
)Write an SVG visualization of tree with diagnostics from an existing inference object to path.
This method forwards keyword arguments to graphFigure(tree, inference; ...).