Your first fit: flat \(\Lambda\)CDM
Fit flat \(\Lambda\)CDM to DESI DR2 BAO and Union3.1 supernovae, with a BBN prior on
\(\omega_\mathrm{b}\). \(\Lambda\)CDM is the bundled W0WaCDM with \(w_0 = -1\) and \(w_a = 0\) fixed.
Download the data once:
cosmonuts install desi_dr2_bao union3.1
Then run the fit from Python or from the command line. The two are equivalent.
import jax
jax.config.update("jax_enable_x64", True)
from cosmonuts import Defined, Fixed, Model, Normal, Uniform, nuts
from cosmonuts.likelihoods import DESIDR2BAO, Union31
from cosmonuts.theories import W0WaCDM
model = Model(W0WaCDM(m_nu=0.06), [DESIDR2BAO(), Union31()], {
"h": Uniform(0.5, 0.9),
"omega_b": Normal(0.02218, 0.00055), # BBN
"omega_cdm": Uniform(0.05, 0.25),
"w0": Fixed(-1.0), # LCDM
"wa": Fixed(0.0),
"Omega_m": Defined(
lambda h, omega_b, omega_cdm: (omega_b + omega_cdm + 0.06 / 93.14) / h**2),
})
chains = nuts(model, jax.random.PRNGKey(0), num_samples=1000,
output="chains/lcdm_union31_desi")
h, Om = chains.samples["h"], chains.derived["Omega_m"]
print(f"h = {h.mean():.4f} ± {h.std():.4f}")
print(f"Omega_m = {Om.mean():.4f} ± {Om.std():.4f}")
python lcdm_union31_desi.py
theory:
W0WaCDM: {m_nu: 0.06}
likelihood:
DESIDR2BAO: null
Union31: null
params:
h: {prior: {min: 0.5, max: 0.9}, ref: 0.68}
omega_b: {prior: {dist: norm, loc: 0.02218, scale: 0.00055}} # BBN
omega_cdm: {prior: {min: 0.05, max: 0.25}, ref: 0.12}
w0: -1.0 # LCDM
wa: 0.0
Omega_m:
value: "lambda h, omega_b, omega_cdm: (omega_b + omega_cdm + 0.06 / 93.14) / h**2"
sampler:
nuts: {num_samples: 1000, num_chains: 4}
output: chains/lcdm_union31_desi
cosmonuts sample lcdm_union31_desi.yaml --test # build, evaluate once, stop
cosmonuts sample lcdm_union31_desi.yaml # NUTS, 4 chains
Either way you get
in about 15 s on a laptop CPU. The chains in chains/ are in Cobaya's format, so
getdist.loadMCSamples("chains/lcdm_union31_desi") reads them.
If a run stops
A run with an output saves its progress as it goes. If it is interrupted (a crash, a
killed job, a dead laptop), run the same thing again with resume on to continue it:
chains = nuts(model, jax.random.PRNGKey(0), num_samples=1000,
output="chains/lcdm_union31_desi", resume=True)
cosmonuts sample lcdm_union31_desi.yaml --resume # or -r, or `resume: true` in the file
What is resumed depends on the sampler:
- NUTS / HMC. Each chain restarts from its last saved draw with the saved step size and
mass matrix (
<output>.adaptation.npz), with no warm-up. New draws are appended to the same files.num_samplescounts all the draws per chain, old ones included. - Nested sampling. The live points, the evidence and the random key are saved after every
chunk (
<output>.nested_state.npz, next to<output>_dead-birth.txt), so the resumed run ends as if it had never stopped. Settings you leave unset are read from the saved run, and settings you do give must match it (nlive,num_delete, ...).frac_remainmay differ, for example to take a finished run to a tighter tolerance.
resume and force (overwrite=True in Python) exclude each other. Without either, a run
whose output already exists stops with FileExistsError instead of overwriting it.