mixle.utils.special module¶
Defines the log-pseudo-determinant, polgamma, trigamma, and digamma inverse functions.
This module is the canonical home for mixle’s hand-rolled stable-math helpers (log_erfcx,
trigamma, digammainv, log1mexp, logsubexp, logsumexp, softmax,
softmax_rows, valid_integer). Import from here rather than re-implementing privately so
the numerically-careful versions stay in one place.
- log_erfcx(x, out=None)[source]
Stable natural log of the scaled complementary error function
log(erfcx(x)).erfcx(x) = exp(x**2) * erfc(x)is the scaled complementary error function, the workhorse of the exponentially-modified-Gaussian tail. A naivelog(erfcx(x))blows up at both ends: for large positivexit underflows (erfcx -> 0solog -> -inf) and for large negativexit overflows (theexp(x**2)factor inerfcx->infsolog -> inf). Three branches keep it finite and accurate everywhere:large positive
x: the asymptotic serieserfcx(x) ~ 1/(x*sqrt(pi)) * (1 - 1/(2 x^2) + 3/(4 x^4) - ...), in log space;large negative
x:log(erfcx(x)) = x**2 + log(erfc(x))witherfc(x) -> 2finite, so no overflow;moderate
x: the directlog(erfcx(x)).
The branches match
log(erfcx)to machine precision on their overlaps. This is what keeps the EMG tail from underflowing/overflowing.
- stirling2(n, k)[source]
Stirling number of the second kind S(n, k).
Counts the number of ways to partition n labeled objects into k non-empty unlabeled subsets. Computed with the standard recurrence S(n, k) = k*S(n-1, k) + S(n-1, k-1) using exact integer arithmetic.
- logpdet(x_mat)[source]
Computes the log-pseudo-determinant for a symmetric dense matrix.
- Parameters:
x_mat (np.ndarray) – 2-d Numpy array representing a matrix.
- Returns:
float, log-pseudo-determinant.
- Return type:
- trigamma(y, out=None)[source]
Trigamma function.
- digammainv(y)[source]
Inverse digamma function evaluated on y.
- log1mexp(x)[source]
Return
log(1 - exp(x))forx <= 0, stable across the whole range.Uses the two-regime split (Mächler, “Accurately Computing log(1 - exp(-|a|))”):
log(-expm1(x))whenexp(x)is small andlog1p(-exp(x))when it is close to 1, so1 - exp(x)is never formed by a catastrophically cancelling subtraction. Returns-infforx >= 0(where1 - exp(x) <= 0).
- logsubexp(log_hi, log_lo)[source]
Return
log(exp(log_hi) - exp(log_lo))forlog_hi >= log_lo, computed stably.Evaluates
log_hi + log1mexp(log_lo - log_hi)so a far-tail difference whose two operands are individually indistinguishable from 0 (or 1) in probability space still returns a finite large-negative log-mass instead oflog(0) = -inf. Returns-infwhen the difference is non-positive (log_hi <= log_lo).
- logsumexp(a, axis=None)[source]
Stable
log(sum(exp(a)))via the max-shift trick.Thin wrapper over
scipy.special.logsumexp()providing mixle’s canonical scalar/array fallback. Theaxis=None(full reduction) result is returned as a Pythonfloatto match the private re-implementations this replaces; a reduced array is returned otherwise. Empty input reduces to-infand a non-finite running max propagates (+infstays+inf).
- softmax(log_scores, axis=-1)[source]
Numerically stable softmax of
log_scoresalongaxis, with an all--infguard.Subtracts the per-slice maximum before exponentiating. A slice that is entirely
-inf(no finite log-score) has no defined softmax and would otherwise yieldnan; it is filled with a uniform distribution1 / nover that axis instead.
- softmax_rows(log_scores)[source]
Row-wise (
axis=1) softmax of a(B, K)log-score matrix, with an all--infguard.Convenience wrapper for
softmax()withaxis=1: a row that is entirely-infis replaced by the uniform distribution1 / Kinstead of yieldingnan.
- valid_integer(x, *, nonneg=False)[source]
Return whether
xis a finite (optionally non-negative) integer value.Coerces
xtofloatand checks it is finite and integer-valued (floor(x) == x). Any coercion failure returnsFalse. Withnonneg=Truethe value must additionally be>= 0.