EnergyFlow.jl

Energy Mover's Distance for collider events in Julia.

EnergyFlow.jl computes the Energy Mover's Distance (EMD) between collider events, with multiple exact and approximate solver backends and a flexible choice of ground metrics. It is a Julia alternative to the Python EnergyFlow package.

The EMD (Komiske, Metodiev, Thaler, 2019) views each event as a distribution of energy over a metric space and measures the minimum "work" — energy times distance — needed to rearrange one event into the other. Its balanced transport term is

\[\mathrm{EMD}_{\beta,R}(\mathcal{E}_0, \mathcal{E}_1) = \min_{f_{ij} \ge 0} \sum_{ij} f_{ij} \left(\frac{d_{ij}}{R}\right)^{\beta}\]

subject to transport constraints, where $f_{ij}$ is the energy transported from particle $i$ to particle $j$ and $d_{ij}$ is their ground distance. For unnormalized events with unequal total weight, EnergyFlow.jl adds a unit-cost fictitious particle to balance the transport problem.

Highlights

Installation

Requires Julia 1.9 or later. Install EnergyFlow.jl from Julia's General registry:

using Pkg
Pkg.add("EnergyFlow")

Quick Start

using EnergyFlow

# Events are M×3 matrices: one row per particle, columns [pT, y, φ]
ev0 = [1.0  0.5  0.1;
       0.8 -0.3  0.4;
       0.6  0.1 -0.2]

ev1 = [0.9  0.4  0.0;
       0.7 -0.2  0.3]

# Single-pair EMD. EtaPhiMetric wraps the azimuthal coordinate.
val = emd(ev0, ev1;
          R=1.0, beta=1.0, norm=true, metric=EtaPhiMetric())

# Cross-pairwise: a 1×1 matrix
D = emds([ev0], [ev1]; norm=true, metric=EtaPhiMetric())

# Self-pairwise: flat upper-triangular vector of length n*(n-1)/2
dists = emds([ev0, ev1]; norm=true, metric=EtaPhiMetric())

Where to go next

Citing

The EMD was introduced in:

P. T. Komiske, E. M. Metodiev, J. Thaler, The Metric Space of Collider Events, Phys. Rev. Lett. 123, 041801 (2019), arXiv:1902.02346.

See the repository's CITATION.cff for how to cite this package.