$$ \sigma_{f} = \sqrt{\sum_{i=1}^m \left( \frac{\partial f}{\partial x_i}\right)^{\!2} \sigma_{x_i}^2} $$
$$ \sigma_{f} = \sqrt{\sum_{i=1}^m \left( \frac{\partial f}{\partial x_i}\right)^{\!2} \sigma_{x_i}^2 + \sum_{j\neq k} \frac{\partial f}{\partial x_j} \frac{\partial f}{\partial x_k} \operatorname{cov}(x_j, x_k)} $$
$\operatorname{cov}(x_j, x_k)$ sind die Einträge der Kovarianzmatrix und beschreiben die Korrelation zwischen den Fehlern von $x_j$ und $x_k$
konkret für zwei Messgrößen x, y, die $N$ mal gemessen wurden:
$$ \operatorname{cov}(x, y) = \frac{\sum_{i = 1}^{N} (x_i - \bar{x})(y_i - \bar{y})}{N} $$
uncertainties
¶ufloat
, repräsentiert Wert mit Fehlerfrom uncertainties import ufloat
x = ufloat(5, 1)
y = ufloat(3, 1)
x + y
Korrelationen werden von uncertainties beachtet:
x = ufloat(3, 1)
y = ufloat(3, 1)
print(x - y)
print(x - x) # error is zero!
print(x == y)
uncertainties.unumpy
ergänzt numpy:
import numpy as np
import uncertainties.unumpy as unp
x = [1, 2, 3, 4, 5]
err = [0.1, 0.3, 0.1, 0.8, 1.0]
y = unp.uarray(x, err)
unp.cos(unp.exp(y))
Man muss daran denken, die Funktionen aus unumpy zu benutzen (exp
, cos
, etc.)
np.cos(x)
Zugriff auf Wert und Standardabweichung mit n
und s
:
x = ufloat(5, 1)
print(x.n)
print(x.s)
Bei unumpy
mit nominal_values
und std_devs
x = unp.uarray([1, 2, 3], [0.3, 0.3, 0.1])
print(unp.nominal_values(x))
print(unp.std_devs(x))
Kann man natürlich auch abkürzen:
from uncertainties.unumpy import (nominal_values as noms,
std_devs as stds)
print(noms(x))
print(stds(x))
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (8, 4)
plt.rcParams['font.size'] = 16
x = np.array([90, 60, 45, 100, 15, 23, 52, 30, 71, 88])
y = np.array([90, 71, 65, 100, 45, 60, 75, 85, 100, 80])
plt.plot(x, y, 'ro')
plt.xlabel('x')
plt.ylabel('y')
plt.show()
vermute eine lineare Korrelation der Messwerte. Stützen der Hypothese mit Korrelationskoeffizient:
$$r = \frac{cov(x, y)}{\sigma_x \sigma_y}, \quad -1 \leq r \leq 1$$
x_mean = np.mean(x)
y_mean = np.mean(y)
dx = x - x_mean
dy = y - y_mean
corr_coeff = np.sum(dx * dy) / np.sqrt(np.sum(dx**2) * np.sum(dy**2))
print(corr_coeff)
Korrelation zwischen Variablen mit correlated_values erzeugen:
from uncertainties import correlated_values
values = [1, 2]
cov = [[0.5, 0.25],
[0.25, 0.2]]
x, y = correlated_values(values, cov)
korrelierte Fit-Parameter führen zu nichts-sagenden Ergebnissen. Kontrolle: Korrelationsmatrix.
%matplotlib inline
from numpy.random import normal
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (10, 8)
plt.rcParams['font.size'] = 16
from scipy.optimize import curve_fit
from uncertainties import correlated_values, correlation_matrix
def f1(x, a, phi):
return a * np.cos(x + phi)
def f2(x, a, b):
return a * np.cos(x) + b * np.sin(x)
x = np.linspace(0, 4 * np.pi, 15)
y = 5 * np.sin(x) + 5 * np.cos(x) + np.random.normal(0, 0.8, 15)
params1, cov1 = curve_fit(f1, x, y)
params2, cov2 = curve_fit(f2, x, y)
params1 = correlated_values(params1, cov1)
params2 = correlated_values(params2, cov2)
x_plot = np.linspace(0, 4 * np.pi, 1000)
plt.plot(x, y, 'k.')
plt.plot(x_plot, f1(x_plot, *noms(params1)), label='f1', lw=2)
plt.plot(x_plot, f2(x_plot, *noms(params2)), '--', label='f2', lw=2)
plt.legend()
fig, (ax1, ax2) = plt.subplots(2, 1)
print(correlation_matrix(params1))
print(correlation_matrix(params2))
mat1 = ax1.matshow(correlation_matrix(params1), cmap='RdBu_r', vmin=-1, vmax=1)
mat2 = ax2.matshow(correlation_matrix(params2), cmap='RdBu_r', vmin=-1, vmax=1)
fig.colorbar(mat1, ax=ax1)
fig.colorbar(mat2, ax=ax2)
Man kann keine ufloat
s plotten:
x = np.linspace(0, 10)
y = unp.uarray(np.linspace(0, 5), 1)
#plt.plot(x, y, 'rx')
plt.errorbar(x, unp.nominal_values(y), yerr=unp.std_devs(y), fmt='rx')
SymPy importieren:
import sympy
Mathematische Variablen erzeugen mit var()
:
x, y, z = sympy.var('x y z')
x + y + z
Differenzieren mit diff()
:
f = x + y**3 - sympy.cos(z)**2
print(f.diff(x))
print(f.diff(y))
print(f.diff(z))
print(f.diff(z, z, z))
Eine Funktion, die automatisch die Fehlerformel generiert:
import sympy
def error(f, err_vars=None):
from sympy import Symbol, latex
s = 0
latex_names = dict()
if err_vars == None:
err_vars = f.free_symbols
for v in err_vars:
err = Symbol('latex_std_' + v.name)
s += f.diff(v)**2 * err**2
latex_names[err] = '\\sigma_{' + latex(v) + '}'
return latex(sympy.sqrt(s), symbol_names=latex_names)
E, q, r = sympy.var('E_x q r')
f = E + q**2 * r
print(f)
print(error(f))
print()
$$f= E + q^2 r \quad\rightarrow\quad \sigma_f = \sqrt{\sigma_{E_{x}}^{2} + 4 \sigma_{q}^{2} q^{2} r^{2} + \sigma_{r}^{2} q^{4}}$$