Skip to article frontmatterSkip to article content

Signature

Open In Colab

A gtsam.Signature is a helper object used to construct discrete conditionals (DiscreteConditional and DiscreteDistribution). It provides a compact and readable way to define a conditional probability table (CPT) along with the variables involved.

While in C++ Signature enables expressive syntax like (D|E,B) = "9/1 2/8 3/7 1/9", this syntax does not translate directly to Python. However, the core concept of specifying a key, its parents, and a CPT string is central to how discrete factors are created in the Python wrapper.

This notebook explains the CPT string format and shows how to use the signature concept to easily create discrete conditionals and Bayes nets in Python.

import gtsam
from gtsam.symbol_shorthand import A, B, C

The Signature CPT String Format

The power of the signature concept comes from its compact CPT string representation.

  • Parent Assignment Order: The table is specified in an order where the parents’ assignments count up like a binary number. The last parent in the list varies fastest. For parents A, B, the order is A=0,B=0, then A=0,B=1, then A=1,B=0, then A=1,B=1.

  • Child Probabilities: For each parent assignment, you provide the probabilities for the child variable’s outcomes. These are often written as ratios separated by a /. For a binary child, "9/1" is shorthand for P(Child=0)=0.9, P(Child=1)=0.1. The values are automatically normalized.

Example: For P(CA,B)P(C | A, B) where A, B, and C are binary, the string "1/9 2/8 3/7 4/6" corresponds to:

  1. A=0, B=0: P(C=0)=0.1,P(C=1)=0.9P(C=0)=0.1, P(C=1)=0.9

  2. A=0, B=1: P(C=0)=0.2,P(C=1)=0.8P(C=0)=0.2, P(C=1)=0.8

  3. A=1, B=0: P(C=0)=0.3,P(C=1)=0.7P(C=0)=0.3, P(C=1)=0.7

  4. A=1, B=1: P(C=0)=0.4,P(C=1)=0.6P(C=0)=0.4, P(C=1)=0.6

Using the Signature Concept in Python

The most common and direct way to use this concept in Python is to pass the signature components (key, parents, CPT string) directly into the DiscreteConditional or DiscreteDistribution constructors. This bypasses the need to create an explicit Signature object.

# Define keys for three binary variables
KeyA = (A(0), 2)
KeyB = (B(0), 2)
KeyC = (C(0), 2)

# Create a prior (no parents) P(A)
# This is the signature: A % "8/2"
p_A = gtsam.DiscreteDistribution(KeyA, "8/2")
p_A
Loading...
# Create a conditional P(B|A)
# Signature: (B|A) = "1/9 6/4"
# Parent A=0: P(B)=0.1/0.9; Parent A=1: P(B)=0.6/0.4
p_B_given_A = gtsam.DiscreteConditional(KeyB, [KeyA], "1/9 6/4")
p_B_given_A
Loading...
# The constructors for factor graph and Bayes nets are also overloaded
dbn = gtsam.DiscreteBayesNet()
dbn.add(KeyA, "8/2")
dbn.add(KeyB, [KeyA], "1/9 6/4")
dbn
Loading...