Skip to content

liulu

liulu is a Python package implementing the streaming model of redshift-space distortions (RSD) — the mapping from the real-space galaxy/halo correlation function and the pairwise velocity distribution to the redshift-space correlation function (Scoccimarro 2004; Reid & White 2011):

\[ 1 + \xi^s(s_\perp, s_\parallel) = aH \int \bigl[1 + \xi(r)\bigr]\, \mathcal{P}(v_\text{los} \mid r_\perp, r_\parallel)\, \mathrm{d}y \]

where \(y\) is the real-space line-of-sight separation, \(r=\sqrt{s_\perp^2+y^2}\), and \(v_\text{los}=aH\,(s_\parallel-y)\).

Given a real-space \(\xi(r)\) and a model for the pairwise velocity moments, liulu evaluates the redshift-space 2-point function \(\xi^s(s_\perp,s_\parallel)\) and its Legendre multipoles \(\xi_0, \xi_2, \xi_4\).

Why it exists

The quality of a streaming-model prediction is set almost entirely by the velocity PDF \(\mathcal{P}(v_\text{los}\mid r_\perp,r_\parallel)\). liulu treats the PDF as a pluggable component and ships several, from a Gaussian up to the generalized-hyperbolic family, so you can trade accuracy against cost:

PDF moments used best for
GaussianPDF mean, variance quick baselines
SkewTPDF + skewness, kurtosis skewed/leptokurtic tails
NIGPDF same 4 moments, analytic recommended default — best shape at fixed moments
GeneralizedHyperbolicPDF / TabulatedGHPDF + free class index \(\lambda\) research / last-percent tuning

The validation against \(N\)-body halo catalogues (see Validation) shows NIG cuts the quadrupole-dip residual ~10× over the skew-\(t\) at fixed moments, and is the recommended production choice.

30-second example

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

xi_real = TabulatedXi(r_table=r, xi_table=xi)                  # measured xi(r)
moments = TabulatedMoments(r_table=r, v_r=v_r,                 # pairwise v moments
                           sigma_r=sigma_r, sigma_t=sigma_t,
                           gamma_r=gamma_r, kappa_r=kappa_r, kappa_t=kappa_t)
model = StreamingModel(xi_real, NIGPDF(moments), aH=aH, y_max=120.0)

s = np.geomspace(1, 50, 19)
xi0, _, xi2, _, xi4 = model.multipoles(s, ell_max=4)

See the Quickstart for an end-to-end runnable version.

Where to go next