mixle.stats.combinator.exponential_tilt module

Exponential-tilting combinator: reweight a base distribution by exp(theta . T(x)).

ExponentialTiltedDistribution wraps a base distribution and applies an exponential change of measure (an Esscher transform):

p_theta(x) = exp(theta . T(x)) * p_base(x) / Z(theta), Z(theta) = E_base[exp(theta . T(X))],

where T is a sufficient statistic and Z(theta) the moment/cumulant generating function. This single operation covers several classic use cases:

  • general tilt – an arbitrary statistic T (default identity T(x) = x);

  • tempering / powerT(x) = log p_base(x) gives p_theta ~ p_base^{1+theta} (annealed importance sampling, parallel tempering);

  • Esscher / MGF tilt – continuous exponential-family bases (Gaussian, Gamma, …) whose Z(theta) is closed form (rare-event importance sampling, actuarial pricing).

The normalizer Z(theta) is resolved in three ways, in order: an explicit user log_normalizer (the CGF); a registered analytic tilt for the base family (identity statistic only – these also yield the exact in-family tilted distribution, so sampling is exact); otherwise exact enumeration Z = sum_a p(a) exp(theta . T(a)) for an enumerable base. It pairs with the support tools (the tilted normalizer is the same sum the enumeration bounds reason about) and sits beside TruncatedDistribution – truncation is the degenerate tilt whose statistic is a {0, -inf} indicator.

class TiltResult(log_normalizer, closed_form=None)[source]

Bases: object

Result of resolving the tilt normalizer: log Z(theta) and, when the tilt closes in the base family, the exact tilted distribution (same family) for exact sampling.

Parameters:
  • log_normalizer (float)

  • closed_form (SequenceEncodableProbabilityDistribution | None)

log_normalizer: float
closed_form: SequenceEncodableProbabilityDistribution | None = None
register_exponential_tilt(dist_type, fn)[source]

Register an analytic identity-statistic tilt fn(base, theta) -> TiltResult for dist_type.

Parameters:
Return type:

None

registered_tilt_families()[source]

Return the names of base families with a registered analytic tilt.

Return type:

list[str]

tilt_log_normalizer(base, theta, statistic_kind, statistic_fn, user_normalizer)[source]

Resolve log Z(theta) (and any closed-form tilted distribution) for a base + statistic.

Resolution order: explicit user_normalizer -> registered analytic tilt (identity statistic only) -> exact enumeration over an enumerable base. Raises if none applies.

Parameters:
Return type:

TiltResult

class ExponentialTiltedDistribution(base, theta, statistic=None, log_normalizer=None, name=None, keys=None)[source]

Bases: SequenceEncodableProbabilityDistribution

A base distribution reweighted by exp(theta . T(x)) and renormalized by Z(theta).

Parameters:
density(x)[source]

Return the tilted probability/density at x.

Parameters:

x (Any)

Return type:

float

log_density(x)[source]

Return log p_base(x) + theta . T(x) - log Z.

Parameters:

x (Any)

Return type:

float

seq_log_density(x)[source]

Return per-row tilted log-densities for an encoded batch.

Parameters:

x (tuple[Any, ndarray])

Return type:

ndarray

closed_form()[source]

Return the in-family tilted distribution when the tilt closes in the base family, else None.

Return type:

SequenceEncodableProbabilityDistribution | None

sampler(seed=None)[source]

Return a sampler (exact for registered/enumerable bases; SIR otherwise).

Parameters:

seed (int | None)

Return type:

ExponentialTiltedSampler

estimator(pseudo_count=None, fit='theta')[source]

Return an estimator. fit='theta' fits the tilt by the exponential-family score equation E_theta[T] = mean(T(data)) (base + statistic fixed); fit='base' holds theta fixed and refits the base on the data, re-tilting (the fixed-tilt analogue of the truncation estimator).

Parameters:
Return type:

ExponentialTiltedEstimator

dist_to_encoder()[source]

Return the data encoder (base encoding plus the precomputed statistic per row).

Return type:

ExponentialTiltedDataEncoder

support_size()[source]

Tilting preserves the support, so the cardinality is the base’s.

Return type:

int | None

enumerator()[source]

Enumerate the support in descending tilted-probability order.

Return type:

ExponentialTiltedEnumerator

class ExponentialTiltedEnumerator(dist)[source]

Bases: DistributionEnumerator

Reweight the base enumeration by theta . T(a) - log Z and re-sort descending.

Parameters:

dist (ExponentialTiltedDistribution)

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

Bases: DistributionSampler

Sample the tilted distribution: exact via the closed-form / enumerated tilted pmf, else SIR.

Parameters:
  • dist (ExponentialTiltedDistribution)

  • seed (int | None)

sample(size=None)[source]

Draw one tilted value (or a list of size).

Parameters:

size (int | None)

class ExponentialTiltedAccumulator(dim, base_accumulator, keys=None)[source]

Bases: SingleChildAccumulator

Accumulate the count and the weighted sum of the statistic T (the exp-family score data).

Carries extra scalar statistics (sum_t, count) alongside the bare child value, so it overrides the delegation trio; only key_merge/key_replace (which forward to the child) are inherited.

Parameters:
  • dim (int)

  • base_accumulator (SequenceEncodableStatisticAccumulator)

  • keys (str | None)

update(x, weight, estimate)[source]
Parameters:
  • x (Any)

  • weight (float)

  • estimate (ExponentialTiltedDistribution | None)

Return type:

None

seq_update(x, weights, estimate)[source]
Parameters:
Return type:

None

initialize(x, weight, rng)[source]
Parameters:
Return type:

None

seq_initialize(x, weights, rng)[source]
Parameters:
Return type:

None

combine(suff_stat)[source]
Parameters:

suff_stat (Any)

Return type:

ExponentialTiltedAccumulator

value()[source]
Return type:

Any

from_value(x)[source]
Parameters:

x (Any)

Return type:

ExponentialTiltedAccumulator

scale(c)[source]

Scale linear sufficient statistics in-place by c.

The structural default is correct for ordinary weighted sums, nested tuples/lists/dicts, and numeric arrays. Families whose value() payload includes non-linear metadata such as support bounds must override this method and leave that metadata unscaled.

Parameters:

c (float)

Return type:

ExponentialTiltedAccumulator

acc_to_encoder()[source]
Return type:

DataSequenceEncoder

class ExponentialTiltedAccumulatorFactory(dim, base_factory, keys=None)[source]

Bases: StatisticAccumulatorFactory

Factory for ExponentialTiltedAccumulator.

Parameters:
  • dim (int)

  • base_factory (StatisticAccumulatorFactory)

  • keys (str | None)

make()[source]
Return type:

ExponentialTiltedAccumulator

class ExponentialTiltedEstimator(prototype, pseudo_count=None, fit='theta', max_iter=60, tol=1e-8)[source]

Bases: ParameterEstimator

Fit the tilt by the exp-family score equation (fit='theta') or refit the base (fit='base').

Parameters:
  • prototype (ExponentialTiltedDistribution)

  • pseudo_count (float | None)

  • fit (str)

  • max_iter (int)

  • tol (float)

accumulator_factory()[source]
Return type:

ExponentialTiltedAccumulatorFactory

estimate(nobs, suff_stat)[source]
Parameters:
Return type:

ExponentialTiltedDistribution

class ExponentialTiltedDataEncoder(dist)[source]

Bases: MaskedBaseEncoder

Encode observations via the base encoder, plus the precomputed statistic T per row.

Parameters:

dist (ExponentialTiltedDistribution)