`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 |