{ "cells": [ { "cell_type": "markdown", "id": "eb8fdaa2-329e-459e-bcde-4fdd9e87c6ed", "metadata": {}, "source": [ "(what_is_uncertain_number)=\n", "# What is an uncertain number" ] }, { "cell_type": "markdown", "id": "61326dc1", "metadata": {}, "source": [ "```{important}\n", "*Uncertain Number* refers to a unified class of mathematical constructs useful for uncertainty representation that generalize real numbers, intervals, probability distributions, interval bounds on probability distributions (i.e. [probability boxes (p-boxes)](https://en.wikipedia.org/wiki/Probability_box)), and finite [Dempster-Shafer structures (DSS)](https://en.wikipedia.org/wiki/Dempster–Shafer_theory). \n", "```" ] }, { "cell_type": "markdown", "id": "479b7d5c-dfca-4682-a5d0-b10f912bd577", "metadata": {}, "source": [ "The Python library `pyuncertainnumber` provides a closed computation environmnent where one can easily compute with uncertain numbers. Similar to automatic inference, one only needs to characterise the uncertain quantities of interest in his own analysis as uncertain numbers given the empirical knowledge, and then `pyuncertainnumber` will provide automatic uncertainty quantification.\n", " \n", "These constructs are closely related to each other. `pyuncertainnumber` facilitates the computations of mixed-type uncertainties, which is common in real-world engineering analyses, since it is provided a consistent interface to work with uncertain numbers.\n", "\n", "
\n", " \n", "
Constructs of uncertain numbers
\n", "
\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "c8fcc65d-498c-4bca-9bd0-e87660931c8b", "metadata": {}, "outputs": [], "source": [ "import pyuncertainnumber as pun # yeah, pun intended\n", "import numpy as np" ] }, { "cell_type": "markdown", "id": "c85e25d1-401a-48e5-aaff-04cbc46a3251", "metadata": {}, "source": [ "### `Interval` type of uncertain number\n", "\n", "an interval indicates a value imprecisely known within a range where no assumptions of likelihood about the enclosed values are made;" ] }, { "cell_type": "code", "execution_count": 3, "id": "0d3d2dfb-2696-42dc-96ed-049638164aee", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "UncertainNumber(essence='interval', intervals=[3.0,4.0], _construct=[3.0,4.0], nominal_value=3.5)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pun.I(3, 4)" ] }, { "cell_type": "markdown", "id": "d500c70a-faf7-4711-ad42-4f1716b7d3f5", "metadata": {}, "source": [ "### `Distribution` type of uncertain number" ] }, { "cell_type": "code", "execution_count": 4, "id": "f5f0f88c-10cc-42d1-92ce-f73e62661437", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "UncertainNumber(essence='distribution', _construct=dist ~ gaussian(4, 1), nominal_value=4.0)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pun.D(\"gaussian\", (4, 1))" ] }, { "cell_type": "markdown", "id": "1e5c4cf9-5c3e-4aff-8ec5-4ba11996cca7", "metadata": {}, "source": [ "### `P-box` type of uncertain number\n", "\n", "P-boxes can be considered as interval bounds on cumulative distributions and Parametric p-boxes $F_{X}(x|\\theta^{I})$ are probability distributions whose parameters $\\theta^{I}$ and samples are intervals, and an interval ($I = [a, b]$) can be identified as a p-box $[H_a(x), H_b(x)]$ whose bounds are unit step functions denoted by $H(x)$;" ] }, { "cell_type": "code", "execution_count": 5, "id": "0599e3cc-d801-48da-a247-b192748eb233", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "UncertainNumber(essence='pbox', _construct=Pbox ~ (range=[0.910, 9.090], mean=[4.000, 6.000], var=[1.000, 1.000], shape=norm), nominal_value=5.0)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pun.normal([4, 6], 1)" ] }, { "cell_type": "markdown", "id": "c5f75908-96b0-406e-9139-bfba7f1a4ae9", "metadata": {}, "source": [ "### `Dempster Shafer structure` type of uncertain number\n", "\n", "a DSS can be deemed as a discrete distribution with interval quantiles. A p-box can be discretised into a DSS with pairs of intervals (focal elements) and probability masses $\\{([a_i, b_i], p_i)_{1}^{N}\\}$, and conversely a DSS can be stacked with a list of intervals." ] }, { "cell_type": "code", "execution_count": 6, "id": "8f76e8d5-fb01-43fa-8a6b-0a3628767df4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "UncertainNumber(essence='pbox', _construct=Pbox ~ (range=[1.000, 6.000], mean=[2.002, 5.497], var=[666.000, 666.000]), nominal_value=3.749)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# dempster-shafer-type uncertain number\n", "pun.DSS(intervals=[[1,5], [3,6]], masses=[0.5, 0.5])" ] }, { "cell_type": "markdown", "id": "41e7d58f-1f49-419a-8396-10662ccf4900", "metadata": {}, "source": [ "```{note}\n", "Besides the above constructors, one can also use the canonical constructor style to construct uncertain numbers where one can specify many fields related to the quantity of interest, for example the units.\n", "```" ] }, { "cell_type": "code", "execution_count": 7, "id": "0c747b9d-2619-4398-b8d2-c806f5955ef7", "metadata": {}, "outputs": [], "source": [ "un = pun.UncertainNumber(\n", " name='elas_modulus', \n", " symbol='E', \n", " units='Pa', \n", " essence='pbox', \n", " pbox_parameters=['gaussian', ([0,12],[1,4])])" ] }, { "cell_type": "markdown", "id": "ce18c2a7-52b3-4f2c-b57b-ef860bf5fdc2", "metadata": {}, "source": [ "Information about the uncertain number can be hinted from the `describe()` method." ] }, { "cell_type": "code", "execution_count": 8, "id": "54ee2f2a-7c40-4fcb-86b3-41bfcfcb767e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'This is a pbox-type Uncertain Number that follows a gaussian distribution with parameters ([0, 12], [1, 4])'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "un.describe(style=\"verbose\")" ] }, { "cell_type": "markdown", "id": "58f0812d-ae9a-4c05-8d67-6bdce9fc075e", "metadata": {}, "source": [ "## what you can do with `uncertain numbers`\n", "\n", "The framework of `uncertain numbers`, embedded in the library `pyuncertainnumber`, facilitates trustworthy management of uncertainty. **It provides capabilities across the typical uncertainty analysis pipeline, encompassing characterisation, aggregation, propagation, and applications including reliability analysis and optimisation under uncertainty, especailly with a focus on imprecise probabilities.** \n", "\n", "With the idea of duck-typing, one can directly compute with uncertain numbers through a Python function by drop-in replacements of real numbers (represented by basic Python numeric types or Numpy arrays). Numpy ufuncs are also supported in the definition of the function. Moreover, in cases when you cannot access the function (i.e. non-intrusive), there are metholodogies in house to deal with." ] }, { "cell_type": "code", "execution_count": 9, "id": "d83f8987-1194-4c85-ad36-108e27b7fa5b", "metadata": {}, "outputs": [], "source": [ "def foo(x, y, z):\n", " return x**3 + np.exp(y) - 5*z" ] }, { "cell_type": "code", "execution_count": 10, "id": "e94d0be3-4f0d-40d7-9804-ad3d02122aa0", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "np.float64(-4.23594390106935)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# a deterministic call of the function with plain numbers will yield a result\n", "foo(1.5, 2., 3)" ] }, { "cell_type": "code", "execution_count": 11, "id": "508aa944-10b6-43e8-83ef-dfee3fd9608b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "UncertainNumber(essence='pbox', _construct=Pbox ~ (range=[-27.424, 97.171], mean=[-20.473, 25.895], var=[20.938, 154.317]), nominal_value=2.711)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# uncertainty arithmetic \n", "\n", "i = pun.I(1, 2)\n", "p = pun.normal([2, 3], 0.5)\n", "dss = pun.DSS(intervals=[[1,5], [3,6]], masses=[0.5, 0.5])\n", "\n", "foo(i, p, dss)" ] }, { "cell_type": "markdown", "id": "ffc69fbf-dead-4fa8-9ead-67b5e385dfd3", "metadata": {}, "source": [ "**additional examples**\n", "\n", "see {ref}`up` for propagation, see {ref}`aggregation` for aggregation.\n", "\n", "More examples demonstrating these capabilities are underway. Stay tuned!" ] }, { "cell_type": "markdown", "id": "2f18ed07-a9d9-4284-a628-266c259b9688", "metadata": {}, "source": [ "```{tip}\n", "As shown in {ref}`getting_started`, one can always fall back on computing with those constructs directly for low-level controls during computation.\n", "```" ] }, { "cell_type": "code", "execution_count": 12, "id": "2d1dc87a-ea8b-425a-8788-c6fbf57a6050", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Pbox ~ (range=[-27.424, 97.171], mean=[-20.473, 25.895], var=[20.938, 154.317])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pyuncertainnumber import pba\n", "i = pba.I(1, 2)\n", "p = pba.normal([2, 3], 0.5)\n", "dss = pba.DSS(intervals=[[1,5], [3,6]], masses=[0.5, 0.5])\n", "\n", "foo(i, p, dss)" ] } ], "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.11.10" } }, "nbformat": 4, "nbformat_minor": 5 }