Parametric and Interval Models¶
In this notebook, we will show how to create and work with parametric and interval models. ## Parametric Models
Stormvogel represents parametric transition values as sympy expressions. Any polynomial or rational function over sympy.Symbol parameters is a valid transition value, which means you can write them using ordinary Python arithmetic.
[1]:
import sympy as sp
For example, a polynomial in two variables:
[2]:
x, y, z = sp.symbols("x y z")
polynomial1 = x**2 + y**2
print(polynomial1)
polynomial2 = 6 * z**3 + z + 2
print(polynomial2)
rational_function = polynomial1 / polynomial2
print(rational_function)
x**2 + y**2
6*z**3 + z + 2
(x**2 + y**2)/(6*z**3 + z + 2)
To create a parametric model (e.g. pMC or pMDP) we simply use these sympy expressions as transition probabilities. As an example, we build a parametric Knuth–Yao dice: a coin with success probability x is flipped repeatedly to simulate a six-sided die.
[3]:
from stormvogel import model, bird
from stormvogel.show import show
# A single symbolic parameter for the coin bias.
x = sp.Symbol("x")
# we build the Knuth–Yao dice using the bird model builder
def delta(
s: bird.State,
) -> list[tuple[float | sp.Expr, bird.State]] | None:
match s.s:
case 0:
return [(x, bird.State(s=1)), (1 - x, bird.State(s=2))]
case 1:
return [(x, bird.State(s=3)), (1 - x, bird.State(s=4))]
case 2:
return [(x, bird.State(s=5)), (1 - x, bird.State(s=6))]
case 3:
return [(x, bird.State(s=1)), (1 - x, bird.State(s=7, d=1))]
case 4:
return [
(x, bird.State(s=7, d=2)),
(1 - x, bird.State(s=7, d=3)),
]
case 5:
return [
(x, bird.State(s=7, d=4)),
(1 - x, bird.State(s=7, d=5)),
]
case 6:
return [(x, bird.State(s=2)), (1 - x, bird.State(s=7, d=6))]
case 7:
return [(1, s)]
def labels(s: bird.State):
if s.s == 7:
return f"rolled{str(s.d)}"
knuth_yao_pmc = bird.build_bird(
delta=delta,
init=bird.State(s=0),
labels=labels,
modeltype=model.ModelType.DTMC,
)
show(knuth_yao_pmc)
/tmp/ipykernel_1255/1846297749.py:10: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
s: bird.State,
/tmp/ipykernel_1255/1846297749.py:11: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
) -> list[tuple[float | sp.Expr, bird.State]] | None:
/tmp/ipykernel_1255/1846297749.py:37: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
def labels(s: bird.State):
/tmp/ipykernel_1255/1846297749.py:44: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
init=bird.State(s=0),
/tmp/ipykernel_1255/1846297749.py:14: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(x, bird.State(s=1)), (1 - x, bird.State(s=2))]
/tmp/ipykernel_1255/1846297749.py:16: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(x, bird.State(s=3)), (1 - x, bird.State(s=4))]
/tmp/ipykernel_1255/1846297749.py:18: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(x, bird.State(s=5)), (1 - x, bird.State(s=6))]
/tmp/ipykernel_1255/1846297749.py:20: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(x, bird.State(s=1)), (1 - x, bird.State(s=7, d=1))]
/tmp/ipykernel_1255/1846297749.py:23: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
(x, bird.State(s=7, d=2)),
/tmp/ipykernel_1255/1846297749.py:24: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
(1 - x, bird.State(s=7, d=3)),
/tmp/ipykernel_1255/1846297749.py:28: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
(x, bird.State(s=7, d=4)),
/tmp/ipykernel_1255/1846297749.py:29: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
(1 - x, bird.State(s=7, d=5)),
/tmp/ipykernel_1255/1846297749.py:32: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(x, bird.State(s=2)), (1 - x, bird.State(s=7, d=6))]
[3]:
<stormvogel.visualization.JSVisualization at 0x7f581019a120>
The symbol x was auto-declared on the model as soon as it appeared in a transition. You can inspect the parameters any time:
[4]:
print("Parameters:", knuth_yao_pmc.parameters)
Parameters: ('x',)
We can now evaluate the model by assigning the parameter x to any concrete value. This induces a regular DTMC with fixed probabilities.
[5]:
p = 1 / 2
eval_knuth_yao_pmc = knuth_yao_pmc.get_instantiated_model({"x": p})
show(eval_knuth_yao_pmc)
[5]:
<stormvogel.visualization.JSVisualization at 0x7f580fcc3b10>
Interval Models¶
We can also set an interval between two values x and y as transition value, meaning that we don’t know the probability precisely, but we know it is between x and y. We represent intervals using model.Interval, where we have two attributes: lower and upper. Both of these should be an element of type Number, i.e., int, float or Fraction.
[6]:
interval = model.Interval(1 / 3, 2 / 3)
print(interval)
[0.3333333333333333,0.6666666666666666]
Similar to parametric models, creating an interval model is as straightforward as just setting some interval objects as transition values.
[7]:
from stormvogel import bird
from stormvogel.show import show
# We create our interval values
interval = model.Interval(2 / 7, 6 / 7)
inv_interval = model.Interval(1 / 7, 5 / 7)
# we build the knuth yao dice using the bird model builder
def delta(s: bird.State) -> list[tuple[float | model.Interval, bird.State]] | None:
match s.s:
case 0:
return [(interval, bird.State(s=1)), (inv_interval, bird.State(s=2))]
case 1:
return [(interval, bird.State(s=3)), (inv_interval, bird.State(s=4))]
case 2:
return [(interval, bird.State(s=5)), (inv_interval, bird.State(s=6))]
case 3:
return [(interval, bird.State(s=1)), (inv_interval, bird.State(s=7, d=1))]
case 4:
return [
(interval, bird.State(s=7, d=2)),
(inv_interval, bird.State(s=7, d=3)),
]
case 5:
return [
(interval, bird.State(s=7, d=4)),
(inv_interval, bird.State(s=7, d=5)),
]
case 6:
return [(interval, bird.State(s=2)), (inv_interval, bird.State(s=7, d=6))]
case 7:
return [(1, s)]
def labels(s: bird.State):
if s.s == 7:
return f"rolled{str(s.d)}"
knuth_yao_imc = bird.build_bird(
delta=delta,
init=bird.State(s=0),
labels=labels,
modeltype=model.ModelType.DTMC,
)
show(knuth_yao_imc)
/tmp/ipykernel_1255/1271625296.py:10: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
def delta(s: bird.State) -> list[tuple[float | model.Interval, bird.State]] | None:
/tmp/ipykernel_1255/1271625296.py:36: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
def labels(s: bird.State):
/tmp/ipykernel_1255/1271625296.py:43: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
init=bird.State(s=0),
/tmp/ipykernel_1255/1271625296.py:13: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(interval, bird.State(s=1)), (inv_interval, bird.State(s=2))]
/tmp/ipykernel_1255/1271625296.py:15: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(interval, bird.State(s=3)), (inv_interval, bird.State(s=4))]
/tmp/ipykernel_1255/1271625296.py:17: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(interval, bird.State(s=5)), (inv_interval, bird.State(s=6))]
/tmp/ipykernel_1255/1271625296.py:19: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(interval, bird.State(s=1)), (inv_interval, bird.State(s=7, d=1))]
/tmp/ipykernel_1255/1271625296.py:22: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
(interval, bird.State(s=7, d=2)),
/tmp/ipykernel_1255/1271625296.py:23: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
(inv_interval, bird.State(s=7, d=3)),
/tmp/ipykernel_1255/1271625296.py:27: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
(interval, bird.State(s=7, d=4)),
/tmp/ipykernel_1255/1271625296.py:28: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
(inv_interval, bird.State(s=7, d=5)),
/tmp/ipykernel_1255/1271625296.py:31: DeprecationWarning: bird.State is deprecated, use bird.BirdState instead.
return [(interval, bird.State(s=2)), (inv_interval, bird.State(s=7, d=6))]
[7]:
<stormvogel.visualization.JSVisualization at 0x7f580fbf8050>
[ ]: