Source code for labtoolbox.uncertainty.uncertainty

import numpy as _np
from warnings import warn as _warn

[docs] def numerical(f, x_val, x_err, params=()): """ Uncertainty propagation via numerical derivatives. Parameters ---------- f : callable Function `f(x1, ..., xn; a1, ..., am)` that returns an array of shape (N,). x_val : list of np.ndarray List of input arrays `x1,..., xn`, each with shape (N,). x_err : list of np.ndarray List of uncertainty arrays corresponding to each `x_i`, shape (N,). params : tuple, optional Tuple of constant parameters `(a1, ..., am)` to be passed to the function. Returns ---------- f_val : np.ndarray Central values of the function, shape (N,). f_err : np.ndarray Propagated uncertainty, shape (N,). """ _warn( "This function is part of a legacy module and may be removed in future versions. " "Use labtoolbox.stats.propagate instead.", category=DeprecationWarning, stacklevel=2 ) N = x_val[0].shape[0] n_vars = len(x_val) # Valori centrali della funzione f_val = f(*x_val, *params) f_var = _np.zeros(N) for i in range(n_vars): x = x_val[i] # Calcolo h_i come distanza minima tra punti consecutivi diviso 100 dx = _np.diff(x) min_dx = _np.min(_np.abs(dx[dx != 0])) if _np.any(dx != 0) else 1.0 h = min_dx / 100 # Copia degli array per ±h x_plus = [x.copy() for x in x_val] x_minus = [x.copy() for x in x_val] x_plus[i] += h x_minus[i] -= h f_plus = f(*x_plus, *params) f_minus = f(*x_minus, *params) df_dxi = (f_plus - f_minus) / (2 * h) f_var += (df_dxi * x_err[i])**2 f_err = _np.sqrt(f_var) return f_val, f_err
[docs] def montecarlo(func, values, errs, N=10_000, seed=None): """ Estimate the propagated uncertainty on a function of N variables using Monte Carlo simulation. Parameters ---------- func : callable The function to evaluate. Must accept the same number of arguments as the length of `values`. values : array-like Central values of the input variables. Must be of the same length as `errs`. errs : array-like Standard deviations (1-sigma uncertainties) of the input variables. N : int, optional Number of Monte Carlo samples to generate. Default is `1e4`. seed : int or None, optional Seed for the random number generator, for reproducibility. Default is None. Returns ------- mean : float Mean value of the function evaluated over the sampled inputs. std : float Standard deviation (uncertainty) of the function output. Notes ----- - The input variables are sampled as independent normal distributions with given means and standard deviations. - Correlations between input variables are not taken into account. Example ------- >>> def f(x, y): return x * y >>> montecarlo(f, [2.0, 3.0], [0.1, 0.2]) (6.00..., 0.42...) """ values = _np.array(values) errs = _np.array(errs) _warn( "This function is part of a legacy module and may be removed in future versions. " "Use labtoolbox.stats.propagate instead.", category=DeprecationWarning, stacklevel=2 ) if values.shape != errs.shape: raise ValueError("values and uncertainties must have the same shape.") rng = _np.random.default_rng(seed) # Generate samples from normal distributions samples = [ rng.normal(loc=mu, scale=sigma, size=N) for mu, sigma in zip(values, errs) ] # Evaluate the function over all sampled inputs samples = _np.array(samples) # shape: (n_vars, N) outputs = func(*samples) mean = _np.mean(outputs) std = _np.std(outputs, ddof=1) return mean, std