Distributions
Every distribution below implements log_prob, a reparameterized
sample where possible, and closed-form mean/variance where they
exist. Parameters may themselves be
Expr (typically Param),
so a distribution’s shape can be learned or driven by upstream geometry.
Each family below is shown with its probability-density plots and, where
useful, parameter-sensitivity sweeps.
The cumulative distribution cdf and its inverse quantile are mutual
duals: a distribution provides whichever it has in closed form and the
other is derived from it by a shared, differentiable monotone root-find (a
bracket-expanding bisection with implicit-function-theorem gradients). A
distribution therefore never needs both hand-written — supplying one is
enough for it to serve as a copula marginal (needs cdf) and as a
reparameterized sample source or process innovation (needs quantile).
Univariate
Gaussian(mean, sigma)
Weibull(scale, concentration)
Exponential(rate)
LogNormal(mu, sigma)
Gamma(concentration, rate)
Beta(alpha, beta)
Uniform(low, high)
Gumbel(loc, scale)
TruncatedGaussian(mean, sigma, low, high)
Parameter sensitivity
Each univariate distribution also has a small-multiples sensitivity panel and per-parameter sweeps, e.g.:
Weibull — parameter sensitivity grid
Gaussian — effect of sigma
Cumulative distributions
Gaussian, Weibull, Exponential, LogNormal, Uniform, and Gumbel provide both
a closed-form cdf and a closed-form quantile; families that give
only one have the other filled in by inversion, and families that provide
neither (Gamma, Beta) raise on both.
Weibull — CDF (closed-form quantile)
Gamma — CDF (numeric)
- class prophys.distributions.Gaussian(mean=0.0, sigma=1.0)[source]
- Parameters:
mean (Any)
sigma (Any)
- class prophys.distributions.Weibull(scale=1.0, concentration=1.0)[source]
Scale-shape parameterization:
p(x) = (k/lam) (x/lam)^(k-1) exp(-(x/lam)^k).- Parameters:
scale (Any)
concentration (Any)
- class prophys.distributions.Exponential(rate=1.0)[source]
- Parameters:
rate (Any)
- class prophys.distributions.LogNormal(mu=0.0, sigma=1.0)[source]
- Parameters:
mu (Any)
sigma (Any)
- class prophys.distributions.Gamma(concentration=1.0, rate=1.0)[source]
- Parameters:
concentration (Any)
rate (Any)
- class prophys.distributions.Uniform(low=0.0, high=1.0)[source]
- Parameters:
low (Any)
high (Any)
- class prophys.distributions.Gumbel(loc=0.0, scale=1.0)[source]
- Parameters:
loc (Any)
scale (Any)
Circular
For angular quantities like wind direction, where ordinary Gaussians are wrong because \(0\) and \(2\pi\) are the same point.
Higher kappa -> more concentrated around loc.
A Gaussian wrapped onto the circle.
Directional climatologies
DirectionalMixture is the standard
representation of a directional climatology — wind rose, wave rose,
current regime, or any other joint distribution of “which direction” and
“how strong”: the circle is divided into sectors, each with an occurrence
weight, a circular spread (a VonMises
around the sector center), and its own conditional intensity distribution
(e.g. a per-sector Weibull of wind
speed). All parameters — sector weights, spreads, and every conditional
intensity distribution’s parameters — are ordinary Exprs, so a
climatology fitted from met-mast or reanalysis observations is a single
fit_distribution() call, and its sector weights can
just as well be design variables (e.g. trading off wake losses against a
site’s directional wind resource).
import jax.numpy as jnp
import prophys as prp
sector_speeds = [
prp.Weibull(scale=prp.Param(f"scale_{i}", init=7.0), concentration=2.0)
for i in range(8)
]
wind_rose = prp.DirectionalMixture.evenly_spaced(
weights=prp.Param("sector_weights", shape=(8,), init=jnp.full((8,), 1 / 8)),
intensities=sector_speeds,
)
wind_rose.log_prob(direction=jnp.deg2rad(200.0), intensity=9.5)
- class prophys.distributions.DirectionalMixture(directions, concentrations, intensities, logits)[source]
A joint distribution over an angle and a conditional intensity — the standard representation of directional climatologies (wind or wave climate, current regimes, directional seismic loading): the circle is divided into k directional sectors, each with an occurrence weight, a circular spread around its center direction, and its own conditional intensity distribution (e.g. a per-sector Weibull of wind speed).
directions: sector center angles in radians, shape
(k,)concentrations: von Mises concentration per sector, shape
(k,)(higher = narrower sector; may be a learnable Param)intensities: k conditional intensity distributions, one per sector
logits: unnormalized sector occurrence log-weights, shape
(k,)(normalized internally via softmax; may be a learnable Param)
All parameters are Expr instances, so the whole climatology is calibratable against observed
(angle, intensity)pairs with fit_distribution.- Parameters:
directions (Any)
concentrations (Any)
intensities (Sequence[Distribution])
logits (Any)
- classmethod evenly_spaced(weights, intensities, concentration=None)[source]
Build a climatology with k sectors evenly spaced around the circle (sector 0 centered at angle 0) from occurrence weights (e.g. observed sector frequencies, shape
(k,), normalized internally). concentration defaults to a spread that roughly tiles the circle (kappa such that one sector width ~ one std).- Parameters:
- Return type:
- log_prob(direction, intensity)[source]
Joint log-density of
(direction, intensity)pairs (radians, intensity units), elementwise over the inputs.
Multivariate & mixtures
Cholesky-parameterized covariance — always positive-definite under gradient updates.
Finite mixture with softmax-normalized weights. Its cdf is the
weight-averaged component CDFs (strictly increasing), so the derived
quantile is unambiguous — a mixture can serve as a copula
marginal or as an autoregressive process’s innovation.
Kernel-density estimate from raw samples — stays differentiable.
Piecewise-constant density from bin edges/probabilities.
- class prophys.distributions.MultivariateGaussian(mean, cholesky)[source]
mean shape (d,), cholesky shape (d, d) — lower-triangular factor of the covariance (
cov = L @ L.T); parameterizing via the Cholesky factor keeps the covariance positive-definite by construction under gradient updates.- Parameters:
mean (Any)
cholesky (Any)
- class prophys.distributions.Mixture(components, logits)[source]
A finite mixture of component distributions with (possibly learnable) log-weights, normalized internally via softmax.
- Parameters:
components (Sequence[Distribution])
logits (Any)
- class prophys.distributions.Empirical(samples, bandwidth=0.1)[source]
A distribution defined by a fixed sample set, e.g. observed wind speeds. log_prob uses kernel-density estimation (Gaussian kernel, bandwidth bw) so it stays differentiable; sample resamples with replacement.
- Parameters:
samples (Any)
bandwidth (float)
Copulas & dependence structures
A GaussianCopula couples arbitrary
marginals (each needs a cdf for the density and a quantile for
sampling — either closed-form or derived, so a
Mixture marginal works too) through a
correlation matrix that is parameterized so it is always valid — an
unconstrained gradient step can never produce a non-positive-definite
correlation matrix.
- class prophys.distributions.GaussianCopula(marginals, corr_raw)[source]
A Gaussian copula coupling marginals (a list of Distribution, each exposing cdf and quantile) via a correlation structure.
The correlation is parameterized by a raw unconstrained vector (the hyperspherical/LKJ-style Cholesky construction lives in the native prophys._ffi.copula_logp kernel), so it may be an Expr/Param and remain a valid correlation matrix under any gradient step.
- Parameters:
marginals (Sequence[Distribution])
corr_raw (Any)
- sample(key, shape=())[source]
Draw joint samples of shape
(*shape, d).Reparameterized: correlated standard normals through the same Cholesky-from-raw construction the log_prob kernel uses, mapped to uniforms by the normal CDF, then through each marginal’s quantile — so gradients flow to both corr_raw and every marginal parameter.
Discrete distributions