boundlab.zono.Zono#

final class boundlab.zono.Zono[source]#

Bases: Expr

A centerless zonotope \(\sum_k G_{\cdot k} \varepsilon_k\).

gen holds the coefficients with the flattened error axis last; table says which slice of that axis belongs to which Error. Binary operations align the tables first (align_fill_zeros()), which is what keeps shared symbols shared.

Methods

__init__

absub

Bound on the magnitude: \(\max(|lb|, ub) \ge \sup |x|\).

add

Same-class addition; __add__ dispatches here when classes match and otherwise groups the addends in an ExprGroup.

align_fill_zeros

Rebuild both zonotopes over the merged symbol table.

broadcast_to

chw

Center/halfwidth form: c = (ub + lb) / 2, w = (ub - lb) / 2.

classset

The set of component classes present in this value.

convert_from

Build a zonotope from a single Error symbol or Noise interval.

convert_to

Hook: convert self into expr_type, or None when this class does not know how.

einsum

Apply the linear map described by an integer-label einsum.

error

Diagonal zonotope scaling each component of err by amplitude.

expanded_to_table

Embed into a larger symbol table, zero-filling the new spans.

from_exprlike

Lift a tensor/scalar into a broadcast Bias; pass Expr through.

full_abs

lb

Sound elementwise lower bound on every concrete value represented.

lbub

(lb, ub) in one call; components override it when computing both at once is cheaper than two passes.

matmul

mean

numel

reasons_breakdown

Total halfwidth and its split over the symbols' Reasons labels — each symbol contributes its coefficient-slice's concretized width.

reshape

rmatmul

single

Zonotope over one error symbol with an explicit coefficient tensor.

split

Split into (matching, rest) so that matching + rest == self.

squeeze

sum

to

Convert to another component class, exactly.

to_intervals

Collapse to the box hull Bias(c) + Noise(w).

torch_print

Diagnostics as a TensorFormat.

transpose

ub

Sound elementwise upper bound on every concrete value represented.

unsqueeze

zeros

table: SpanTable[Error]#
gen: Generator#
__init__(table, gen)[source]#
property shape_dtype: ShapeDtype#

Allocation-free (shape, dtype) metadata of the value.

classmethod convert_from(expr)[source]#

Build a zonotope from a single Error symbol or Noise interval.

Bias has no zonotope counterpart, so an Intervals group keeps its center outside the Zono and only its Noise part converts here.

static single(err, generator)[source]#

Zonotope over one error symbol with an explicit coefficient tensor.

static error(err, amplitude=1.0)[source]#

Diagonal zonotope scaling each component of err by amplitude.

static zeros(shape_dtype, table=None)[source]#
full_abs()[source]#
ub()[source]#

Sound elementwise upper bound on every concrete value represented.

lb()[source]#

Sound elementwise lower bound on every concrete value represented.

lbub()[source]#

(lb, ub) in one call; components override it when computing both at once is cheaper than two passes.

chw()[source]#

Center/halfwidth form: c = (ub + lb) / 2, w = (ub - lb) / 2.

einsum(subscripts, *operands)[source]#

Apply the linear map described by an integer-label einsum.

subscripts holds one label tuple per input followed by the output labels (see boundlab.utils.einsum_parser()). This is the single linear primitive: __mul__, __matmul__, sum and mean all lower to it, so implementing it soundly makes every derived linear operation sound.

align_fill_zeros(other)[source]#

Rebuild both zonotopes over the merged symbol table.

Spans one side does not carry are zero-filled, so afterwards the two generators are column-aligned and any coefficient-wise operation is meaningful.

expanded_to_table(table)[source]#

Embed into a larger symbol table, zero-filling the new spans.

add(other)[source]#

Same-class addition; __add__ dispatches here when classes match and otherwise groups the addends in an ExprGroup.

reshape(*shape)[source]#
transpose(*perm)[source]#
broadcast_to(*shape)[source]#
reasons_breakdown()[source]#

Total halfwidth and its split over the symbols’ Reasons labels — each symbol contributes its coefficient-slice’s concretized width.

torch_print(group='reason')[source]#

Diagnostics as a TensorFormat.

The result is safe to hand to Torch diagnostic output under tracing: only plain arrays cross the callback boundary, never expression metadata (which may hold tracers, e.g. reason weights).

property T: Self#
__add__(other)#
__mul__(other)#
absub()#

Bound on the magnitude: \(\max(|lb|, ub) \ge \sup |x|\).

classset()#

The set of component classes present in this value.

A single component reports {type(self)}, an ExprGroup its member classes, and Zeros the empty set. Handlers use this to decide which part of a value they know how to transform.

convert_to(expr_type)#

Hook: convert self into expr_type, or None when this class does not know how. The other half of to().

property dtype: dtype#
static from_exprlike(expr, shape)#

Lift a tensor/scalar into a broadcast Bias; pass Expr through.

matmul(other)#
mean(axis, keepdims=False)#
property ndim: int#
numel()#
rmatmul(other)#
property shape: Sequence[Any]#
split(ty)#

Split into (matching, rest) so that matching + rest == self.

The main way handlers peel off the component class they transform while passing the remainder through untouched.

squeeze(axes=None)#
sum(axis, keepdims=False)#
to(expr_type)#

Convert to another component class, exactly.

Identity short-circuits; otherwise the target’s convert_from is tried, then this class’s convert_to. Raises TypeError when neither side knows the conversion — conversions never approximate.

to_intervals(name='')#

Collapse to the box hull Bias(c) + Noise(w).

Sound but lossy: every correlation between error symbols is dropped, so downstream cancellation (x - x = 0) no longer happens.

unsqueeze(axes)#