mixle.stats.directional.von_mises module¶
Von Mises distributions for circular angular data.
Observations are angles in radians. A Von Mises distribution with mean direction mu and
concentration kappa >= 0 has log-density
log(f(theta; mu, kappa)) = kappa * cos(theta - mu) - log(2*pi*I_0(kappa)),
the circular analogue of a Gaussian (kappa = 0 is uniform on the circle; large kappa concentrates near
mu). This is the one-dimensional companion to von_mises_fisher (the von
Mises-Fisher distribution on a sphere).
Wrap-around semantics – read this before comparing scores across families. Any finite real x
is accepted and interpreted modulo 2*pi: only cos(x) and sin(x) ever enter the
density, the sufficient statistics, and the estimator, so x, x + 2*pi and x + 200*pi
are indistinguishable observations of the same angle. The density integrates to one over a single
period (-pi, pi], not over the real line – integrated over a wider interval it exceeds one.
Two consequences for non-angular data:
Fitting a real-line column (money, durations, counts) silently wraps it onto the circle; the fit is a valid circular density of
x mod 2*pibut says nothing aboutxitself.The log-density is not comparable to real-line families’ log-densities. A column spanning
kperiods overlays its mass onto one period, so the wrapped model can “win” a likelihood comparison against any real-line family by roughlylog(k)nats per observation without modeling the data at all. Compare von Mises scores only against other circular models, on data that is genuinely angular.
It is a two-parameter exponential family with sufficient statistics (cos theta, sin theta):
- log(f) = eta1*cos(theta) + eta2*sin(theta) + log_const,
eta1 = kappa*cos(mu), eta2 = kappa*sin(mu), log_const = -log(2*pi*I_0(kappa)).
The natural parameters and normalizer are precomputed (the Bessel term I_0 lives only in the scalar
log_const), so the per-row score is linear in the encoded cos/sin fields and lowers cleanly
to generated NumPy, Torch, and Numba kernels.
Reference: Mardia & Jupp, Directional Statistics (Wiley, 2000).
- exception VonMisesFitError[source]
Bases:
RuntimeErrorRaised when circular moments have no finite von Mises fit.
- class VonMisesDistribution(mu, kappa, name=None, keys=None)[source]
Bases:
SequenceEncodableProbabilityDistributionVon Mises distribution on the circle with mean direction mu and concentration kappa >= 0.
Observations are angles in radians, interpreted modulo
2*pi:log_density(x)equalslog_density(x + 2*pi*k)for every integerk, and the density normalizes over one period, not over the real line. Scores are therefore comparable only to other circular models – see the module docstring for why a wrapped fit of real-line data can spuriously out-score every real-line family.- classmethod compute_capabilities()[source]
Describe backend support for generated von Mises kernels.
- classmethod compute_declaration()[source]
Return the structured compute declaration for von Mises distributions.
- static backend_legacy_sufficient_statistics(x, params, engine)[source]
Return per-row (count, cos, sin) sufficient statistics in accumulator order.
- static exp_family_sufficient_statistics(x, engine)[source]
Return von Mises sufficient statistics
T(x) = (cos x, sin x).
- static exp_family_natural_parameters(params, engine)[source]
Return von Mises natural parameters
eta = (kappa cos mu, kappa sin mu).
- static exp_family_log_partition(params, engine)[source]
Return von Mises log partition
A = log(2 pi I_0(kappa)) = -log_const.
- static exp_family_from_natural(eta)[source]
Return the von Mises with natural parameters
eta = (kappa cos mu, kappa sin mu).- Parameters:
eta (Any)
- Return type:
VonMisesDistribution
- static backend_log_density_from_params(cos_t, sin_t, eta1, eta2, log_const, engine)[source]
Engine-neutral von Mises log-density from natural parameters (linear in cos/sin).
- density(x)[source]
Return the probability density at a single angle.
- log_density(x)[source]
Return the log-density at a single angle (radians), wrapping
xmodulo2*pi.Any finite real is accepted; values outside
(-pi, pi]are folded onto the circle, so this is the density ofx mod 2*pi, normalized over one period only.
- seq_log_density(x)[source]
Return vectorized log-density values for sequence-encoded (cos, sin) observations.
- backend_seq_log_density(x, engine)[source]
Engine-neutral vectorized log-density for encoded data.
- classmethod backend_stacked_params(dists, engine)[source]
Return stacked natural parameters for a homogeneous mixture kernel.
- classmethod backend_stacked_log_density(x, params, engine)[source]
Return an
(n, k)matrix of von Mises log densities.
- classmethod backend_stacked_sufficient_statistics(x, weights, params, engine)[source]
Return stacked sufficient statistics using engine-resident arrays.
- sampler(seed=None)[source]
Return a sampler for drawing angles from this distribution.
- Parameters:
seed (int | None)
- Return type:
VonMisesSampler
- estimator(pseudo_count=None)[source]
Return an estimator for fitting this distribution from data.
- Parameters:
pseudo_count (float | None)
- Return type:
VonMisesEstimator
- dist_to_encoder()[source]
Return the data encoder used by this distribution for vectorized methods.
- Return type:
VonMisesDataEncoder
- class VonMisesSampler(dist, seed=None)[source]
Bases:
DistributionSamplerDraw iid angles from a von Mises distribution.
- Parameters:
dist (VonMisesDistribution)
seed (int | None)
- class VonMisesAccumulator(name=None, keys=None)[source]
Bases:
SequenceEncodableStatisticAccumulatorAccumulate weighted count and circular moments (sum of cos / sin) for von Mises estimation.
- update(x, weight, estimate)[source]
Accumulate one weighted circular moment contribution.
- initialize(x, weight, rng)[source]
Initialize statistics from one angle.
- Parameters:
x (float)
weight (float)
rng (RandomState | None)
- Return type:
None
- seq_update(x, weights, estimate)[source]
Accumulate circular moments from encoded cos/sin values.
- seq_initialize(x, weights, rng)[source]
Initialize statistics from encoded angles.
- Parameters:
weights (ndarray)
rng (RandomState | None)
- Return type:
None
- combine(suff_stat)[source]
Merge another von Mises sufficient-statistic tuple.
- from_value(x)[source]
Replace accumulator contents from circular-moment statistics.
- scale(c)[source]
Scale linear von Mises sufficient statistics.
- Parameters:
c (float)
- Return type:
VonMisesAccumulator
- acc_to_encoder()[source]
Return the encoder used by this accumulator.
- Return type:
VonMisesDataEncoder
- class VonMisesAccumulatorFactory(name=None, keys=None)[source]
Bases:
StatisticAccumulatorFactoryFactory for VonMisesAccumulator.
- make()[source]
Create a fresh von Mises accumulator.
- Return type:
VonMisesAccumulator
- class VonMisesEstimator(pseudo_count=None, suff_stat=None, name=None, keys=None)[source]
Bases:
ParameterEstimatorMaximum-likelihood estimator for the von Mises mean direction and concentration.
The MLE is
mu = atan2(sum sin, sum cos)andkappa = A^{-1}(R)whereRis the mean resultant length andA(kappa) = I_1(kappa) / I_0(kappa).The data must be angles in radians. Any finite real is accepted and wrapped modulo
2*pi(onlycos/sinenter the statistics), so fitting a non-angular real-line column does not fail – it silently fits the circular law ofx mod 2*pi, whose log-likelihood is normalized over one period and is not comparable to real-line families (see the module docstring).- Parameters:
- accumulator_factory()[source]
Return an accumulator factory for von Mises circular moments.
- Return type:
VonMisesAccumulatorFactory