GeneralizedHyperbolic#
The Generalized Hyperbolic (GH) distribution is the most general member of the family — the normal variance-mean mixture
with a full GIG subordinator. Because the GIG nests the Gamma, InverseGamma, and InverseGaussian as limits, GH contains the VarianceGamma, NormalInverseGamma, and NormalInverseGaussian as special cases — reach for it when you want the most flexible model.
Density gallery#
Beyond the shared location \(\mu\), skewness \(\gamma\), and dispersion \(\Sigma\), GH exposes the GIG shape \(p\), which tunes the tail weight independently. Here we vary \(p\) at a fixed positive skew.
Parametrizations#
Built from the shared location/shape block and the GIG subordinator:
Symbol |
Attribute |
Meaning |
|---|---|---|
\(\mu\) |
|
location \((d,)\) |
\(\gamma\) |
|
skewness \((d,)\) |
\(\Sigma = L_\Sigma L_\Sigma^\top\) |
|
dispersion Cholesky \((d, d)\) |
\(p\) |
|
GIG shape (any real) |
\(a\) |
|
GIG rate (\(> 0\)) |
\(b\) |
|
GIG rate (\(> 0\)) |
The marginal is not an exponential family, but the joint \((X, Y)\) is — its natural parametrization \(\theta\), the closed-form Bessel log-density, and the EM/MCECM algorithms are derived in The Generalized Hyperbolic Distribution and EM Algorithm for Generalized Hyperbolic Distributions.
Quick usage#
Raw \((\gamma, \Sigma, a, b)\) are identified only up to the scale gauge \(Y \mapsto cY\) (see EM Algorithm for Generalized Hyperbolic Distributions); compare the invariants \(\mu\), \(\gamma E[Y]\), and \(E[Y]\,\Sigma\) instead.
mu = jnp.array([0.0, 0.0])
gamma = jnp.array([0.3, -0.4])
Sigma = jnp.array([[1.0, 0.3], [0.3, 1.0]])
gh = GeneralizedHyperbolic.from_classical(mu=mu, gamma=gamma, sigma=Sigma, p=-0.5, a=1.0, b=1.0)
print("mean:", np.asarray(gh.mean()))
print("cov:\n", np.asarray(gh.cov()))
X = gh.rvs(2_000, seed=0)
# default_init warm-starts from the best of the NIG / VG / NInvG sub-model fits
result = GeneralizedHyperbolic.default_init(X).fit(X, max_iter=50, tol=1e-3)
fit = result.model
ey = float(fit.joint.subordinator().mean())
print("converged:", bool(result.converged), "n_iter:", int(result.n_iter))
print("mu:", np.asarray(fit.mu))
print("gamma * E[Y]:", np.asarray(fit.gamma) * ey) # true [0.3, -0.4] (E[Y]=1)
print("E[Y] * Sigma:\n", ey * np.asarray(fit.sigma()))
print("mean:", np.asarray(fit.mean()))
print("cov:\n", np.asarray(fit.cov()))
mean: [ 0.3 -0.4]
cov:
[[1.09 0.18]
[0.18 1.16]]
converged: True n_iter: 8
mu: [-0.01877 0.03617]
gamma * E[Y]: [ 0.30823 -0.40721]
E[Y] * Sigma:
[[0.93183 0.26059]
[0.26059 0.94615]]
mean: [ 0.28947 -0.37104]
cov:
[[1.03602 0.12295]
[0.12295 1.12798]]
The \(d = 1\) sibling UnivariateGeneralizedHyperbolic
adds cdf / ppf; the FactorGeneralizedHyperbolic
scales to high dimensions.