Tsallis statistics for artificial intelligence, built on JAX.
Tsallis (non-extensive) statistics generalizes Boltzmann–Gibbs–Shannon statistics through a single entropic index
qjax exposes these jit/vmap-friendly JAX functions. Because
import jax, jax.numpy as jnp
import qjax
# q-deformed functions (recover log / exp as q -> 1)
qjax.q_log(2.0, q=1.5)
qjax.q_exp(1.0, q=1.5)
# Tsallis information measures
p = jnp.array([0.5, 0.3, 0.2])
qjax.tsallis_entropy(p, q=2.0) # -> Shannon entropy as q -> 1
qjax.tsallis_divergence(p, p, q=2.0) # -> KL divergence as q -> 1
# q-Gaussian distribution (heavy-tailed for 1 < q < 3)
x = jnp.linspace(-4, 4, 100)
qjax.q_gaussian_pdf(x, q=1.5, beta=1.0)
samples = qjax.sample(jax.random.PRNGKey(0), q=1.5, beta=1.0, shape=(1000,))
# Sparse softmax: q=1 -> softmax, q=2 -> sparsemax (exact zeros)
qjax.tsallis_entmax(jnp.array([2.0, 1.0, -1.0]), q=2.0)qjax is organized as a small set of composable, fully differentiable primitives. Each is a pure function of
qjax |
Definition | Limit |
|---|---|---|
q_log |
||
q_exp |
||
tsallis_entropy |
||
tsallis_cross_entropy |
||
tsallis_divergence |
||
q_gaussian_pdf |
||
tsallis_entmax |
where tsallis_entmax is exactly sparsemax at
qjaxis a research library. The numerics are tested across the$q \to 1$ limit, gradients, andjit/vmap, but the API may still evolve.
q_log and q_exp are inverse deformations of log/exp; the accompanying q_log(a·b) = q_add(q_log a, q_log b)).
qjax.q_log(x, q=1.5) # (x**(1-q) - 1) / (1-q)
qjax.q_add(qjax.q_log(2.0, 1.4), qjax.q_log(3.0, 1.4), 1.4) # == q_log(6.0, 1.4)p = jnp.array([0.5, 0.3, 0.2])
r = jnp.array([0.25, 0.25, 0.5])
qjax.tsallis_entropy(p, q=2.0) # -> Shannon entropy as q -> 1
qjax.tsallis_cross_entropy(p, r, q=2.0) # q-deformed cross-entropy loss
qjax.tsallis_divergence(p, r, q=2.0) # -> KL(p || r) as q -> 1A maximum-Tsallis-entropy distribution: heavy-tailed (Student-$t$) for
x = jnp.linspace(-4, 4, 100)
qjax.q_gaussian_pdf(x, q=1.5, beta=1.0)
qjax.q_gaussian_logpdf(x, q=1.5, beta=1.0)
qjax.sample(jax.random.PRNGKey(0), q=1.5, beta=1.0, shape=(1000,))tsallis_entmax interpolates between dense softmax (
z = jnp.array([2.0, 1.0, 0.1, -1.0])
qjax.tsallis_entmax(z, q=1.0) # softmax (dense)
qjax.tsallis_entmax(z, q=2.0) # sparsemax (exact zeros)Because
import jax
x = jnp.linspace(-3, 3, 200)
nll = lambda q: -jnp.mean(qjax.q_gaussian_logpdf(x, q, 1.0))
grad_q = jax.grad(nll)(1.5) # well-defined gradient w.r.t. the entropic indexThis is what makes
When training labels are noisy, ordinary softmax cross-entropy is unbounded — a confidently mislabeled example incurs an arbitrarily large loss, so an over-parameterized network ends up memorizing the noise. Replacing the logarithm with the deformed
For a one-hot target with true class
As
The figure trains a small 3-class classifier on two shapes (blobs, spiral) from clean data up to 40% label noise, comparing the Boltzmann–Gibbs–Shannon baseline (
See the classification example for the full setup.
qjax requires Python 3.10+ and depends only on jax and matplotlib. It is managed with uv.
| Use case | Command |
|---|---|
| As a dependency | uv add qjax |
| Development | uv sync --extra dev (tests + linter) |
| Building the docs | uv sync --extra docs (Sphinx + Furo) |
For GPU/TPU acceleration, install the matching JAX build by following the JAX installation guide.
Contributions are welcome — new
Released under the MIT License.
