@@ -40,6 +40,8 @@ def __init__(self, corr_item):
40
40
self .tracer1 = corr_item .tracer1
41
41
self .tracer2 = corr_item .tracer2
42
42
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 )
43
45
44
46
# Read the data file and init the corrdinate grids
45
47
data_path = corr_item .config ['data' ].get ('filename' )
@@ -155,19 +157,7 @@ def inv_masked_cov(self):
155
157
"""
156
158
if self ._inv_masked_cov is None :
157
159
# 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 ()
171
161
172
162
return self ._inv_masked_cov
173
163
@@ -587,7 +577,12 @@ def create_monte_carlo(self, fiducial_model, scale=None, seed=None, forecast=Fal
587
577
588
578
# Compute cholesky decomposition
589
579
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 )
591
586
592
587
# Create the mock
593
588
if seed is not None :
@@ -603,8 +598,43 @@ def create_monte_carlo(self, fiducial_model, scale=None, seed=None, forecast=Fal
603
598
if forecast :
604
599
self .mc_mock = masked_fiducial
605
600
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
+
608
609
self .masked_mc_mock = self .mc_mock [self .data_mask ]
609
610
610
611
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