mirror of
https://github.com/fjosw/pyerrors.git
synced 2025-03-15 14:50:25 +01:00
first version of new bookeeping system
This commit is contained in:
parent
b86dda2394
commit
e4d7d56180
4 changed files with 38 additions and 54 deletions
2
.github/workflows/pytest.yml
vendored
2
.github/workflows/pytest.yml
vendored
|
@ -33,4 +33,4 @@ jobs:
|
|||
pip install pytest-benchmark
|
||||
|
||||
- name: Run tests
|
||||
run: pytest --cov=pyerrors -v
|
||||
run: pytest --cov=pyerrors -vv
|
||||
|
|
|
@ -24,9 +24,6 @@ class Obs:
|
|||
|
||||
Attributes
|
||||
----------
|
||||
e_tag_global : int
|
||||
Integer which determines which part of the name belongs
|
||||
to the ensemble and which to the replicum.
|
||||
S_global : float
|
||||
Standard value for S (default 2.0)
|
||||
S_dict : dict
|
||||
|
@ -41,12 +38,11 @@ class Obs:
|
|||
Standard value for N_sigma (default 1.0)
|
||||
"""
|
||||
__slots__ = ['names', 'shape', 'r_values', 'deltas', 'N', '_value', '_dvalue',
|
||||
'ddvalue', 'reweighted', 'S', 'tau_exp', 'N_sigma', 'e_names',
|
||||
'e_content', 'e_dvalue', 'e_ddvalue', 'e_tauint', 'e_dtauint',
|
||||
'ddvalue', 'reweighted', 'S', 'tau_exp', 'N_sigma',
|
||||
'e_dvalue', 'e_ddvalue', 'e_tauint', 'e_dtauint',
|
||||
'e_windowsize', 'e_rho', 'e_drho', 'e_n_tauint', 'e_n_dtauint',
|
||||
'idl', 'is_merged', 'tag', '__dict__']
|
||||
|
||||
e_tag_global = 0
|
||||
S_global = 2.0
|
||||
S_dict = {}
|
||||
tau_exp_global = 0.0
|
||||
|
@ -141,6 +137,19 @@ class Obs:
|
|||
def dvalue(self):
|
||||
return self._dvalue
|
||||
|
||||
@property
|
||||
def e_names(self):
|
||||
return sorted(set([o.split('|')[0] for o in self.names]))
|
||||
|
||||
@property
|
||||
def e_content(self):
|
||||
res = {}
|
||||
for e, e_name in enumerate(self.e_names):
|
||||
res[e_name] = sorted(filter(lambda x: x.startswith(e_name + '|'), self.names))
|
||||
if e_name in self.names:
|
||||
res[e_name].append(e_name)
|
||||
return res
|
||||
|
||||
def expand_deltas(self, deltas, idx, shape):
|
||||
"""Expand deltas defined on idx to a regular, contiguous range, where holes are filled by 0.
|
||||
If idx is of type range, the deltas are not changed
|
||||
|
@ -202,23 +211,12 @@ class Obs:
|
|||
N_sigma : float
|
||||
number of standard deviations from zero until the tail is
|
||||
attached to the autocorrelation function (default 1)
|
||||
e_tag : int
|
||||
number of characters which label the ensemble. The remaining
|
||||
ones label replica (default 0)
|
||||
fft : bool
|
||||
determines whether the fft algorithm is used for the computation
|
||||
of the autocorrelation function (default True)
|
||||
"""
|
||||
|
||||
if 'e_tag' in kwargs:
|
||||
e_tag_local = kwargs.get('e_tag')
|
||||
if not isinstance(e_tag_local, int):
|
||||
raise TypeError('Error: e_tag is not integer')
|
||||
else:
|
||||
e_tag_local = Obs.e_tag_global
|
||||
|
||||
self.e_names = sorted(set([o[:e_tag_local] for o in self.names]))
|
||||
self.e_content = {}
|
||||
e_content = self.e_content
|
||||
self.e_dvalue = {}
|
||||
self.e_ddvalue = {}
|
||||
self.e_tauint = {}
|
||||
|
@ -295,36 +293,26 @@ class Obs:
|
|||
else:
|
||||
self.N_sigma = Obs.N_sigma_global
|
||||
|
||||
if max([len(x) for x in self.names]) <= e_tag_local:
|
||||
for e, e_name in enumerate(self.e_names):
|
||||
self.e_content[e_name] = [e_name]
|
||||
else:
|
||||
for e, e_name in enumerate(self.e_names):
|
||||
if len(e_name) < e_tag_local:
|
||||
self.e_content[e_name] = [e_name]
|
||||
else:
|
||||
self.e_content[e_name] = sorted(filter(lambda x: x.startswith(e_name), self.names))
|
||||
|
||||
for e, e_name in enumerate(self.e_names):
|
||||
|
||||
r_length = []
|
||||
for r_name in self.e_content[e_name]:
|
||||
for r_name in e_content[e_name]:
|
||||
if self.idl[r_name] is range:
|
||||
r_length.append(len(self.idl[r_name]))
|
||||
else:
|
||||
r_length.append((self.idl[r_name][-1] - self.idl[r_name][0] + 1))
|
||||
|
||||
e_N = np.sum([self.shape[r_name] for r_name in self.e_content[e_name]])
|
||||
e_N = np.sum([self.shape[r_name] for r_name in e_content[e_name]])
|
||||
w_max = max(r_length) // 2
|
||||
e_gamma[e_name] = np.zeros(w_max)
|
||||
self.e_rho[e_name] = np.zeros(w_max)
|
||||
self.e_drho[e_name] = np.zeros(w_max)
|
||||
|
||||
for r_name in self.e_content[e_name]:
|
||||
for r_name in e_content[e_name]:
|
||||
e_gamma[e_name] += self.calc_gamma(self.deltas[r_name], self.idl[r_name], self.shape[r_name], w_max, fft)
|
||||
|
||||
gamma_div = np.zeros(w_max)
|
||||
for r_name in self.e_content[e_name]:
|
||||
for r_name in e_content[e_name]:
|
||||
gamma_div += self.calc_gamma(np.ones((self.shape[r_name])), self.idl[r_name], self.shape[r_name], w_max, fft)
|
||||
e_gamma[e_name] /= gamma_div[:w_max]
|
||||
|
||||
|
@ -384,11 +372,11 @@ class Obs:
|
|||
self.ddvalue += (self.e_dvalue[e_name] * self.e_ddvalue[e_name]) ** 2
|
||||
|
||||
self._dvalue = np.sqrt(self.dvalue)
|
||||
if self.dvalue == 0.0:
|
||||
if self._dvalue == 0.0:
|
||||
self.ddvalue = 0.0
|
||||
else:
|
||||
self.ddvalue = np.sqrt(self.ddvalue) / self.dvalue
|
||||
return 0
|
||||
return
|
||||
|
||||
def print(self, level=1):
|
||||
"""Print basic properties of the Obs."""
|
||||
|
@ -400,7 +388,7 @@ class Obs:
|
|||
else:
|
||||
percentage = np.abs(self.dvalue / self.value) * 100
|
||||
print('Result\t %3.8e +/- %3.8e +/- %3.8e (%3.3f%%)' % (self.value, self.dvalue, self.ddvalue, percentage))
|
||||
if hasattr(self, 'e_names'):
|
||||
if hasattr(self, 'e_dvalue'):
|
||||
if len(self.e_names) > 1:
|
||||
print(' Ensemble errors:')
|
||||
for e_name in self.e_names:
|
||||
|
|
|
@ -30,9 +30,8 @@ def test_least_squares():
|
|||
out = pe.least_squares(x, oy, func)
|
||||
beta = out.fit_parameters
|
||||
|
||||
pe.Obs.e_tag_global = 5
|
||||
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, 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)
|
||||
|
|
|
@ -135,7 +135,7 @@ def test_fft():
|
|||
test_obs2 = copy.deepcopy(test_obs1)
|
||||
test_obs1.gamma_method()
|
||||
test_obs2.gamma_method(fft=False)
|
||||
assert max(np.abs(test_obs1.e_rho[''] - test_obs2.e_rho[''])) <= 10 * np.finfo(np.float64).eps
|
||||
assert max(np.abs(test_obs1.e_rho['t'] - test_obs2.e_rho['t'])) <= 10 * np.finfo(np.float64).eps
|
||||
assert np.abs(test_obs1.dvalue - test_obs2.dvalue) <= 10 * max(test_obs1.dvalue, test_obs2.dvalue) * np.finfo(np.float64).eps
|
||||
|
||||
|
||||
|
@ -190,22 +190,19 @@ def test_derived_observables():
|
|||
assert i_am_one.e_ddvalue['t'] <= 2 * np.finfo(np.float64).eps
|
||||
|
||||
|
||||
def test_multi_ens_system():
|
||||
names = []
|
||||
for i in range(100 + int(np.random.rand() * 50)):
|
||||
tmp_string = ''
|
||||
for _ in range(int(2 + np.random.rand() * 4)):
|
||||
tmp_string += random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)
|
||||
names.append(tmp_string)
|
||||
names = list(set(names))
|
||||
samples = [np.random.rand(5)] * len(names)
|
||||
new_obs = pe.Obs(samples, names)
|
||||
def test_multi_ens():
|
||||
names = ['A0', 'A1|r001', 'A1|r002']
|
||||
test_obs = pe.Obs([np.random.rand(50), np.random.rand(50), np.random.rand(50)], names)
|
||||
assert test_obs.e_names == ['A0', 'A1']
|
||||
assert test_obs.e_content['A0'] == ['A0']
|
||||
assert test_obs.e_content['A1'] == ['A1|r001', 'A1|r002']
|
||||
|
||||
for e_tag_length in range(1, 6):
|
||||
new_obs.gamma_method(e_tag=e_tag_length)
|
||||
e_names = sorted(set([n[:e_tag_length] for n in names]))
|
||||
assert e_names == new_obs.e_names
|
||||
assert sorted(x for y in sorted(new_obs.e_content.values()) for x in y) == sorted(new_obs.names)
|
||||
my_sum = 0
|
||||
ensembles = []
|
||||
for i in range(100):
|
||||
my_sum += pe.Obs([np.random.rand(50)], [str(i)])
|
||||
ensembles.append(str(i))
|
||||
assert my_sum.e_names == sorted(ensembles)
|
||||
|
||||
|
||||
def test_overloaded_functions():
|
||||
|
|
Loading…
Add table
Reference in a new issue