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