mixle.stats.directional.wrapped_cauchy module

Wrapped Cauchy distribution – a heavy-tailed circular law on angles.

Wrapping a Cauchy around the circle gives the wrapped Cauchy, the circular analogue of the Cauchy and a heavier-tailed alternative to the von Mises. With mean direction mu and mean-resultant length rho in [0, 1),

f(theta; mu, rho) = (1 - rho^2) / (2 pi (1 + rho^2 - 2 rho cos(theta - mu))),

uniform on the circle at rho = 0 and increasingly peaked at mu as rho -> 1. Its first trigonometric moment is exactly rho e^{i mu}, so the mean direction and concentration are estimated in closed form from the mean resultant (the circular analogue of the sample mean). It samples exactly: rho corresponds to wrapping a Cauchy of scale gamma = -log rho.

Reference: Mardia & Jupp, Directional Statistics (Wiley, 2000).

class WrappedCauchyDistribution(mu, rho, name=None, keys=None)[source]

Bases: SequenceEncodableProbabilityDistribution

Wrapped Cauchy distribution with mean direction mu and concentration rho in [0, 1).

Parameters:
density(x)[source]

Return the probability density at a single angle (radians).

Parameters:

x (float)

Return type:

float

log_density(x)[source]

Return the log-density at a single angle (radians).

Parameters:

x (float)

Return type:

float

seq_log_density(x)[source]

Return vectorized log-density values for sequence-encoded (cos, sin) observations.

Parameters:

x (tuple[ndarray, ndarray])

Return type:

ndarray

classmethod compute_capabilities()[source]
classmethod compute_declaration()[source]
static backend_legacy_sufficient_statistics(x, params, engine)[source]

Per-row circular moments in accumulator order (sum_cos, sum_sin, count).

Parameters:
Return type:

tuple[Any, …]

static backend_log_density_from_params(cos_t, sin_t, cos_mu, sin_mu, rho, engine)[source]

Engine-neutral wrapped-Cauchy log-density from pre-computed observation/parameter trig.

Parameters:
Return type:

Any

backend_seq_log_density(x, engine)[source]

Engine-neutral vectorized log-density for encoded (cos, sin) data.

Parameters:
Return type:

Any

classmethod backend_stacked_params(dists, engine)[source]

Stacked wrapped-Cauchy parameters (trig computed host-side) for a homogeneous mixture kernel.

Parameters:
  • dists (Sequence[WrappedCauchyDistribution])

  • engine (Any)

Return type:

dict[str, Any]

classmethod backend_stacked_log_density(x, params, engine)[source]

Return an (n, k) matrix of wrapped-Cauchy log densities.

Parameters:
Return type:

Any

classmethod backend_stacked_sufficient_statistics(x, weights, params, engine)[source]

Stacked circular moments (sum_cos, sum_sin, count) using engine-resident arrays.

Parameters:
Return type:

tuple[Any, Any, Any]

sampler(seed=None)[source]

Return a sampler for drawing angles from this distribution.

Parameters:

seed (int | None)

Return type:

WrappedCauchySampler

estimator(pseudo_count=None)[source]

Return a closed-form (mean-resultant) estimator for mu and rho.

Parameters:

pseudo_count (float | None)

Return type:

WrappedCauchyEstimator

dist_to_encoder()[source]

Return the data encoder used by this distribution (cos/sin of the angle).

Return type:

WrappedCauchyDataEncoder

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

Bases: DistributionSampler

Draw angles by wrapping a Cauchy of scale -log rho around the circle.

Parameters:
  • dist (WrappedCauchyDistribution)

  • seed (int | None)

sample(size=None)[source]

Draw observations.

Combinator samplers (mixture/sequence/…) accept batched. With batched=True (the default) each child stream is drawn in one vectorized call instead of a per-draw Python loop – far faster. Because every child sampler owns an independent RandomState, batching consumes each stream in the same order as the loop, so the draws are identical to the legacy path. batched=False forces that legacy per-draw loop as a guaranteed- stable reference. Leaf samplers are already vectorized and ignore the flag.

Parameters:

size (int | None)

Return type:

float | ndarray

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

Bases: SequenceEncodableStatisticAccumulator

Accumulate the weighted circular resultant (sum cos, sum sin, count).

Parameters:
  • name (str | None)

  • keys (str | None)

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

  • weight (float)

  • estimate (WrappedCauchyDistribution | None)

Return type:

None

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

None

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

None

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

None

combine(suff_stat)[source]
Parameters:

suff_stat (tuple[float, float, float])

Return type:

WrappedCauchyAccumulator

value()[source]
Return type:

tuple[float, float, float]

from_value(x)[source]
Parameters:

x (tuple[float, float, float])

Return type:

WrappedCauchyAccumulator

key_merge(stats_dict)[source]

Pool this accumulator’s statistics into stats_dict under its merge key.

The structural default implements the common single-key pattern: store the accumulator under self.keys the first time the key is seen, else combine into the one already there. Accumulators with several named keys (e.g. an HMM’s init/trans/state keys) or a non-accumulator stats payload override this. A keys of None (the default) is a no-op.

Parameters:

stats_dict (dict[str, Any])

Return type:

None

key_replace(stats_dict)[source]

Replace this accumulator’s statistics from the pooled stats_dict entry (see key_merge).

Parameters:

stats_dict (dict[str, Any])

Return type:

None

acc_to_encoder()[source]
Return type:

WrappedCauchyDataEncoder

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

Bases: StatisticAccumulatorFactory

Factory for WrappedCauchyAccumulator.

Parameters:
  • name (str | None)

  • keys (str | None)

make()[source]
Return type:

WrappedCauchyAccumulator

class WrappedCauchyEstimator(rho_max=1.0 - 1.0e-8, name=None, keys=None)[source]

Bases: ParameterEstimator

Estimate mu and rho from the mean resultant (the first trigonometric moment).

Parameters:
accumulator_factory()[source]
Return type:

WrappedCauchyAccumulatorFactory

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

WrappedCauchyDistribution

class WrappedCauchyDataEncoder[source]

Bases: DataSequenceEncoder

Encode angles as their cosine and sine.

seq_encode(x)[source]

Encode the iid observation sequence x for vectorized evaluation.

Parameters:

x (Sequence[float])

Return type:

tuple[ndarray, ndarray]