EHY simplex-uniformity test#
Public verdict: validated and exposed as pysht.simplex.ehy_uniformity.
It is a pySHT-native addition with no SHT 0.1.9 crosswalk entry.
Geometry and statistic#
For \(D\) compositional components the simplex is a flat \(m=D-1\) dimensional manifold embedded in \(\mathbb R^D\). Ambient Euclidean distance equals its intrinsic flat distance, its Hausdorff volume is \(\sqrt D/(D-1)!\), and its uniform density is \(f_0=(D-1)!/\sqrt D\). Consequently EHY equations (1) and (4) become
The null is uniformity with respect to simplex volume. The parameter domain is \(\alpha>0\), \(\alpha\ne1\), and \(1\le J<n\). Boundary compositions are part of the closed simplex and are allowed. All first \(J\) neighbor contributions are summed. Rejection is lower-tail for \(0<\alpha<1\) and upper-tail for \(\alpha>1\), following Theorem 1 and its remarks in Ebner, Henze, and Yukich (2018).
Calibration and checks#
The null simulator draws Dirichlet(1, ..., 1) samples, which are exactly
uniform with respect to simplex volume. There are no fitted nuisance
parameters. The public stream consumes \(nD\) gamma/exponential-derived
Dirichlet values per replicate from the supplied NumPy generator, after the
observed statistic; the precise low-level variate consumption is NumPy’s
documented Generator.dirichlet stream and is replayed through that public
method rather than assumed from a gamma implementation. Corrected Monte Carlo
\(p=(b+1)/(B+1)\) and uncertainty fields are reported.
An independent direct-distance formula verifies the Hausdorff-density factor and every first-\(J\) term. Tests cover row and common component permutations, closed-boundary values, duplicates, both tails, stream replay, and the 9,999 draw performance budget.
Complexity#
With \(n\) rows and \(D\) components, one statistic costs \(O(n^2D)\) time. The distance matrix uses \(O(n^2)\) storage and the row-at-a-time distance workspace uses \(O(nD)\), so a \(B\)-draw calibration costs \(O(Bn^2D)\) time and \(O(n^2+nD)\) peak storage rather than storage proportional to \(B\).
Release evidence#
At \((n,D,J)=(25,3,2)\), each independent 20,000-dataset stream was compared with its own independently seeded 99,999-statistic reference bank:
\(\alpha\) |
reference seed |
dataset seed |
0.01 |
0.05 |
0.10 |
|---|---|---|---|---|---|
0.5 |
20260914 |
20260915 |
200 (0.01000) |
971 (0.04855) |
1,944 (0.09720) |
0.5 |
20260932 |
20260916 |
188 (0.00940) |
943 (0.04715) |
1,955 (0.09775) |
2.0 |
20260914 |
20260915 |
227 (0.01135) |
1,071 (0.05355) |
2,003 (0.10015) |
2.0 |
20260932 |
20260916 |
200 (0.01000) |
942 (0.04710) |
1,927 (0.09635) |
Every cell passes the release tolerance. Because all observed datasets in one
stream share a finite reference bank, the tolerance is
\(\max\{0.005,4\sqrt{a(1-a)(1/20000+1/99999)}\}\) at nominal level \(a\) and
includes both dataset and reference-quantile uncertainty. Seed 20260926 generated 2,000
size-40 Dirichlet(50,50,50) alternatives; with \(\alpha=0.5\), \(J=1\), and a
19,999-statistic null bank from seed 20260925, 2,000/2,000 rejected at 0.05.
This is a named concentration-alternative check only.
The table uses empirical reference banks rather than 20,000 literal public
9,999-draw calls. Separate fixtures replay Generator.dirichlet, the selected
tail, tie handling, and corrected public p-value exactly.