joshspeagle / dynesty

Dynamic Nested Sampling package for computing Bayesian posteriors and evidences
https://dynesty.readthedocs.io/
MIT License
347 stars 76 forks source link

`ValueError` in `propose_live` #178

Closed ColmTalbot closed 3 years ago

ColmTalbot commented 4 years ago

Hi @joshspeagle, I've seen the following error a few times

Traceback (most recent call last):
...
  File "/PATH/python3.7/site-packages/bilby/core/sampler/dynesty.py", line 234, in run_sampler
    out = self._run_external_sampler_with_checkpointing()
  File "/PATH/python3.7/site-packages/bilby/core/sampler/dynesty.py", line 308, in _run_external_sampler_with_checkpointing
    self._run_nested_wrapper(sampler_kwargs)
  File "/PATH/python3.7/site-packages/bilby/core/sampler/dynesty.py", line 284, in _run_nested_wrapper
    self.sampler.run_nested(**kwargs)
  File "/PATH/python3.7/site-packages/dynesty/sampler.py", line 928, in run_nested
    add_live=add_live)):
  File "/PATH/python3.7/site-packages/dynesty/sampler.py", line 782, in sample
    u, v, logl, nc = self._new_point(loglstar_new, logvol)
  File "/PATH/python3.7/site-packages/dynesty/sampler.py", line 380, in _new_point
    u, v, logl, nc, blob = self._get_point_value(loglstar)
  File "/PATH/python3.7/site-packages/dynesty/sampler.py", line 364, in _get_point_value
    self._fill_queue(loglstar)
  File "/PATH/python3.7/site-packages/dynesty/sampler.py", line 333, in _fill_queue
    point, axes = self.propose_point()
  File "/PATH/python3.7/site-packages/dynesty/nestedsamplers.py", line 624, in propose_live
    ell_idx = ell_idxs[self.rstate.randint(nidx)]
  File "mtrand.pyx", line 992, in mtrand.RandomState.randint
ValueError: Range cannot be empty (low >= high) unless no samples are taken

Unfortunately, I haven't been able to make a really firm reproducible version of this error as it generally happens quite late in the sampling.

It looks like this is the offending code block

https://github.com/joshspeagle/dynesty/blob/c95c2ec938d847e5e3672e6caa5f700846327dc4/dynesty/nestedsamplers.py#L645-L656 https://github.com/joshspeagle/dynesty/blob/c95c2ec938d847e5e3672e6caa5f700846327dc4/dynesty/nestedsamplers.py#L657-L666

The issue seems to be that the new bounding ellipses don't contain the point being evolved. A while nidx ==0: rather than if nidx == 0: might resolve this. However, it was preceded by this warning

/PATH/python3.7/site-packages/dynesty/bounding.py:606: RuntimeWarning: invalid value encountered in double_scalars
  self.expand_tot = self.vol_tot / vol_tot_orig
/PATH/python3.7/site-packages/dynesty/bounding.py:183: RuntimeWarning: invalid value encountered in double_scalars
  f = np.exp((np.log(vol) - np.log(self.vol)) / self.n)  # linear factor
/PATH/python3.7/site-packages/dynesty/bounding.py:401: RuntimeWarning: invalid value encountered in double_scalars
  self.expand_tot *= vol_tot / self.vol_tot
/PATH/python3.7/site-packages/dynesty/bounding.py:606: RuntimeWarning: invalid value encountered in double_scalars
  self.expand_tot = self.vol_tot / vol_tot_orig
PATH/python3.7/site-packages/dynesty/bounding.py:183: RuntimeWarning: invalid value encountered in double_scalars
  f = np.exp((np.log(vol) - np.log(self.vol)) / self.n)  # linear factor
/PATH/python3.7/site-packages/dynesty/bounding.py:401: RuntimeWarning: invalid value encountered in double_scalars
  self.expand_tot *= vol_tot / self.vol_tot

I'm not sure if this happened immediately before the failure, but is it possible that the issue is down to the remaining volume underflowing? Another data point is that this was looking at a posterior which was much narrower than the prior.

Have you seen this behaviour before?

joshspeagle commented 4 years ago

I have seen this pop up before, and usually it is precisely because of an underflow error due to really small covariances when this happens:

Another data point is that this was looking at a posterior which was much narrower than the prior.

Would it be possible to just reparameterize the problem here? Or should I try and add in even more safety checks? Also, are you using v1.0.1 (pip) or 1.0.2 (github)?

ColmTalbot commented 4 years ago

This case was passed on to me from someone else, so I'm not entirely sure which version was being used.

I suggested that they try just reducing the prior range.

Is there any possible fix to the underflow, or attempt to create the bounds multiple times? Otherwise, it might be helpful to throw an error saying that it can't construct bounds that contain the point.

joshspeagle commented 4 years ago

Yea, I can try to include a specific warning when this occurs. I can also add in some additional error checks in line with #78 and #140. I'll leave the issue open and mark this as a small fix so I can patch it in next time I get around to fixing up the code. Thanks.

joshspeagle commented 3 years ago

A very late follow-up to this, but I believe the recent improvements to the stability and behaviour of the bounding distributions (#219 and others) should now resolve this and other similar issues, so I'm tentatively closing this.