From 5351a7d42072b0fc81f2862fffd5344d01ee9440 Mon Sep 17 00:00:00 2001 From: Alexander Harvey Nitz Date: Thu, 9 Jul 2020 21:43:41 +0200 Subject: [PATCH 1/4] hook up boundary types to dynesty --- examples/inference/single/single.ini | 14 ++++++++---- pycbc/boundaries.py | 4 ++++ pycbc/distributions/joint.py | 32 ++++++++++++++++++++++++++++ pycbc/inference/sampler/dynesty.py | 27 +++++++++++++++++++++++ 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/examples/inference/single/single.ini b/examples/inference/single/single.ini index 7d6a887e380..6728d379d25 100644 --- a/examples/inference/single/single.ini +++ b/examples/inference/single/single.ini @@ -21,10 +21,11 @@ strain-high-pass = 15 sample-rate = 2048 [sampler] -name = emcee_pt -ntemps = 4 -nwalkers = 100 -niterations = 300 +name = dynesty +nlive = 100 +#ntemps = 4 +#nwalkers = 100 +#niterations = 300 [sampler-burn_in] burn-in-test = min_iterations @@ -62,6 +63,11 @@ max-tc = 1187008882.5 name = uniform_radius min-distance = 10 max-distance = 60 +#btype-min-distance = reflected +#btype-max-distance = reflected [prior-inclination] name = sin_angle +cyclic-inclination = +min-inclination = 0 +max-inclination = 1 diff --git a/pycbc/boundaries.py b/pycbc/boundaries.py index cef305dfa42..4199308c864 100644 --- a/pycbc/boundaries.py +++ b/pycbc/boundaries.py @@ -311,12 +311,16 @@ def __init__(self, min_bound=-numpy.inf, max_bound=numpy.inf, # can be used with arrays if self._min.name == 'reflected' and self._max.name == 'reflected': self._reflect = numpy.vectorize(self._reflect_well) + self.reflected = 'well' elif self._min.name == 'reflected': self._reflect = numpy.vectorize(self._min.reflect_right) + self.reflected = 'min' elif self._max.name == 'reflected': self._reflect = numpy.vectorize(self._max.reflect_left) + self.reflected = 'max' else: self._reflect = _pass + self.reflected = False def __repr__(self): return str(self.__class__)[:-1] + " " + " ".join( diff --git a/pycbc/distributions/joint.py b/pycbc/distributions/joint.py index d99e4ef4f85..f48d1ea4e0b 100644 --- a/pycbc/distributions/joint.py +++ b/pycbc/distributions/joint.py @@ -195,6 +195,38 @@ def rvs(self, size=1): return out + @property + def well_reflected(self): + """ Get list of which parameters are well reflected + """ + reflect = [] + bounds = self.bounds + for param in bounds: + if bounds[param].reflected == 'well': + reflect.append(param) + return reflect + + @property + def cyclic(self): + """ Get list of which parameters are cyclic + """ + cyclic = [] + bounds = self.bounds + for param in bounds: + if bounds[param].cyclic: + cyclic.append(param) + return cyclic + + @property + def bounds(self): + """ Get the dict of boundaries + """ + bnds = {} + for dist in self.distributions: + if hasattr(dist, 'bounds'): + bnds.update(dist.bounds) + return bnds + def cdfinv(self, **original): """ Apply the inverse cdf to the array of values [0, 1]. Every variable parameter must be given as a keyword argument. diff --git a/pycbc/inference/sampler/dynesty.py b/pycbc/inference/sampler/dynesty.py index a7fd4972216..7c07997de28 100644 --- a/pycbc/inference/sampler/dynesty.py +++ b/pycbc/inference/sampler/dynesty.py @@ -104,6 +104,29 @@ def __init__(self, model, nlive, nprocesses=1, else: self.run_with_checkpoint = False + # Check for cyclic boundaries + periodic = [] + cyclic = self.model.prior_distribution.cyclic + for i, param in enumerate(self.variable_params): + if param in cyclic: + logging.info('Param: %s will be cyclic', param) + periodic.append(i) + + if len(periodic) == 0: + periodic = None + + # Check for reflected boundaries. Dynesty only supports + # reflection on both min and max of boundary. + reflective = [] + reflect = self.model.prior_distribution.well_reflected + for i, param in enumerate(self.variable_params): + if param in reflect: + logging.info("Param: %s will be well reflected", param) + reflective.append(i) + + if len(reflective) == 0: + reflective = None + if self.nlive < 0: # Interpret a negative input value for the number of live points # (which is clearly an invalid input in all senses) @@ -111,6 +134,8 @@ def __init__(self, model, nlive, nprocesses=1, self._sampler = dynesty.DynamicNestedSampler(log_likelihood_call, prior_call, self.ndim, pool=self.pool, + reflective=reflective, + periodic=periodic, **kwargs) self.run_with_checkpoint = False logging.info("Checkpointing not currently supported with" @@ -119,6 +144,8 @@ def __init__(self, model, nlive, nprocesses=1, self._sampler = dynesty.NestedSampler(log_likelihood_call, prior_call, self.ndim, nlive=self.nlive, + reflective=reflective, + periodic=periodic, pool=self.pool, **kwargs) # properties of the internal sampler which should not be pickled From 9bf4f4054970ed0477b5b5e58bd3e3c720775391 Mon Sep 17 00:00:00 2001 From: Alexander Harvey Nitz Date: Thu, 9 Jul 2020 21:45:16 +0200 Subject: [PATCH 2/4] nc --- examples/inference/single/single.ini | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/examples/inference/single/single.ini b/examples/inference/single/single.ini index 6728d379d25..7d6a887e380 100644 --- a/examples/inference/single/single.ini +++ b/examples/inference/single/single.ini @@ -21,11 +21,10 @@ strain-high-pass = 15 sample-rate = 2048 [sampler] -name = dynesty -nlive = 100 -#ntemps = 4 -#nwalkers = 100 -#niterations = 300 +name = emcee_pt +ntemps = 4 +nwalkers = 100 +niterations = 300 [sampler-burn_in] burn-in-test = min_iterations @@ -63,11 +62,6 @@ max-tc = 1187008882.5 name = uniform_radius min-distance = 10 max-distance = 60 -#btype-min-distance = reflected -#btype-max-distance = reflected [prior-inclination] name = sin_angle -cyclic-inclination = -min-inclination = 0 -max-inclination = 1 From 46eef8724e4ede7556f386d43188eb65b42c3979 Mon Sep 17 00:00:00 2001 From: Alexander Harvey Nitz Date: Thu, 9 Jul 2020 21:54:35 +0200 Subject: [PATCH 3/4] ws --- pycbc/distributions/joint.py | 6 +++--- pycbc/inference/sampler/dynesty.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pycbc/distributions/joint.py b/pycbc/distributions/joint.py index f48d1ea4e0b..f0c7b7eb2b8 100644 --- a/pycbc/distributions/joint.py +++ b/pycbc/distributions/joint.py @@ -205,7 +205,7 @@ def well_reflected(self): if bounds[param].reflected == 'well': reflect.append(param) return reflect - + @property def cyclic(self): """ Get list of which parameters are cyclic @@ -224,8 +224,8 @@ def bounds(self): bnds = {} for dist in self.distributions: if hasattr(dist, 'bounds'): - bnds.update(dist.bounds) - return bnds + bnds.update(dist.bounds) + return bnds def cdfinv(self, **original): """ Apply the inverse cdf to the array of values [0, 1]. Every diff --git a/pycbc/inference/sampler/dynesty.py b/pycbc/inference/sampler/dynesty.py index 7c07997de28..fe42d29e0b9 100644 --- a/pycbc/inference/sampler/dynesty.py +++ b/pycbc/inference/sampler/dynesty.py @@ -111,17 +111,17 @@ def __init__(self, model, nlive, nprocesses=1, if param in cyclic: logging.info('Param: %s will be cyclic', param) periodic.append(i) - + if len(periodic) == 0: periodic = None - + # Check for reflected boundaries. Dynesty only supports # reflection on both min and max of boundary. reflective = [] reflect = self.model.prior_distribution.well_reflected for i, param in enumerate(self.variable_params): if param in reflect: - logging.info("Param: %s will be well reflected", param) + logging.info("Param: %s will be well reflected", param) reflective.append(i) if len(reflective) == 0: From 683aeaf8c0746c5c564937f3d69ed3d1c23cfab8 Mon Sep 17 00:00:00 2001 From: Alexander Harvey Nitz Date: Fri, 10 Jul 2020 10:03:40 +0200 Subject: [PATCH 4/4] ws --- pycbc/inference/sampler/dynesty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycbc/inference/sampler/dynesty.py b/pycbc/inference/sampler/dynesty.py index fe42d29e0b9..9857ff239b4 100644 --- a/pycbc/inference/sampler/dynesty.py +++ b/pycbc/inference/sampler/dynesty.py @@ -123,7 +123,7 @@ def __init__(self, model, nlive, nprocesses=1, if param in reflect: logging.info("Param: %s will be well reflected", param) reflective.append(i) - + if len(reflective) == 0: reflective = None