mixle.stats.univariate.continuous.exgaussian module

Exponentially-modified Gaussian distributions over real values.

Observations are real-valued floats. The EMG models X = N(mu, sigma2) + Exp(rate=lam) – a Gaussian

convolved with a positive-shifting exponential, giving a right-skewed density. Its stable log-density is

log f(x) = log(lam/2) - 0.5*u^2 + log(erfcx(z)),

where u = (x - mu)/sigma and z = (lam*sigma - u)/sqrt(2) and sigma = sqrt(sigma2). Using log_erfcx keeps the right tail (large z) from underflowing.

The MLE has no closed form (the score equations couple mu, sigma2, lam), so the estimator uses a method-of-moments fit from the accumulated first three moments, which is consistent and the usual practical choice for the EMG.

class ExponentiallyModifiedGaussianDistribution(mu, sigma2, lam, name=None, keys=None)[source]

Bases: SequenceEncodableProbabilityDistribution

Exponentially-modified Gaussian: X = N(mu, sigma2) + Exp(rate=lam).

Parameters:
density(x)[source]

Density of the EMG at observation x (see log_density).

Parameters:

x (float)

Return type:

float

log_density(x)[source]

Stable log-density of the EMG at x.

log f(x) = log(lam/2) - 0.5*u^2 + log_erfcx(z) with u = (x - mu)/sigma and z = (lam*sigma - u)/sqrt(2).

Parameters:

x (float)

Return type:

float

seq_ld_lambda()[source]

Return vectorized log-density callables for encoded data.

Return type:

list[Callable]

seq_log_density(x)[source]

Vectorized EMG log-density at sequence-encoded input x.

Parameters:

x (ndarray)

Return type:

ndarray

classmethod compute_capabilities()[source]

Declare NumPy/Torch scoring capabilities for EMG log-density kernels.

backend_seq_log_density(x, engine)[source]

Engine-neutral vectorized EMG log-density for encoded data.

Parameters:
Return type:

Any

cdf(x)[source]

Cumulative distribution function P(X <= x) (exact, via scipy’s exponnorm).

Parameters:

x (float)

Return type:

float

quantile(q)[source]

Inverse CDF F^{-1}(q).

Parameters:

q (float)

Return type:

float

sampler(seed=None)[source]

Return an ExponentiallyModifiedGaussianSampler for this distribution.

Parameters:

seed (int | None)

Return type:

ExponentiallyModifiedGaussianSampler

estimator(pseudo_count=None)[source]

Return an ExponentiallyModifiedGaussianEstimator (method-of-moments).

Parameters:

pseudo_count (float | None)

Return type:

ExponentiallyModifiedGaussianEstimator

dist_to_encoder()[source]

Return the encoder for exponentially modified Gaussian observations.

Return type:

ExponentiallyModifiedGaussianDataEncoder

class ExponentiallyModifiedGaussianSampler(dist, seed=None)[source]

Bases: DistributionSampler

Sample an EMG by adding independent Gaussian and exponential draws.

Parameters:
  • dist (ExponentiallyModifiedGaussianDistribution)

  • seed (int | None)

sample(size=None, *, batched=True)[source]

Draw size iid EMG samples (a single float if size is None).

Parameters:
Return type:

float | ndarray

class ExponentiallyModifiedGaussianAccumulator(keys=None, name=None)[source]

Bases: SequenceEncodableStatisticAccumulator

Accumulate weighted central moments for method-of-moments EMG estimation.

Parameters:
  • keys (str | None)

  • name (str | None)

update(x, weight, estimate)[source]

Update weighted central moments from one observation.

Parameters:
  • x (float)

  • weight (float)

  • estimate (ExponentiallyModifiedGaussianDistribution | None)

Return type:

None

initialize(x, weight, rng)[source]

Initialize weighted central moments from one observation.

Parameters:
Return type:

None

seq_initialize(x, weights, rng)[source]

Initialize weighted central moments from encoded observations.

Parameters:
Return type:

None

seq_update(x, weights, estimate)[source]

Update weighted central moments from encoded observations.

Centering the batch on its own mean removes the E[x^2]-E[x]^2 cancellation, but a SINGLE centering pass does not remove all of it: the computed mean carries the rounding of a large-magnitude sum, and that residue enters the third moment linearly – which is the moment lam is inverted from, so the fitted rate drifted at large data offsets. The second pass in centered_batch_moments() computes the residue at spread scale, where it is exact, and makes the fit shift-equivariant.

Parameters:
  • x (ndarray)

  • weights (ndarray)

  • estimate (ExponentiallyModifiedGaussianDistribution | None)

Return type:

None

combine(suff_stat)[source]

Merge another accumulator’s central-moment summary.

Parameters:

suff_stat (tuple[float, float, float, float])

Return type:

ExponentiallyModifiedGaussianAccumulator

value()[source]

Return count, mean, second central moment, and third central moment.

Return type:

tuple[float, float, float, float]

from_value(x)[source]

Restore count and central-moment state from value output.

Parameters:

x (tuple[float, float, float, float])

Return type:

ExponentiallyModifiedGaussianAccumulator

scale(c)[source]

Scale the weighted moment summary by a constant.

Parameters:

c (float)

Return type:

ExponentiallyModifiedGaussianAccumulator

acc_to_encoder()[source]

Return the encoder compatible with EMG moment statistics.

Return type:

ExponentiallyModifiedGaussianDataEncoder

class ExponentiallyModifiedGaussianAccumulatorFactory(name=None, keys=None)[source]

Bases: StatisticAccumulatorFactory

Create EMG central-moment accumulators.

Parameters:
  • name (str | None)

  • keys (str | None)

make()[source]

Create an empty EMG accumulator.

Return type:

ExponentiallyModifiedGaussianAccumulator

class ExponentiallyModifiedGaussianEstimator(name=None, keys=None)[source]

Bases: ParameterEstimator

Estimate EMG parameters from weighted central moments.

The fit is SHIFT-EQUIVARIANT: estimating on x + c returns mu + c with sigma2 and lam unchanged, for any constant c the data can carry – epoch seconds (~1.7e9), 2**31 and 1e12 included. The moments come from ExponentiallyModifiedGaussianAccumulator, which centers each batch twice for exactly this reason; a single centering pass moved the fit by 1.3e-4 at 1e12, silently.

Parameters:
  • name (str | None)

  • keys (str | None)

accumulator_factory()[source]

Return a factory for EMG central-moment accumulators.

Return type:

ExponentiallyModifiedGaussianAccumulatorFactory

estimate(nobs, suff_stat)[source]

Estimate an EMG from the accumulated (count, mean, M2, M3) via method of moments.

Parameters:
Return type:

ExponentiallyModifiedGaussianDistribution

class ExponentiallyModifiedGaussianDataEncoder[source]

Bases: DataSequenceEncoder

Encode sequences of iid EMG observations (data type float).

seq_encode(x)[source]

Validate and encode EMG observations as a finite float array.

Parameters:

x (list[float] | ndarray)

Return type:

ndarray