From b1816137aa5811cce39562fb0370c4d7def163cb Mon Sep 17 00:00:00 2001 From: "jasper.martins" Date: Wed, 1 Apr 2026 09:57:43 +0000 Subject: [PATCH 1/5] add test if proposals are set --- test/core/sampler/dynesty_test.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/core/sampler/dynesty_test.py b/test/core/sampler/dynesty_test.py index 342e6ca3b..9285cfa97 100644 --- a/test/core/sampler/dynesty_test.py +++ b/test/core/sampler/dynesty_test.py @@ -159,6 +159,13 @@ def test_dynesty_native_methods_initialize(self, sample, bound): """ self.init_sampler(sample=sample, bound=bound) + def test_proposals_set_on_init(self): + self.init_sampler(proposals=["diff", "volumetric"]) + self.assertEqual( + self.dysampler.internal_sampler_next.sampler_kwargs["proposals"], + ["diff", "volumetric"] + ) + def test_get_expected_outputs(): label = "par0" From 61cc638618e79b318f68277defffd637989e9844 Mon Sep 17 00:00:00 2001 From: "jasper.martins" Date: Wed, 1 Apr 2026 09:58:53 +0000 Subject: [PATCH 2/5] fix passing of proposal method --- bilby/core/sampler/dynesty.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bilby/core/sampler/dynesty.py b/bilby/core/sampler/dynesty.py index 7505ecb20..55ffe6e77 100644 --- a/bilby/core/sampler/dynesty.py +++ b/bilby/core/sampler/dynesty.py @@ -266,6 +266,7 @@ def sampler_init_kwargs(self): periodic=self.kwargs.get("periodic", None), reflective=self.kwargs.get("reflective", None), maxmcmc=self.maxmcmc, + proposals=self.proposals, ) if kwargs["sample"] == "act-walk": From 05c5f49ea1aaa55db5b6694f5271499c0818c03b Mon Sep 17 00:00:00 2001 From: "jasper.martins" Date: Wed, 1 Apr 2026 10:04:05 +0000 Subject: [PATCH 3/5] removed bounds containing "live" --- bilby/core/sampler/dynesty.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/bilby/core/sampler/dynesty.py b/bilby/core/sampler/dynesty.py index 55ffe6e77..024211503 100644 --- a/bilby/core/sampler/dynesty.py +++ b/bilby/core/sampler/dynesty.py @@ -128,8 +128,9 @@ class Dynesty(NestedSampler): nlive: int, (1000) The number of live points, note this can also equivalently be given as one of [nlive, nlives, n_live_points, npoints] - bound: {'live', 'live-multi', 'none', 'single', 'multi', 'balls', 'cubes'}, ('live') - Method used to select new points + bound: {'none', 'single', 'multi', 'balls', 'cubes'}, ('none') + Bounding method used for dynesty-native samplers to select new points. + For bilby-implemented sampling methods this only affects volumetric proposals. sample: {'act-walk', 'acceptance-walk', 'unif', 'rwalk', 'slice', 'rslice', 'hslice', 'rwalk_dynesty'}, ('act-walk') Method used to sample uniformly within the likelihood constraints, @@ -159,7 +160,7 @@ def _dynesty_init_kwargs(self): if param.default != param.empty } kwargs["sample"] = "act-walk" - kwargs["bound"] = "live" + kwargs["bound"] = "none" kwargs["update_interval"] = 600 kwargs["facc"] = 0.2 return kwargs @@ -258,8 +259,7 @@ def sampler_function_kwargs(self): def sampler_init_kwargs(self): kwargs = {key: self.kwargs[key] for key in self._dynesty_init_kwargs} # if we're using a Bilby implemented sampling method we need to register the - # method. If we aren't we need to make sure the default "live" isn't set as - # the bounding method + # method. internal_kwargs = dict( ndim=self.ndim, nonbounded=self.kwargs.get("nonbounded", None), @@ -272,7 +272,6 @@ def sampler_init_kwargs(self): if kwargs["sample"] == "act-walk": internal_kwargs["nact"] = self.nact internal_sampler = dynesty_utils.ACTTrackingEnsembleWalk(**internal_kwargs) - bound = "none" logger.info( f"Using the bilby-implemented ensemble rwalk sampling tracking the " f"autocorrelation function and thinning by {internal_sampler.thin} with " @@ -282,7 +281,6 @@ def sampler_init_kwargs(self): internal_kwargs["naccept"] = self.naccept internal_kwargs["walks"] = self.kwargs["walks"] internal_sampler = dynesty_utils.EnsembleWalkSampler(**internal_kwargs) - bound = "none" logger.info( f"Using the bilby-implemented ensemble rwalk sampling method with an " f"average of {internal_sampler.naccept} accepted steps up to chain " @@ -291,24 +289,14 @@ def sampler_init_kwargs(self): elif kwargs["sample"] == "rwalk": internal_kwargs["nact"] = self.nact internal_sampler = dynesty_utils.AcceptanceTrackingRWalk(**internal_kwargs) - bound = "none" logger.info( f"Using the bilby-implemented ensemble rwalk sampling method with ACT " f"estimated chain length. An average of {2 * internal_sampler.nact} " f"steps will be accepted up to chain length {internal_sampler.maxmcmc}." ) - elif kwargs["bound"] == "live": - logger.info( - "Live-point based bound method requested with dynesty sample " - f"'{kwargs['sample']}', overwriting to 'multi'" - ) - internal_sampler = kwargs["sample"] - bound = "multi" else: internal_sampler = kwargs["sample"] - bound = kwargs["bound"] kwargs["sample"] = internal_sampler - kwargs["bound"] = bound return kwargs def _translate_kwargs(self, kwargs): From 05d504d3ffe56d8d8a1eeceaaa6bb73d2c0dd404 Mon Sep 17 00:00:00 2001 From: "jasper.martins" Date: Wed, 1 Apr 2026 10:37:51 +0000 Subject: [PATCH 4/5] update dynesty guide --- docs/dynesty-guide.txt | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/docs/dynesty-guide.txt b/docs/dynesty-guide.txt index b04a6d40d..ea15c50f2 100644 --- a/docs/dynesty-guide.txt +++ b/docs/dynesty-guide.txt @@ -68,27 +68,30 @@ There are a number of keyword arguments that influence these sampling methods: above. The allowed values are * :code:`diff`: `ter Braak + (2006) `_ - differential evolution. This is the default for :code:`bound="live"` and - :code:`bound="live-multi"`. + differential evolution. This is the default. - * :code:`volumetric`: sample from an ellipsoid centered on the current point. - This is the proposal distribution implemented in :code:`dynesty` and the - default for all other :code:`bound` options. This was the default proposal + * :code:`volumetric`: sample from region centered on the current point. + This is the proposal distribution implemented in :code:`dynesty`. This was the default proposal distribution for :code:`Bilby<2`, however, in many applications it leads to longer autocorrelation times and struggles to explore multi-modal distributions. + Setting, eg., :code:`bound=multi` adapts the proposal region shape similar to :code:`dynesty` implemented + multi-ellipsoid volumetric sampling. + Note that bilby does not further tune the scale of individual proposals as done in dynesty. + Performance for :code:`bound='none'` is expected to be very poor. -Finally, we implement two custom :code:`dynesty.sampler.Sampler` classes to -facilitate the differential evolution proposal and average acceptance tracking. - -#. :code:`bound="live"` uses the :code:`LivePointSampler` which adapts the - :code:`walks` to average :code:`naccept` accepted steps when in - :code:`acceptance-walk` mode and passes the current live points to the - sample method. - -#. :code:`bound="live-multi"` combines the functionality of :code:`"live"` with - the :code:`dynesty` implemented :code:`multi` method for multi-ellipsoid - :code:`volumetric` sampling. This method is intended when using both the - :code:`diff` and :code:`volumetric` proposals. +.. note:: + For :code:`bilby<3.0` and :code:`dynesty<3.0.0`, we implement two custom + :code:`dynesty.sampler.Sampler` classes to facilitate the differential evolution proposal and average acceptance tracking. + + #. :code:`bound="live"` uses the :code:`LivePointSampler` which adapts the + :code:`walks` to average :code:`naccept` accepted steps when in + :code:`acceptance-walk` mode and passes the current live points to the + sample method. + + #. :code:`bound="live-multi"` combines the functionality of :code:`"live"` with + the :code:`dynesty` implemented :code:`multi` method for multi-ellipsoid + :code:`volumetric` sampling. This method is intended when using both the + :code:`diff` and :code:`volumetric` proposals. Understanding the output ------------------------ From 458d749dc12d85c9533201618fe73073343ddc6d Mon Sep 17 00:00:00 2001 From: Michael Jasper Martins Date: Tue, 28 Jul 2026 09:37:59 +0200 Subject: [PATCH 5/5] fix tests --- bilby/core/sampler/dynesty.py | 4 +++- test/core/sampler/dynamic_dynesty_test.py | 2 +- test/core/sampler/dynesty_test.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bilby/core/sampler/dynesty.py b/bilby/core/sampler/dynesty.py index 024211503..1575c445f 100644 --- a/bilby/core/sampler/dynesty.py +++ b/bilby/core/sampler/dynesty.py @@ -266,9 +266,11 @@ def sampler_init_kwargs(self): periodic=self.kwargs.get("periodic", None), reflective=self.kwargs.get("reflective", None), maxmcmc=self.maxmcmc, - proposals=self.proposals, ) + if self.proposals: + internal_kwargs["proposals"] = self.proposals + if kwargs["sample"] == "act-walk": internal_kwargs["nact"] = self.nact internal_sampler = dynesty_utils.ACTTrackingEnsembleWalk(**internal_kwargs) diff --git a/test/core/sampler/dynamic_dynesty_test.py b/test/core/sampler/dynamic_dynesty_test.py index 4de2f6014..d46a7198d 100644 --- a/test/core/sampler/dynamic_dynesty_test.py +++ b/test/core/sampler/dynamic_dynesty_test.py @@ -29,7 +29,7 @@ def test_default_kwargs(self): """Only test the kwargs where we specify different defaults to dynesty""" expected = dict( sample="act-walk", - bound="live", + bound="none", facc=0.2, save_bounds=False, update_interval=600, diff --git a/test/core/sampler/dynesty_test.py b/test/core/sampler/dynesty_test.py index 9285cfa97..5c477a5cc 100644 --- a/test/core/sampler/dynesty_test.py +++ b/test/core/sampler/dynesty_test.py @@ -87,7 +87,7 @@ def test_default_kwargs(self): facc=0.2, save_bounds=False, dlogz=0.1, - bound="live", + bound="none", update_interval=600, ) for key in expected: