bilby-laplace 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bilby_laplace-0.2.0/.gitignore +51 -0
- bilby_laplace-0.2.0/CHANGELOG.md +112 -0
- bilby_laplace-0.2.0/CITATION.cff +21 -0
- bilby_laplace-0.2.0/LICENSE +21 -0
- bilby_laplace-0.2.0/MANIFEST.in +6 -0
- bilby_laplace-0.2.0/PKG-INFO +131 -0
- bilby_laplace-0.2.0/README.md +92 -0
- bilby_laplace-0.2.0/docs/background/theory.md +93 -0
- bilby_laplace-0.2.0/docs/changelog.md +1 -0
- bilby_laplace-0.2.0/docs/examples.md +51 -0
- bilby_laplace-0.2.0/docs/guide/covariance.md +154 -0
- bilby_laplace-0.2.0/docs/guide/how-it-works.md +71 -0
- bilby_laplace-0.2.0/docs/guide/resampling.md +76 -0
- bilby_laplace-0.2.0/docs/index.md +38 -0
- bilby_laplace-0.2.0/docs/installation.md +44 -0
- bilby_laplace-0.2.0/docs/javascripts/mathjax.js +19 -0
- bilby_laplace-0.2.0/docs/quickstart.md +63 -0
- bilby_laplace-0.2.0/docs/reference/api.md +45 -0
- bilby_laplace-0.2.0/pyproject.toml +77 -0
- bilby_laplace-0.2.0/setup.cfg +4 -0
- bilby_laplace-0.2.0/src/bilby_laplace/__init__.py +9 -0
- bilby_laplace-0.2.0/src/bilby_laplace/_version.py +24 -0
- bilby_laplace-0.2.0/src/bilby_laplace/comparison.py +980 -0
- bilby_laplace-0.2.0/src/bilby_laplace/gw_fisher.py +268 -0
- bilby_laplace-0.2.0/src/bilby_laplace/laplace.py +1379 -0
- bilby_laplace-0.2.0/src/bilby_laplace/sampler.py +5165 -0
- bilby_laplace-0.2.0/src/bilby_laplace.egg-info/PKG-INFO +131 -0
- bilby_laplace-0.2.0/src/bilby_laplace.egg-info/SOURCES.txt +59 -0
- bilby_laplace-0.2.0/src/bilby_laplace.egg-info/dependency_links.txt +1 -0
- bilby_laplace-0.2.0/src/bilby_laplace.egg-info/entry_points.txt +2 -0
- bilby_laplace-0.2.0/src/bilby_laplace.egg-info/requires.txt +15 -0
- bilby_laplace-0.2.0/src/bilby_laplace.egg-info/scm_file_list.json +71 -0
- bilby_laplace-0.2.0/src/bilby_laplace.egg-info/scm_version.json +8 -0
- bilby_laplace-0.2.0/src/bilby_laplace.egg-info/top_level.txt +1 -0
- bilby_laplace-0.2.0/tests/conftest.py +109 -0
- bilby_laplace-0.2.0/tests/test_checkpoint_resume.py +71 -0
- bilby_laplace-0.2.0/tests/test_comparison.py +265 -0
- bilby_laplace-0.2.0/tests/test_constraint_priors.py +177 -0
- bilby_laplace-0.2.0/tests/test_cov_scaling.py +69 -0
- bilby_laplace-0.2.0/tests/test_emcee.py +544 -0
- bilby_laplace-0.2.0/tests/test_evidence_use_ratio.py +124 -0
- bilby_laplace-0.2.0/tests/test_laplace.py +377 -0
- bilby_laplace-0.2.0/tests/test_map_periodic.py +68 -0
- bilby_laplace-0.2.0/tests/test_map_search.py +200 -0
- bilby_laplace-0.2.0/tests/test_map_spike_guard.py +247 -0
- bilby_laplace-0.2.0/tests/test_metrics.py +96 -0
- bilby_laplace-0.2.0/tests/test_mixture_proposal.py +307 -0
- bilby_laplace-0.2.0/tests/test_mode_mixture.py +1200 -0
- bilby_laplace-0.2.0/tests/test_nlikelihood.py +108 -0
- bilby_laplace-0.2.0/tests/test_periodic_proposal.py +103 -0
- bilby_laplace-0.2.0/tests/test_pool.py +83 -0
- bilby_laplace-0.2.0/tests/test_prior_floor.py +149 -0
- bilby_laplace-0.2.0/tests/test_prior_precision.py +146 -0
- bilby_laplace-0.2.0/tests/test_proposal_covariance.py +139 -0
- bilby_laplace-0.2.0/tests/test_proposals.py +178 -0
- bilby_laplace-0.2.0/tests/test_rejection_sampling.py +88 -0
- bilby_laplace-0.2.0/tests/test_resolve_sampling_cov.py +95 -0
- bilby_laplace-0.2.0/tests/test_smc_multimode.py +144 -0
- bilby_laplace-0.2.0/tests/test_smc_pool.py +229 -0
- bilby_laplace-0.2.0/tests/test_validate_covariance.py +153 -0
- bilby_laplace-0.2.0/tests/test_waveform_fisher.py +408 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# setuptools-scm auto-generated; do not commit
|
|
2
|
+
src/bilby_laplace/_version.py
|
|
3
|
+
|
|
4
|
+
# Build / packaging
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
**/__pycache__/
|
|
9
|
+
*.py[cod]
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
# Common runtime outputs
|
|
13
|
+
outdir/
|
|
14
|
+
*.png
|
|
15
|
+
*.npz
|
|
16
|
+
|
|
17
|
+
# macOS
|
|
18
|
+
.DS_Store
|
|
19
|
+
|
|
20
|
+
# Vim
|
|
21
|
+
*.swp
|
|
22
|
+
*.swo
|
|
23
|
+
|
|
24
|
+
# Examples
|
|
25
|
+
*outdir*
|
|
26
|
+
|
|
27
|
+
# Paper working directory (studies, runs, figures) - kept out of the package repo
|
|
28
|
+
paper/
|
|
29
|
+
|
|
30
|
+
# MkDocs build output
|
|
31
|
+
site/
|
|
32
|
+
|
|
33
|
+
# Test / coverage artifacts
|
|
34
|
+
.coverage
|
|
35
|
+
.coverage.*
|
|
36
|
+
coverage.xml
|
|
37
|
+
htmlcov/
|
|
38
|
+
.pytest_cache/
|
|
39
|
+
|
|
40
|
+
# Claude Code guidance - local only, kept out of git history
|
|
41
|
+
CLAUDE.md
|
|
42
|
+
.claude/
|
|
43
|
+
|
|
44
|
+
# Run logs from `make <sampler> > x.log`
|
|
45
|
+
examples/**/*.log
|
|
46
|
+
|
|
47
|
+
# Editor settings
|
|
48
|
+
.vscode/
|
|
49
|
+
|
|
50
|
+
# Example outputs: `make compare` writes a results README and figures here
|
|
51
|
+
examples/*/README.md
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
Versions correspond to git tags; version numbers follow
|
|
7
|
+
[Semantic Versioning](https://semver.org/).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## [Unreleased]
|
|
12
|
+
|
|
13
|
+
## [0.2.0] — 2026-11-11
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Resampling methods: `resample="smc"` (via [aspire](https://github.com/bilby-dev/aspire)),
|
|
18
|
+
`"inprior"` (draw from the proposal within the prior support, no reweighting) and `"emcee"`.
|
|
19
|
+
- Multimodal proposals: `n_modes`, with `mode_searches` (`"hypercube"`, `"symmetric"`,
|
|
20
|
+
`"symmetric-polish"`, `"multistart"`), `mode_search_nsamples`, `mode_search_subspace`,
|
|
21
|
+
`mode_separation_sigma`, `mode_symmetries`, `mode_symmetry_tol`, `mode_symmetry_polish_max`,
|
|
22
|
+
`mode_multistart_nstarts` and `mode_weights`. Candidates from all searches are pooled and ranked
|
|
23
|
+
by log-posterior before selection. The mixture is recorded in `meta_data["mode_mixture"]`,
|
|
24
|
+
including which search proposed each mode.
|
|
25
|
+
- `proposal_covariance`: `"diagonal"` (independent truncated normals) or `"full"` (the correlated
|
|
26
|
+
Gaussian restricted to the prior box). Recorded in `meta_data["proposal_covariance"]`.
|
|
27
|
+
- `fisher_method="waveform"`: the waveform Fisher matrix for gravitational-wave likelihoods,
|
|
28
|
+
including phase/time/distance-marginalised likelihoods (via the Schur complement, with
|
|
29
|
+
`marginalized_reference` on `LaplacePosteriorEstimator`) and detector-based sky frames.
|
|
30
|
+
- `map_restarts` (default 4): independent `differential_evolution` runs in the MAP search, keeping
|
|
31
|
+
the best.
|
|
32
|
+
- `map_spike_guard` (default True) and `map_spike_delta`: reject MAP candidates that sit on a
|
|
33
|
+
needle spike of the log-posterior.
|
|
34
|
+
- `map_vectorized` (default True): evaluate the `differential_evolution` population as one batch,
|
|
35
|
+
so the MAP search uses `npool`.
|
|
36
|
+
- `smc_prior_flow`, `smc_prior_fraction`, `smc_progress` and `smc_plot_every` for SMC runs.
|
|
37
|
+
- `sampling_cov`: supply a precomputed covariance.
|
|
38
|
+
- `cov_scaling` accepts a per-parameter dict.
|
|
39
|
+
- `jacobian_cap_scale`, `hessian_kwargs`, `use_unit_cube` and `max_iterations` options.
|
|
40
|
+
- Validation of the Hessian-derived covariance along its principal axes; directions wider than
|
|
41
|
+
the Gaussian predicts are inflated.
|
|
42
|
+
- Checkpoint and resume for the batched resampling methods and SMC.
|
|
43
|
+
- Parallel likelihood evaluation through `npool` / `pool`.
|
|
44
|
+
- `bilby_laplace.comparison`: JSD/EMD comparison of results against a reference, used by the
|
|
45
|
+
examples.
|
|
46
|
+
- Examples: gaussian, rosenbrock, BBH_HLV, BNS_3G and AntiGlitch.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- `resample="inprior"` uses `proposal_covariance="full"` by default; every other method uses
|
|
51
|
+
`"diagonal"`.
|
|
52
|
+
- The multiprocessing pool is created before the MAP search.
|
|
53
|
+
- A secondary mode with a higher log-posterior than the primary MAP logs a warning.
|
|
54
|
+
- `fail_on_error` defaults to True.
|
|
55
|
+
- Unit-cube Hessian defaults: `initial_step=0.001`, `step_factor=2`, `maxiter=10`; the unit-cube
|
|
56
|
+
precision is floored at the prior precision.
|
|
57
|
+
- Renamed to reflect that the estimated matrix is the posterior precision, not the Fisher
|
|
58
|
+
information: `matrix.py` → `laplace.py`, `FisherMatrixPosteriorEstimator` →
|
|
59
|
+
`LaplacePosteriorEstimator`, `calculate_FIM` → `calculate_posterior_precision`, `calculate_iFIM`
|
|
60
|
+
→ `calculate_posterior_covariance`.
|
|
61
|
+
- The `sample_array`/`sample_dataframe` sentinel for the expansion point is `sample="MAP"` (was
|
|
62
|
+
`"maxL"`); other strings raise `ValueError`.
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
|
|
66
|
+
- `Constraint` priors are applied in the MAP search, Hessian, mode search and Laplace evidence
|
|
67
|
+
(`log_prior` delegates to `PriorDict.ln_prob`; MAP starts use `sample_subset_constrained`).
|
|
68
|
+
- `log_evidence_laplace` includes bilby's constraint normalisation factor.
|
|
69
|
+
- `prior_parameters` substitution happens before the prior-support test in the SMC and in-prior
|
|
70
|
+
draws.
|
|
71
|
+
- Latin hypercube starts that violate a constraint are dropped from the mode search.
|
|
72
|
+
- The hypercube mode search keeps the best polish of a region, not the first.
|
|
73
|
+
- An exact symmetry mirror is not rejected as a duplicate of its own source by the separation gate.
|
|
74
|
+
- The waveform Fisher uses the injection as the marginalised-parameter reference only when
|
|
75
|
+
`use_injection_for_map=True`.
|
|
76
|
+
- Local MAP polishes wrap periodic parameters instead of treating their bounds as walls.
|
|
77
|
+
- `resample=None` reports the fraction of draws outside the prior support.
|
|
78
|
+
- The sampling seed reaches every stage, including SMC.
|
|
79
|
+
|
|
80
|
+
### Removed
|
|
81
|
+
|
|
82
|
+
- The manual finite-difference Hessian fallback and `fd_eps`; `scipy>=1.15` is required.
|
|
83
|
+
- `get_maximum_likelihood_sample()`, an alias of `get_MAP_sample()`.
|
|
84
|
+
- The bounds arguments of `_pool_log_likelihood`; support is tested once per batch.
|
|
85
|
+
- The GW150914 example (needs a data download).
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## [0.1.0] — 2026-03-02
|
|
90
|
+
|
|
91
|
+
Initial release.
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
|
|
95
|
+
- `Fisher` sampler class — a Bilby plugin that registers as `bilby.laplace` /
|
|
96
|
+
`laplace` via the `bilby.samplers` entry-point group.
|
|
97
|
+
- `FisherMatrixPosteriorEstimator` — computes the MAP estimate and inverse Fisher
|
|
98
|
+
Information Matrix (iFIM) covariance for a given likelihood and prior.
|
|
99
|
+
- FIM calculation using `scipy.differentiate.hessian` (scipy ≥ 1.15) with automatic
|
|
100
|
+
finite-difference fallback for older scipy.
|
|
101
|
+
- Rejection sampling and importance sampling resampling modes.
|
|
102
|
+
- Batched sampling loop with a `tqdm` progress bar reporting per-batch efficiency.
|
|
103
|
+
- Optional corner diagnostic plot (`plot_diagnostic=True`) comparing the Gaussian
|
|
104
|
+
proposal with the resampled posterior.
|
|
105
|
+
- `result.meta_data["run_statistics"]` populated with sampling efficiency, likelihood
|
|
106
|
+
evaluation count, and wall-clock time.
|
|
107
|
+
- `examples/gaussian_example.py` — minimal runnable demo on a 2-D Gaussian likelihood.
|
|
108
|
+
- Version managed by `setuptools-scm` from git tags.
|
|
109
|
+
|
|
110
|
+
[Unreleased]: https://github.com/GregoryAshton/bilby-laplace/compare/v0.2.0...HEAD
|
|
111
|
+
[0.2.0]: https://github.com/GregoryAshton/bilby-laplace/compare/v0.1.0...v0.2.0
|
|
112
|
+
[0.1.0]: https://github.com/GregoryAshton/bilby-laplace/releases/tag/v0.1.0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it as below."
|
|
3
|
+
title: "bilby-laplace"
|
|
4
|
+
abstract: >-
|
|
5
|
+
A Bilby sampler plugin that builds a Laplace-approximation mixture (MAP
|
|
6
|
+
search, secondary-mode search, curvature at each mode) and uses it to seed
|
|
7
|
+
or correct stochastic sampling.
|
|
8
|
+
type: software
|
|
9
|
+
authors:
|
|
10
|
+
- family-names: Ashton
|
|
11
|
+
given-names: Gregory
|
|
12
|
+
license: MIT
|
|
13
|
+
repository-code: "https://github.com/GregoryAshton/bilby-laplace"
|
|
14
|
+
url: "https://gregoryashton.github.io/bilby-laplace/"
|
|
15
|
+
keywords:
|
|
16
|
+
- bayesian inference
|
|
17
|
+
- laplace approximation
|
|
18
|
+
- bilby
|
|
19
|
+
- gravitational waves
|
|
20
|
+
version: 0.2.0
|
|
21
|
+
date-released: 2026-11-11
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Gregory Ashton
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bilby-laplace
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Bilby sampler plugin: Laplace approximation with rejection/importance resampling
|
|
5
|
+
Author: Gregory Ashton
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/GregoryAshton/bilby-laplace
|
|
8
|
+
Project-URL: Documentation, https://gregoryashton.github.io/bilby-laplace/
|
|
9
|
+
Project-URL: Source, https://github.com/GregoryAshton/bilby-laplace
|
|
10
|
+
Project-URL: Issues, https://github.com/GregoryAshton/bilby-laplace/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/GregoryAshton/bilby-laplace/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: bayesian inference,laplace approximation,bilby,gravitational waves
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: bilby>=2.7
|
|
26
|
+
Requires-Dist: numpy
|
|
27
|
+
Requires-Dist: scipy>=1.15
|
|
28
|
+
Requires-Dist: pandas
|
|
29
|
+
Requires-Dist: tqdm
|
|
30
|
+
Provides-Extra: docs
|
|
31
|
+
Requires-Dist: mkdocs<2; extra == "docs"
|
|
32
|
+
Requires-Dist: mkdocs-material; extra == "docs"
|
|
33
|
+
Requires-Dist: mkdocstrings[python]; extra == "docs"
|
|
34
|
+
Requires-Dist: pymdown-extensions; extra == "docs"
|
|
35
|
+
Provides-Extra: test
|
|
36
|
+
Requires-Dist: pytest; extra == "test"
|
|
37
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
|
|
40
|
+
# bilby-laplace
|
|
41
|
+
|
|
42
|
+
A [Bilby](https://bilby-dev.github.io/bilby/) sampler plugin that estimates posteriors
|
|
43
|
+
via the **Laplace approximation** — a Gaussian fitted at the maximum a posteriori (MAP)
|
|
44
|
+
point using the Hessian of the log-posterior — followed by optional resampling to
|
|
45
|
+
correct for non-Gaussianity.
|
|
46
|
+
|
|
47
|
+
The method is fast, scales well to moderate dimensions, and produces asymptotically
|
|
48
|
+
exact posterior samples when the true posterior is close to Gaussian. It is
|
|
49
|
+
useful as a cheap cross-check against nested sampling results.
|
|
50
|
+
|
|
51
|
+
> **Documentation:** full guides, the configuration/API reference, and background on
|
|
52
|
+
> the method are at **<https://gregoryashton.github.io/bilby-laplace/>**.
|
|
53
|
+
|
|
54
|
+
Originally derived from [bilby PR #933](https://github.com/bilby-dev/bilby/pull/933).
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install bilby-laplace
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or from source:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/GregoryAshton/bilby-laplace
|
|
66
|
+
cd bilby-laplace
|
|
67
|
+
pip install -e .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Bilby discovers the sampler automatically via its plugin entry-point system — no
|
|
71
|
+
further configuration is needed.
|
|
72
|
+
|
|
73
|
+
## Quick start
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import bilby
|
|
77
|
+
|
|
78
|
+
result = bilby.run_sampler(
|
|
79
|
+
likelihood=likelihood,
|
|
80
|
+
priors=priors,
|
|
81
|
+
sampler="laplace",
|
|
82
|
+
outdir="outdir",
|
|
83
|
+
label="my_run",
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
result.plot_corner()
|
|
87
|
+
print(result.posterior)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Features
|
|
91
|
+
|
|
92
|
+
- Several resampling strategies to correct for non-Gaussianity: `rejection`,
|
|
93
|
+
`importance`, `inprior`, `smc` (via [aspire](https://github.com/bilby-dev/aspire)),
|
|
94
|
+
or none.
|
|
95
|
+
- Two covariance routes: the numerical Hessian (`fisher_method="hessian"`, any
|
|
96
|
+
likelihood) or the genuine waveform Fisher matrix (`fisher_method="waveform"`, for
|
|
97
|
+
gravitational-wave likelihoods).
|
|
98
|
+
- Supply a precomputed covariance via `sampling_cov` (e.g. from gwfast / GWFish).
|
|
99
|
+
- Multimodal posteriors via SMC with `n_modes > 1`.
|
|
100
|
+
- Laplace log-evidence always available; rejection and SMC add independent estimates.
|
|
101
|
+
|
|
102
|
+
See the [documentation](https://gregoryashton.github.io/bilby-laplace/) for the full list
|
|
103
|
+
of options and guidance on choosing between them.
|
|
104
|
+
|
|
105
|
+
## Examples
|
|
106
|
+
|
|
107
|
+
Runnable examples are in [`examples/`](https://github.com/GregoryAshton/bilby-laplace/tree/main/examples) (gaussian, rosenbrock, BBH, BNS).
|
|
108
|
+
Each has a `Makefile`:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
cd examples/gaussian
|
|
112
|
+
make laplace
|
|
113
|
+
make compare
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Citing
|
|
117
|
+
|
|
118
|
+
If you use `bilby-laplace`, please cite the software release; citation metadata
|
|
119
|
+
is in [`CITATION.cff`](https://github.com/GregoryAshton/bilby-laplace/blob/main/CITATION.cff) (GitHub's "Cite this repository" button
|
|
120
|
+
reads it).
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
MIT; see [`LICENSE`](https://github.com/GregoryAshton/bilby-laplace/blob/main/LICENSE).
|
|
125
|
+
|
|
126
|
+
## Documentation development
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
pip install -e ".[docs]"
|
|
130
|
+
mkdocs serve
|
|
131
|
+
```
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# bilby-laplace
|
|
2
|
+
|
|
3
|
+
A [Bilby](https://bilby-dev.github.io/bilby/) sampler plugin that estimates posteriors
|
|
4
|
+
via the **Laplace approximation** — a Gaussian fitted at the maximum a posteriori (MAP)
|
|
5
|
+
point using the Hessian of the log-posterior — followed by optional resampling to
|
|
6
|
+
correct for non-Gaussianity.
|
|
7
|
+
|
|
8
|
+
The method is fast, scales well to moderate dimensions, and produces asymptotically
|
|
9
|
+
exact posterior samples when the true posterior is close to Gaussian. It is
|
|
10
|
+
useful as a cheap cross-check against nested sampling results.
|
|
11
|
+
|
|
12
|
+
> **Documentation:** full guides, the configuration/API reference, and background on
|
|
13
|
+
> the method are at **<https://gregoryashton.github.io/bilby-laplace/>**.
|
|
14
|
+
|
|
15
|
+
Originally derived from [bilby PR #933](https://github.com/bilby-dev/bilby/pull/933).
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install bilby-laplace
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or from source:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
git clone https://github.com/GregoryAshton/bilby-laplace
|
|
27
|
+
cd bilby-laplace
|
|
28
|
+
pip install -e .
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Bilby discovers the sampler automatically via its plugin entry-point system — no
|
|
32
|
+
further configuration is needed.
|
|
33
|
+
|
|
34
|
+
## Quick start
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import bilby
|
|
38
|
+
|
|
39
|
+
result = bilby.run_sampler(
|
|
40
|
+
likelihood=likelihood,
|
|
41
|
+
priors=priors,
|
|
42
|
+
sampler="laplace",
|
|
43
|
+
outdir="outdir",
|
|
44
|
+
label="my_run",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
result.plot_corner()
|
|
48
|
+
print(result.posterior)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Features
|
|
52
|
+
|
|
53
|
+
- Several resampling strategies to correct for non-Gaussianity: `rejection`,
|
|
54
|
+
`importance`, `inprior`, `smc` (via [aspire](https://github.com/bilby-dev/aspire)),
|
|
55
|
+
or none.
|
|
56
|
+
- Two covariance routes: the numerical Hessian (`fisher_method="hessian"`, any
|
|
57
|
+
likelihood) or the genuine waveform Fisher matrix (`fisher_method="waveform"`, for
|
|
58
|
+
gravitational-wave likelihoods).
|
|
59
|
+
- Supply a precomputed covariance via `sampling_cov` (e.g. from gwfast / GWFish).
|
|
60
|
+
- Multimodal posteriors via SMC with `n_modes > 1`.
|
|
61
|
+
- Laplace log-evidence always available; rejection and SMC add independent estimates.
|
|
62
|
+
|
|
63
|
+
See the [documentation](https://gregoryashton.github.io/bilby-laplace/) for the full list
|
|
64
|
+
of options and guidance on choosing between them.
|
|
65
|
+
|
|
66
|
+
## Examples
|
|
67
|
+
|
|
68
|
+
Runnable examples are in [`examples/`](https://github.com/GregoryAshton/bilby-laplace/tree/main/examples) (gaussian, rosenbrock, BBH, BNS).
|
|
69
|
+
Each has a `Makefile`:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
cd examples/gaussian
|
|
73
|
+
make laplace
|
|
74
|
+
make compare
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Citing
|
|
78
|
+
|
|
79
|
+
If you use `bilby-laplace`, please cite the software release; citation metadata
|
|
80
|
+
is in [`CITATION.cff`](https://github.com/GregoryAshton/bilby-laplace/blob/main/CITATION.cff) (GitHub's "Cite this repository" button
|
|
81
|
+
reads it).
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
MIT; see [`LICENSE`](https://github.com/GregoryAshton/bilby-laplace/blob/main/LICENSE).
|
|
86
|
+
|
|
87
|
+
## Documentation development
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pip install -e ".[docs]"
|
|
91
|
+
mkdocs serve
|
|
92
|
+
```
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Fisher, Hessian & precision
|
|
2
|
+
|
|
3
|
+
A common point of confusion: the matrix the default route computes is **not** the
|
|
4
|
+
Fisher information matrix, even though such code is often loosely called "the Fisher
|
|
5
|
+
matrix". This page makes the distinction precise, because it explains both the
|
|
6
|
+
naming in the code and why the `"waveform"` route can give a better-behaved result.
|
|
7
|
+
|
|
8
|
+
## The decomposition
|
|
9
|
+
|
|
10
|
+
For a Gaussian likelihood with mean \( \mu(\theta) \), data \( d \), and noise
|
|
11
|
+
covariance \( C \), write the residual \( r = d - \mu(\theta) \). The second
|
|
12
|
+
derivative of the log-likelihood splits cleanly:
|
|
13
|
+
|
|
14
|
+
\[
|
|
15
|
+
-\partial_i \partial_j \log L
|
|
16
|
+
= \underbrace{(\partial_i \mu)^{\mathsf T} C^{-1} (\partial_j \mu)}_{\textstyle F_{ij}\ \text{(Fisher)}}
|
|
17
|
+
\;-\; \underbrace{r^{\mathsf T} C^{-1} (\partial_i \partial_j \mu)}_{\textstyle \text{residual}\times\text{curvature}}
|
|
18
|
+
\]
|
|
19
|
+
|
|
20
|
+
For gravitational waves the noise-weighted inner product
|
|
21
|
+
\( (a\mid b) = 4\,\mathrm{Re}\int a^* b / S_n\, \mathrm{d}f \) **is** \( a^{\mathsf T} C^{-1} b \),
|
|
22
|
+
so with \( \mu \to h(\theta) \):
|
|
23
|
+
|
|
24
|
+
\[
|
|
25
|
+
-\partial_i \partial_j \log L = (\partial_i h \mid \partial_j h) - (r \mid \partial_i \partial_j h).
|
|
26
|
+
\]
|
|
27
|
+
|
|
28
|
+
Three distinct objects appear:
|
|
29
|
+
|
|
30
|
+
| Object | Definition | Properties |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| **Fisher information** \( F \) | \( \mathbb{E}[-\partial^2 \log L] = (\partial_i h\mid\partial_j h) \) | expectation; model + noise only; positive semi-definite; data-independent |
|
|
33
|
+
| **Observed information** \( J \) | \( -\partial^2 \log L \) at a point | single realisation; \( = F - (r\mid\partial^2 h) \); can be indefinite |
|
|
34
|
+
| **Posterior precision** | \( -\partial^2 \log(L\pi) = J + (-\partial^2\log\pi) \) | what the Laplace approximation actually uses |
|
|
35
|
+
|
|
36
|
+
## Why the routes differ
|
|
37
|
+
|
|
38
|
+
- **`fisher_method="hessian"`** numerically estimates the *posterior precision* —
|
|
39
|
+
the third row, including the prior. It is the observed information plus the prior
|
|
40
|
+
curvature.
|
|
41
|
+
- **`fisher_method="waveform"`** computes \( F \) directly — the first term only —
|
|
42
|
+
plus a diagonal prior precision.
|
|
43
|
+
|
|
44
|
+
The two agree **in expectation**: at the true parameters the residual is pure noise,
|
|
45
|
+
\( \mathbb{E}[(r\mid X)] = 0 \), so \( \mathbb{E}[-\partial^2\log L] = F \). This is
|
|
46
|
+
the Fisher information identity, and the basis of the Cramér–Rao bound.
|
|
47
|
+
|
|
48
|
+
For a **single** dataset they differ by the residual–curvature term, which is
|
|
49
|
+
zero-mean but has nonzero variance, is **not sign-definite**, and shrinks roughly
|
|
50
|
+
like \( \mathcal{O}(1/\mathrm{SNR}) \). Dropping it is the *linear-signal
|
|
51
|
+
approximation*. Evaluating at the MAP does not remove it: the gradient vanishes
|
|
52
|
+
there, but the residual still has a component off the signal manifold that projects
|
|
53
|
+
onto \( \partial_i\partial_j h \).
|
|
54
|
+
|
|
55
|
+
## Consequences in practice
|
|
56
|
+
|
|
57
|
+
1. The Hessian route computes the **noisy** object: even with perfect
|
|
58
|
+
differentiation, \( J \) includes the indefinite residual–curvature term, which is
|
|
59
|
+
why the inversion needs eigenvalue flooring. The waveform route computes the clean
|
|
60
|
+
PSD \( F \).
|
|
61
|
+
2. The Hessian route differentiates a **scalar** to get a *second* derivative — the
|
|
62
|
+
accuracy ceiling is roughly \( \sqrt{\varepsilon_f} \). The Fisher needs only
|
|
63
|
+
*first* derivatives of \( h \), then a Gram product — better conditioned and
|
|
64
|
+
positive semi-definite for free.
|
|
65
|
+
|
|
66
|
+
A subtlety worth stating: for a *specific* dataset, the inverse observed information
|
|
67
|
+
\( J^{-1} \) is actually the better local Gaussian fit to the realised posterior (the
|
|
68
|
+
Laplace approximation *is* a Taylor expansion of the realised log-posterior). Tools
|
|
69
|
+
like [gwfast](https://github.com/CosmoStatGW/gwfast) and
|
|
70
|
+
[GWFish](https://github.com/janosch314/GWFish) compute \( F \) because they are doing
|
|
71
|
+
*forecasting* (expected errors, Cramér–Rao). Here we only need a **proposal**
|
|
72
|
+
covariance — and \( F \) is a clean, PSD, well-conditioned surrogate that equals
|
|
73
|
+
\( J \) in expectation, so it is usually the better engineering choice when available.
|
|
74
|
+
|
|
75
|
+
## Conditioning
|
|
76
|
+
|
|
77
|
+
GW Fisher matrices are notoriously ill-conditioned — condition numbers of
|
|
78
|
+
\( 10^{10} \)–\( 10^{20} \) from strong degeneracies (distance–inclination, the
|
|
79
|
+
masses, sky position). Inverting in double precision loses about
|
|
80
|
+
\( \log_{10}(\kappa) \) digits, so a poorly-conditioned matrix can be inverted to
|
|
81
|
+
*zero* correct digits.
|
|
82
|
+
|
|
83
|
+
Two independent sources contribute:
|
|
84
|
+
|
|
85
|
+
- **Scale-driven** conditioning (parameters span many orders of magnitude). Removed
|
|
86
|
+
by **diagonal preconditioning** — rescaling by \( \sqrt{\mathrm{diag}} \) before
|
|
87
|
+
inversion. This is the shared trick used by both GWFish and gwfast.
|
|
88
|
+
- **Correlation-driven** conditioning (genuine parameter degeneracies). Preconditioning
|
|
89
|
+
cannot help here; only a better parameterisation or the Fisher form does.
|
|
90
|
+
|
|
91
|
+
The unit-cube Hessian path already normalises scales via the prior CDF transform, so
|
|
92
|
+
its residual conditioning is correlation-driven; the parameter-space and
|
|
93
|
+
waveform-Fisher paths benefit much more from preconditioning.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--8<-- "CHANGELOG.md"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
Runnable example scripts live in the [`examples/`](https://github.com/GregoryAshton/bilby-laplace/tree/main/examples)
|
|
4
|
+
directory. Each script supports multiple samplers and a `--compare` mode that prints
|
|
5
|
+
a summary table and a corner plot overlaying the methods.
|
|
6
|
+
|
|
7
|
+
Each example directory has a `Makefile`; run targets from within it:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cd examples/gaussian
|
|
11
|
+
make laplace # raw Laplace (no resampling)
|
|
12
|
+
make rejection # rejection resampling
|
|
13
|
+
make rejection-user # rejection with a user-supplied sampling_cov
|
|
14
|
+
make smc # SMC resampling
|
|
15
|
+
make dynesty # nested-sampling reference
|
|
16
|
+
make compare # load all results, print evidence table, plot
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Available examples
|
|
20
|
+
|
|
21
|
+
| Example | What it demonstrates |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `examples/gaussian` | 2-D correlated Gaussian — the Laplace approximation is exact here, so it is the cleanest correctness check. Includes a `rejection-user` variant that feeds the known covariance via `sampling_cov`. |
|
|
24
|
+
| `examples/rosenbrock` | A strongly non-Gaussian, curved target — a stress test where `resample="smc"` matters. |
|
|
25
|
+
| `examples/BBH_HLV` | A simulated binary-black-hole injection in an H–L–V network (no data download needed). A realistic high-dimensional GW problem. |
|
|
26
|
+
| `examples/BNS_3G` | A binary-neutron-star injection in a 3rd-generation network. |
|
|
27
|
+
| `examples/AntiGlitch` | A simulated anti-glitch in Gaussian noise. |
|
|
28
|
+
|
|
29
|
+
## A minimal script
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
import bilby
|
|
33
|
+
|
|
34
|
+
likelihood = ... # any bilby Likelihood
|
|
35
|
+
priors = ... # a bilby PriorDict
|
|
36
|
+
|
|
37
|
+
result = bilby.run_sampler(
|
|
38
|
+
likelihood=likelihood,
|
|
39
|
+
priors=priors,
|
|
40
|
+
sampler="laplace",
|
|
41
|
+
resample="rejection",
|
|
42
|
+
target_nsamples=5000,
|
|
43
|
+
plot_diagnostic=True,
|
|
44
|
+
outdir="outdir",
|
|
45
|
+
label="example",
|
|
46
|
+
)
|
|
47
|
+
result.plot_corner()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
See the [gaussian example](https://github.com/GregoryAshton/bilby-laplace/blob/main/examples/gaussian/run.py)
|
|
51
|
+
for a complete, self-contained script including the likelihood definition.
|