From ea315fda27ec7e937a5749dedf40133861cbfd3d Mon Sep 17 00:00:00 2001 From: Will Handley Date: Tue, 1 Feb 2022 23:04:19 +0000 Subject: [PATCH 1/5] Updated to be resilient to nans in cl calculations --- cobaya/likelihoods/base_classes/planck_clik.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cobaya/likelihoods/base_classes/planck_clik.py b/cobaya/likelihoods/base_classes/planck_clik.py index f0075cef4..31bfab2b9 100644 --- a/cobaya/likelihoods/base_classes/planck_clik.py +++ b/cobaya/likelihoods/base_classes/planck_clik.py @@ -115,6 +115,11 @@ def get_requirements(self): def logp(self, **params_values): # get Cl's from the theory code cl = self.provider.get_Cl(units="FIRASmuK2") + for cl_key, cl_array in cl.items(): + if cl_key != 'ell': + if np.any(np.isnan(cl_array)): + self.log.error("nans in cl['%s']: returning logzero and carrying on." % cl_key) + return -np.inf return self.log_likelihood(cl, **params_values) def log_likelihood(self, cl, **params_values): From 032a16b7361bf5e44d9efaf31996f60c6ade2955 Mon Sep 17 00:00:00 2001 From: Will Handley Date: Tue, 1 Feb 2022 23:04:37 +0000 Subject: [PATCH 2/5] Updated polychord input parameters for 1.20 --- cobaya/samplers/polychord/polychord.py | 16 ++++++++------- cobaya/samplers/polychord/polychord.yaml | 26 ++++++++++++++++++++---- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/cobaya/samplers/polychord/polychord.py b/cobaya/samplers/polychord/polychord.py index 05b341507..9041ee7a2 100644 --- a/cobaya/samplers/polychord/polychord.py +++ b/cobaya/samplers/polychord/polychord.py @@ -136,13 +136,15 @@ def initialize(self): int(o * read_dnumber(self.num_repeats, dim_block)) for o, dim_block in zip(oversampling_factors, self.grade_dims)] # Assign settings - pc_args = ["nlive", "num_repeats", "nprior", "do_clustering", - "precision_criterion", "max_ndead", "boost_posterior", "feedback", - "logzero", "posteriors", "equals", "compression_factor", - "cluster_posteriors", "write_resume", "read_resume", "write_stats", - "write_live", "write_dead", "base_dir", "grade_frac", "grade_dims", - "feedback", "read_resume", "base_dir", "file_root", "grade_frac", - "grade_dims"] + pc_args = ["nlive", "num_repeats", "nprior", "nfail", "do_clustering", + "feedback", "precision_criterion", "logzero", + "logalmostzero", "max_ndead", "boost_posterior", + "posteriors", "equals", "cluster_posteriors", + "write_resume", "write_paramnames", "read_resume", + "write_stats", "write_live", "write_dead", "write_prior", + "maximise", "compression_factor", "synchronous", "base_dir", + "file_root", "seed", "grade_dims", "grade_frac", "nlives"] + # As stated above, num_repeats is ignored, so let's not pass it pc_args.pop(pc_args.index("num_repeats")) settings: Any = load_module('pypolychord.settings', path=self._poly_build_path, diff --git a/cobaya/samplers/polychord/polychord.yaml b/cobaya/samplers/polychord/polychord.yaml index 24e586bc5..a63e57a28 100644 --- a/cobaya/samplers/polychord/polychord.yaml +++ b/cobaya/samplers/polychord/polychord.yaml @@ -16,6 +16,8 @@ num_repeats: 2d # Number of prior samples drawn before starting compression # Can be in units of nlive (but not dimension) as Xnlive nprior: 10nlive +# Number of failed spawns before stopping nested sampling. +nfail : nlive # Whether to check for and explore multi-modality on the posterior do_clustering: True # Stopping criterion: fraction of the total evidence contained in the live points @@ -27,20 +29,36 @@ max_ndead: .inf compression_factor: 0.36787944117144233 # = exp(-1) # Callback function -- see documentation callback_function: -# Numerical value of log(0) sent to PolyChord's Fortran code +# The loglikelihood value at which PolyChord considers points +# 'invalid', and excludes them at the prior level. # If null: `numpy.nan_to_num(-numpy.inf)` -# NB: smaller values tend to produce errors when using `ifort` logzero: -1e30 +# The loglikelihood value at which PolyChord considers points +# 'unphysical', but will still rejection sample from the prior to +# generate nprior points larger than this value. +# If null: `numpy.nan_to_num(-numpy.inf)` +logalmostzero: -1e30 # Increase number of posterior samples boost_posterior: 0 # increase up to `num_repeats` # Verbosity during the sampling process. Set to one of [0,1,2,3] feedback: # default: Same as global `verbosity` +# Parallelise with synchronous workers, rather than asynchronous ones. +# This can be set to False if the likelihood speed is known to be +# approximately constant across the parameter space. Synchronous +# parallelisation is less effective than asynchronous by a factor ~O(1) +# for large parallelisation. +synchronous : True +# Variable number of live points option. This dictionary is a mapping +# between loglike contours and nlive. +# You should still set nlive to be a sensible number, as this indicates +# how often to update the clustering, and to define the default value. +nlives : {} # Exploiting speed hierarchy # -------------------------- # whether to measure actual speeds for your machine/threading at starting rather # than using stored values measure_speeds: True -# Amount of oversampling of each parameter block, relative to their speeds +# #Amount of oversampling of each parameter block, relative to their speeds # Value from 0 (no oversampling) to 1 (spend the same amount of time in all blocks) # Can be larger than 1 if extra oversampling of fast blocks required. oversample_power: 0.4 @@ -57,7 +75,7 @@ blocking: confidence_for_unbounded: 0.9999995 # 5 sigmas of the prior # Seeding runs # ------------ -seed: # postitive integer +seed: # positive integer # Raw output of PolyChord (no need to change them, normally) # ---------------------------------------------------------- file_root: From 2d3f905bb49cc2a09c60abc82fa932ea0aab9a18 Mon Sep 17 00:00:00 2001 From: Will Handley Date: Thu, 3 Feb 2022 15:41:58 +0000 Subject: [PATCH 3/5] reverted polychord changes --- cobaya/samplers/polychord/polychord.py | 16 +++++++-------- cobaya/samplers/polychord/polychord.yaml | 26 ++++-------------------- 2 files changed, 11 insertions(+), 31 deletions(-) diff --git a/cobaya/samplers/polychord/polychord.py b/cobaya/samplers/polychord/polychord.py index c5f2a77dc..442cfd19b 100644 --- a/cobaya/samplers/polychord/polychord.py +++ b/cobaya/samplers/polychord/polychord.py @@ -136,15 +136,13 @@ def initialize(self): int(o * read_dnumber(self.num_repeats, dim_block)) for o, dim_block in zip(oversampling_factors, self.grade_dims)] # Assign settings - pc_args = ["nlive", "num_repeats", "nprior", "nfail", "do_clustering", - "feedback", "precision_criterion", "logzero", - "logalmostzero", "max_ndead", "boost_posterior", - "posteriors", "equals", "cluster_posteriors", - "write_resume", "write_paramnames", "read_resume", - "write_stats", "write_live", "write_dead", "write_prior", - "maximise", "compression_factor", "synchronous", "base_dir", - "file_root", "seed", "grade_dims", "grade_frac", "nlives"] - + pc_args = ["nlive", "num_repeats", "nprior", "do_clustering", + "precision_criterion", "max_ndead", "boost_posterior", "feedback", + "logzero", "posteriors", "equals", "compression_factor", + "cluster_posteriors", "write_resume", "read_resume", "write_stats", + "write_live", "write_dead", "base_dir", "grade_frac", "grade_dims", + "feedback", "read_resume", "base_dir", "file_root", "grade_frac", + "grade_dims"] # As stated above, num_repeats is ignored, so let's not pass it pc_args.pop(pc_args.index("num_repeats")) settings: Any = load_module('pypolychord.settings', path=self._poly_build_path, diff --git a/cobaya/samplers/polychord/polychord.yaml b/cobaya/samplers/polychord/polychord.yaml index a63e57a28..24e586bc5 100644 --- a/cobaya/samplers/polychord/polychord.yaml +++ b/cobaya/samplers/polychord/polychord.yaml @@ -16,8 +16,6 @@ num_repeats: 2d # Number of prior samples drawn before starting compression # Can be in units of nlive (but not dimension) as Xnlive nprior: 10nlive -# Number of failed spawns before stopping nested sampling. -nfail : nlive # Whether to check for and explore multi-modality on the posterior do_clustering: True # Stopping criterion: fraction of the total evidence contained in the live points @@ -29,36 +27,20 @@ max_ndead: .inf compression_factor: 0.36787944117144233 # = exp(-1) # Callback function -- see documentation callback_function: -# The loglikelihood value at which PolyChord considers points -# 'invalid', and excludes them at the prior level. +# Numerical value of log(0) sent to PolyChord's Fortran code # If null: `numpy.nan_to_num(-numpy.inf)` +# NB: smaller values tend to produce errors when using `ifort` logzero: -1e30 -# The loglikelihood value at which PolyChord considers points -# 'unphysical', but will still rejection sample from the prior to -# generate nprior points larger than this value. -# If null: `numpy.nan_to_num(-numpy.inf)` -logalmostzero: -1e30 # Increase number of posterior samples boost_posterior: 0 # increase up to `num_repeats` # Verbosity during the sampling process. Set to one of [0,1,2,3] feedback: # default: Same as global `verbosity` -# Parallelise with synchronous workers, rather than asynchronous ones. -# This can be set to False if the likelihood speed is known to be -# approximately constant across the parameter space. Synchronous -# parallelisation is less effective than asynchronous by a factor ~O(1) -# for large parallelisation. -synchronous : True -# Variable number of live points option. This dictionary is a mapping -# between loglike contours and nlive. -# You should still set nlive to be a sensible number, as this indicates -# how often to update the clustering, and to define the default value. -nlives : {} # Exploiting speed hierarchy # -------------------------- # whether to measure actual speeds for your machine/threading at starting rather # than using stored values measure_speeds: True -# #Amount of oversampling of each parameter block, relative to their speeds +# Amount of oversampling of each parameter block, relative to their speeds # Value from 0 (no oversampling) to 1 (spend the same amount of time in all blocks) # Can be larger than 1 if extra oversampling of fast blocks required. oversample_power: 0.4 @@ -75,7 +57,7 @@ blocking: confidence_for_unbounded: 0.9999995 # 5 sigmas of the prior # Seeding runs # ------------ -seed: # positive integer +seed: # postitive integer # Raw output of PolyChord (no need to change them, normally) # ---------------------------------------------------------- file_root: From 4ef537ce98cf3fab21b29c0f799af9c27652df17 Mon Sep 17 00:00:00 2001 From: Will Handley Date: Fri, 11 Feb 2022 12:21:43 +0000 Subject: [PATCH 4/5] Updated pliklite and CamSpec to also check for nan cls --- .../base_classes/planck_2018_CamSpec_python.py | 5 +++++ cobaya/likelihoods/base_classes/planck_clik.py | 12 ++++++------ cobaya/likelihoods/base_classes/planck_pliklite.py | 5 +++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/cobaya/likelihoods/base_classes/planck_2018_CamSpec_python.py b/cobaya/likelihoods/base_classes/planck_2018_CamSpec_python.py index 36fb7c4c6..41ce4bb7a 100644 --- a/cobaya/likelihoods/base_classes/planck_2018_CamSpec_python.py +++ b/cobaya/likelihoods/base_classes/planck_2018_CamSpec_python.py @@ -270,6 +270,11 @@ def chi_squared(self, CT, CTE, CEE, data_params): def logp(self, **data_params): Cls = self.provider.get_Cl(ell_factor=True) + for Cl_key, Cl_array in Cls.items(): + if Cl_key != 'ell': + if np.any(np.isnan(Cl_array)): + self.log.error("nans in Cls['%s']: returning logzero and carrying on." % Cl_key) + return -np.inf return -0.5 * self.chi_squared(Cls.get('tt'), Cls.get('te'), Cls.get('ee'), data_params) diff --git a/cobaya/likelihoods/base_classes/planck_clik.py b/cobaya/likelihoods/base_classes/planck_clik.py index 245e35f36..3d4795003 100644 --- a/cobaya/likelihoods/base_classes/planck_clik.py +++ b/cobaya/likelihoods/base_classes/planck_clik.py @@ -115,13 +115,13 @@ def get_requirements(self): def logp(self, **params_values): # get Cl's from the theory code - cl = self.provider.get_Cl(units="FIRASmuK2") - for cl_key, cl_array in cl.items(): - if cl_key != 'ell': - if np.any(np.isnan(cl_array)): - self.log.error("nans in cl['%s']: returning logzero and carrying on." % cl_key) + Cls = self.provider.get_Cl(units="FIRASmuK2") + for Cl_key, Cl_array in Cls.items(): + if Cl_key != 'ell': + if np.any(np.isnan(Cl_array)): + self.log.error("nans in Cls['%s']: returning logzero and carrying on." % Cl_key) return -np.inf - return self.log_likelihood(cl, **params_values) + return self.log_likelihood(Cls, **params_values) def log_likelihood(self, cl, **params_values): # fill with Cl's diff --git a/cobaya/likelihoods/base_classes/planck_pliklite.py b/cobaya/likelihoods/base_classes/planck_pliklite.py index 7e8ace449..44f307e3a 100644 --- a/cobaya/likelihoods/base_classes/planck_pliklite.py +++ b/cobaya/likelihoods/base_classes/planck_pliklite.py @@ -157,5 +157,10 @@ def chi_squared(self, c_l_arr, calPlanck=1): def logp(self, **data_params): Cls = self.provider.get_Cl(ell_factor=True) + for Cl_key, Cl_array in Cls.items(): + if Cl_key != 'ell': + if np.any(np.isnan(Cl_array)): + self.log.error("nans in Cls['%s']: returning logzero and carrying on." % Cl_key) + return -np.inf return -0.5 * self.get_chi_squared(0, Cls.get('tt'), Cls.get('te'), Cls.get('ee'), data_params[self.calibration_param]) From c0a9db25347cc562c6680b477395f5212451f7dd Mon Sep 17 00:00:00 2001 From: Will Handley Date: Fri, 11 Feb 2022 12:26:30 +0000 Subject: [PATCH 5/5] That should be all of the relevant likelihood calls to get_Cl --- cobaya/likelihoods/base_classes/cmblikes.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cobaya/likelihoods/base_classes/cmblikes.py b/cobaya/likelihoods/base_classes/cmblikes.py index 978161fc7..1be442855 100644 --- a/cobaya/likelihoods/base_classes/cmblikes.py +++ b/cobaya/likelihoods/base_classes/cmblikes.py @@ -578,8 +578,13 @@ def exact_chi_sq(self, C, Chat, L): (np.trace(M) - self.nmaps - np.linalg.slogdet(M)[1])) def logp(self, **data_params): - cls = self.provider.get_Cl(ell_factor=True) - return self.log_likelihood(cls, **data_params) + Cls = self.provider.get_Cl(ell_factor=True) + for Cl_key, Cl_array in Cls.items(): + if Cl_key != 'ell': + if np.any(np.isnan(Cl_array)): + self.log.error("nans in Cls['%s']: returning logzero and carrying on." % Cl_key) + return -np.inf + return self.log_likelihood(Cls, **data_params) # noinspection PyUnboundLocalVariable def log_likelihood(self, dls, **data_params):