[7] Tests for Equality of Distributions#

pysht.equaldist tests equality of complete data-generating distributions, not only equality of a particular mean or covariance.

Function

Design

Statistic

Calibration

energy_ksamp

two or more samples

DISCO \(F_\alpha\)

exact/Monte Carlo label permutation

mmd_2samp

two samples

unbiased \(\mathrm{MMD}_u^2\)

exact/Monte Carlo label permutation

bg_2samp

two samples

Biswas–Ghosh distance contrast

exact/Monte Carlo label permutation

All inputs are Euclidean observations. One-dimensional arrays mean univariate samples; matrices use rows as observations. Permutation inference assumes the pooled observations are exchangeable under the null. It is not valid for paired, clustered, stratified, or serially dependent samples without a design- specific randomization scheme.

Exact calibration is invariant to Euclidean isometries. Fixed-seed Monte Carlo replay also holds when metric canonicalization completes within its fixed work budget and distance ranks are separated from their floating equality boundary. At that boundary, or when symmetric geometry exhausts the budget and triggers coordinate ordering, a rotation can select a different, still uniformly valid Monte Carlo plan. Use exact mode when transformation replay is essential and the orbit is tractable.

mmd_2samp deliberately accepts only the characteristic RBF and Laplacian kernels. The median heuristic, when selected, is computed once from strictly positive pooled distances and remains fixed for the observed and every permuted labeling.

Ball Divergence is not public in this release. Its mathematical closed-ball rule requires exact equality for equal radii, but ordinary Euclidean distance evaluation can split those ties after an isometry; a tolerance can instead merge genuinely distinct radii. The private research implementation remains blocked until that distinction has a correctness-certified solution.

import numpy as np
from pysht import equaldist

rng = np.random.default_rng(2026)
x = rng.normal(size=(30, 3))
y = rng.normal(loc=0.5, size=(35, 3))

result = equaldist.energy_ksamp(x, y, n_resamples=999, rng=17)
result.pvalue

See the new distribution-test validation ledger and the Biswas–Ghosh record.

Functions#

Tests for equality of probability distributions.

The public functions use exact or corrected Monte Carlo randomization. A private Ball Divergence research prototype is retained below, but is excluded from __all__ because floating-point equality of computed ball radii does not yet have a correctness-certified implementation.

pysht.equaldist.bg_2samp(x, y, *, calibration='permutation', n_resamples=9_999, rng=None)[source]#

Test whether two univariate or multivariate distributions are equal.

The Biswas-Ghosh statistic compares the average within-sample and between-sample Euclidean distances. Its permutation calibration is exact under exchangeability when all labelings are enumerated; this implementation uses Monte Carlo label permutations and the nonzero correction (exceedances + 1) / (n_resamples + 1).

Parameters:
x, y

Independent samples. One-dimensional inputs represent univariate data; two-dimensional inputs use rows for observations and columns for features. The samples must have the same number of features and at least two observations each.

calibration

"permutation" (the default) automatically enumerates all labelings when their count does not exceed n_resamples and otherwise uses Monte Carlo permutations. Use "exact" to require enumeration or "monte-carlo" to require sampling. No asymptotic selector is exposed because the legacy variance calculation is not row-order invariant.

n_resamples

Monte Carlo sample size and computational budget for exact enumeration. Must be a positive integer.

rng

None, an integer seed, or a numpy.random.Generator. Exact enumeration validates but does not consume the generator.

Returns
——-
DistanceTestResult

An immutable result whose string form follows R’s htest display.

Parameters:
  • x (ArrayLike)

  • y (ArrayLike)

  • calibration (str)

  • n_resamples (int)

  • rng (int | integer | Generator | None)

Return type:

DistanceTestResult

Notes

The permutation null requires exchangeability of the pooled observations. A fixed integer seed gives identical results after reordering rows or swapping the two samples. Coordinates are first centered at an overflow-safe per-feature midpoint, then coordinates and distances are divided by positive common scales. This preserves representable spacings around a huge common location, leaves the permutation ordering unchanged in exact arithmetic, and prevents scale-dependent overflow and underflow. result.statistic remains the raw statistic from the paper; the dimensionless value and maximum-distance scale are retained as result.normalized_statistic and result.distance_scale. The raw statistic may be zero or infinite when its scale lies outside float64, while the normalized calibration remains valid. Numerically tied permutation statistics are included in the upper tail using a relative tolerance of 100 double-precision epsilons. For Monte Carlo calibration, the reported standard error estimates the conditional standard deviation of the corrected estimator using q_hat = exceedances / B. A 95 percent Clopper–Pearson interval records uncertainty in the underlying permutation tail probability.

References

Biswas, M. and Ghosh, A. K. (2014). A nonparametric two-sample test applicable to high dimensional data. Journal of Multivariate Analysis, 123, 160-171. https://doi.org/10.1016/j.jmva.2013.09.004

pysht.equaldist.energy_ksamp(*samples, exponent=1.0, calibration='permutation', n_resamples=9_999, rng=None)[source]#

Perform the DISCO energy test for equality of two or more distributions.

The statistic is the distance-components pseudo-F ratio of Rizzo and Székely (2010), using Euclidean distance raised to exponent. Values strictly between zero and two characterize equality of distributions under the paper’s moment conditions. Calibration relabels the pooled observations while preserving every group size.

Parameters:
*samples

Two or more independent samples. One-dimensional inputs are treated as one-feature observations. Every sample must have at least two rows and all samples must have the same feature count.

exponent

Distance exponent in the open interval (0, 2).

calibration, n_resamples, rng

Exact or corrected Monte Carlo fixed-size label permutation controls.

Parameters:
  • samples (ArrayLike)

  • exponent (float)

  • calibration (Literal['permutation', 'exact', 'monte-carlo'])

  • n_resamples (int)

  • rng (int | integer | Generator | None)

Return type:

ResamplingTestResult

References

Rizzo, M. L. and Székely, G. J. (2010). DISCO analysis: A nonparametric extension of analysis of variance. Annals of Applied Statistics, 4, 1034–1055. https://doi.org/10.1214/09-AOAS245

pysht.equaldist.mmd_2samp(x, y, *, kernel='rbf', bandwidth='median', calibration='permutation', n_resamples=9_999, rng=None)[source]#

Perform a characteristic-kernel maximum mean discrepancy test.

pySHT reports the unequal-sample unbiased estimator MMD_u^2. The RBF or Laplacian Gram matrix, including a median-heuristic bandwidth when requested, is computed once from the pooled observations and held fixed across every label permutation.

References

Gretton, A., Borgwardt, K. M., Rasch, M. J., Schölkopf, B. and Smola, A. (2012). A kernel two-sample test. Journal of Machine Learning Research, 13, 723–773. https://jmlr.org/papers/v13/gretton12a.html

Parameters:
  • x (ArrayLike)

  • y (ArrayLike)

  • kernel (Literal['rbf', 'laplacian'])

  • bandwidth (str | float)

  • calibration (Literal['permutation', 'exact', 'monte-carlo'])

  • n_resamples (int)

  • rng (int | integer | Generator | None)

Return type:

ResamplingTestResult