From 8d52c7de8efdeabeb97804366496720ea3c23028 Mon Sep 17 00:00:00 2001 From: Michael Lauria Date: Fri, 22 Nov 2019 11:29:36 -0700 Subject: [PATCH 1/2] suggested change to correct small eigenvalues in covariance --- src/qinfer/distributions.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/qinfer/distributions.py b/src/qinfer/distributions.py index c3b7417..32881f8 100644 --- a/src/qinfer/distributions.py +++ b/src/qinfer/distributions.py @@ -393,9 +393,16 @@ def particle_covariance_mtx(cls, weights, locations): # positive-semidefinite covariance matrix. If a negative eigenvalue # is produced, we should warn the caller of this. assert np.all(np.isfinite(cov)) - if not np.all(la.eig(cov)[0] >= 0): - warnings.warn('Numerical error in covariance estimation causing positive semidefinite violation.', ApproximationWarning) - + vals, vecs = la.eig(cov) + small_vals = abs(vals) < 1e-12 + vals[small_vals] = 0 + if not np.all(vals >= 0): + warnings.warn( + 'Numerical error in covariance estimation causing positive semidefinite violation.', + ApproximationWarning + ) + if np.any(small_vals): + return (vecs * vals) @ vecs.T.conj() return cov def est_mean(self): @@ -1007,12 +1014,12 @@ def n_rvs(self): def sample(self, n=1): return self.dist.rvs(size=n)[:, np.newaxis] - + class DirichletDistribution(Distribution): r""" The dirichlet distribution, whose pdf at :math:`x` is proportional to :math:`\prod_i x_i^{\alpha_i-1}`. - + :param alpha: The list of concentration parameters. """ def __init__(self, alpha): @@ -1021,7 +1028,7 @@ def __init__(self, alpha): raise ValueError('The input alpha must be a 1D list of concentration parameters.') self._dist = st.dirichlet(alpha=self.alpha) - + @property def alpha(self): return self._alpha From 9363f608a14fe596b98b5dd8e26d62811871ba0c Mon Sep 17 00:00:00 2001 From: Michael Lauria Date: Fri, 13 Dec 2019 13:54:06 -0700 Subject: [PATCH 2/2] only change negative values --- src/qinfer/distributions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qinfer/distributions.py b/src/qinfer/distributions.py index 32881f8..3984bdb 100644 --- a/src/qinfer/distributions.py +++ b/src/qinfer/distributions.py @@ -394,14 +394,14 @@ def particle_covariance_mtx(cls, weights, locations): # is produced, we should warn the caller of this. assert np.all(np.isfinite(cov)) vals, vecs = la.eig(cov) - small_vals = abs(vals) < 1e-12 - vals[small_vals] = 0 + small_negative_vals = (vals < 0) & (vals > -1e-12) + vals[small_negative_vals] = 0 if not np.all(vals >= 0): warnings.warn( 'Numerical error in covariance estimation causing positive semidefinite violation.', ApproximationWarning ) - if np.any(small_vals): + if np.any(small_negative_vals): return (vecs * vals) @ vecs.T.conj() return cov