boundlab.zonoq.ZonoQ#

final class boundlab.zonoq.ZonoQ[source]#

Bases: Expr

Correlated linear and quadratic zonotope terms.

Represents sum_i L_i eps_i + sum_ij Q_ij eps_i eps_j. L and Q share one error table so both terms refer to the same symbols.

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

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

Lift a linear or quadratic component into a correlated ZonoQ.

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

Purely linear diagonal term; use Quad.error for a quadratic one.

expanded_to_table

from_exprlike

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

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.

make

matmul

mean

numel

reasons_breakdown

reshape

rmatmul

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

L: Zono#
Q: Quad#
__init__(L, Q)[source]#
property shape_dtype: ShapeDtype#

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

property table: SpanTable#
static make(L=None, Q=None, copy=None)[source]#
static error(err, amplitude=1.0)[source]#

Purely linear diagonal term; use Quad.error for a quadratic one.

classmethod convert_from(expr)[source]#

Lift a linear or quadratic component into a correlated ZonoQ.

Error/Noise sources become purely linear; use Quad.convert_from first to obtain a quadratic one.

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]#
expanded_to_table(table)[source]#
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]#
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)#