Skip to content

Commit 95020e5

Browse files
authored
Merge branch 'main' into bilback
2 parents fd3f3af + e1fb084 commit 95020e5

17 files changed

Lines changed: 2272 additions & 178 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3+
4+
name: Test against latest dynesty
5+
6+
on:
7+
push:
8+
branches: [ "main" ]
9+
pull_request:
10+
branches: [ "main" ]
11+
merge_group:
12+
release:
13+
types:
14+
- published
15+
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.ref }}
18+
cancel-in-progress: true
19+
20+
env:
21+
CONDA_PATH: /opt/conda/
22+
23+
jobs:
24+
build:
25+
26+
name: ${{ matrix.python.name }} unit tests
27+
runs-on: ubuntu-latest
28+
container: ghcr.io/bilby-dev/bilby-python${{ matrix.python.short-version }}:latest
29+
strategy:
30+
fail-fast: false
31+
matrix:
32+
python:
33+
- name: Python 3.12
34+
version: 3.12
35+
short-version: 312
36+
37+
steps:
38+
- uses: actions/checkout@v4
39+
with:
40+
fetch-depth: 0
41+
fetch-tags: true
42+
- name: Install package
43+
run: |
44+
# activate env so that conda list shows the correct environment
45+
source $CONDA_PATH/bin/activate python${{ matrix.python.short-version }}
46+
python -m pip install .
47+
python -m pip install git+https://github.com/joshspeagle/dynesty@master
48+
conda list --show-channel-urls
49+
shell: bash
50+
- name: Run unit tests
51+
run: |
52+
python -m pytest --durations 10 -k dynesty
53+
- name: Run sampler tests
54+
run: |
55+
python -m pytest test/integration/sampler_run_test.py --durations 10 -v -k dynesty

AUTHORS.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
# Authors
22

33
This file lists all the authors in first-name alphabetical order who have
4-
contributed (either by code contribution or indirectly). If your name is not
5-
listed here, please contact anyone on this list and raise your concern.
4+
contributed (either by code contribution or indirectly) to Bilby while development
5+
happened on git.ligo.org. On GitHub, all contributors are tracked at
6+
https://github.com/bilby-dev/bilby/graphs/contributors and so this is no longer
7+
actively maintained. If your name is not listed here and you contributed at
8+
https://git.ligo.org/lscsoft/bilby, please open an issue.
69

710
Abhirup Ghosh
811
Aditya Vijaykumar

CHANGELOG.md

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,60 @@ The original MRs are only visible on the [LIGO GitLab repository](https://git.li
55

66
## [Unreleased]
77

8-
### Deprecated
8+
## [2.7.0]
9+
10+
There are a few significant changes/additions in this release along with minor changes and removals.
11+
12+
### Major changes
13+
14+
* `Likelihood` instances can now be called as `likelihood.log_likelihood(parameters)`, see [here](https://bilby-dev.github.io/bilby/parameters.html) for more information.
15+
* Support the new API in [`dynesty=3`](https://github.com/joshspeagle/dynesty/releases/tag/v3.0.0)
16+
* Add a [new `WaveformGenerator`](https://bilby-dev.github.io/bilby/api/bilby.gw.waveform_generator.GWSignalWaveformGenerator.html) capable of using arbitrary waveform models implemented through the `gwsignal` waveform interface.
17+
18+
### Additions
19+
* Added WeightedCategorical-Prior by @JasperMartins in https://github.com/bilby-dev/bilby/pull/893
20+
* ENH: Implement DiscreteValues prior by @unkaktus in https://github.com/bilby-dev/bilby/pull/947
21+
* ENH: Allow no parameters as state by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/941
22+
* ENH: add support for new dynesty api by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/950
23+
* FEAT: add gwsignal waveform generator by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/877
24+
25+
### Fixes
26+
* BUG: Fix sampling efficiency warning by @fgittins in https://github.com/bilby-dev/bilby/pull/953
27+
* TYPO: fix random call in example by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/973
28+
* BUG: Fix matched filter SNR calculation in time domain injection by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/957
29+
* TST: mark whitened strain tests as flaky by @mj-will in https://github.com/bilby-dev/bilby/pull/987
30+
* MAINT: update file extension logic by @mj-will in https://github.com/bilby-dev/bilby/pull/962
31+
* BUG: fix a bug with the dynesty v3 interface using dynesty native sampling by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/994
32+
* BUG: fix a bug where some priors fail to read due to missing conversion functions by @asb5468 https://github.com/bilby-dev/bilby/pull/940
33+
* BUG: fix how kwargs are passed to custom dynesty samplers by @ColmTalbot https://github.com/bilby-dev/bilby/pull/999
34+
35+
### Changes
36+
* ENH: plot_multiple: Allow plotting onto user-defined figure by @unkaktus in https://github.com/bilby-dev/bilby/pull/946
37+
* MAINT: change RNG imports by @mj-will in https://github.com/bilby-dev/bilby/pull/943
38+
* MAINT: np.trapz -> np.trapezoid by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/974
39+
* MAINT: define Planck15-LAL cosmology using LAL constants by @mj-will in https://github.com/bilby-dev/bilby/pull/932
40+
* DEV: make sure all priors return float when needed by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/979
41+
* Replace pytables with h5py by @duncanmmacleod in https://github.com/bilby-dev/bilby/pull/982
42+
43+
### Deprecations
44+
* DEP: deprecate dnest4 interface by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/980
45+
46+
### Removed
47+
* MAINT: remove unsupported roq json weight file format by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/945
48+
49+
### Other changes
50+
* DOC: Fixed README link for opening bilby_pipe issues by @mick-wright in https://github.com/bilby-dev/bilby/pull/922
51+
* DOC: Correct docs for use_ratio argument of run_sampler by @mattpitkin in https://github.com/bilby-dev/bilby/pull/958
52+
* CI: add merge_group to enable merge queue by @mj-will in https://github.com/bilby-dev/bilby/pull/983
53+
* TST: remove dnest4 import test by @ColmTalbot in https://github.com/bilby-dev/bilby/pull/984
54+
* BLD: migrate to pyproject.toml by @mj-will in https://github.com/bilby-dev/bilby/pull/952
55+
* BLD: use release branches by @mj-will in https://github.com/bilby-dev/bilby/pull/954
56+
57+
### New Contributors
58+
* @fgittins made their first contribution in https://github.com/bilby-dev/bilby/pull/953
59+
* @duncanmmacleod made their first contribution in https://github.com/bilby-dev/bilby/pull/982
960

10-
- `dnest4` is no longer tested, the plugin package should be used instead.
61+
**Full Changelog**: https://github.com/bilby-dev/bilby/compare/v2.6.0...v2.7.0
1162

1263
## [2.6.0]
1364

@@ -1184,7 +1235,9 @@ First `pip` installable version https://pypi.org/project/BILBY/ .
11841235
- All chainconsumer dependency as this was causing issues.
11851236

11861237

1187-
[Unreleased]: https://github.com/bilby-dev/bilby/compare/v2.5.2...main
1238+
[Unreleased]: https://github.com/bilby-dev/bilby/compare/v2.7.0...main
1239+
[2.7.0]: https://github.com/bilby-dev/bilby/compare/v2.6.0...v2.7.0
1240+
[2.6.0]: https://github.com/bilby-dev/bilby/compare/v2.5.2...v2.6.0
11881241
[2.5.2]: https://github.com/bilby-dev/bilby/compare/v2.5.1...v2.5.2
11891242
[2.5.1]: https://github.com/bilby-dev/bilby/compare/v2.5.0...v2.5.1
11901243
[2.5.0]: https://github.com/bilby-dev/bilby/compare/v2.4.0...v2.5.0

bilby/core/prior/analytical.py

Lines changed: 157 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,33 +1412,73 @@ def cdf(self, val, *, xp=np):
14121412
return xp.clip(result, 0, 1)
14131413

14141414

1415-
class DiscreteValues(Prior):
1416-
def __init__(self, values, name=None, latex_label=None,
1417-
unit=None, boundary="periodic"):
1418-
""" An equal-weighted discrete-valued prior
1415+
class WeightedDiscreteValues(Prior):
1416+
def __init__(
1417+
self,
1418+
values,
1419+
weights=None,
1420+
name=None,
1421+
latex_label=None,
1422+
unit=None,
1423+
boundary="periodic",
1424+
):
1425+
"""A weighted discrete-valued prior
14191426
14201427
Parameters
14211428
==========
1422-
values: array
1429+
values: 1d array_like of numeric type
14231430
The discrete values of the prior.
1431+
weights: 1d array_like of numeric type or None
1432+
The weights of each category. If None, then all values are
1433+
equally weighted. Default: None.
14241434
name: str
1425-
See superclass
1435+
The name of the parameter
14261436
latex_label: str
1427-
See superclass
1437+
The latex label of the parameter. Used for plotting.
14281438
unit: str
1429-
See superclass
1439+
The unit of the parameter. Used for plotting.
14301440
"""
1441+
14311442
nvalues = len(values)
1443+
values = np.array(values)
1444+
if values.shape != (nvalues,):
1445+
raise ValueError(
1446+
f"Shape of argument 'values' must be 1d array-like but has shape {values.shape}"
1447+
)
14321448
minimum = np.min(values)
14331449
# Small delta added to help with MCMC walking
14341450
maximum = np.max(values) * (1 + 1e-15)
1435-
super(DiscreteValues, self).__init__(
1451+
super(WeightedDiscreteValues, self).__init__(
14361452
name=name, latex_label=latex_label, minimum=minimum,
14371453
maximum=maximum, unit=unit, boundary=boundary)
14381454
self.nvalues = nvalues
1439-
self.values = np.sort(np.array(values))
1440-
self.p = 1 / self.nvalues
1441-
self.lnp = -np.log(self.nvalues)
1455+
sorter = np.argsort(values)
1456+
self._values_array = values[sorter]
1457+
1458+
# inititialization of priors from repr only supports
1459+
# python buildins
1460+
self.values = self._values_array.tolist()
1461+
1462+
weights = (
1463+
np.array(weights) / np.sum(weights)
1464+
if weights is not None
1465+
else np.ones(self.nvalues) / self.nvalues
1466+
)
1467+
# check for consistent shape of input
1468+
if weights.shape != (self.nvalues,):
1469+
raise ValueError(
1470+
"Inconsistent shape of weights and number of values:"
1471+
+ f"weights has shape {weights.shape} "
1472+
+ f"while number of values is {self.values}"
1473+
)
1474+
self._weights_array = weights[sorter]
1475+
self.weights = self._weights_array.tolist()
1476+
self._lnweights_array = np.log(self._weights_array)
1477+
1478+
# save cdf for rescaling
1479+
_cumulative_weights_array = np.cumsum(self._weights_array)
1480+
# insert 0 for values smaller than minimum
1481+
self._cumulative_weights_array = np.insert(_cumulative_weights_array, 0, 0)
14421482

14431483
def rescale(self, val):
14441484
"""
@@ -1455,8 +1495,22 @@ def rescale(self, val):
14551495
=======
14561496
Union[float, array_like]: Rescaled probability
14571497
"""
1458-
idx = np.asarray(np.floor(val * self.nvalues), dtype=int)
1459-
return self.values[idx]
1498+
index = np.searchsorted(self._cumulative_weights_array[1:], val)
1499+
return self._values_array[index]
1500+
1501+
def cdf(self, val):
1502+
"""Return the cumulative prior probability of val.
1503+
1504+
Parameters
1505+
==========
1506+
val: Union[float, int, array_like]
1507+
1508+
Returns
1509+
=======
1510+
float: cumulative prior probability of val
1511+
"""
1512+
index = np.searchsorted(self._values_array, val, side="right")
1513+
return self._cumulative_weights_array[index]
14601514

14611515
def prob(self, val):
14621516
"""Return the prior probability of val.
@@ -1469,17 +1523,11 @@ def prob(self, val):
14691523
=======
14701524
float: Prior probability of val
14711525
"""
1472-
if isinstance(val, (float, int)):
1473-
if val in self.values:
1474-
return self.p
1475-
else:
1476-
return 0
1477-
else:
1478-
val = np.atleast_1d(val)
1479-
probs = np.zeros_like(val, dtype=np.float64)
1480-
idxs = np.isin(val, self.values)
1481-
probs[idxs] = self.p
1482-
return probs
1526+
index = np.searchsorted(self._values_array, val)
1527+
index = np.clip(index, 0, self.nvalues - 1)
1528+
p = np.where(self._values_array[index] == val, self._weights_array[index], 0)
1529+
# turn 0d numpy array to scalar
1530+
return p[()]
14831531

14841532
def ln_prob(self, val):
14851533
"""Return the logarithmic prior probability of val
@@ -1493,24 +1541,86 @@ def ln_prob(self, val):
14931541
float:
14941542
14951543
"""
1496-
if isinstance(val, (float, int)):
1497-
if val in self.values:
1498-
return self.lnp
1499-
else:
1500-
return -np.inf
1501-
else:
1502-
val = np.atleast_1d(val)
1503-
probs = -np.inf * np.ones_like(val, dtype=np.float64)
1504-
idxs = np.isin(val, self.values)
1505-
probs[idxs] = self.lnp
1506-
return probs
1544+
index = np.searchsorted(self._values_array, val)
1545+
index = np.clip(index, 0, self.nvalues - 1)
1546+
lnp = np.where(
1547+
self._values_array[index] == val, self._lnweights_array[index], -np.inf
1548+
)
1549+
# turn 0d numpy array to scalar
1550+
return lnp[()]
15071551

15081552

1509-
class Categorical(DiscreteValues):
1510-
def __init__(self, ncategories, name=None, latex_label=None,
1553+
class DiscreteValues(WeightedDiscreteValues):
1554+
def __init__(self, values, name=None, latex_label=None,
15111555
unit=None, boundary="periodic"):
1512-
""" An equal-weighted Categorical prior
1556+
"""An equal-weighted discrete-valued prior
15131557
1558+
Parameters
1559+
==========
1560+
values: array
1561+
The discrete values of the prior.
1562+
name: str
1563+
See superclass
1564+
latex_label: str
1565+
See superclass
1566+
unit: str
1567+
See superclass
1568+
"""
1569+
weights = np.ones_like(values)
1570+
super(DiscreteValues, self).__init__(
1571+
values=values,
1572+
weights=weights,
1573+
name=name,
1574+
latex_label=latex_label,
1575+
unit=unit,
1576+
boundary=boundary,
1577+
)
1578+
1579+
1580+
class WeightedCategorical(WeightedDiscreteValues):
1581+
def __init__(
1582+
self,
1583+
ncategories,
1584+
weights=None,
1585+
name=None,
1586+
latex_label=None,
1587+
unit=None,
1588+
boundary="periodic",
1589+
):
1590+
"""A weighted Categorical prior
1591+
1592+
Parameters
1593+
==========
1594+
ncategories: int
1595+
The number of available categories. The prior mass support is then
1596+
integers [0, ncategories - 1].
1597+
weights: 1d array_like or None
1598+
The weights of each category. If None, then all categories are
1599+
equally weighted. Default None.
1600+
name: str
1601+
The name of the parameter
1602+
latex_label: str
1603+
The latex label of the parameter. Used for plotting.
1604+
unit: str
1605+
The unit of the parameter. Used for plotting.
1606+
"""
1607+
self.ncategories = ncategories
1608+
values = np.arange(0, ncategories)
1609+
super(WeightedCategorical, self).__init__(
1610+
values=values,
1611+
weights=weights,
1612+
name=name,
1613+
latex_label=latex_label,
1614+
unit=unit,
1615+
boundary=boundary,
1616+
)
1617+
1618+
1619+
class Categorical(DiscreteValues):
1620+
def __init__(
1621+
self, ncategories, name=None, latex_label=None, unit=None, boundary="periodic"
1622+
):
1623+
"""An equal-weighted Categorical prior
15141624
Parameters
15151625
==========
15161626
ncategories: int
@@ -1523,9 +1633,15 @@ def __init__(self, ncategories, name=None, latex_label=None,
15231633
unit: str
15241634
See superclass
15251635
"""
1636+
self.ncategories = ncategories
15261637
values = np.arange(0, ncategories)
1527-
DiscreteValues.__init__(self, values=values, name=name, latex_label=latex_label,
1528-
unit=unit, boundary=boundary)
1638+
super(Categorical, self).__init__(
1639+
values=values,
1640+
name=name,
1641+
latex_label=latex_label,
1642+
unit=unit,
1643+
boundary=boundary,
1644+
)
15291645

15301646

15311647
class Triangular(Prior):

0 commit comments

Comments
 (0)