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 34 Returns 35 ------- 36 ferr : float 37 the uncertainty in `f(x0)` given `xerr` uncertainty in `x0` 38 ''' 39 40 # Increment size for finite difference 41 # Numerical Methods in C recommends h * x, where x is the variable and 42 # h = sqrt(machine precision). For a 64-bit (double) float, that implies 43 # h = 2e-8. For a 32-bit (single) float, that implies h = 3e-4. 44 # We choose a larger value to reduce roundoff error. Note 45 # that very large h causes formula error where secant line is not parallel 46 # to instantaneous slope. 47 if h is None: 48 h = 1e-7 49 h = 1e-3 50 51 ferr = np.float64(0) 52 53 for i,xi in enumerate(x0): 54 xplus = x0.copy() 55 xminus = x0.copy() 56 xplus[i] = xplus[i] + h*xi 57 xminus[i] = xminus[i] - h*xi 58 59 # Centered finite difference estimate of derivative 60 dfdx = ( func(*xplus,**kwargs) - func(*xminus,**kwargs) ) / ( xplus[i]-xminus[i] ) 61 62 ferr += dfdx**2 * xerr[i]**2 63 64 ferr = np.sqrt(ferr) 65 66 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 35 Returns 36 ------- 37 ferr : float 38 the uncertainty in `f(x0)` given `xerr` uncertainty in `x0` 39 ''' 40 41 # Increment size for finite difference 42 # Numerical Methods in C recommends h * x, where x is the variable and 43 # h = sqrt(machine precision). For a 64-bit (double) float, that implies 44 # h = 2e-8. For a 32-bit (single) float, that implies h = 3e-4. 45 # We choose a larger value to reduce roundoff error. Note 46 # that very large h causes formula error where secant line is not parallel 47 # to instantaneous slope. 48 if h is None: 49 h = 1e-7 50 h = 1e-3 51 52 ferr = np.float64(0) 53 54 for i,xi in enumerate(x0): 55 xplus = x0.copy() 56 xminus = x0.copy() 57 xplus[i] = xplus[i] + h*xi 58 xminus[i] = xminus[i] - h*xi 59 60 # Centered finite difference estimate of derivative 61 dfdx = ( func(*xplus,**kwargs) - func(*xminus,**kwargs) ) / ( xplus[i]-xminus[i] ) 62 63 ferr += dfdx**2 * xerr[i]**2 64 65 ferr = np.sqrt(ferr) 66 67 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
Returns
- ferr (float):
the uncertainty in
f(x0)
givenxerr
uncertainty inx0