Skip to content

Pairwise velocity moments — vel_m10 … vel_c22, vel_binned

Eight central moments of the radial pairwise velocity between halo mass-bin pairs, on a radial grid — plus a derived recipe (vel_binned) that aggregates them exactly onto arbitrary mass bins.

m10 = reg.predict("vel_m10", "LCDM", 0.25, [0.31, 0.677, 0.967, 0.83])   # (1, 91, 37)
art = reg.load("vel_m10", "LCDM", 0.25)
art.pair_keys   # 91 mass-bin pairs
art.r           # 37 radial bins over [0, 150] Mpc/h (wide grid)
  • Keys: vel_m10, vel_c20, vel_c02, vel_c12, vel_c30, vel_c40, vel_c04, vel_c22 (trained), and vel_binned (derived).
  • Output: (1, 91, 37) — 91 mass-pair × 37 radial bins (trimmed columns NaN).
  • Mass bins: 13 adaptive bins over log₁₀M ∈ [12.5, 14.2] — 0.1 dex over [12.5, 13.5), 0.25 dex over [13.5, 14.0), cap [14.0, 14.2) — giving 91 ordered pairs. The high-mass cap is signal-to-noise motivated.
  • Radial grid: 37 wide bins — roughly log-spaced 1–2.5 Mpc/h widths below 15 Mpc/h, 5 Mpc/h above (adopted 2026-07-06 after a bin-width exploration: 20–30% less noise per bin, better held-out accuracy for all eight moments, and the averaging systematic stays below the noise; the earlier 72-bin quasi-log grid is retired).

Moments

Moment Meaning Sign Transform
m10 mean radial infall signed arcsinh
c20 variance ∥ + log
c02 variance ⊥ + log
c12 skew cross term signed arcsinh
c30 skew ∥ signed arcsinh
c40, c04, c22 4th-order + log

Representation & accuracy

Each moment is a weighted-PCA GP (n_components = 16, n_restarts = 10) under the per-moment transform above (log for positive moments, arcsinh for signed) — the transform is what holds the high-order moments at the noise floor. Every emulator carries a frozen-seed ε de-bias correction built on the 13-bin columns (vel_fine_seed_debias.py).

The honest per-emulator numbers (in-sample and interior corner-excluded LOO χ) live in the manifest: reg.entry("vel_c20", gravity, 0.25)["accuracy"]. The end-to-end acceptance test is the aggregated recipe at the 5-box fiducial: χ 0.46–0.94 (ΛCDM) and 0.80–1.81 (f(R), all 8 moments; the maximum is the fourth-order c04 — the signal-weighted infill repaired the formerly-worst c02, and the 2026-07-15 admission slotted c12 in at 0.99–1.13). Against fiducial boxes that do not share the design's random seeds, the shipped emulators read χ 0.43–0.72 (ΛCDM holdout boxes 19–30) and 1.1–2.3 (f(R), 25 boxes on 2.2× tighter error bars) — with the correction off those jump to 1.9–2.8 / 2.5–4.3 and become 68–94% coherent, which is the shared-seed offset the correction removes (evidence: registration_widea/vel_indepseed_oos.json).

χ, not fractional error

Velocity moments cross zero, so fractional error is meaningless. Accuracy is quoted as χ = residual / SEM; χ < 1 means at or below the simulation noise floor.

vel_binned — arbitrary mass bins

The trained surfaces live on the 13-bin grid; vel_binned aggregates all eight moments onto your mass bins through the exact raw-moment pair-count algebra (weights n_a n_b (1 + ξ_hh^ab(r)) modelled from the hmf + bias/ξ emulators; weight-model error vs measured pair counts: median 2–6×10⁻⁴):

res = reg.predict("vel_binned", "LCDM", 0.25, th,
                  mass_edges=[12.5, 13.0, 13.5],   # each edge ON the 13-bin grid
                  moments=("m10", "c20"))
res["moments"]["m10"]    # (Nbin, Nbin, 37); res["r"], res["validity"]

Edges must be built from whole fine-grid cells — whole-bin aggregation is what keeps the conversion exact.

f(R) — all 8 moments

The f(R) velocity moments are registered (z = 0.25) for all eight moments, as seed-paired boosts composed onto the ΛCDM emulator: log-ratio for the positive 4th moments (c40, c04, c22), additive-arcsinh for c20/c02/c12/c30; m10 uses the direct 5-parameter GP. The per-box seed-paired difference cancels most of the cosmic variance.

vel_c12/fRn1 was the late arrival (registered 2026-07-15): its first boost — fitted on the retired 72-bin narrow grid with a noise-scaled transform — failed the aggregation acceptance test in 2026-07 and the moment shipped ΛCDM-only for two weeks. Re-tested on the current wide bins with the family's plain additive-arcsinh transform it passes every test: interior LOO χ = 1.51 (in-family), fiducial aggregation χ = 1.24 (ceiling 2.5), independent-seed 25-box aggregation χ = 1.53 with the seed correction on (family range 1.1–2.3). Until then the recipe returned NaN for f(R) c12; that behaviour survives only as a fallback if no f(R) vel_c12 resolves from the registry.

f(R) is intrinsically harder (a fifth parameter over the same design points): at the wide binning the boosts' design-interior LOO sits at χ ≈ 1.3–1.9 (at the retired narrow binning the noisy fourth moments ran up to χ ≈ 7) — a design-sampling limit (the direct GP is worse), not a representation failure. The five signal-weighted supplemental pairs (imodel 68–72) now train the c02, c20 and c12 boosts (interior LOO 2.03→1.57, 1.89→1.59, and 1.51 for the newly admitted c12); the other four f(R) moments keep design-only training — augmenting them tests worse (blanket augmentation would take m10 from χ 1.43 to 2.58). All ΛCDM moments train on the augmented set. See f(R) gravity.

Rejected levers (don't re-explore)

Established on the campaign-era measurements (scripts now in git history):

  • Standardized moments (kurtosis c40/c20², etc.): the dimensionless ratio cancels ~4× of the across-box variance, but reconstructing the raw moment re-injects it — no deployable gain for the raw moments.
  • r_max trimming: trimming the large-r tail makes LOO χ worse for every moment; the full r-range carries signal and the SEM-weighted PCA already down-weights the noisy columns. (Bin-width choices, by contrast, paid off twice: the first exploration replaced the linear 2.5 Mpc/h grid, which lost 2–23× the noise floor below r = 10, with a quasi-log one; the second, 2026-07, widened it to the current 37 bins.)

Evidence scripts

vel_fine_lcdm_eval.py, vel_fine_frn1_eval.py, vel_fine_recon_gate.py, vel_rbin_explore.py, vel_rwidth_explore.py, vel_widea_vs_logb_fiducial.py, vel_frn1_indepseed_oos.py, vel_fine_seed_debias.py, vel_fine_register.py, plot_velocity_fine.py. (The retired 0.5-dex-era scripts — vel_validation.py, velocity_ablation.py, plot_velocity.py, … — live in git history.)