acgc.erroranalysis
Propagation of error through complex numerical models
1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3"""Propagation of error through complex numerical models 4""" 5import numpy as np 6 7def funcerror_uncorr(func,x0,xerr,h=None,**kwargs): 8 '''Propagate uncertainties in function parameters to uncertainty in function value. 9 10 The uncertainty will be evaluated at f(x0). The method uses 11 a numerical estimate of the derivative of f(x0). For non-linear functions 12 the method is appropriate for small relative errors (i.e. small xerr/x0). 13 The method neglects possible error correlations between multiple parameters 14 in x0. 15 The function variables must all be continuous variables 16 (no categorical or discrete variables). 17 18 Example. To find the uncertainty in `f(x,y)` at for values `x=1; y=2`, where 19 the uncertainty (e.g. standard error) in `x` is 0.1 and the uncertainty in `y` 20 is 0.3. 21 ```print( funcerr_uncorr( f, [1,2], [0.1,0.3] ) )``` 22 23 Parameters 24 ---------- 25 func : callable 26 function to be evaluated 27 x0 : list or tuple (n,) 28 parameter values for func 29 xerr : list or tuple (n,) 30 uncertainty in parameter values x0 31 h : float, default=1e-3 32 fractional perturbation to x0 used to estimate slope of func via finite difference 33 **kwargs : (optional) 34 kwargs will be passed to func without error 35 36 Returns 37 ------- 38 ferr : float 39 the uncertainty in `f(x0)` given `xerr` uncertainty in `x0` 40 ''' 41 42 # Increment size for finite difference 43 # Numerical Methods in C recommends h * x, where x is the variable and 44 # h = sqrt(machine precision). For a 64-bit (double) float, that implies 45 # h = 2e-8. For a 32-bit (single) float, that implies h = 3e-4. 46 # We choose a larger value to reduce roundoff error. Note 47 # that very large h causes formula error where secant line is not parallel 48 # to instantaneous slope. 49 if h is None: 50 h = 1e-7 51 h = 1e-3 52 53 ferr = np.float64(0) 54 55 for i,xi in enumerate(x0): 56 xplus = x0.copy() 57 xminus = x0.copy() 58 xplus[i] = xplus[i] + h*xi 59 xminus[i] = xminus[i] - h*xi 60 61 # Centered finite difference estimate of derivative 62 dfdx = ( func(*xplus,**kwargs) - func(*xminus,**kwargs) ) / ( xplus[i]-xminus[i] ) 63 64 ferr += dfdx**2 * xerr[i]**2 65 66 ferr = np.sqrt(ferr) 67 68 return ferr
def
funcerror_uncorr(func, x0, xerr, h=None, **kwargs):
8def funcerror_uncorr(func,x0,xerr,h=None,**kwargs): 9 '''Propagate uncertainties in function parameters to uncertainty in function value. 10 11 The uncertainty will be evaluated at f(x0). The method uses 12 a numerical estimate of the derivative of f(x0). For non-linear functions 13 the method is appropriate for small relative errors (i.e. small xerr/x0). 14 The method neglects possible error correlations between multiple parameters 15 in x0. 16 The function variables must all be continuous variables 17 (no categorical or discrete variables). 18 19 Example. To find the uncertainty in `f(x,y)` at for values `x=1; y=2`, where 20 the uncertainty (e.g. standard error) in `x` is 0.1 and the uncertainty in `y` 21 is 0.3. 22 ```print( funcerr_uncorr( f, [1,2], [0.1,0.3] ) )``` 23 24 Parameters 25 ---------- 26 func : callable 27 function to be evaluated 28 x0 : list or tuple (n,) 29 parameter values for func 30 xerr : list or tuple (n,) 31 uncertainty in parameter values x0 32 h : float, default=1e-3 33 fractional perturbation to x0 used to estimate slope of func via finite difference 34 **kwargs : (optional) 35 kwargs will be passed to func without error 36 37 Returns 38 ------- 39 ferr : float 40 the uncertainty in `f(x0)` given `xerr` uncertainty in `x0` 41 ''' 42 43 # Increment size for finite difference 44 # Numerical Methods in C recommends h * x, where x is the variable and 45 # h = sqrt(machine precision). For a 64-bit (double) float, that implies 46 # h = 2e-8. For a 32-bit (single) float, that implies h = 3e-4. 47 # We choose a larger value to reduce roundoff error. Note 48 # that very large h causes formula error where secant line is not parallel 49 # to instantaneous slope. 50 if h is None: 51 h = 1e-7 52 h = 1e-3 53 54 ferr = np.float64(0) 55 56 for i,xi in enumerate(x0): 57 xplus = x0.copy() 58 xminus = x0.copy() 59 xplus[i] = xplus[i] + h*xi 60 xminus[i] = xminus[i] - h*xi 61 62 # Centered finite difference estimate of derivative 63 dfdx = ( func(*xplus,**kwargs) - func(*xminus,**kwargs) ) / ( xplus[i]-xminus[i] ) 64 65 ferr += dfdx**2 * xerr[i]**2 66 67 ferr = np.sqrt(ferr) 68 69 return ferr
Propagate uncertainties in function parameters to uncertainty in function value.
The uncertainty will be evaluated at f(x0). The method uses a numerical estimate of the derivative of f(x0). For non-linear functions the method is appropriate for small relative errors (i.e. small xerr/x0). The method neglects possible error correlations between multiple parameters in x0. The function variables must all be continuous variables (no categorical or discrete variables).
Example. To find the uncertainty in f(x,y)
at for values x=1; y=2
, where
the uncertainty (e.g. standard error) in x
is 0.1 and the uncertainty in y
is 0.3.
print( funcerr_uncorr( f, [1,2], [0.1,0.3] ) )
Parameters
- func (callable): function to be evaluated
- x0 (list or tuple (n,)): parameter values for func
- xerr (list or tuple (n,)): uncertainty in parameter values x0
- h (float, default=1e-3): fractional perturbation to x0 used to estimate slope of func via finite difference
- **kwargs ((optional)): kwargs will be passed to func without error
Returns
- ferr (float):
the uncertainty in
f(x0)
givenxerr
uncertainty inx0