Skip to content

Quickstart

This walks through a complete, runnable prediction: build the inputs, choose a velocity PDF, and compute the redshift-space multipoles.

1. Inputs

You need a real-space \(\xi(r)\), pairwise velocity moments, and the constant \(aH\). Here we use simple analytic stand-ins so the example runs without data; in practice these come from a simulation measurement or theory (see Inputs & interpolation).

import numpy as np
from liulu import StreamingModel
from liulu.physics.real_space import TabulatedXi
from liulu.physics.pairwise_velocity import TabulatedMoments
from liulu.physics.velocity_pdf import NIGPDF, SkewTPDF, GaussianPDF

# tabulation grid in r [Mpc/h]
r = np.geomspace(0.5, 60.0, 40)

# real-space correlation function (power-law stand-in)
xi = 1.5 * (r / 8.0) ** -1.8

# pairwise velocity moments (stand-ins; real ones are measured/modelled)
v_r     = -300.0 * np.exp(-r / 15.0)          # mean radial infall (km/s)
sigma_r = 400.0 * np.ones_like(r)             # radial dispersion (km/s)
sigma_t = 300.0 * np.ones_like(r)             # tangential dispersion (km/s)
gamma_r = -0.3 * np.exp(-r / 10.0)            # radial skewness
kappa_r =  0.8 * np.exp(-r / 10.0)            # radial excess kurtosis
kappa_t =  0.4 * np.exp(-r / 10.0)            # tangential excess kurtosis

2. Build the physics components

xi_real = TabulatedXi(r_table=r, xi_table=xi)

moments = TabulatedMoments(
    r_table=r, v_r=v_r, sigma_r=sigma_r, sigma_t=sigma_t,
    gamma_r=gamma_r, kappa_r=kappa_r, kappa_t=kappa_t,
)

aH = 91.0   # a * H(z) in km/s/(Mpc/h); e.g. ~91 for LCDM at z=0.25

TabulatedMoments takes the user-friendly sigma_*/gamma_*/kappa_* and converts them to the canonical central moments c_ij internally (see Conventions).

3. Choose a PDF and run

model = StreamingModel(xi_real, NIGPDF(moments), aH=aH, y_max=120.0)

s = np.geomspace(1.0, 50.0, 19)
mp = model.multipoles(s, ell_max=4)
xi0, xi1, xi2, xi3, xi4 = mp          # odd multipoles are ~0 by symmetry

print(np.c_[s, s**2 * xi0, s**2 * xi2])

multipoles returns an array indexed by \(\ell\); take mp[0], mp[2], mp[4] for the monopole, quadrupole, hexadecapole.

4. Swap the PDF

The PDF is a drop-in component — compare models by swapping the one line:

for pdf in (GaussianPDF(moments), SkewTPDF(moments), NIGPDF(moments)):
    xi2 = StreamingModel(xi_real, pdf, aH=aH, y_max=120.0).multipoles(s, ell_max=4)[2]
    print(type(pdf).__name__, (s**2 * xi2)[:5])

Other outputs

model.xi_s_smu(s, mu)            # xi^s on a (s, mu) grid
model.xi_s_2d(s_perp, s_par)     # xi^s on the (s_perp, s_par) plane
model.wedges(s, mu_edges=[(0,0.5),(0.5,1.0)])   # mu wedges

See the API reference for full signatures, and Validation for how the PDF choice plays out against \(N\)-body halos.