pymc.ZeroSumNormal#

class pymc.ZeroSumNormal(*args, zerosum_axes=None, n_zerosum_axes=None, support_shape=None, dims=None, **kwargs)[source]#

ZeroSumNormal distribution, i.e Normal distribution where one or several axes are constrained to sum to zero. By default, the last axis is constrained to sum to zero. See n_zerosum_axes kwarg for more details.

\[\begin{split}\begin{align*} ZSN(\sigma) = N \Big( 0, \sigma^2 (I - \tfrac{1}{n}J) \Big) \\ \text{where} \ ~ J_{ij} = 1 \ ~ \text{and} \\ n = \text{nbr of zero-sum axes} \end{align*}\end{split}\]
Parameters:
sigmatensor_like of float

Scale parameter (sigma > 0). It’s actually the standard deviation of the underlying, unconstrained Normal distribution. Defaults to 1 if not specified. sigma cannot have length > 1 across the zero-sum axes.

n_zerosum_axes: int, defaults to 1

Number of axes along which the zero-sum constraint is enforced, starting from the rightmost position. Defaults to 1, i.e the rightmost axis.

zerosum_axes: int, deprecated please use n_zerosum_axes as its successor
dims: sequence of strings, optional

Dimension names of the distribution. Works the same as for other PyMC distributions. Necessary if shape is not passed.

shape: tuple of integers, optional

Shape of the distribution. Works the same as for other PyMC distributions. Necessary if dims or observed is not passed.

Warning

Currently, ``sigma``cannot have length > 1 across the zero-sum axes to ensure the zero-sum constraint.

n_zerosum_axes has to be > 0. If you want the behavior of n_zerosum_axes = 0, just use pm.Normal.

Examples

Define a ZeroSumNormal variable, with sigma=1 and n_zerosum_axes=1 by default:

COORDS = {
    "regions": ["a", "b", "c"],
    "answers": ["yes", "no", "whatever", "don't understand question"],
}
with pm.Model(coords=COORDS) as m:
    # the zero sum axis will be 'answers'
    v = pm.ZeroSumNormal("v", dims=("regions", "answers"))

with pm.Model(coords=COORDS) as m:
    # the zero sum axes will be 'answers' and 'regions'
    v = pm.ZeroSumNormal("v", dims=("regions", "answers"), n_zerosum_axes=2)

with pm.Model(coords=COORDS) as m:
    # the zero sum axes will be the last two
    v = pm.ZeroSumNormal("v", shape=(3, 4, 5), n_zerosum_axes=2)

Methods

ZeroSumNormal.dist([sigma, n_zerosum_axes, ...])

Creates a tensor variable corresponding to the cls distribution.