mixle.stats.univariate.continuous.rician module

Rician (Rice) distribution – the envelope of a sinusoid in additive Gaussian noise.

The amplitude X = sqrt((nu + sigma Z1)^2 + (sigma Z2)^2) of a 2-D Gaussian offset from the origin by nu (the line-of-sight / signal component), Z1, Z2 ~ N(0, 1). Models fading envelopes with a dominant path (wireless/radar/sonar), MRI magnitude noise, and wind speed. With nu >= 0 and scale sigma > 0,

f(x; nu, sigma) = (x / sigma^2) exp(-(x^2 + nu^2) / (2 sigma^2)) I0(x nu / sigma^2), x > 0,

where I0 is the modified Bessel function (evaluated stably via the exponentially scaled ive). At nu = 0 it reduces to the Rayleigh; for large nu/sigma it approaches a Gaussian. It samples exactly from the 2-D Gaussian envelope and has a closed-form method-of-moments fit from the second and fourth moments: sigma^2 = (m2 - sqrt(2 m2^2 - m4))/2 and nu^2 = m2 - 2 sigma^2.

Reference: Rice, “Mathematical analysis of random noise”, Bell System Tech. J. (1944/1945).

class RicianDistribution(nu, sigma, name=None, keys=None)[source]

Bases: SequenceEncodableProbabilityDistribution

Rician distribution with non-centrality nu >= 0 and scale sigma > 0.

Parameters:
density(x)[source]

Return the probability density at x.

Parameters:

x (float)

Return type:

float

log_density(x)[source]

Return the log-density at x (-inf for x <= 0).

Parameters:

x (float)

Return type:

float

seq_log_density(x)[source]

Return vectorized log-density for a sequence-encoded array of observations.

Parameters:

x (ndarray)

Return type:

ndarray

classmethod compute_capabilities()[source]

Describe backend support for generated Rician kernels.

classmethod compute_declaration()[source]

Return the structured compute declaration for Rician distributions.

static backend_legacy_sufficient_statistics(x, params, engine)[source]

Per-row Rician power sums in accumulator order (count, sum x^2, sum x^4).

Parameters:
Return type:

tuple[Any, …]

static backend_log_density_from_params(x, nu, sigma, engine)[source]

Engine-neutral Rician log-density (-inf for x <= 0).

Parameters:
Return type:

Any

backend_seq_log_density(x, engine)[source]

Engine-neutral vectorized log-density for encoded data.

Parameters:
Return type:

Any

classmethod backend_stacked_params(dists, engine)[source]

Stacked Rician parameters for a homogeneous mixture kernel.

Parameters:
Return type:

dict[str, Any]

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

Return an (n, k) matrix of Rician log densities.

Parameters:
Return type:

Any

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

Stacked Rician power sums (count, sum x^2, sum x^4) using engine-resident arrays.

Parameters:
Return type:

tuple[Any, Any, Any]

cdf(x)[source]

Cumulative distribution function P(X <= x) (Marcum-Q, via scipy rice).

Parameters:

x (float)

Return type:

float

quantile(q)[source]

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

Parameters:

q (float)

Return type:

float

mean()[source]

Mean sigma sqrt(pi/2) L_{1/2}(-nu^2/(2 sigma^2)) (stable via the scaled Bessel ive).

Return type:

float

variance()[source]

Variance E[X^2] - mean^2 with E[X^2] = nu^2 + 2 sigma^2.

Return type:

float

entropy()[source]

Differential entropy in nats, by adaptive quadrature of -f(x) log f(x) over x > 0.

At nu = 0 the Rician is exactly the Rayleigh, whose entropy is the closed form 1 + log(sigma / sqrt(2)) + euler_gamma / 2. For nu > 0 the density’s log I0(x nu / sigma^2) term has no closed-form expectation (Rice, ‘Mathematical analysis of random noise’, 1944/1945), so the integral is evaluated numerically against the exact log-density.

Return type:

float

sampler(seed=None)[source]

Return a sampler (the envelope of a 2-D Gaussian offset by nu).

Parameters:

seed (int | None)

Return type:

RicianSampler

estimator(pseudo_count=None)[source]

Return a closed-form method-of-moments estimator.

Parameters:

pseudo_count (float | None)

Return type:

RicianEstimator

dist_to_encoder()[source]

Return the data encoder used by this distribution (the raw value).

Return type:

RicianDataEncoder

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

Bases: DistributionSampler

Draw X = sqrt((nu + sigma Z1)^2 + (sigma Z2)^2) for Z1, Z2 ~ N(0, 1).

Parameters:
  • dist (RicianDistribution)

  • seed (int | None)

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

Draw one sample or an array of iid samples.

Parameters:
Return type:

float | ndarray

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

Bases: SquaredPowerSumTrack, SequenceEncodableStatisticAccumulator

Accumulate the weighted power sums (count, sum x^2, sum x^4) for the moment fit.

The whole accumulator is SquaredPowerSumTrack – shape, validation and the conditioning-gated shift-anchored track on y = x**2, which is the quantity this family’s M-step differences. It is shared with the Nakagami family, whose accumulator was character-for- character the same; the duplicate-body gate caught the pair and de-duplicating it is what keeps a fix landing on one from missing the other.

Parameters:
  • name (str | None)

  • keys (str | None)

acc_to_encoder()[source]

Return the encoder used by this accumulator.

Return type:

RicianDataEncoder

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

Bases: StatisticAccumulatorFactory

Factory for RicianAccumulator.

Parameters:
  • name (str | None)

  • keys (str | None)

make()[source]

Create a fresh Rician accumulator.

Return type:

RicianAccumulator

class RicianEstimator(pseudo_count=None, suff_stat=None, name=None, keys=None)[source]

Bases: ParameterEstimator

Method-of-moments estimator from E[X^2] and E[X^4] (closed-form quadratic in sigma^2).

The quadratic is solved in its RATIONALIZED form, sigma^2 = Var(X^2) / (2 (E[X^2] + sqrt(E[X^2]^2 - Var(X^2)))), whenever the accumulated statistics carry the shift-anchored payload (see RicianAccumulator). Algebraically it is the same root as (m2 - sqrt(2 m2^2 - m4)) / 2, but it differences raw moments once instead of twice, and the one difference it needs is supplied exactly by the anchored track. That makes the fit accurate at any nu/sigma: measured against exact rational arithmetic on the same 2000-point samples, the historical form lost 5.4e-9 relative at nu/sigma 1e4, 4.1e-5 at 1e6 and 44% at 1e8, and now measures 3.5e-15, 7.1e-13 and 3.5e-11. With a plain raw tuple – statistics the conditioning gate never needed to anchor, or ones that arrived already reduced from an engine kernel or an older serialization – the historical path is used bit-identically, and estimate warns rather than returning a scale it cannot stand behind.

Parameters:
accumulator_factory()[source]

Return an accumulator factory for Rician power-sum statistics.

Return type:

RicianAccumulatorFactory

estimate(nobs, suff_stat)[source]

Estimate Rician noncentrality and scale from second and fourth moments.

Parameters:
Return type:

RicianDistribution

class RicianDataEncoder[source]

Bases: DataSequenceEncoder

Encode observations as a float array.

seq_encode(x)[source]

Encode observations as a floating-point array, admitting finite rows outside the support.

A negative value is scored -inf by RicianDistribution.seq_log_density() (and by the scalar path), so a mixture whose other component owns it can encode the whole batch (P02-F03). Refusing it here made Mixture[Gaussian, Rician] unencodable (Q01-F02). The accumulator still refuses a negative row that carries weight. Non-finite values stay refused.

Parameters:

x (Sequence[float])

Return type:

ndarray