Skip to content

Commit fbf6532

Browse files
committed
Add option to cholesky decompose the masked cov
1 parent 9eb82a7 commit fbf6532

File tree

1 file changed

+46
-16
lines changed

1 file changed

+46
-16
lines changed

vega/data.py

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ def __init__(self, corr_item):
4040
self.tracer1 = corr_item.tracer1
4141
self.tracer2 = corr_item.tracer2
4242
self.use_metal_autos = corr_item.config['model'].getboolean('use_metal_autos', True)
43+
self.invert_full_cov = corr_item.config['data'].getboolean('invert-full-cov', False)
44+
self.cholesky_masked_cov = corr_item.config['data'].getboolean('cholesky-masked-cov', False)
4345

4446
# Read the data file and init the corrdinate grids
4547
data_path = corr_item.config['data'].get('filename')
@@ -155,19 +157,7 @@ def inv_masked_cov(self):
155157
"""
156158
if self._inv_masked_cov is None:
157159
# Compute inverse of the covariance matrix
158-
masked_cov = self.cov_mat[:, self.data_mask]
159-
masked_cov = masked_cov[self.data_mask, :]
160-
try:
161-
linalg.cholesky(self.cov_mat)
162-
print('LOG: Full matrix is positive definite')
163-
except linalg.LinAlgError:
164-
print('WARNING: Full matrix is not positive definite')
165-
try:
166-
linalg.cholesky(masked_cov)
167-
print('LOG: Reduced matrix is positive definite')
168-
except linalg.LinAlgError:
169-
print('WARNING: Reduced matrix is not positive definite')
170-
self._inv_masked_cov = linalg.inv(masked_cov)
160+
self.compute_masked_invcov()
171161

172162
return self._inv_masked_cov
173163

@@ -587,7 +577,12 @@ def create_monte_carlo(self, fiducial_model, scale=None, seed=None, forecast=Fal
587577

588578
# Compute cholesky decomposition
589579
if (self._cholesky is None or self._recompute) and not forecast:
590-
self._cholesky = linalg.cholesky(self._scale * self.cov_mat)
580+
if self.cholesky_masked_cov:
581+
masked_cov = self.cov_mat[:, self.data_mask]
582+
masked_cov = masked_cov[self.data_mask, :]
583+
self._cholesky = linalg.cholesky(self._scale * masked_cov)
584+
else:
585+
self._cholesky = linalg.cholesky(self._scale * self.cov_mat)
591586

592587
# Create the mock
593588
if seed is not None:
@@ -603,8 +598,43 @@ def create_monte_carlo(self, fiducial_model, scale=None, seed=None, forecast=Fal
603598
if forecast:
604599
self.mc_mock = masked_fiducial
605600
else:
606-
ran_vec = np.random.randn(self.full_data_size)
607-
self.mc_mock = self._cholesky.dot(ran_vec) + masked_fiducial
601+
self.mc_mock = np.full(self.full_data_size, np.nan)
602+
if self.cholesky_masked_cov:
603+
ran_vec = np.random.randn(self.data_mask.sum())
604+
self.mc_mock[self.data_mask] = masked_fiducial + self._cholesky.dot(ran_vec)
605+
else:
606+
ran_vec = np.random.randn(self.full_data_size)
607+
self.mc_mock = masked_fiducial + self._cholesky.dot(ran_vec)
608+
608609
self.masked_mc_mock = self.mc_mock[self.data_mask]
609610

610611
return self.mc_mock
612+
613+
def compute_masked_invcov(self):
614+
"""Compute the masked inverse of the covariance matrix.
615+
"""
616+
masked_cov = self.cov_mat[:, self.data_mask]
617+
masked_cov = masked_cov[self.data_mask, :]
618+
619+
try:
620+
linalg.cholesky(self.cov_mat)
621+
print('LOG: Full matrix is positive definite')
622+
except linalg.LinAlgError:
623+
if self.invert_full_cov:
624+
raise ValueError('Full matrix is not positive definite. '
625+
'Use invert-full-cov = False to work with the masked covariance')
626+
else:
627+
print('WARNING: Full matrix is not positive definite')
628+
629+
try:
630+
linalg.cholesky(masked_cov)
631+
print('LOG: Reduced matrix is positive definite')
632+
except linalg.LinAlgError:
633+
print('WARNING: Reduced matrix is not positive definite')
634+
635+
if self.invert_full_cov:
636+
inv_cov = linalg.inv(self.cov_mat)
637+
self._inv_masked_cov = inv_cov[:, self.data_mask]
638+
self._inv_masked_cov = self._inv_masked_cov[self.data_mask, :]
639+
else:
640+
self._inv_masked_cov = linalg.inv(masked_cov)

0 commit comments

Comments
 (0)