Skip to content

Families

The semantic registry of distribution families.

families

The semantic registry of distribution families.

One record per family says what a distribution is, independently of any host library: its parameters with their constraints and ranks, the type and event rank of a sample, its support, whether it is discrete, whether a sample is reparameterizable, and the spelling each transpile target uses. The compiler, the reference runtime, and every renderer read this table; host-specific metadata such as the torch.distributions class is kept beside it in the layers that need it and checked against it in tests, so a family cannot mean one thing to the checker and another to a backend.

Four families form the measure algebra a program's operator forms lower to. Restrict(base, low, high) is the restriction of a base to an interval, a sub-probability measure whose density is the base's inside the interval and whose mass is the base's mass there; Mixture(weights, component) is the weighted sum of measures, with raw weights, whose mass is the weighted sum of the components' masses and whose component is either one sampleable plated over the mixture axis or a tensor of sampleables, one per component; Normalize(base) rescales a measure to a probability measure; PointMass(value) is the Dirac measure. A sample or observe step normalizes the measure it draws from, so Restrict at a step is the truncated family and a mixture of restricted components weighs each by its mass.

FAMILIES module-attribute

FAMILIES: Mapping[str, DistributionFamily] = MappingProxyType({item.name: item for item in _FAMILIES})

Every family by source name.

The mapping is closed: a name absent here is not a distribution family, and no backend may invent one.

ParameterConstraint

ParameterConstraint = str

A symbolic constraint on a parameter value, such as "positive", "unit_interval", "simplex", "positive_definite", or "dependent" when the admissible values depend on other parameters. A compositional family's parameters use "sampleable" for a distribution it is built from and "transform" for a named bijector chain; an atom's "numeric" value is an integer or a real, and fixes which the atom samples.

SupportKind

SupportKind = str

A symbolic description of where samples live, in the same vocabulary as the parameter constraints.

FamilyParameter dataclass

FamilyParameter(name: str, constraint: ParameterConstraint, rank: int)

One parameter of a distribution family.

PARAMETER DESCRIPTION
name

The parameter's name, as the source spells it by keyword.

TYPE: str

constraint

The symbolic constraint on admissible values.

TYPE: ParameterConstraint

rank

The tensor rank of one parameter value: 0 for a scalar, 1 for a vector, 2 for a matrix.

TYPE: int

DistributionFamily dataclass

DistributionFamily(name: str, parameters: tuple[FamilyParameter, ...], support: SupportKind, element: TypeExpr, event_rank: int, event_source: str | None, discrete: bool, reparameterizable: bool, compositional: bool, targets: Mapping[str, str] = dict(), finite_support: tuple[object, ...] | None = None, relaxes: tuple[str, tuple[object, ...]] | None = None)

The semantic record of one distribution family.

PARAMETER DESCRIPTION
name

The family's source name, such as "Normal".

TYPE: str

parameters

The parameters, in the order a positional application supplies them. Alternative parameterizations, such as probs and logits, are both listed; an application supplies one.

TYPE: tuple[FamilyParameter, ...]

support

Where samples live.

TYPE: SupportKind

element

The scalar type of one sample element.

TYPE: TypeExpr

event_rank

The rank of one sample: 0 for a scalar family, 1 for a vector family, 2 for a matrix family.

TYPE: int

event_source

The parameter whose trailing event_rank dimensions fix the sample's event shape, or None when the family is scalar or the shape comes from elsewhere.

TYPE: str | None

discrete

Whether samples are discrete.

TYPE: bool

reparameterizable

Whether a sample can be drawn as a differentiable function of the parameters.

TYPE: bool

compositional

Whether the family is built from other distributions or morphisms rather than from tensor parameters alone.

TYPE: bool

targets

The spelling each transpile target uses for the family.

TYPE: Mapping[str, str] DEFAULT: dict()

finite_support

The finite set of values a sample ranges over, when the family has one independent of its parameters.

TYPE: tuple[object, ...] | None DEFAULT: None

relaxes

The discrete family a continuous relaxation stands in for, and the atoms of that family's support as the relaxation's samples spell them: a marginalization over the relaxation enumerates those atoms under the discrete family's masses, as the torch runtime does.

TYPE: tuple[str, tuple[object, ...]] | None DEFAULT: None

id property

The family's stable identity.

RETURNS DESCRIPTION
DistributionId

An identity derived from the builtin namespace and the name, the same in every module.

parameter_names property

parameter_names: tuple[str, ...]

The parameter names in positional order.

RETURNS DESCRIPTION
tuple[str, ...]

The names.

__post_init__

__post_init__() -> None

Freeze the target spellings and check the parameter names.

RAISES DESCRIPTION
ValueError

If two parameters share a name, or event_source names no parameter.

Source code in src/quivers/qiec/families.py
def __post_init__(self) -> None:
    """Freeze the target spellings and check the parameter names.

    Raises
    ------
    ValueError
        If two parameters share a name, or ``event_source`` names no
        parameter.
    """
    object.__setattr__(self, "targets", MappingProxyType(dict(self.targets)))
    names = [parameter.name for parameter in self.parameters]
    if len(set(names)) != len(names):
        raise ValueError(f"family {self.name!r} repeats a parameter name")
    if self.event_source is not None and self.event_source not in names:
        raise ValueError(
            f"family {self.name!r} names event source "
            f"{self.event_source!r}, which is not a parameter"
        )

parameter

parameter(name: str) -> FamilyParameter

Look up a parameter by name.

PARAMETER DESCRIPTION
name

The parameter's name.

TYPE: str

RETURNS DESCRIPTION
FamilyParameter

The parameter.

RAISES DESCRIPTION
KeyError

If the family has no such parameter.

Source code in src/quivers/qiec/families.py
def parameter(self, name: str) -> FamilyParameter:
    """Look up a parameter by name.

    Parameters
    ----------
    name : str
        The parameter's name.

    Returns
    -------
    FamilyParameter
        The parameter.

    Raises
    ------
    KeyError
        If the family has no such parameter.
    """
    for parameter in self.parameters:
        if parameter.name == name:
            return parameter
    raise KeyError(f"family {self.name!r} has no parameter {name!r}")

family

family(name: str) -> DistributionFamily

Look up a distribution family by source name.

PARAMETER DESCRIPTION
name

The family's source name.

TYPE: str

RETURNS DESCRIPTION
DistributionFamily

The family's semantic record.

RAISES DESCRIPTION
KeyError

If no family has the name.

Source code in src/quivers/qiec/families.py
def family(name: str) -> DistributionFamily:
    """Look up a distribution family by source name.

    Parameters
    ----------
    name : str
        The family's source name.

    Returns
    -------
    DistributionFamily
        The family's semantic record.

    Raises
    ------
    KeyError
        If no family has the name.
    """
    try:
        return FAMILIES[name]
    except KeyError as error:
        raise KeyError(f"unknown distribution family {name!r}") from error