from gtbook.display import show
discrete
This notebook contains some utility functions for discrete inference, primarily for use in Chapter 2 of the book.
DiscretePrior
DiscretePrior
is something that was previously defined here but is now built into GTSAM as DiscreteDistribution
:
= 0, 5 # A key is an identifier (0 in this example) and a cardinality (e.g., 5)
C = gtsam.DiscreteDistribution(C, "25/20/30/20/5")
prior False)
test_eq(prior.empty(),
# TODO: this does not support key formatting yet, just shows the key (0 in this case)
show(prior)
= prior(3)
prior_probability_for_3 0.2) test_eq(prior_probability_for_3,
Variables
We would like to make it easier for people to create discrete variables, with a meaningful name, and meaningful strings associated with discrete values. Below is it possible design:
Variables
Variables ()
A problem domain for discrete variables.
DiscreteVariable
DiscreteVariable (name:str, domain:list[str])
Creating discrete variables
Here is an example: - we first create the variables
instance - then define a new discrete category using the discrete
method - we then check that it has a name
and a domain
= Variables()
variables = ["cardboard", "paper", "can", "scrap metal", "bottle"]
categories = variables.discrete("Category", categories)
Category
"Category")
test_eq(variables.name(Category), test_eq(variables.domain(Category), categories)
Binary variables are supported as a special case:
= variables.binary("Conductivity")
Conductivity "false", "true"]) test_eq(variables.domain(Conductivity), [
Assignments
Providing the domains to the Variables
data structure also makes it easy to create an assignment. An assignment, which has the type DiscreteValues
in GTSAM, is a mapping from discrete keys to discrete values.
= variables.assignment({Category: "can"})
assignment isinstance(assignment, gtsam.DiscreteValues), True)
test_eq(0]], categories.index("can")) test_eq(assignment[C[
Rendering assignments
We also create a markdown renderer for DiscreteValues
, awaiting the ability of pybind11 to wrap classes inherited from STL containers:
We have the functionality to provide a key formatter
= variables.keyFormatter()
keyFormatter 0]), "Category") test_eq(keyFormatter(Category[
We can also create a names dictionary that allows our rendering code to retrieve the domain for a given key:
= variables.names()
names isinstance(names, dict), True)
test_eq(len(names), 2)
test_eq(0: ['cardboard', 'paper', 'can', 'scrap metal', 'bottle'], 1: ['false', 'true']}) test_eq(names, {
With these 2 in hand, we could create a markdown renderer:
test_eq(
variables.values_markdown(assignment),"|Variable|value|\n|:-:|:-:|\n|Category|can|\n",
)
And HTML:
HTML(variables.values_html(assignment))
Variable | value |
---|---|
Category | can |
Series of discrete variables
As of version 0.0.14
, we also support generating a set of discrete keys with integer indices, to support reasoning over time:
= variables.size()
n
# add 5 variables
= variables.discrete_series('s', range(1,5), ["no", "yes"])
states +4)
test_eq(variables.size(), n
# calling twice should not add any more
= variables.discrete_series('s', range(1,5), ["no", "yes"])
states +4)
test_eq(variables.size(), n
1]), "s1")
test_eq(variables.name(states[1]), ["no", "yes"]) test_eq(variables.domain(states[
= variables.size()
n
# expand range
= variables.discrete_series('s', range(9,10), ["no", "yes"])
states +1)
test_eq(variables.size(), n9]), "s9") test_eq(variables.name(states[
Rendering all variables defined
It would be nice to inspect a Variables
instance easily in a notebook, and we can easily support this by supplying an HTML representation::
variables
Variable | Domain |
---|---|
Category | cardboard, paper, can, scrap metal, bottle |
Conductivity | false, true |
s1 | no, yes |
s2 | no, yes |
s3 | no, yes |
s4 | no, yes |
s9 | no, yes |