Propagation of epistemic uncertainty

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 Interval dependency.

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

See also

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 Propagation of aleatory uncertainty for the propagation of aleatory uncertainty and more realistically Mix uncertainty propagation for a mixed situation.

import numpy as np
from pyuncertainnumber import pba, b2b
import pyuncertainnumber as pun

interval arithmetic

def f(x):
    """a universal signature that takes iterable and vectorised inputs"""

    if isinstance(x, np.ndarray):  # foo_vectorised signature
        if x.ndim == 1:
            x = x[None, :]
        return x[:, 0] ** 3 + x[:, 1] + x[:, 2]
    else:
        return x[0] ** 3 + x[1] + x[2]  # foo_iterable signature


a = pba.I(1, 5)
b = pba.I(7, 13)
c = pba.I(5, 10)   

a direct call duck-typing

f([a, b, c])
[13.0,148.0]

b2b: a bespoke function for interval propagation

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.

# endpoints
b2b(
    vars = [a, b, c],
    func = f,
    interval_strategy = 'endpoints',
)
[13.0,148.0]
# subinterval - direct/endpoints
b2b(
    vars = [a, b, c],
    func = f,
    interval_strategy = "subinterval",
    subinterval_style= "direct",
    n_sub=20
)
[13.0,148.0]
%%capture
# optimisation through genetic algorithm
r = b2b(
    vars = [a, b, c],
    func = f,
    interval_strategy = "ga",
)
print(r)
[13.01861169516981,147.7571712576113]
%%capture
# optimisation through bayesian optimisation
rr = b2b(
    vars = [a, b, c],
    func = f,
    interval_strategy = "bo",
)
print(rr)
[13.0,148.0]
# cauchy deviate method
b2b(
    vars = [a, b, c],
    func = f,
    interval_strategy = "cauchy_deviate",
    n_sam=40_000,
)
[-11.655025046085044,100.65502504608504]

Propagation: a high-level API for propagation with uncertain numbers

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.

See xx for an engineering example.

a = pun.I(1, 5)
b = pun.I(7, 13)
c = pun.I(5, 10)

p = pun.Propagation(
    vars = [a, b, c],
    func = f, 
    method = 'subinterval',
)
INFO: interval propagation
p.run(subinterval_style="direct", n_sub=20)
UncertainNumber(essence='interval', intervals=[13.0,148.0], _construct=[13.0,148.0], nominal_value=80.5)