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) given xerr uncertainty in x0