{ "cells": [ { "cell_type": "markdown", "id": "f845b670", "metadata": {}, "source": [ "(epistemic_propagation)=\n", "# Propagation of epistemic uncertainty\n", "\n", "{ref}`interval_analysis` introduces the calculation of intervals for a regirorous analysis. However, naive interval analysis has some caveats such as the dependency issue, as shown in {ref}`interval_dependency`. \n", "\n", "This notebook will demonstrate a wider scope of interval analysis methods that assist in acommpolishing rigirorou engineering computations by handling the caveats as well as extending to work with black box models\n" ] }, { "cell_type": "markdown", "id": "e259b9fd", "metadata": {}, "source": [ "```{seealso}\n", "There is an increasing awareness, among the scientific computation community, of the differentiation of aleatory and epistemic uncertainty and that different methods are needed for characterisation and propagation. See {ref}`aleatory_propagation` for the propagation of aleatory uncertainty and more realistically {ref}`mix_propagation` for a mixed situation.\n", "```" ] }, { "cell_type": "code", "execution_count": 22, "id": "db81ffb2-4c4d-45fc-8467-c3992d2c597c", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from pyuncertainnumber import pba, b2b\n", "import pyuncertainnumber as pun" ] }, { "cell_type": "markdown", "id": "26e8c3ee", "metadata": {}, "source": [ "#### interval arithmetic" ] }, { "cell_type": "code", "execution_count": 7, "id": "75861582-70e1-4e81-9dbe-c651472c4e78", "metadata": {}, "outputs": [], "source": [ "def f(x):\n", " \"\"\"a universal signature that takes iterable and vectorised inputs\"\"\"\n", "\n", " if isinstance(x, np.ndarray): # foo_vectorised signature\n", " if x.ndim == 1:\n", " x = x[None, :]\n", " return x[:, 0] ** 3 + x[:, 1] + x[:, 2]\n", " else:\n", " return x[0] ** 3 + x[1] + x[2] # foo_iterable signature\n", "\n", "\n", "a = pba.I(1, 5)\n", "b = pba.I(7, 13)\n", "c = pba.I(5, 10) " ] }, { "cell_type": "markdown", "id": "7e2bca59-b44b-4159-a029-88fc9f12a9a4", "metadata": {}, "source": [ "a direct call duck-typing" ] }, { "cell_type": "code", "execution_count": 8, "id": "c11ad514-d9e1-4adb-a218-89d03ad313db", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[13.0,148.0]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f([a, b, c])" ] }, { "cell_type": "markdown", "id": "79cb91c1-f993-4ee5-ba74-df2dea61b09b", "metadata": {}, "source": [ "#### b2b: a bespoke function for interval propagation\n", "\n", "`pyuncertainnumber` supports a wide spectrum of methodologies for interval propagation, intrusively and nonintrusively, including vertex method(a.k.a endpoints method), subinterval reconstitution method, Cauchy deviate method, and most generally optimistion based methods such as genetic algorithm and bayesian optimisation. Particularly, one can easily dispatch any of these methods using the function `b2b`. Here below enumerates their usage via a simple demo." ] }, { "cell_type": "code", "execution_count": 9, "id": "68553fc1-14f9-46f7-a848-1897934a70f9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[13.0,148.0]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# endpoints\n", "b2b(\n", " vars = [a, b, c],\n", " func = f,\n", " interval_strategy = 'endpoints',\n", ")\n" ] }, { "cell_type": "code", "execution_count": 10, "id": "b9162691-4492-4ef3-a886-4fc07085ac8e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[13.0,148.0]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# subinterval - direct/endpoints\n", "b2b(\n", " vars = [a, b, c],\n", " func = f,\n", " interval_strategy = \"subinterval\",\n", " subinterval_style= \"direct\",\n", " n_sub=20\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "46df922e-69f3-4154-818f-75804fbdf2be", "metadata": {}, "outputs": [], "source": [ "%%capture\n", "# optimisation through genetic algorithm\n", "r = b2b(\n", " vars = [a, b, c],\n", " func = f,\n", " interval_strategy = \"ga\",\n", ")" ] }, { "cell_type": "code", "execution_count": 12, "id": "214d6351", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[13.01861169516981,147.7571712576113]\n" ] } ], "source": [ "print(r)" ] }, { "cell_type": "code", "execution_count": 13, "id": "3e7ce68e-b1b9-438a-b5fd-e686e25dc60a", "metadata": {}, "outputs": [], "source": [ "%%capture\n", "# optimisation through bayesian optimisation\n", "rr = b2b(\n", " vars = [a, b, c],\n", " func = f,\n", " interval_strategy = \"bo\",\n", ")" ] }, { "cell_type": "code", "execution_count": 14, "id": "8aa0580b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[13.0,148.0]\n" ] } ], "source": [ "print(rr)" ] }, { "cell_type": "code", "execution_count": 21, "id": "8d0d123b-f490-497a-b3a9-920ed884b302", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[-11.655025046085044,100.65502504608504]" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# cauchy deviate method\n", "b2b(\n", " vars = [a, b, c],\n", " func = f,\n", " interval_strategy = \"cauchy_deviate\",\n", " n_sam=40_000,\n", ")" ] }, { "cell_type": "markdown", "id": "3357e133-a799-432a-946e-134dc51f6e23", "metadata": {}, "source": [ "#### Propagation: a high-level API for propagation with uncertain numbers\n", "\n", "The advantage of `Propagation` is that it automatically provides propagation capability with any types of uncertain number, whatever their underlying uncertainty representations (constructs) are. Apparently, for an analysis with all interval-value variables, it also works though seems a bit an overkill.\n", "\n", "See xx for an engineering example." ] }, { "cell_type": "code", "execution_count": 23, "id": "a2746bb0-0e09-4d5b-ae65-6de0756777a6", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO: interval propagation\n" ] } ], "source": [ "a = pun.I(1, 5)\n", "b = pun.I(7, 13)\n", "c = pun.I(5, 10)\n", "\n", "p = pun.Propagation(\n", " vars = [a, b, c],\n", " func = f, \n", " method = 'subinterval',\n", ")" ] }, { "cell_type": "code", "execution_count": 26, "id": "0f34351c-a493-4f1d-822e-69f73cf0c22d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "UncertainNumber(essence='interval', intervals=[13.0,148.0], _construct=[13.0,148.0], nominal_value=80.5)" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p.run(subinterval_style=\"direct\", n_sub=20)" ] } ], "metadata": { "kernelspec": { "display_name": "pbox_nn", "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 }