eft4py Output¶
Solve a Horndeski dark-energy background with
eft4py, plot it with cplots, and compare it
with ΛCDM from CAMB, all through the same as_observables / background() calls.
Not executed during the docs build
eft4py is not a docs dependency, so the code below is shown verbatim. The full,
interactive version is the marimo notebook
notebooks/eft4py_background.py,
which declares its dependencies inline:
Solve¶
Quintessence, $G_2 = X - V\phi^2$ and $G_4 = M_{\rm pl}^2/2$, with the field at rest at $a = 10^{-6}$ and $V$ tuned so that $H(a=1) = H_0$:
import numpy as np
import sympy as sp
import cplots
from eft4py import Cosmology, HorndeskiModel, ScipyBackground, frozen_field, get_symbols
s = get_symbols()
V = sp.Symbol("V", positive=True)
model = HorndeskiModel(G2=s.X - V * s.phi**2, G4=s.Mpl**2 / 2, parameters=[V])
h, phi_ini = 0.7, 3.0
Omega_r = Cosmology.from_physical(h=h, omega_b=0.0245, omega_cdm=0.1225).Omega_r
cosmo = Cosmology(h=h, Omega_m=0.3, Omega_r=Omega_r)
solver = ScipyBackground(model, [V], ic=frozen_field(phi_ini), a_ini=1e-6, rtol=1e-9)
theta = solver.shoot([cosmo.Omega_de * 3 * cosmo.H0**2 / phi_ini**2], cosmo, index=0)
grid = solver.solve(theta, cosmo, np.linspace(np.log(1 / 11), 0.0, 400)) # z = 10 -> 0
Wrap and plot¶
as_observables recognises the eft4py grid; BackgroundPanels puts each kind of
quantity on its own panel, with the units you ask for:
out = cplots.as_observables(grid) # -> Eft4pyOutput
out.available_background() # canonical names + raw eft4py fields
cplots.BackgroundPanels(
out,
["H", "dL", "dA", "dC", "w_de", "Omega_de", "alpha_M"],
units={"H": "km/s/Mpc"},
ncols=3,
latex_labels=True,
).show("plotly")
hi_class format¶
eft4py exports its grid in hi_class's format, which is what the adapter reads:
So an eft4py run and a hi_class run come out of cplots with the same names and units, and overlay directly:
Any redshift grid¶
z= resamples. A BackgroundSolution uses eft4py's own interpolators:
from eft4py.solvers import BackgroundSolution
z = np.linspace(0.01, 3.0, 60)
sol = cplots.as_observables(BackgroundSolution.from_grid(grid))
cplots.BackgroundEvolution(sol, ["dA", "dC"], z=z, latex_labels=True).show()
Compare with CAMB¶
CAMB's H is in km/s/Mpc and eft4py's in 1/Mpc; the overlay converts to the units requested (or to the first source's):
import camb
pars = camb.set_params(H0=70, ombh2=0.0245, omch2=0.3 * h**2 - 0.0245, mnu=0.0, omk=0.0)
cplots.BackgroundPanels(
{"eft4py": grid, r"CAMB ($\Lambda$CDM)": camb.get_background(pars)},
["H", "dA"],
z=z,
units={"H": "km/s/Mpc"},
latex_labels=True,
).show()
A frozen field (large $\phi_{\rm ini}$) sits on ΛCDM; a light one rolls and departs from it at late times.