Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Homogeneous Spatiotemporal Poisson Process — From Scratch and With NumPyro

Open In Colab

A homogeneous spatiotemporal Poisson process on D×[t0,t1)D \times [t_0, t_1) with intensity λ>0\lambda > 0 has count N∼Poisson(λ ∣D∣ (t1−t0))N \sim \mathrm{Poisson}(\lambda \,|D|\,(t_1-t_0)), conditional events i.i.d. uniform on the slab, and Janossy log-likelihood log⁡L=nlog⁡λ−λ∣D∣(t1−t0)\log L = n \log \lambda - \lambda |D| (t_1 - t_0). It is the natural null model in space-time statistics: deviations from this — clusters, pulses, drifts — are what the inhomogeneous and Hawkes-style models in xtremax exist to capture.

This notebook walks through both layers of xtremax for the spatiotemporal HPP.

  1. From scratch — pure-JAX primitives (hpp_spatiotemporal_log_prob, hpp_spatiotemporal_sample).

  2. With NumPyro — wrap the same process as a numpyro.distributions.Distribution and recover λ\lambda via NUTS.

Setup

/home/azureuser/localfiles/xtremax/.venv/bin/python: No module named pip
Note: you may need to restart the kernel to use updated packages.
/home/azureuser/localfiles/xtremax/.venv/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

1. From scratch — the primitives layer

Pick a 10×1010 \times 10 box in space, a 5-unit time window, and intensity λ=0.5\lambda = 0.5. Expected count is λ∣D∣T=0.5⋅100⋅5=250\lambda |D| T = 0.5 \cdot 100 \cdot 5 = 250.

Drew 226 events (uncapped Poisson was 226).
E[N] = λ |D| T = 250.0.

Visualise the realisation as a space-time scatter — colour encodes time so the temporal evolution is visible at a glance.

<Figure size 600x500 with 2 Axes>

Log-likelihood

The Janossy form drops the −log⁡(n!)-\log(n!) count normaliser and the iid-uniform −nlog⁡(∣D∣T)-n \log(|D| T) location density — same convention as the inhomogeneous spatiotemporal log-prob, so they compose.

log L = -406.651

2. With NumPyro — recover λ from a single realisation

We treat the count as the sufficient statistic for λ\lambda and run NUTS. Use a weakly-informative log-normal prior so the posterior reflects the data rather than the prior.

Observed n = 267
Posterior mean: 0.535, true: 0.5
Posterior 95% CI: [0.476, 0.593]
<Figure size 600x300 with 1 Axes>

The 95% CI tightens around the true rate as TT or ∣D∣|D| grows — the count alone determines λ\lambda via the Poisson sufficiency, and the posterior precision scales with λ∣D∣T\sqrt{\lambda |D| T}.