Skip to content

Commit 8d52c7d

Browse files
committed
suggested change to correct small eigenvalues in covariance
1 parent 8170c84 commit 8d52c7d

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

src/qinfer/distributions.py

+13-6
Original file line numberDiff line numberDiff line change
@@ -393,9 +393,16 @@ def particle_covariance_mtx(cls, weights, locations):
393393
# positive-semidefinite covariance matrix. If a negative eigenvalue
394394
# is produced, we should warn the caller of this.
395395
assert np.all(np.isfinite(cov))
396-
if not np.all(la.eig(cov)[0] >= 0):
397-
warnings.warn('Numerical error in covariance estimation causing positive semidefinite violation.', ApproximationWarning)
398-
396+
vals, vecs = la.eig(cov)
397+
small_vals = abs(vals) < 1e-12
398+
vals[small_vals] = 0
399+
if not np.all(vals >= 0):
400+
warnings.warn(
401+
'Numerical error in covariance estimation causing positive semidefinite violation.',
402+
ApproximationWarning
403+
)
404+
if np.any(small_vals):
405+
return (vecs * vals) @ vecs.T.conj()
399406
return cov
400407

401408
def est_mean(self):
@@ -1007,12 +1014,12 @@ def n_rvs(self):
10071014

10081015
def sample(self, n=1):
10091016
return self.dist.rvs(size=n)[:, np.newaxis]
1010-
1017+
10111018
class DirichletDistribution(Distribution):
10121019
r"""
10131020
The dirichlet distribution, whose pdf at :math:`x` is proportional to
10141021
:math:`\prod_i x_i^{\alpha_i-1}`.
1015-
1022+
10161023
:param alpha: The list of concentration parameters.
10171024
"""
10181025
def __init__(self, alpha):
@@ -1021,7 +1028,7 @@ def __init__(self, alpha):
10211028
raise ValueError('The input alpha must be a 1D list of concentration parameters.')
10221029

10231030
self._dist = st.dirichlet(alpha=self.alpha)
1024-
1031+
10251032
@property
10261033
def alpha(self):
10271034
return self._alpha

0 commit comments

Comments
 (0)