Merge branch 'fjosw:develop' into feature/input_2.0

This commit is contained in:
jkuhl-uni 2021-12-16 11:11:28 +01:00 committed by GitHub
commit 307738c4fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 2343 additions and 1048 deletions

View file

@ -79,6 +79,26 @@ def test_T_symmetry():
T_symmetric = my_corr.T_symmetry(my_corr)
def test_fit_correlator():
my_corr = pe.correlators.Corr([pe.pseudo_Obs(1.01324, 0.05, 't'), pe.pseudo_Obs(2.042345, 0.0004, 't')])
def f(a, x):
y = a[0] + a[1] * x
return y
fit_res = my_corr.fit(f)
assert fit_res[0] == my_corr[0]
assert fit_res[1] == my_corr[1] - my_corr[0]
def test_plateau():
my_corr = pe.correlators.Corr([pe.pseudo_Obs(1.01324, 0.05, 't'), pe.pseudo_Obs(1.042345, 0.008, 't')])
my_corr.plateau([0, 1], method="fit")
my_corr.plateau([0, 1], method="mean")
with pytest.raises(Exception):
my_corr.plateau()
def test_utility():
corr_content = []
for t in range(8):

94
tests/covobs_test.py Normal file
View file

@ -0,0 +1,94 @@
import autograd.numpy as np
import pyerrors as pe
import pytest
np.random.seed(0)
def test_covobs():
val = 1.123124
cov = .243423
name = 'Covariance'
co = pe.cov_Obs(val, cov, name)
co.gamma_method()
co.details()
assert (co.dvalue == np.sqrt(cov))
assert (co.value == val)
do = 2 * co
assert (do.covobs[name].grad[0] == 2)
do = co * co
assert (do.covobs[name].grad[0] == 2 * val)
assert np.array_equal(do.covobs[name].cov, co.covobs[name].cov)
pi = [16.7457, -19.0475]
cov = [[3.49591, -6.07560], [-6.07560, 10.5834]]
cl = pe.cov_Obs(pi, cov, 'rAP')
pl = pe.misc.gen_correlated_data(pi, np.asarray(cov), 'rAPpseudo')
def rAP(p, g0sq):
return -0.0010666 * g0sq * (1 + np.exp(p[0] + p[1] / g0sq))
for g0sq in [1, 1.5, 1.8]:
oc = rAP(cl, g0sq)
oc.gamma_method()
op = rAP(pl, g0sq)
op.gamma_method()
assert(np.isclose(oc.value, op.value, rtol=1e-14, atol=1e-14))
[o.gamma_method() for o in cl]
assert(pe.covariance(cl[0], cl[1]) == cov[0][1])
assert(pe.covariance(cl[0], cl[1]) == cov[1][0])
do = cl[0] * cl[1]
assert(np.array_equal(do.covobs['rAP'].grad, np.transpose([pi[1], pi[0]]).reshape(2, 1)))
def test_covobs_overloading():
covobs = pe.cov_Obs([0.5, 0.5], np.array([[0.02, 0.02], [0.02, 0.02]]), 'test')
assert (covobs[0] / covobs[1]) == 1
assert (covobs[0] - covobs[1]) == 0
my_obs = pe.pseudo_Obs(2.3, 0.2, 'obs')
assert (my_obs * covobs[0] / covobs[1]) == my_obs
covobs = pe.cov_Obs(0.0, 0.3, 'test')
assert not covobs.is_zero()
def test_covobs_name_collision():
covobs = pe.cov_Obs(0.5, 0.002, 'test')
my_obs = pe.pseudo_Obs(2.3, 0.2, 'test')
with pytest.raises(Exception):
summed_obs = my_obs + covobs
covobs2 = pe.cov_Obs(0.3, 0.001, 'test')
with pytest.raises(Exception):
summed_obs = covobs + covobs2
def test_covobs_replica_separator():
with pytest.raises(Exception):
covobs = pe.cov_Obs(0.5, 0.002, 'test|r2')
def test_covobs_init():
covobs = pe.cov_Obs(0.5, 0.002, 'test')
covobs = pe.cov_Obs([1, 2], [0.1, 0.2], 'test')
covobs = pe.cov_Obs([1, 2], np.array([0.1, 0.2]), 'test')
covobs = pe.cov_Obs([1, 2], [[0.1, 0.2], [0.1, 0.2]], 'test')
covobs = pe.cov_Obs([1, 2], np.array([[0.1, 0.2], [0.1, 0.2]]), 'test')
def test_covobs_exceptions():
with pytest.raises(Exception):
covobs = pe.cov_Obs(0.1, [[0.1, 0.2], [0.1, 0.2]], 'test')
with pytest.raises(Exception):
covobs = pe.cov_Obs(0.1, np.array([[0.1, 0.2], [0.1, 0.2]]), 'test')
with pytest.raises(Exception):
covobs = pe.cov_Obs([0.5, 0.1], np.array([[2, 1, 3], [1, 2, 3]]), 'test')
with pytest.raises(Exception):
covobs = pe.cov_Obs([0.5, 0.1], np.random.random((2, 2, 2)), 'test')

View file

@ -10,3 +10,25 @@ def test_gamma_matrices():
assert np.allclose(matrix @ matrix, np.identity(4))
assert np.allclose(matrix, matrix.T.conj())
assert np.allclose(pe.dirac.gamma5, pe.dirac.gamma[0] @ pe.dirac.gamma[1] @ pe.dirac.gamma[2] @ pe.dirac.gamma[3])
def test_grid_dirac():
for gamma in ['Identity',
'Gamma5',
'GammaX',
'GammaY',
'GammaZ',
'GammaT',
'GammaXGamma5',
'GammaYGamma5',
'GammaZGamma5',
'GammaTGamma5',
'SigmaXT',
'SigmaXY',
'SigmaXZ',
'SigmaYT',
'SigmaYZ',
'SigmaZT']:
pe.dirac.Grid_gamma(gamma)
with pytest.raises(Exception):
pe.dirac.Grid_gamma('Not a gamma matrix')

View file

@ -2,12 +2,34 @@ import autograd.numpy as np
import math
import scipy.optimize
from scipy.odr import ODR, Model, RealData
from scipy.linalg import cholesky
from scipy.stats import norm
import pyerrors as pe
import pytest
np.random.seed(0)
def test_fit_lin():
x = [0, 2]
y = [pe.pseudo_Obs(0, 0.1, 'ensemble'),
pe.pseudo_Obs(2, 0.1, 'ensemble')]
res = pe.fits.fit_lin(x, y)
assert res[0] == y[0]
assert res[1] == (y[1] - y[0]) / (x[1] - x[0])
x = y = [pe.pseudo_Obs(0, 0.1, 'ensemble'),
pe.pseudo_Obs(2, 0.1, 'ensemble')]
res = pe.fits.fit_lin(x, y)
m = (y[1] - y[0]) / (x[1] - x[0])
assert res[0] == y[1] - x[1] * m
assert res[1] == m
def test_least_squares():
dim = 10 + int(30 * np.random.rand())
x = np.arange(dim)
@ -27,20 +49,86 @@ def test_least_squares():
y = a[0] * np.exp(-a[1] * x)
return y
out = pe.least_squares(x, oy, func)
out = pe.least_squares(x, oy, func, expected_chisquare=True, resplot=True, qqplot=True)
beta = out.fit_parameters
str(out)
repr(out)
len(out)
for i in range(2):
beta[i].gamma_method(S=1.0)
assert math.isclose(beta[i].value, popt[i], abs_tol=1e-5)
assert math.isclose(pcov[i, i], beta[i].dvalue ** 2, abs_tol=1e-3)
assert math.isclose(pe.covariance(beta[0], beta[1]), pcov[0, 1], abs_tol=1e-3)
pe.Obs.e_tag_global = 0
chi2_pyerrors = np.sum(((f(x, *[o.value for o in beta]) - y) / yerr) ** 2) / (len(x) - 2)
chi2_scipy = np.sum(((f(x, *popt) - y) / yerr) ** 2) / (len(x) - 2)
assert math.isclose(chi2_pyerrors, chi2_scipy, abs_tol=1e-10)
out = pe.least_squares(x, oy, func, const_par=[beta[1]])
assert((out.fit_parameters[0] - beta[0]).is_zero())
assert((out.fit_parameters[1] - beta[1]).is_zero())
oyc = []
for i, item in enumerate(x):
oyc.append(pe.cov_Obs(y[i], yerr[i]**2, 'cov' + str(i)))
outc = pe.least_squares(x, oyc, func)
betac = outc.fit_parameters
for i in range(2):
betac[i].gamma_method(S=1.0)
assert math.isclose(betac[i].value, popt[i], abs_tol=1e-5)
assert math.isclose(pcov[i, i], betac[i].dvalue ** 2, abs_tol=1e-3)
assert math.isclose(pe.covariance(betac[0], betac[1]), pcov[0, 1], abs_tol=1e-3)
def test_correlated_fit():
num_samples = 400
N = 10
x = norm.rvs(size=(N, num_samples))
r = np.zeros((N, N))
for i in range(N):
for j in range(N):
r[i, j] = np.exp(-0.1 * np.fabs(i - j))
errl = np.sqrt([3.4, 2.5, 3.6, 2.8, 4.2, 4.7, 4.9, 5.1, 3.2, 4.2])
errl *= 4
for i in range(N):
for j in range(N):
r[i, j] *= errl[i] * errl[j]
c = cholesky(r, lower=True)
y = np.dot(c, x)
x = np.arange(N)
for linear in [True, False]:
data = []
for i in range(N):
if linear:
data.append(pe.Obs([[i + 1 + o for o in y[i]]], ['ens']))
else:
data.append(pe.Obs([[np.exp(-(i + 1)) + np.exp(-(i + 1)) * o for o in y[i]]], ['ens']))
[o.gamma_method() for o in data]
if linear:
def fitf(p, x):
return p[1] + p[0] * x
else:
def fitf(p, x):
return p[1] * np.exp(-p[0] * x)
fitp = pe.least_squares(x, data, fitf, expected_chisquare=True)
fitpc = pe.least_squares(x, data, fitf, correlated_fit=True)
for i in range(2):
diff = fitp[i] - fitpc[i]
diff.gamma_method()
assert(diff.is_zero_within_error(sigma=1.5))
def test_total_least_squares():
dim = 10 + int(30 * np.random.rand())
@ -70,16 +158,62 @@ def test_total_least_squares():
odr.set_job(fit_type=0, deriv=1)
output = odr.run()
out = pe.total_least_squares(ox, oy, func)
out = pe.total_least_squares(ox, oy, func, expected_chisquare=True)
beta = out.fit_parameters
pe.Obs.e_tag_global = 5
str(out)
repr(out)
len(out)
for i in range(2):
beta[i].gamma_method(e_tag=5, S=1.0)
beta[i].gamma_method(S=1.0)
assert math.isclose(beta[i].value, output.beta[i], rel_tol=1e-5)
assert math.isclose(output.cov_beta[i, i], beta[i].dvalue ** 2, rel_tol=2.5e-1), str(output.cov_beta[i, i]) + ' ' + str(beta[i].dvalue ** 2)
assert math.isclose(pe.covariance(beta[0], beta[1]), output.cov_beta[0, 1], rel_tol=2.5e-1)
pe.Obs.e_tag_global = 0
out = pe.total_least_squares(ox, oy, func, const_par=[beta[1]])
diff = out.fit_parameters[0] - beta[0]
assert(diff / beta[0] < 1e-3 * beta[0].dvalue)
assert((out.fit_parameters[1] - beta[1]).is_zero())
oxc = []
for i, item in enumerate(x):
oxc.append(pe.cov_Obs(x[i], xerr[i]**2, 'covx' + str(i)))
oyc = []
for i, item in enumerate(x):
oyc.append(pe.cov_Obs(y[i], yerr[i]**2, 'covy' + str(i)))
outc = pe.total_least_squares(oxc, oyc, func)
betac = outc.fit_parameters
for i in range(2):
betac[i].gamma_method(S=1.0)
assert math.isclose(betac[i].value, output.beta[i], rel_tol=1e-3)
assert math.isclose(output.cov_beta[i, i], betac[i].dvalue ** 2, rel_tol=2.5e-1), str(output.cov_beta[i, i]) + ' ' + str(betac[i].dvalue ** 2)
assert math.isclose(pe.covariance(betac[0], betac[1]), output.cov_beta[0, 1], rel_tol=2.5e-1)
outc = pe.total_least_squares(oxc, oyc, func, const_par=[betac[1]])
diffc = outc.fit_parameters[0] - betac[0]
assert(diffc / betac[0] < 1e-3 * betac[0].dvalue)
assert((outc.fit_parameters[1] - betac[1]).is_zero())
outc = pe.total_least_squares(oxc, oy, func)
betac = outc.fit_parameters
for i in range(2):
betac[i].gamma_method(S=1.0)
assert math.isclose(betac[i].value, output.beta[i], rel_tol=1e-3)
assert math.isclose(output.cov_beta[i, i], betac[i].dvalue ** 2, rel_tol=2.5e-1), str(output.cov_beta[i, i]) + ' ' + str(betac[i].dvalue ** 2)
assert math.isclose(pe.covariance(betac[0], betac[1]), output.cov_beta[0, 1], rel_tol=2.5e-1)
outc = pe.total_least_squares(oxc, oy, func, const_par=[betac[1]])
diffc = outc.fit_parameters[0] - betac[0]
assert(diffc / betac[0] < 1e-3 * betac[0].dvalue)
assert((outc.fit_parameters[1] - betac[1]).is_zero())
def test_odr_derivatives():
@ -99,7 +233,177 @@ def test_odr_derivatives():
out = pe.total_least_squares(x, y, func)
fit1 = out.fit_parameters
with pytest.warns(DeprecationWarning):
tfit = pe.fits.fit_general(x, y, func, base_step=0.1, step_ratio=1.1, num_steps=20)
tfit = fit_general(x, y, func, base_step=0.1, step_ratio=1.1, num_steps=20)
assert np.abs(np.max(np.array(list(fit1[1].deltas.values()))
- np.array(list(tfit[1].deltas.values())))) < 10e-8
def test_r_value_persistence():
def f(a, x):
return a[0] + a[1] * x
a = pe.pseudo_Obs(1.1, .1, 'a')
assert np.isclose(a.value, a.r_values['a'])
a_2 = a ** 2
assert np.isclose(a_2.value, a_2.r_values['a'])
b = pe.pseudo_Obs(2.1, .2, 'b')
y = [a, b]
[o.gamma_method() for o in y]
fitp = pe.fits.least_squares([1, 2], y, f)
assert np.isclose(fitp[0].value, fitp[0].r_values['a'])
assert np.isclose(fitp[0].value, fitp[0].r_values['b'])
assert np.isclose(fitp[1].value, fitp[1].r_values['a'])
assert np.isclose(fitp[1].value, fitp[1].r_values['b'])
fitp = pe.fits.total_least_squares(y, y, f)
assert np.isclose(fitp[0].value, fitp[0].r_values['a'])
assert np.isclose(fitp[0].value, fitp[0].r_values['b'])
assert np.isclose(fitp[1].value, fitp[1].r_values['a'])
assert np.isclose(fitp[1].value, fitp[1].r_values['b'])
fitp = pe.fits.least_squares([1, 2], y, f, priors=y)
assert np.isclose(fitp[0].value, fitp[0].r_values['a'])
assert np.isclose(fitp[0].value, fitp[0].r_values['b'])
assert np.isclose(fitp[1].value, fitp[1].r_values['a'])
assert np.isclose(fitp[1].value, fitp[1].r_values['b'])
def test_prior_fit():
def f(a, x):
return a[0] + a[1] * x
a = pe.pseudo_Obs(0.0, 0.1, 'a')
b = pe.pseudo_Obs(1.0, 0.2, 'a')
y = [a, b]
with pytest.raises(Exception):
fitp = pe.fits.least_squares([0, 1], 1 * np.array(y), f, priors=['0.0(8)', '1.0(8)'])
[o.gamma_method() for o in y]
fitp = pe.fits.least_squares([0, 1], y, f, priors=['0.0(8)', '1.0(8)'])
fitp = pe.fits.least_squares([0, 1], y, f, priors=y, resplot=True, qqplot=True)
def test_error_band():
def f(a, x):
return a[0] + a[1] * x
a = pe.pseudo_Obs(0.0, 0.1, 'a')
b = pe.pseudo_Obs(1.0, 0.2, 'a')
x = [0, 1]
y = [a, b]
fitp = pe.fits.least_squares(x, y, f)
with pytest.raises(Exception):
pe.fits.error_band(x, f, fitp.fit_parameters)
fitp.gamma_method()
pe.fits.error_band(x, f, fitp.fit_parameters)
def fit_general(x, y, func, silent=False, **kwargs):
"""Performs a non-linear fit to y = func(x) and returns a list of Obs corresponding to the fit parameters.
Plausibility of the results should be checked. To control the numerical differentiation
the kwargs of numdifftools.step_generators.MaxStepGenerator can be used.
func has to be of the form
def func(a, x):
y = a[0] + a[1] * x + a[2] * np.sinh(x)
return y
y has to be a list of Obs, the dvalues of the Obs are used as yerror for the fit.
x can either be a list of floats in which case no xerror is assumed, or
a list of Obs, where the dvalues of the Obs are used as xerror for the fit.
Keyword arguments
-----------------
silent -- If true all output to the console is omitted (default False).
initial_guess -- can provide an initial guess for the input parameters. Relevant for non-linear fits
with many parameters.
"""
if not callable(func):
raise TypeError('func has to be a function.')
for i in range(10):
try:
func(np.arange(i), 0)
except:
pass
else:
break
n_parms = i
if not silent:
print('Fit with', n_parms, 'parameters')
global print_output, beta0
print_output = 1
if 'initial_guess' in kwargs:
beta0 = kwargs.get('initial_guess')
if len(beta0) != n_parms:
raise Exception('Initial guess does not have the correct length.')
else:
beta0 = np.arange(n_parms)
if len(x) != len(y):
raise Exception('x and y have to have the same length')
if all(isinstance(n, pe.Obs) for n in x):
obs = x + y
x_constants = None
xerr = [o.dvalue for o in x]
yerr = [o.dvalue for o in y]
elif all(isinstance(n, float) or isinstance(n, int) for n in x) or isinstance(x, np.ndarray):
obs = y
x_constants = x
xerr = None
yerr = [o.dvalue for o in y]
else:
raise Exception('Unsupported types for x')
def do_the_fit(obs, **kwargs):
global print_output, beta0
func = kwargs.get('function')
yerr = kwargs.get('yerr')
length = len(yerr)
xerr = kwargs.get('xerr')
if length == len(obs):
assert 'x_constants' in kwargs
data = RealData(kwargs.get('x_constants'), obs, sy=yerr)
fit_type = 2
elif length == len(obs) // 2:
data = RealData(obs[:length], obs[length:], sx=xerr, sy=yerr)
fit_type = 0
else:
raise Exception('x and y do not fit together.')
model = Model(func)
odr = ODR(data, model, beta0, partol=np.finfo(np.float64).eps)
odr.set_job(fit_type=fit_type, deriv=1)
output = odr.run()
if print_output and not silent:
print(*output.stopreason)
print('chisquare/d.o.f.:', output.res_var)
print_output = 0
beta0 = output.beta
return output.beta[kwargs.get('n')]
res = []
for n in range(n_parms):
res.append(pe.derived_observable(do_the_fit, obs, function=func, xerr=xerr, yerr=yerr, x_constants=x_constants, num_grad=True, n=n, **kwargs))
return res

91
tests/io_test.py Normal file
View file

@ -0,0 +1,91 @@
import os
import gzip
import numpy as np
import pyerrors as pe
import pyerrors.input.json as jsonio
def test_jsonio():
o = pe.pseudo_Obs(1.0, .2, 'one')
o2 = pe.pseudo_Obs(0.5, .1, 'two|r1')
o3 = pe.pseudo_Obs(0.5, .1, 'two|r2')
o4 = pe.merge_obs([o2, o3])
otag = 'This has been merged!'
o4.tag = otag
do = o - .2 * o4
co1 = pe.cov_Obs(1., .123, 'cov1')
co3 = pe.cov_Obs(4., .1 ** 2, 'cov3')
do *= co1 / co3
do.tag = {'A': 2}
o5 = pe.pseudo_Obs(0.8, .1, 'two|r2')
co2 = pe.cov_Obs([1, 2], [[.12, .004], [.004, .02]], 'cov2')
o5 /= co2[0]
o3 /= co2[1]
o5.tag = 2 * otag
testl = [o3, o5]
arr = np.array([o3, o5])
mat = np.array([[pe.pseudo_Obs(1.0, .1, 'mat'), pe.pseudo_Obs(0.3, .1, 'mat')], [pe.pseudo_Obs(0.2, .1, 'mat'), pe.pseudo_Obs(2.0, .4, 'mat')]])
mat[0][1].tag = ['This', 'is', 2, None]
mat[1][0].tag = '{testt}'
mat[1][1].tag = '[tag]'
tt1 = pe.Obs([np.random.rand(100)], ['t|r1'], idl=[range(2, 202, 2)])
tt2 = pe.Obs([np.random.rand(100)], ['t|r2'], idl=[range(2, 202, 2)])
tt3 = pe.Obs([np.random.rand(102)], ['qe'])
tt = tt1 + tt2 + tt3
tt.tag = 'Test Obs: Ä'
ol = [o4, do, testl, mat, arr, np.array([o]), np.array([tt, tt]), [tt, tt], co1, co2, np.array(co2), co1 / co2[0]]
fname = 'test_rw'
jsonio.dump_to_json(ol, fname, indent=1, description='[I am a tricky description]')
rl = jsonio.load_json(fname)
os.remove(fname + '.json.gz')
for o, r in zip(ol, rl):
assert np.all(o == r)
for i in range(len(ol)):
if isinstance(ol[i], pe.Obs):
o = ol[i] - rl[i]
assert(o.is_zero())
assert(ol[i].tag == rl[i].tag)
or1 = np.ravel(ol[i])
or2 = np.ravel(rl[i])
for j in range(len(or1)):
o = or1[j] - or2[j]
assert(o.is_zero())
description = {'I': {'Am': {'a': 'nested dictionary!'}}}
jsonio.dump_to_json(ol, fname, indent=0, gz=False, description=description)
rl = jsonio.load_json(fname, gz=False, full_output=True)
os.remove(fname + '.json')
for o, r in zip(ol, rl['obsdata']):
assert np.all(o == r)
assert(description == rl['description'])
def test_json_string_reconstruction():
my_obs = pe.Obs([np.random.rand(100)], ['name'])
json_string = pe.input.json.create_json_string(my_obs)
reconstructed_obs1 = pe.input.json.import_json_string(json_string)
assert my_obs == reconstructed_obs1
compressed_string = gzip.compress(json_string.encode('utf-8'))
reconstructed_string = gzip.decompress(compressed_string).decode('utf-8')
reconstructed_obs2 = pe.input.json.import_json_string(reconstructed_string)
assert reconstructed_string == json_string
assert my_obs == reconstructed_obs2

View file

@ -7,35 +7,153 @@ import pytest
np.random.seed(0)
def test_matmul():
for dim in [4, 8]:
my_list = []
length = 1000 + np.random.randint(200)
for i in range(dim ** 2):
my_list.append(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']))
my_array = np.array(my_list).reshape((dim, dim))
tt = pe.linalg.matmul(my_array, my_array) - my_array @ my_array
for t, e in np.ndenumerate(tt):
assert e.is_zero(), t
def get_real_matrix(dimension):
base_matrix = np.empty((dimension, dimension), dtype=object)
for (n, m), entry in np.ndenumerate(base_matrix):
exponent_real = np.random.normal(0, 1)
exponent_imag = np.random.normal(0, 1)
base_matrix[n, m] = pe.Obs([np.random.normal(1.0, 0.1, 100)], ['t'])
my_list = []
length = 1000 + np.random.randint(200)
for i in range(dim ** 2):
my_list.append(pe.CObs(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']),
pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2'])))
my_array = np.array(my_list).reshape((dim, dim))
tt = pe.linalg.matmul(my_array, my_array) - my_array @ my_array
for t, e in np.ndenumerate(tt):
assert e.is_zero(), t
return base_matrix
def get_complex_matrix(dimension):
base_matrix = np.empty((dimension, dimension), dtype=object)
for (n, m), entry in np.ndenumerate(base_matrix):
exponent_real = np.random.normal(0, 1)
exponent_imag = np.random.normal(0, 1)
base_matrix[n, m] = pe.CObs(pe.Obs([np.random.normal(1.0, 0.1, 100)], ['t']),
pe.Obs([np.random.normal(1.0, 0.1, 100)], ['t']))
return base_matrix
def test_matmul():
for dim in [4, 6]:
for const in [1, pe.cov_Obs([1.0, 1.0], [[0.001,0.0001], [0.0001, 0.002]], 'norm')[1]]:
my_list = []
length = 100 + np.random.randint(200)
for i in range(dim ** 2):
my_list.append(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']))
my_array = const * np.array(my_list).reshape((dim, dim))
tt = pe.linalg.matmul(my_array, my_array) - my_array @ my_array
for t, e in np.ndenumerate(tt):
assert e.is_zero(), t
my_list = []
length = 100 + np.random.randint(200)
for i in range(dim ** 2):
my_list.append(pe.CObs(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']),
pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2'])))
my_array = np.array(my_list).reshape((dim, dim)) * const
tt = pe.linalg.matmul(my_array, my_array) - my_array @ my_array
for t, e in np.ndenumerate(tt):
assert e.is_zero(), t
def test_jack_matmul():
tt = get_real_matrix(8)
check1 = pe.linalg.jack_matmul(tt, tt) - pe.linalg.matmul(tt, tt)
[o.gamma_method() for o in check1.ravel()]
assert np.all([o.is_zero_within_error(0.1) for o in check1.ravel()])
assert np.all([o.dvalue < 0.001 for o in check1.ravel()])
trace1 = np.trace(check1)
trace1.gamma_method()
assert trace1.dvalue < 0.001
tr = np.random.rand(8, 8)
check2 = pe.linalg.jack_matmul(tt, tr) - pe.linalg.matmul(tt, tr)
[o.gamma_method() for o in check2.ravel()]
assert np.all([o.is_zero_within_error(0.1) for o in check2.ravel()])
assert np.all([o.dvalue < 0.001 for o in check2.ravel()])
trace2 = np.trace(check2)
trace2.gamma_method()
assert trace2.dvalue < 0.001
tt2 = get_complex_matrix(8)
check3 = pe.linalg.jack_matmul(tt2, tt2) - pe.linalg.matmul(tt2, tt2)
[o.gamma_method() for o in check3.ravel()]
assert np.all([o.real.is_zero_within_error(0.1) for o in check3.ravel()])
assert np.all([o.imag.is_zero_within_error(0.1) for o in check3.ravel()])
assert np.all([o.real.dvalue < 0.001 for o in check3.ravel()])
assert np.all([o.imag.dvalue < 0.001 for o in check3.ravel()])
trace3 = np.trace(check3)
trace3.gamma_method()
assert trace3.real.dvalue < 0.001
assert trace3.imag.dvalue < 0.001
tr2 = np.random.rand(8, 8) + 1j * np.random.rand(8, 8)
check4 = pe.linalg.jack_matmul(tt2, tr2) - pe.linalg.matmul(tt2, tr2)
[o.gamma_method() for o in check4.ravel()]
assert np.all([o.real.is_zero_within_error(0.1) for o in check4.ravel()])
assert np.all([o.imag.is_zero_within_error(0.1) for o in check4.ravel()])
assert np.all([o.real.dvalue < 0.001 for o in check4.ravel()])
assert np.all([o.imag.dvalue < 0.001 for o in check4.ravel()])
trace4 = np.trace(check4)
trace4.gamma_method()
assert trace4.real.dvalue < 0.001
assert trace4.imag.dvalue < 0.001
def test_einsum():
def _perform_real_check(arr):
[o.gamma_method() for o in arr]
assert np.all([o.is_zero_within_error(0.001) for o in arr])
assert np.all([o.dvalue < 0.001 for o in arr])
def _perform_complex_check(arr):
[o.gamma_method() for o in arr]
assert np.all([o.real.is_zero_within_error(0.001) for o in arr])
assert np.all([o.real.dvalue < 0.001 for o in arr])
assert np.all([o.imag.is_zero_within_error(0.001) for o in arr])
assert np.all([o.imag.dvalue < 0.001 for o in arr])
tt = [get_real_matrix(4), get_real_matrix(3)]
q = np.tensordot(tt[0], tt[1], 0)
c1 = tt[1] @ q
c2 = pe.linalg.einsum('ij,abjd->abid', tt[1], q)
check1 = c1 - c2
_perform_real_check(check1.ravel())
check2 = np.trace(tt[0]) - pe.linalg.einsum('ii', tt[0])
_perform_real_check([check2])
check3 = np.trace(tt[1]) - pe.linalg.einsum('ii', tt[1])
_perform_real_check([check3])
tt = [get_real_matrix(4), np.random.random((3, 3))]
q = np.tensordot(tt[0], tt[1], 0)
c1 = tt[1] @ q
c2 = pe.linalg.einsum('ij,abjd->abid', tt[1], q)
check1 = c1 - c2
_perform_real_check(check1.ravel())
tt = [get_complex_matrix(4), get_complex_matrix(3)]
q = np.tensordot(tt[0], tt[1], 0)
c1 = tt[1] @ q
c2 = pe.linalg.einsum('ij,abjd->abid', tt[1], q)
check1 = c1 - c2
_perform_complex_check(check1.ravel())
check2 = np.trace(tt[0]) - pe.linalg.einsum('ii', tt[0])
_perform_complex_check([check2])
check3 = np.trace(tt[1]) - pe.linalg.einsum('ii', tt[1])
_perform_complex_check([check3])
tt = [get_complex_matrix(4), np.random.random((3, 3))]
q = np.tensordot(tt[0], tt[1], 0)
c1 = tt[1] @ q
c2 = pe.linalg.einsum('ij,abjd->abid', tt[1], q)
check1 = c1 - c2
_perform_complex_check(check1.ravel())
def test_multi_dot():
for dim in [4, 8]:
for dim in [4, 6]:
my_list = []
length = 1000 + np.random.randint(200)
for i in range(dim ** 2):
my_list.append(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']))
my_array = np.array(my_list).reshape((dim, dim))
my_array = pe.cov_Obs(1.0, 0.002, 'cov') * np.array(my_list).reshape((dim, dim))
tt = pe.linalg.matmul(my_array, my_array, my_array, my_array) - my_array @ my_array @ my_array @ my_array
for t, e in np.ndenumerate(tt):
assert e.is_zero(), t
@ -45,12 +163,25 @@ def test_multi_dot():
for i in range(dim ** 2):
my_list.append(pe.CObs(pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2']),
pe.Obs([np.random.rand(length), np.random.rand(length + 1)], ['t1', 't2'])))
my_array = np.array(my_list).reshape((dim, dim))
my_array = np.array(my_list).reshape((dim, dim)) * pe.cov_Obs(1.0, 0.002, 'cov')
tt = pe.linalg.matmul(my_array, my_array, my_array, my_array) - my_array @ my_array @ my_array @ my_array
for t, e in np.ndenumerate(tt):
assert e.is_zero(), t
def test_jack_multi_dot():
for dim in [2, 4, 8]:
my_array = get_real_matrix(dim)
tt = pe.linalg.jack_matmul(my_array, my_array, my_array) - pe.linalg.matmul(my_array, my_array, my_array)
for t, e in np.ndenumerate(tt):
e.gamma_method()
assert e.is_zero_within_error(0.01)
assert e.is_zero(atol=1e-1), t
assert np.isclose(e.value, 0.0)
def test_matmul_irregular_histories():
dim = 2
length = 500
@ -58,13 +189,13 @@ def test_matmul_irregular_histories():
standard_array = []
for i in range(dim ** 2):
standard_array.append(pe.Obs([np.random.normal(1.1, 0.2, length)], ['ens1']))
standard_matrix = np.array(standard_array).reshape((dim, dim))
standard_matrix = np.array(standard_array).reshape((dim, dim)) * pe.cov_Obs(1.0, 0.002, 'cov') * pe.pseudo_Obs(0.1, 0.002, 'qr')
for idl in [range(1, 501, 2), range(250, 273), [2, 8, 19, 20, 78]]:
irregular_array = []
for i in range(dim ** 2):
irregular_array.append(pe.Obs([np.random.normal(1.1, 0.2, len(idl))], ['ens1'], idl=[idl]))
irregular_matrix = np.array(irregular_array).reshape((dim, dim))
irregular_matrix = np.array(irregular_array).reshape((dim, dim)) * pe.cov_Obs([1.0, 1.0], [[0.001,0.0001], [0.0001, 0.002]], 'norm')[0]
t1 = standard_matrix @ irregular_matrix
t2 = pe.linalg.matmul(standard_matrix, irregular_matrix)
@ -82,7 +213,7 @@ def test_irregular_matrix_inverse():
irregular_array = []
for i in range(dim ** 2):
irregular_array.append(pe.Obs([np.random.normal(1.1, 0.2, len(idl)), np.random.normal(0.25, 0.1, 10)], ['ens1', 'ens2'], idl=[idl, range(1, 11)]))
irregular_matrix = np.array(irregular_array).reshape((dim, dim))
irregular_matrix = np.array(irregular_array).reshape((dim, dim)) * pe.cov_Obs(1.0, 0.002, 'cov') * pe.pseudo_Obs(1.0, 0.002, 'ens2|r23')
invertible_irregular_matrix = np.identity(dim) + irregular_matrix @ irregular_matrix.T
@ -113,8 +244,8 @@ def test_complex_matrix_inverse():
base_matrix = np.empty((dimension, dimension), dtype=object)
matrix = np.empty((dimension, dimension), dtype=complex)
for (n, m), entry in np.ndenumerate(base_matrix):
exponent_real = np.random.normal(3, 5)
exponent_imag = np.random.normal(3, 5)
exponent_real = np.random.normal(2, 3)
exponent_imag = np.random.normal(2, 3)
base_matrix[n, m] = pe.CObs(pe.pseudo_Obs(2 + 10 ** exponent_real, 10 ** (exponent_real - 1), 't'),
pe.pseudo_Obs(2 + 10 ** exponent_imag, 10 ** (exponent_imag - 1), 't'))
@ -169,6 +300,10 @@ def test_matrix_functions():
for j in range(dim):
assert tmp[j].is_zero()
# Check eig function
e2 = pe.linalg.eig(sym)
assert np.all(np.sort(e) == np.sort(e2))
# Check svd
u, v, vh = pe.linalg.svd(sym)
diff = sym - u @ np.diag(v) @ vh
@ -176,6 +311,9 @@ def test_matrix_functions():
for (i, j), entry in np.ndenumerate(diff):
assert entry.is_zero()
# Check determinant
assert pe.linalg.det(np.diag(np.diag(matrix))) == np.prod(np.diag(matrix))
def test_complex_matrix_operations():
dimension = 4

View file

@ -9,6 +9,50 @@ import pytest
np.random.seed(0)
def test_Obs_exceptions():
with pytest.raises(Exception):
pe.Obs([np.random.rand(10)], ['1', '2'])
with pytest.raises(Exception):
pe.Obs([np.random.rand(10)], ['1'], idl=[])
with pytest.raises(Exception):
pe.Obs([np.random.rand(10), np.random.rand(10)], ['1', '1'])
with pytest.raises(Exception):
pe.Obs([np.random.rand(10), np.random.rand(10)], ['1', 1])
with pytest.raises(Exception):
pe.Obs([np.random.rand(10)], [1])
with pytest.raises(Exception):
pe.Obs([np.random.rand(4)], ['name'])
with pytest.raises(Exception):
pe.Obs([np.random.rand(5)], ['1'], idl=[[5, 3, 2 ,4 ,1]])
with pytest.raises(Exception):
pe.Obs([np.random.rand(5)], ['1'], idl=['t'])
with pytest.raises(Exception):
pe.Obs([np.random.rand(5)], ['1'], idl=[range(1, 8)])
my_obs = pe.Obs([np.random.rand(6)], ['name'])
my_obs._value = 0.0
my_obs.details()
with pytest.raises(Exception):
my_obs.plot_tauint()
with pytest.raises(Exception):
my_obs.plot_rho()
with pytest.raises(Exception):
my_obs.plot_rep_dist()
with pytest.raises(Exception):
my_obs.plot_piechart()
with pytest.raises(Exception):
my_obs.gamma_method(S='2.3')
with pytest.raises(Exception):
my_obs.gamma_method(tau_exp=2.3)
my_obs.gamma_method()
my_obs.details()
my_obs.plot_rep_dist()
my_obs += pe.Obs([np.random.rand(6)], ['name2|r1'], idl=[[1, 3, 4, 5, 6, 7]])
my_obs += pe.Obs([np.random.rand(6)], ['name2|r2'])
my_obs.gamma_method()
my_obs.details()
def test_dump():
value = np.random.normal(5, 10)
dvalue = np.abs(np.random.normal(0, 1))
@ -95,6 +139,18 @@ def test_gamma_method():
assert test_obs.e_tauint['t'] - 10.5 <= test_obs.e_dtauint['t']
def test_gamma_method_no_windowing():
for iteration in range(50):
obs = pe.Obs([np.random.normal(1.02, 0.02, 733 + np.random.randint(1000))], ['ens'])
obs.gamma_method(S=0)
assert obs.e_tauint['ens'] == 0.5
assert np.isclose(np.sqrt(np.var(obs.deltas['ens'], ddof=1) / obs.shape['ens']), obs.dvalue)
obs.gamma_method(S=1.1)
assert obs.e_tauint['ens'] > 0.5
with pytest.raises(Exception):
obs.gamma_method(S=-0.2)
def test_gamma_method_persistance():
my_obs = pe.Obs([np.random.rand(730)], ['t'])
my_obs.gamma_method()
@ -183,7 +239,7 @@ def test_covariance_is_variance():
test_obs.gamma_method()
assert np.abs(test_obs.dvalue ** 2 - pe.covariance(test_obs, test_obs)) <= 10 * np.finfo(np.float64).eps
test_obs = test_obs + pe.pseudo_Obs(value, dvalue, 'q', 200)
test_obs.gamma_method(e_tag=0)
test_obs.gamma_method()
assert np.abs(test_obs.dvalue ** 2 - pe.covariance(test_obs, test_obs)) <= 10 * np.finfo(np.float64).eps
@ -221,7 +277,7 @@ def test_gamma_method():
test_obs = pe.pseudo_Obs(value, dvalue, 't', int(1000 * (1 + np.random.rand())))
# Test if the error is processed correctly
test_obs.gamma_method(e_tag=1)
test_obs.gamma_method()
assert np.abs(test_obs.value - value) < 1e-12
assert abs(test_obs.dvalue - dvalue) < 1e-10 * dvalue
@ -241,7 +297,7 @@ def test_derived_observables():
assert np.abs(d_Obs_ad.dvalue-d_Obs_fd.dvalue) < 1000 * np.finfo(np.float64).eps * d_Obs_ad.dvalue
i_am_one = pe.derived_observable(lambda x, **kwargs: x[0] / x[1], [d_Obs_ad, d_Obs_ad])
i_am_one.gamma_method(e_tag=1)
i_am_one.gamma_method()
assert i_am_one.value == 1.0
assert i_am_one.dvalue < 2 * np.finfo(np.float64).eps
@ -290,15 +346,17 @@ def test_overloaded_functions():
for i, item in enumerate(funcs):
ad_obs = item(test_obs)
fd_obs = pe.derived_observable(lambda x, **kwargs: item(x[0]), [test_obs], num_grad=True)
ad_obs.gamma_method(S=0.01, e_tag=1)
ad_obs.gamma_method(S=0.01)
assert np.max((ad_obs.deltas['t'] - fd_obs.deltas['t']) / ad_obs.deltas['t']) < 1e-8, item.__name__
assert np.abs((ad_obs.value - item(val)) / ad_obs.value) < 1e-10, item.__name__
assert np.abs(ad_obs.dvalue - dval * np.abs(deriv[i](val))) < 1e-6, item.__name__
def test_utils():
zero_pseudo_obs = pe.pseudo_Obs(1.0, 0.0, 'null')
my_obs = pe.pseudo_Obs(1.0, 0.5, 't|r01')
my_obs += pe.pseudo_Obs(1.0, 0.5, 't|r02')
str(my_obs)
for tau_exp in [0, 5]:
my_obs.gamma_method(tau_exp=tau_exp)
my_obs.tag = "Test description"
@ -313,6 +371,8 @@ def test_utils():
my_obs.plot_piechart()
assert my_obs > (my_obs - 1)
assert my_obs < (my_obs + 1)
float(my_obs)
str(my_obs)
def test_cobs():
@ -360,6 +420,15 @@ def test_reweighting():
r_obs2 = r_obs[0] * my_obs
assert r_obs2.reweighted
my_irregular_obs = pe.Obs([np.random.rand(500)], ['t'], idl=[range(1, 1001, 2)])
assert not my_irregular_obs.reweighted
r_obs = pe.reweight(my_obs, [my_irregular_obs], all_configs=True)
r_obs = pe.reweight(my_obs, [my_irregular_obs], all_configs=False)
r_obs = pe.reweight(my_obs, [my_obs])
assert r_obs[0].reweighted
r_obs2 = r_obs[0] * my_obs
assert r_obs2.reweighted
def test_merge_obs():
my_obs1 = pe.Obs([np.random.rand(100)], ['t'])
@ -369,6 +438,16 @@ def test_merge_obs():
assert diff == -(my_obs1.value + my_obs2.value) / 2
def test_merge_obs_r_values():
a1 = pe.pseudo_Obs(1.1, .1, 'a|1')
a2 = pe.pseudo_Obs(1.2, .1, 'a|2')
a = pe.merge_obs([a1, a2])
assert np.isclose(a.r_values['a|1'], a1.value)
assert np.isclose(a.r_values['a|2'], a2.value)
assert np.isclose(a.value, np.mean([a1.value, a2.value]))
def test_correlate():
my_obs1 = pe.Obs([np.random.rand(100)], ['t'])
my_obs2 = pe.Obs([np.random.rand(100)], ['t'])
@ -397,6 +476,7 @@ def test_irregular_error_propagation():
pe.Obs([np.random.rand(6)], ['t'], idl=[[4, 18, 27, 29, 57, 80]]),
pe.Obs([np.random.rand(50)], ['t'], idl=[list(range(1, 26)) + list(range(50, 100, 2))])]
for obs1 in obs_list:
obs1.details()
for obs2 in obs_list:
assert obs1 == (obs1 / obs2) * obs2
assert obs1 == (obs1 * obs2) / obs2
@ -447,8 +527,8 @@ def test_gamma_method_irregular():
idx2 = [i + 1 for i in range(len(configs)) if configs[i] == 1]
a = pe.Obs([zero_arr, zero_arr2], ['a1', 'a2'], idl=[idx, idx2])
afull.gamma_method(e_tag=1)
a.gamma_method(e_tag=1)
afull.gamma_method()
a.gamma_method()
expe = (afull.dvalue * np.sqrt(N / np.sum(configs)))
assert (a.dvalue - 5 * a.ddvalue < expe and expe < a.dvalue + 5 * a.ddvalue)
@ -462,20 +542,20 @@ def test_gamma_method_irregular():
arr = np.random.normal(1, .2, size=N)
carr = gen_autocorrelated_array(arr, .346)
a = pe.Obs([carr], ['a'])
a.gamma_method(e_tag=1)
a.gamma_method()
ae = pe.Obs([[carr[i] for i in range(len(carr)) if i % 2 == 0]], ['a'], idl=[[i for i in range(len(carr)) if i % 2 == 0]])
ae.gamma_method(e_tag=1)
ae.gamma_method()
ao = pe.Obs([[carr[i] for i in range(len(carr)) if i % 2 == 1]], ['a'], idl=[[i for i in range(len(carr)) if i % 2 == 1]])
ao.gamma_method(e_tag=1)
ao.gamma_method()
assert(ae.e_tauint['a'] < a.e_tauint['a'])
assert((ae.e_tauint['a'] - 4 * ae.e_dtauint['a'] < ao.e_tauint['a']))
assert((ae.e_tauint['a'] + 4 * ae.e_dtauint['a'] > ao.e_tauint['a']))
def test_covariance2_symmetry():
def test_covariance_symmetry():
value1 = np.random.normal(5, 10)
dvalue1 = np.abs(np.random.normal(0, 1))
test_obs1 = pe.pseudo_Obs(value1, dvalue1, 't')
@ -484,8 +564,8 @@ def test_covariance2_symmetry():
dvalue2 = np.abs(np.random.normal(0, 1))
test_obs2 = pe.pseudo_Obs(value2, dvalue2, 't')
test_obs2.gamma_method()
cov_ab = pe.covariance2(test_obs1, test_obs2)
cov_ba = pe.covariance2(test_obs2, test_obs1)
cov_ab = pe.covariance(test_obs1, test_obs2)
cov_ba = pe.covariance(test_obs2, test_obs1)
assert np.abs(cov_ab - cov_ba) <= 10 * np.finfo(np.float64).eps
assert np.abs(cov_ab) < test_obs1.dvalue * test_obs2.dvalue * (1 + 10 * np.finfo(np.float64).eps)
@ -498,14 +578,20 @@ def test_covariance2_symmetry():
idx = [i + 1 for i in range(len(configs)) if configs[i] == 1]
a = pe.Obs([zero_arr], ['t'], idl=[idx])
a.gamma_method()
assert np.isclose(a.dvalue**2, pe.covariance2(a, a), atol=100, rtol=1e-4)
assert np.isclose(a.dvalue**2, pe.covariance(a, a), atol=100, rtol=1e-4)
cov_ab = pe.covariance2(test_obs1, a)
cov_ba = pe.covariance2(a, test_obs1)
cov_ab = pe.covariance(test_obs1, a)
cov_ba = pe.covariance(a, test_obs1)
assert np.abs(cov_ab - cov_ba) <= 10 * np.finfo(np.float64).eps
assert np.abs(cov_ab) < test_obs1.dvalue * test_obs2.dvalue * (1 + 10 * np.finfo(np.float64).eps)
def test_empty_obs():
o = pe.Obs([np.random.rand(100)], ['test'])
q = o + pe.Obs([], [])
assert q == o
def test_jackknife():
full_data = np.random.normal(1.1, 0.87, 5487)
@ -522,3 +608,11 @@ def test_jackknife():
my_new_obs = my_obs + pe.Obs([full_data], ['test2'])
with pytest.raises(Exception):
my_new_obs.export_jackknife()
def test_import_jackknife():
full_data = np.random.normal(1.105, 0.021, 754)
my_obs = pe.Obs([full_data], ['test'])
my_jacks = my_obs.export_jackknife()
reconstructed_obs = pe.import_jackknife(my_jacks, 'test')
assert my_obs == reconstructed_obs

View file

@ -15,5 +15,18 @@ def test_root_linear():
my_root = pe.roots.find_root(my_obs, root_function)
assert np.isclose(my_root.value, value)
assert np.isclose(my_root.value, my_root.r_values['t'])
difference = my_obs - my_root
assert difference.is_zero()
def test_root_linear_idl():
def root_function(x, d):
return x - d
my_obs = pe.Obs([np.random.rand(50)], ['t'], idl=[range(20, 120, 2)])
my_root = pe.roots.find_root(my_obs, root_function)
difference = my_obs - my_root
assert difference.is_zero()