{ "cells": [ { "cell_type": "markdown", "id": "b99b9acb", "metadata": {}, "source": [ "# Parametric and Interval Models\n", "In this notebook, we will show how to create and work with parametric and interval models.\n", "## Parametric Models" ] }, { "cell_type": "code", "execution_count": 1, "id": "2c761a13", "metadata": { "execution": { "iopub.execute_input": "2026-04-16T05:27:35.467674Z", "iopub.status.busy": "2026-04-16T05:27:35.467397Z", "iopub.status.idle": "2026-04-16T05:27:35.693410Z", "shell.execute_reply": "2026-04-16T05:27:35.692735Z" } }, "outputs": [], "source": [ "from stormvogel import parametric" ] }, { "cell_type": "markdown", "id": "45436d91", "metadata": {}, "source": [ "Polynomials are represented as dictionaries where the keys are the exponents and the values are coefficients. In addition, we must also supply a list of variable names. Rational functions are then represented as a pair of two polynomials (numerator and denominator)." ] }, { "cell_type": "code", "execution_count": 2, "id": "989db974", "metadata": { "execution": { "iopub.execute_input": "2026-04-16T05:27:35.695716Z", "iopub.status.busy": "2026-04-16T05:27:35.695425Z", "iopub.status.idle": "2026-04-16T05:27:35.699902Z", "shell.execute_reply": "2026-04-16T05:27:35.699302Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x^2 + y^2\n", "2.0*1 + z + 6.0*z^3\n", "(x^2 + y^2)/(2.0*1 + z + 6.0*z^3)\n" ] } ], "source": [ "polynomial1 = parametric.Polynomial([\"x\", \"y\"])\n", "polynomial1.add_term((2, 0), 1)\n", "polynomial1.add_term((0, 2), 1)\n", "\n", "print(polynomial1)\n", "\n", "polynomial2 = parametric.Polynomial([\"z\"])\n", "polynomial2.add_term((0,), 2)\n", "polynomial2.add_term((1,), 1)\n", "polynomial2.add_term((3,), 6)\n", "\n", "print(polynomial2)\n", "\n", "rational_function = parametric.RationalFunction(polynomial1, polynomial2)\n", "\n", "print(rational_function)" ] }, { "cell_type": "markdown", "id": "8bd42b56", "metadata": {}, "source": [ "To create a parametric model (e.g. pmc or pmdp) we simply have to set such a value as a transition probability. As an example, we provide the knuth yao dice, but with parameters instead of concrete probabilities." ] }, { "cell_type": "code", "execution_count": 3, "id": "ef86a1da", "metadata": { "execution": { "iopub.execute_input": "2026-04-16T05:27:35.701702Z", "iopub.status.busy": "2026-04-16T05:27:35.701522Z", "iopub.status.idle": "2026-04-16T05:27:35.922340Z", "shell.execute_reply": "2026-04-16T05:27:35.921743Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " Network\n", " \n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", " \n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from stormvogel import model, bird\n", "from stormvogel.show import show\n", "\n", "# we first make polynomials 'x' and '1-x'\n", "x = parametric.Polynomial([\"x\"])\n", "x.add_term((1,), 1)\n", "\n", "invx = parametric.Polynomial([\"x\"])\n", "invx.add_term((1,), -1)\n", "invx.add_term((0,), 1)\n", "\n", "\n", "# we build the knuth yao dice using the bird model builder\n", "def delta(\n", " s: bird.State,\n", ") -> list[tuple[float | parametric.Polynomial, bird.State]] | None:\n", " match s.s:\n", " case 0:\n", " return [(x, bird.State(s=1)), (invx, bird.State(s=2))]\n", " case 1:\n", " return [(x, bird.State(s=3)), (invx, bird.State(s=4))]\n", " case 2:\n", " return [(x, bird.State(s=5)), (invx, bird.State(s=6))]\n", " case 3:\n", " return [(x, bird.State(s=1)), (invx, bird.State(s=7, d=1))]\n", " case 4:\n", " return [\n", " (x, bird.State(s=7, d=2)),\n", " (invx, bird.State(s=7, d=3)),\n", " ]\n", " case 5:\n", " return [\n", " (x, bird.State(s=7, d=4)),\n", " (invx, bird.State(s=7, d=5)),\n", " ]\n", " case 6:\n", " return [(x, bird.State(s=2)), (invx, bird.State(s=7, d=6))]\n", " case 7:\n", " return [(1, s)]\n", "\n", "\n", "def labels(s: bird.State):\n", " if s.s == 7:\n", " return f\"rolled{str(s.d)}\"\n", "\n", "\n", "knuth_yao_pmc = bird.build_bird(\n", " delta=delta,\n", " init=bird.State(s=0),\n", " labels=labels,\n", " modeltype=model.ModelType.DTMC,\n", ")\n", "\n", "show(knuth_yao_pmc)" ] }, { "cell_type": "markdown", "id": "b883e86b", "metadata": {}, "source": [ "We can now evaluate the model by assigning the variable x to any concrete value. This induces a regular dtmc with fixed probabilities." ] }, { "cell_type": "code", "execution_count": 4, "id": "525a0264", "metadata": { "execution": { "iopub.execute_input": "2026-04-16T05:27:35.929568Z", "iopub.status.busy": "2026-04-16T05:27:35.929209Z", "iopub.status.idle": "2026-04-16T05:27:35.960837Z", "shell.execute_reply": "2026-04-16T05:27:35.960163Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " Network\n", " \n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", " \n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p = 1 / 2\n", "\n", "\n", "eval_knuth_yao_pmc = knuth_yao_pmc.get_instantiated_model({\"x\": p})\n", "show(eval_knuth_yao_pmc)" ] }, { "cell_type": "markdown", "id": "fb45a2fe", "metadata": {}, "source": [ "## Interval Models\n", "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 a class in model.py, where we have two attributes: bottom and top. Both of these should be an element of type Number, i.e., int, float or fraction." ] }, { "cell_type": "code", "execution_count": 5, "id": "2039d641", "metadata": { "execution": { "iopub.execute_input": "2026-04-16T05:27:35.968607Z", "iopub.status.busy": "2026-04-16T05:27:35.968373Z", "iopub.status.idle": "2026-04-16T05:27:35.971787Z", "shell.execute_reply": "2026-04-16T05:27:35.971275Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.3333333333333333,0.6666666666666666]\n" ] } ], "source": [ "interval = model.Interval(1 / 3, 2 / 3)\n", "print(interval)" ] }, { "cell_type": "markdown", "id": "fdb156e9", "metadata": {}, "source": [ "Similar to parametric models, creating an interval model is as straightforward as just setting some interval objects as transition values." ] }, { "cell_type": "code", "execution_count": 6, "id": "6a433727", "metadata": { "execution": { "iopub.execute_input": "2026-04-16T05:27:35.973556Z", "iopub.status.busy": "2026-04-16T05:27:35.973346Z", "iopub.status.idle": "2026-04-16T05:27:36.008879Z", "shell.execute_reply": "2026-04-16T05:27:36.008248Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " Network\n", " \n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", " \n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from stormvogel import bird\n", "from stormvogel.show import show\n", "\n", "# We create our interval values\n", "interval = model.Interval(2 / 7, 6 / 7)\n", "inv_interval = model.Interval(1 / 7, 5 / 7)\n", "\n", "\n", "# we build the knuth yao dice using the bird model builder\n", "def delta(s: bird.State) -> list[tuple[float | model.Interval, bird.State]] | None:\n", " match s.s:\n", " case 0:\n", " return [(interval, bird.State(s=1)), (inv_interval, bird.State(s=2))]\n", " case 1:\n", " return [(interval, bird.State(s=3)), (inv_interval, bird.State(s=4))]\n", " case 2:\n", " return [(interval, bird.State(s=5)), (inv_interval, bird.State(s=6))]\n", " case 3:\n", " return [(interval, bird.State(s=1)), (inv_interval, bird.State(s=7, d=1))]\n", " case 4:\n", " return [\n", " (interval, bird.State(s=7, d=2)),\n", " (invx, bird.State(s=7, d=3)),\n", " ]\n", " case 5:\n", " return [\n", " (interval, bird.State(s=7, d=4)),\n", " (invx, bird.State(s=7, d=5)),\n", " ]\n", " case 6:\n", " return [(interval, bird.State(s=2)), (inv_interval, bird.State(s=7, d=6))]\n", " case 7:\n", " return [(1, s)]\n", "\n", "\n", "def labels(s: bird.State):\n", " if s.s == 7:\n", " return f\"rolled{str(s.d)}\"\n", "\n", "\n", "knuth_yao_imc = bird.build_bird(\n", " delta=delta,\n", " init=bird.State(s=0),\n", " labels=labels,\n", " modeltype=model.ModelType.DTMC,\n", ")\n", "\n", "show(knuth_yao_imc)" ] }, { "cell_type": "code", "execution_count": null, "id": "15885467", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.13" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "00dc00b6aca3447287bdfdd08cec4c5d": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_98a711fec6724874a6ec62697bca29a4", "msg_id": "", "outputs": [], "tabbable": null, "tooltip": null } }, "28addf2c7106472b929998a0d4e3b1af": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2d0b7b64d6934e0193ef2c5ca2204587": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3deaab8fdf304dbeaae04f59f273735e": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_28addf2c7106472b929998a0d4e3b1af", "msg_id": "", "outputs": [], "tabbable": null, "tooltip": null } }, "401eaaf0aa74410483d17b7f35d0b087": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_2d0b7b64d6934e0193ef2c5ca2204587", "msg_id": "", "outputs": [], "tabbable": null, "tooltip": null } }, "57c667a39f13403aba4563efa36b4f2e": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_f1385939c48d49f18527b41cb627e8e5", "msg_id": "", "outputs": [], "tabbable": null, "tooltip": null } }, "69238ba330904221b3074c02ef6837d4": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_b2d077b6bc1c4da69305f0a46f1a5f8a", "msg_id": "", "outputs": [], "tabbable": null, "tooltip": null } }, "70c99ada43364e6faf8307a3ff0f7044": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "98a711fec6724874a6ec62697bca29a4": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b2d077b6bc1c4da69305f0a46f1a5f8a": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "c0ce240e754f44fe97bb7be1881389f0": { "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "model_name": "OutputModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_70c99ada43364e6faf8307a3ff0f7044", "msg_id": "", "outputs": [], "tabbable": null, "tooltip": null } }, "f1385939c48d49f18527b41cb627e8e5": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }