From 7568275d5d6f1ae48b938c6cc604dadf43e8395f Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 9 Feb 2022 14:05:44 +0000 Subject: [PATCH 1/4] refactor: io tests split up in several files --- tests/{io_test.py => json_io_test.py} | 45 ------------------------ tests/openQCD_in_test.py | 49 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 45 deletions(-) rename tests/{io_test.py => json_io_test.py} (80%) create mode 100644 tests/openQCD_in_test.py diff --git a/tests/io_test.py b/tests/json_io_test.py similarity index 80% rename from tests/io_test.py rename to tests/json_io_test.py index 92e97902..f5546d9f 100644 --- a/tests/io_test.py +++ b/tests/json_io_test.py @@ -242,48 +242,3 @@ def test_json_dict_io(): jsonio.dump_dict_to_json(od, fname, description=desc) os.remove(fname + '.json.gz') - - -def test_openqcd(): - path = './tests//data/openqcd_test/' - prefix = 'sfqcd' - postfix = '.rwms' - - # sfqcd-1.6: Trajectories instead of confignumbers are printed to file. - rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix) - repname = list(rwfo[0].idl.keys())[0] - assert(rwfo[0].idl[repname] == range(1, 13)) - rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[1], r_stop=[12]) - assert(rwfo[0].idl[repname] == range(1, 13)) - rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[3], r_stop=[8]) - assert(rwfo[0].idl[repname] == range(3, 9)) - rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[2], r_stop=[6]) - assert(rwfo[0].idl[repname] == range(2, 7)) - rwfs = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[1], r_stop=[12], r_step=2) - assert(rwfs[0].idl[repname] == range(1, 12, 2)) - rwfs = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[2], r_stop=[12], r_step=2) - assert(rwfs[0].idl[repname] == range(2, 13, 2)) - rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix) - assert((rwfo[0].r_values[repname] + rwfo[0].deltas[repname][1]) == (rwfs[0].r_values[repname] + rwfs[0].deltas[repname][0])) - - o = pe.pseudo_Obs(1., .01, repname, samples=12) - pe.reweight(rwfo[0], [o]) - - o = pe.pseudo_Obs(1., .01, repname, samples=6) - pe.reweight(rwfo[0], [o]) - o.idl[repname] = range(2, 13, 2) - pe.reweight(rwfo[0], [o]) - pe.reweight(rwfs[0], [o]) - - files = ['openqcd2r1.ms1.dat'] - names = ['openqcd2|r1'] - - # TM with 2 Hasenbusch factors and 2 sources each + RHMC with one source, openQCD 2.0 - rwfo = pe.input.openQCD.read_rwms(path, prefix, version='2.0', files=files, names=names) - assert(len(rwfo) == 2) - assert(rwfo[0].value == 0.9999974970236312) - assert(rwfo[1].value == 1.184681251089919) - repname = list(rwfo[0].idl.keys())[0] - assert(rwfo[0].idl[repname] == range(1, 10)) - rwfo = pe.input.openQCD.read_rwms(path, prefix, version='2.0', files=files, names=names, r_start=[1], r_stop=[8]) - assert(rwfo[0].idl[repname] == range(1, 9)) diff --git a/tests/openQCD_in_test.py b/tests/openQCD_in_test.py new file mode 100644 index 00000000..d1dc999d --- /dev/null +++ b/tests/openQCD_in_test.py @@ -0,0 +1,49 @@ +import os +import numpy as np +import pyerrors as pe +import pytest + + +def test_openqcd(): + path = './tests//data/openqcd_test/' + prefix = 'sfqcd' + postfix = '.rwms' + + # sfqcd-1.6: Trajectories instead of confignumbers are printed to file. + rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix) + repname = list(rwfo[0].idl.keys())[0] + assert(rwfo[0].idl[repname] == range(1, 13)) + rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[1], r_stop=[12]) + assert(rwfo[0].idl[repname] == range(1, 13)) + rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[3], r_stop=[8]) + assert(rwfo[0].idl[repname] == range(3, 9)) + rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[2], r_stop=[6]) + assert(rwfo[0].idl[repname] == range(2, 7)) + rwfs = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[1], r_stop=[12], r_step=2) + assert(rwfs[0].idl[repname] == range(1, 12, 2)) + rwfs = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix, r_start=[2], r_stop=[12], r_step=2) + assert(rwfs[0].idl[repname] == range(2, 13, 2)) + rwfo = pe.input.openQCD.read_rwms(path, prefix, version='1.6', postfix=postfix) + assert((rwfo[0].r_values[repname] + rwfo[0].deltas[repname][1]) == (rwfs[0].r_values[repname] + rwfs[0].deltas[repname][0])) + + o = pe.pseudo_Obs(1., .01, repname, samples=12) + pe.reweight(rwfo[0], [o]) + + o = pe.pseudo_Obs(1., .01, repname, samples=6) + pe.reweight(rwfo[0], [o]) + o.idl[repname] = range(2, 13, 2) + pe.reweight(rwfo[0], [o]) + pe.reweight(rwfs[0], [o]) + + files = ['openqcd2r1.ms1.dat'] + names = ['openqcd2|r1'] + + # TM with 2 Hasenbusch factors and 2 sources each + RHMC with one source, openQCD 2.0 + rwfo = pe.input.openQCD.read_rwms(path, prefix, version='2.0', files=files, names=names) + assert(len(rwfo) == 2) + assert(rwfo[0].value == 0.9999974970236312) + assert(rwfo[1].value == 1.184681251089919) + repname = list(rwfo[0].idl.keys())[0] + assert(rwfo[0].idl[repname] == range(1, 10)) + rwfo = pe.input.openQCD.read_rwms(path, prefix, version='2.0', files=files, names=names, r_start=[1], r_stop=[8]) + assert(rwfo[0].idl[repname] == range(1, 9)) From 471eabeb8cfe034fb5eee62a0de200cd27ed243b Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 9 Feb 2022 14:18:36 +0000 Subject: [PATCH 2/4] fix: Bug in export of derivative of correlator containing covobs fixed, test added. --- pyerrors/input/json.py | 3 +++ tests/json_io_test.py | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/pyerrors/input/json.py b/pyerrors/input/json.py index 6b854874..cdf203f2 100644 --- a/pyerrors/input/json.py +++ b/pyerrors/input/json.py @@ -171,6 +171,9 @@ def create_json_string(ol, description='', indent=1): names.append(key) idl.append(value) my_obs = Obs(samples, names, idl) + my_obs._covobs = obs._covobs + for name in obs._covobs: + my_obs.names.append(name) my_obs.reweighted = obs.reweighted my_obs.is_merged = obs.is_merged return my_obs diff --git a/tests/json_io_test.py b/tests/json_io_test.py index f5546d9f..04ccfd9f 100644 --- a/tests/json_io_test.py +++ b/tests/json_io_test.py @@ -242,3 +242,12 @@ def test_json_dict_io(): jsonio.dump_dict_to_json(od, fname, description=desc) os.remove(fname + '.json.gz') + + +def test_renorm_deriv_of_corr(tmp_path): + c = pe.Corr([pe.pseudo_Obs(i, .1, 'test') for i in range(10)]) + c *= pe.cov_Obs(1., .1, '#ren') + c = c.deriv() + pe.input.json.dump_to_json(c, (tmp_path / 'test').as_posix()) + recover = pe.input.json.load_json((tmp_path / 'test').as_posix()) + assert np.all([o == 0 for o in (c - recover)[1:-1]]) From f8c8b27ec3bf4090f78b239bee20586b7c5da5db Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 9 Feb 2022 14:41:59 +0000 Subject: [PATCH 3/4] docs: CHANGELOG updated --- CHANGELOG.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73d9eab9..f2503841 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,30 +2,39 @@ All notable changes to this project will be documented in this file. -## [2.0.0] - 2021-??-?? +## [2.0.0] - 2022-??-?? ### Added +- The possibility to work with Monte Carlo histories which are evenly or unevenly spaced was added. +- `cov_Obs` added as a possibility to propagate the error of non Monte Carlo data together with Monte Carlo data. - `CObs` class added which can handle complex valued Markov chain Monte Carlo data and the corresponding error propagation. - Matrix to matrix operations like the matrix inverse now also work for complex matrices and matrices containing entries that are not `Obs` but `float` or `int`. -- The possibility to work with Monte Carlo histories which are evenly or unevenly spaced was added. +- Support for a new `json.gz` file format was added - The Corr class now has additional methods like `reverse`, `T_symmetry`, `correlate` and `reweight`. -- `linalg` module now has explicit functions `inv` and `cholesky`. +- `Corr.m_eff` can now cope with periodic and anti-periodic correlation functions +- Forward, backward and improved variants of the first and second derivative were added to the `Corr` class +- The `linalg` module now has explicit functions `inv` and `cholesky`. - `Obs` objects now have methods `is_zero` and `is_zero_within_error` as well as overloaded comparison operations. - Functions to convert Obs data to or from jackknife was added. - Alternative matrix multiplication routine `jack_matmul` was added to `linalg` module which makes use of the jackknife approximation and is much faster for large matrices. - Additional input routines for npr data added to `input.hadrons`. +- The `sfcf` and `openQCD` input modules can now handle all recent file type versions. +- `extract_t0` can now visualize the extraction on the fly +- Module added which provides the Dirac gamma matrices in the Grid convention. - Version number added. ### Changed - The internal bookkeeping system for ensembles/replica was changed. The separator for replica is now `|`. - The fit functions were renamed to `least_squares` and `total_least_squares`. +- The output of the fit functions is now a dedicated results class which keeps track of all relevant information - The fit functions can now deal with provided covariance matrices. - The convention for the fit range in the Corr class has been changed. -- Obs.print was renamed to Obs.details and the output was improved. +- Various method of the `Corr` class were renamed +- `Obs.print` was renamed to `Obs.details` and the output was improved. - The default value for `Corr.prange` is now `None`. - The `input` module was restructured to contain one submodule per data source. - Performance of Obs.__init__ improved. -### Deprecated +### Removed - The function `plot_corrs` was deprecated as all its functionality is now contained within `Corr.show` - The kwarg `bias_correction` in `derived_observable` was removed - Obs no longer have an attribute `e_Q` From ca040972729c4e09527275f370b5c8a722810243 Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 9 Feb 2022 15:32:18 +0000 Subject: [PATCH 4/4] feat: thin method added to Corr class which allows to thin out a correlator in order suppress correlations between neighbouring entries --- pyerrors/correlators.py | 18 ++++++++++++++++++ tests/correlators_test.py | 8 ++++++++ 2 files changed, 26 insertions(+) diff --git a/pyerrors/correlators.py b/pyerrors/correlators.py index 694dc9a5..cb40be1a 100644 --- a/pyerrors/correlators.py +++ b/pyerrors/correlators.py @@ -376,6 +376,24 @@ class Corr: """Reverse the time ordering of the Corr""" return Corr(self.content[:: -1]) + def thin(self, spacing=2, offset=0): + """Thin out a correlator to suppress correlations + + Parameters + ---------- + spacing : int + Keep only every 'spacing'th entry of the correlator + offset : int + Offset the equal spacing + """ + new_content = [] + for t in range(self.T): + if (offset + t) % spacing != 0: + new_content.append(None) + else: + new_content.append(self.content[t]) + return Corr(new_content) + def correlate(self, partner): """Correlate the correlator with another correlator or Obs diff --git a/tests/correlators_test.py b/tests/correlators_test.py index 1a394d63..2bbea0b5 100644 --- a/tests/correlators_test.py +++ b/tests/correlators_test.py @@ -283,3 +283,11 @@ def test_hankel(): corr.Hankel(2) corr.Hankel(6, periodic=True) + +def test_thin(): + c = pe.Corr([pe.pseudo_Obs(i, .1, 'test') for i in range(10)]) + c *= pe.cov_Obs(1., .1, '#ren') + thin = c.thin() + thin.fit(lambda a, x: a[0] * x) + c.thin(offset=1) + c.thin(3, offset=1)