Worst case analysis and sensitivity studies using Extreme Value and/or Monte Carlo methods.
Project description
worstcase
Overview
pip install worstcase
Worst case analysis and sensitivity studies using Extreme Value and/or Monte Carlo methods.
This package coexists alongside far more capable uncertainty analysis and error propagation packages such as uncertainties (first-order propagation), soerp (second-order propagation), and mcerp (Monte Carlo propagation).
This package is designed for engineering applications where worst case analysis computations are often done using the Extreme Value method over single-valued functions while falling back to the Monte Carlo method when the worst case is known to not exist at the extremes. The Extreme Value method is implemented as a brute-force search; the Monte Carlo method is implemented with Latin Hypercube Sampling over a uniform distribution.
This package does not transparently handle parameter covariance across functions. Instead, the graph of parameter dependence must be a tree (and therefore acyclic). Constructing a worst case analysis requires explicit definition of what the underlying parameter dependencies are.
Usage
import worstcase as wca
import numpy as np
wca.config.n = 2000 # Number of Monte Carlo runs. (default: 5000)
wca.config.sigfig = 4 # Number of significant firues to print. (default: 3)
The primitive varying parameter is a Param. Params are constructed either by tolerance (absolute or relative) or by range. Params may be given units from the default unit registry of Pint (default is unitless). A tag for printing is also optional (default is an empty string). A Param has the fields nom (nominal value), lb (lower bound), and ub (upper bound).
spd_initial = wca.param.bytol(nom=2, tol=0.1, rel=True, unit=wca.unit("m/s"), tag="v0")
accel = wca.param.byrange(nom=0.2, lb=0.1, ub=0.5, unit=wca.unit("m/s**2"), tag="a")
distance = wca.param.byrange(nom=1, lb=0.8, ub=1.1, unit=wca.unit.km, tag="x")
print([spd_initial, accel, distance])
[v0: 2 m/s (nom), 1.8 m/s (lb), 2.2 m/s (ub),
a: 200 mm/s² (nom), 100 mm/s² (lb), 500 mm/s² (ub),
x: 1 km (nom), 800 m (lb), 1.1 km (ub)]
A more complex parameter is built up as a ParamBuilder. ParamBuilders are constructed by decorating single-valued functions by ev (Extreme Value) or mc (Monte Carlo). The arguments passed to the ParamBuilder are partially bound to the underlying function. A parameter dependency tree can be drawn using the assigned tags; ParamBuilder will assume a tag corresponding to the function name as a default.
@wca.param.ev(spd_initial, accel, distance)
def spd_final(v, a, x):
return np.sqrt(v ** 2 + 2 * a * x)
print(spd_final)
spd_final (ev)
├── a
├── v0
└── x
ParamBuilder is a callable and the returned value depends on the arguments supplied. If no arguments are supplied, the parameter is built and a Param is returned.
print(spd_final())
spd_final: 20.1 m/s (nom), 12.78 m/s (lb), 33.24 m/s (ub)
Alternatively, the ParamBuilder binding to the underlying function can be updated and a new ParamBuilder is returned.
spd_final_noaccel = spd_final(a=0 * wca.unit("m/s**2"), tag="spd_noaccel")
print(spd_final_noaccel)
spd_noaccel (ev)
├── v0
└── x
Finally, if the ParamBuilder binding is updated such that no arguments are varying parameters then the underlying function will be called to return a single value.
result = spd_final_noaccel(3 * wca.unit("m/s"), x=10 * wca.unit.m)
print(result)
3.0 meter / second
ParamBuilders can be used to construct other ParamBuilders.
spd_rel = wca.param.bytol(nom=20, tol=1, rel=False, unit=wca.unit("mi/hr"), tag="vrel")
@wca.param.mc(spd_final, spd_rel)
def spd_total(vf, vr):
return vf + vr
print(spd_total)
print(spd_total())
spd_total (mc)
├── spd_final (ev)
│ ├── a
│ ├── v0
│ └── x
└── vrel
spd_total: 29.04 m/s (nom), 21.36 m/s (lb), 42.52 m/s (ub)
ParamBuilders can be modified with the ss method to perform a sensitivity study. By supplying a Param or ParamBuilder (or a list of them), a new ParamBuilder is returned where all other varying parameters are set to their nominal value. A few examples below.
accel_sens = spd_total.ss(accel, tag="accel-sens")
print(accel_sens)
print(accel_sens())
accel-sens (mc)
└── spd_final (ev)
└── a
accel-sens: 29.04 m/s (nom), 23.23 m/s (lb), 40.62 m/s (ub)
accel_distance_sens = spd_total.ss([accel, distance], tag="accel/distance-sens")
print(accel_distance_sens)
print(accel_distance_sens())
accel/distance-sens (mc)
└── spd_final (ev)
├── a
└── x
accel/distance-sens: 29.04 m/s (nom), 21.75 m/s (lb), 42.16 m/s (ub)
finalspd_sens = spd_total.ss(spd_final, tag="finalspd-sens")
print(finalspd_sens)
print(finalspd_sens())
finalspd-sens (mc)
└── spd_final (ev)
├── a
├── v0
└── x
finalspd-sens: 29.04 m/s (nom), 21.73 m/s (lb), 42.18 m/s (ub)
relspd_sens = spd_total.ss(spd_rel, tag="relspd-sens")
print(relspd_sens)
print(relspd_sens())
relspd-sens (mc)
└── vrel
relspd-sens: 29.04 m/s (nom), 28.59 m/s (lb), 29.49 m/s (ub)
Params implement a few of the Pint Quantity methods for usability.
assert spd_total.check("[length]/[time]")
# also try: spd_total.dimensionality
print(spd_total.units) # meter / second
# also try: spd_total.u
print(spd_total().ito(wca.unit("km/hr"))) # spd_total: 104.5 km/hr (nom)...
# also try: spd_total().ito_base_units()
# spd_total().ito_reduced_units()
# spd_total().ito_root_units()
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file worstcase-0.2.2.tar.gz
.
File metadata
- Download URL: worstcase-0.2.2.tar.gz
- Upload date:
- Size: 7.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.6 CPython/3.9.4 Windows/10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cd8a5460ba0e5b795660eccc22cbfa75969bfa6098ecb96f18b0b9e90ab526a3 |
|
MD5 | 55f72ec835b9c66d2bb51d4c5620cb6f |
|
BLAKE2b-256 | c1a058a2b6a971f84b6612d7c833a295e9217e73a80598afcb886b0885824a0b |
File details
Details for the file worstcase-0.2.2-py3-none-any.whl
.
File metadata
- Download URL: worstcase-0.2.2-py3-none-any.whl
- Upload date:
- Size: 6.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.6 CPython/3.9.4 Windows/10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3a3c3560a2e6ba058c06e57d92a9c4b5f8a1d486df051de409408c52c90c460a |
|
MD5 | 1bb95f0d44565095ed0f41a06bb66d6e |
|
BLAKE2b-256 | 80f492fc1fdfce08a4e260b044564b9db332a6f5cb9e0c6cfa2be5d17ed5ab97 |