From 31901400234902bd730ad46ec94273da3d137855 Mon Sep 17 00:00:00 2001 From: Simon Kuberski Date: Tue, 7 Dec 2021 17:15:46 +0100 Subject: [PATCH 1/3] Ensure fixed dimensions of cov and grad in covobs. Allow for differences of O(1e-14) in two cov matrices, when combining observables --- pyerrors/covobs.py | 3 +++ pyerrors/obs.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pyerrors/covobs.py b/pyerrors/covobs.py index b0eb4efb..64d90150 100644 --- a/pyerrors/covobs.py +++ b/pyerrors/covobs.py @@ -23,6 +23,7 @@ class Covobs: self.cov = np.array(cov) if self.cov.ndim == 0: self.N = 1 + self.cov = np.diag([self.cov]) elif self.cov.ndim == 1: self.N = len(self.cov) self.cov = np.diag(self.cov) @@ -48,6 +49,8 @@ class Covobs: self.grad[pos] = 1. else: self.grad = np.array(grad) + if self.grad.ndim == 1: + self.grad = np.reshape(self.grad, (self.N, 1)) self.value = mean def errsq(self): diff --git a/pyerrors/obs.py b/pyerrors/obs.py index bea4f7e0..934b2518 100644 --- a/pyerrors/obs.py +++ b/pyerrors/obs.py @@ -1069,7 +1069,7 @@ def derived_observable(func, data, array_mode=False, **kwargs): for o in raveled_data: for name in o.cov_names: if name in allcov: - if not np.array_equal(allcov[name], o.covobs[name].cov): + if not np.allclose(allcov[name], o.covobs[name].cov, rtol=1e-14, atol=1e-14): raise Exception('Inconsistent covariance matrices for %s!' % (name)) else: allcov[name] = o.covobs[name].cov From 7c5465d828d3712f3bd467b1447a2c846c3c8aa9 Mon Sep 17 00:00:00 2001 From: Simon Kuberski Date: Tue, 7 Dec 2021 17:33:40 +0100 Subject: [PATCH 2/3] Added tests when changing cov and grad in covobs --- pyerrors/covobs.py | 52 ++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/pyerrors/covobs.py b/pyerrors/covobs.py index 64d90150..9343dc41 100644 --- a/pyerrors/covobs.py +++ b/pyerrors/covobs.py @@ -20,19 +20,7 @@ class Covobs: grad : list or array Gradient of the Covobs wrt. the means belonging to cov. """ - self.cov = np.array(cov) - if self.cov.ndim == 0: - self.N = 1 - self.cov = np.diag([self.cov]) - elif self.cov.ndim == 1: - self.N = len(self.cov) - self.cov = np.diag(self.cov) - elif self.cov.ndim == 2: - self.N = self.cov.shape[0] - if self.cov.shape[1] != self.N: - raise Exception('Covariance matrix has to be a square matrix!') - else: - raise Exception('Covariance matrix has to be a 2 dimensional square matrix!') + self.set_cov(cov) if '|' in name: raise Exception("Covobs name must not contain replica separator '|'.") self.name = name @@ -45,15 +33,43 @@ class Covobs: else: if pos > self.N: raise Exception('pos %d too large for covariance matrix with dimension %dx%d!' % (pos, self.N, self.N)) - self.grad = np.zeros((self.N, 1)) - self.grad[pos] = 1. + self._grad = np.zeros((self.N, 1)) + self._grad[pos] = 1. else: - self.grad = np.array(grad) - if self.grad.ndim == 1: - self.grad = np.reshape(self.grad, (self.N, 1)) + self.set_grad(grad) self.value = mean def errsq(self): """ Return the variance (= square of the error) of the Covobs """ return float(np.dot(np.transpose(self.grad), np.dot(self.cov, self.grad))) + + def set_cov(self, cov): + self._cov = np.array(cov) + if self._cov.ndim == 0: + self.N = 1 + self._cov = np.diag([self._cov]) + elif self._cov.ndim == 1: + self.N = len(self._cov) + self._cov = np.diag(self._cov) + elif self._cov.ndim == 2: + self.N = self._cov.shape[0] + if self._cov.shape[1] != self.N: + raise Exception('Covariance matrix has to be a square matrix!') + else: + raise Exception('Covariance matrix has to be a 2 dimensional square matrix!') + + def set_grad(self, grad): + self._grad = np.array(grad) + if self._grad.ndim in [0, 1]: + self._grad = np.reshape(self._grad, (self.N, 1)) + elif self._grad.ndim != 2: + raise Exception('Invalid dimension of grad!') + + @property + def cov(self): + return self._cov + + @property + def grad(self): + return self._grad From a5cf0270d37867599c2a588ddfeab0891a7eb75f Mon Sep 17 00:00:00 2001 From: Simon Kuberski Date: Wed, 8 Dec 2021 08:55:40 +0100 Subject: [PATCH 3/3] Hidden _set_cov and _set_grad, modified test for equality of covs --- pyerrors/covobs.py | 8 ++++---- pyerrors/obs.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyerrors/covobs.py b/pyerrors/covobs.py index 9343dc41..2c8f81fc 100644 --- a/pyerrors/covobs.py +++ b/pyerrors/covobs.py @@ -20,7 +20,7 @@ class Covobs: grad : list or array Gradient of the Covobs wrt. the means belonging to cov. """ - self.set_cov(cov) + self._set_cov(cov) if '|' in name: raise Exception("Covobs name must not contain replica separator '|'.") self.name = name @@ -36,7 +36,7 @@ class Covobs: self._grad = np.zeros((self.N, 1)) self._grad[pos] = 1. else: - self.set_grad(grad) + self._set_grad(grad) self.value = mean def errsq(self): @@ -44,7 +44,7 @@ class Covobs: """ return float(np.dot(np.transpose(self.grad), np.dot(self.cov, self.grad))) - def set_cov(self, cov): + def _set_cov(self, cov): self._cov = np.array(cov) if self._cov.ndim == 0: self.N = 1 @@ -59,7 +59,7 @@ class Covobs: else: raise Exception('Covariance matrix has to be a 2 dimensional square matrix!') - def set_grad(self, grad): + def _set_grad(self, grad): self._grad = np.array(grad) if self._grad.ndim in [0, 1]: self._grad = np.reshape(self._grad, (self.N, 1)) diff --git a/pyerrors/obs.py b/pyerrors/obs.py index 934b2518..c27670ed 100644 --- a/pyerrors/obs.py +++ b/pyerrors/obs.py @@ -1069,7 +1069,7 @@ def derived_observable(func, data, array_mode=False, **kwargs): for o in raveled_data: for name in o.cov_names: if name in allcov: - if not np.allclose(allcov[name], o.covobs[name].cov, rtol=1e-14, atol=1e-14): + if not np.allclose(allcov[name], o.covobs[name].cov): raise Exception('Inconsistent covariance matrices for %s!' % (name)) else: allcov[name] = o.covobs[name].cov