Skip to article frontmatterSkip to article content

DiscreteConditional

Open In Colab

A DiscreteConditional represents a conditional probability distribution, P(FrontalParents)P(\text{Frontal} | \text{Parents}), for a set of discrete variables. It is a fundamental building block for representing directed graphical models, like Bayes Nets.

It is a DecisionTreeFactor underneath, but with the additional structure that it distinguishes between frontal (child) and parent variables. The stored values are the probabilities, and for any given assignment to the parent variables, the probabilities of the frontal variable(s) sum to 1.

import gtsam
import numpy as np
import graphviz

from gtsam.symbol_shorthand import C, S, R

Creating a DiscreteConditional

A DiscreteConditional is created by specifying the frontal (child) key(s), the parent key(s), and the conditional probability table (CPT). The CPT can be given as a list of numbers or a formatted string.

# Define keys for three binary variables: Cloudy, Sprinkler, Rain
# The first element is the gtsam Key, the second is the cardinality.
Cloudy = (C(0), 2)
Sprinkler = (S(0), 2)
Rain = (R(0), 2)

# Create P(Cloudy), a conditional with no parents (a prior).
# This is equivalent to a DiscreteDistribution.
p_C = gtsam.DiscreteConditional(Cloudy, [], "0.5/0.5")
print("--- P(Cloudy) ---")
p_C.print()

# Create P(Sprinkler | Cloudy)
# CPT is ordered by parent assignments: C=0, C=1
# For C=0 (false), P(S=0|C=0)=0.5, P(S=1|C=0)=0.5
# For C=1 (true),  P(S=0|C=1)=0.9, P(S=1|C=1)=0.1
p_S_given_C = gtsam.DiscreteConditional(Sprinkler, [Cloudy], "0.5/0.5 0.9/0.1")
print("\n--- P(Sprinkler | Cloudy) ---")
p_S_given_C.print()

# Create P(Rain | Cloudy)
# For C=0 (false), P(R=0|C=0)=0.2, P(R=1|C=0)=0.8
# For C=1 (true),  P(R=0|C=1)=0.8, P(R=1|C=1)=0.2
p_R_given_C = gtsam.DiscreteConditional(Rain, [Cloudy], "0.2/0.8 0.8/0.2")
print("\n--- P(Rain | Cloudy) ---")
p_R_given_C.print()
--- P(Cloudy) ---
Discrete Conditional
 P( c0 ):
 Leaf  0.5


--- P(Sprinkler | Cloudy) ---
Discrete Conditional
 P( s0 | c0 ):
 Choice(s0) 
 0 Choice(c0) 
 0 0 Leaf  0.5
 0 1 Leaf  0.9
 1 Choice(c0) 
 1 0 Leaf  0.5
 1 1 Leaf  0.1


--- P(Rain | Cloudy) ---
Discrete Conditional
 P( r0 | c0 ):
 Choice(r0) 
 0 Choice(c0) 
 0 0 Leaf  0.2
 0 1 Leaf  0.8
 1 Choice(c0) 
 1 0 Leaf  0.8
 1 1 Leaf  0.2

Operations on DiscreteConditional

# --- Evaluation ---
# Evaluate the probability for a full assignment of variables.
values = gtsam.DiscreteValues()
values[C(0)] = 1 # Cloudy = true
values[S(0)] = 0 # Sprinkler = false

prob = p_S_given_C.evaluate(values)
log_prob = p_S_given_C.logProbability(values)
print(f"P(S=0|C=1) = {prob} (log: {log_prob})")

# --- Sampling ---
# Sample the frontal variable given an assignment for the parents.
parent_values = gtsam.DiscreteValues()
parent_values[C(0)] = 1 # Condition on Cloudy = true
sampled_sprinkler = p_S_given_C.sample(parent_values)
print(f"\nSample for Sprinkler given Cloudy=true: {sampled_sprinkler}")

# --- Argmax (Most Probable Explanation) ---
# Find the most likely assignment of the frontal variable given parents.
mpe_sprinkler = p_S_given_C.argmax(parent_values)
print(f"Most likely state for Sprinkler given Cloudy=true: {mpe_sprinkler}")
P(S=0|C=1) = 0.9 (log: -0.10536051565782628)

Sample for Sprinkler given Cloudy=true: 0
Most likely state for Sprinkler given Cloudy=true: 0
# --- Choose (Conditioning on parent values) ---
# Restricting a conditional on a parent value yields a new conditional
# (or a prior if all parents are specified).

# Let's fix Cloudy=false (0)
given_C_false = gtsam.DiscreteValues()
given_C_false[C(0)] = 0
p_S = p_S_given_C.choose(given_C_false)

print("P(S | C=false):")
p_S.print()

# --- Likelihood ---
# Create a likelihood factor on the parents given a value for the child.
frontal_values = gtsam.DiscreteValues()
frontal_values[S(0)] = 1 # Evidence: Sprinkler=true
likelihood_of_C = p_S_given_C.likelihood(frontal_values)

print("\nLikelihood L(C | S=true):")
likelihood_of_C.print()
P(S | C=false):
Discrete Conditional
 P( s0 ):
 Leaf  0.5


Likelihood L(C | S=true):
DecisionTreeFactor
 f[ (c0,2), ]
 Choice(c0) 
 0 Leaf  0.5
 1 Leaf  0.1

Displaying with Markdown/HTML

The rich display for a conditional shows the full CPT.

p_S_given_C
Loading...