intervals

compression_safeguards.utils.intervals

Types and helpers to construct safe intervals for the safeguards.

Classes:

  • Interval

    Single interval over a N-sized ndarray of data type T.

  • Lower

    Array wrapper to override an Interval's lower bound using comparison syntax.

  • Upper

    Array wrapper to override an Interval's upper bound using comparison syntax.

  • IntervalUnion

    Union of U intervals, each over a N-sized ndarray of data type T.

Ni module-attribute

Ni = TypeVar('Ni', bound=int)

The number of elements in the interval (invariant).

U module-attribute

U = TypeVar('U', bound=int, covariant=True)

The maximum number of intervals in an interval union (covariant).

Ui module-attribute

Ui = TypeVar('Ui', bound=int)

The maximum number of intervals in an interval union (invariant).

Interval

Interval(
    *,
    _lower: ndarray[tuple[N], dtype[T]],
    _upper: ndarray[tuple[N], dtype[T]],
)

Bases: Generic[T, N]

flowchart LR compression_safeguards.utils.intervals.Interval[Interval] click compression_safeguards.utils.intervals.Interval href "" "compression_safeguards.utils.intervals.Interval"

Single interval over a N-sized ndarray of data type T.

Construction

An interval should only be constructed using

Overriding lower and upper bounds

The lower and upper bounds of the interval can be set as follows:

Lower(lower_data) <= interval <= Upper(upper_data)

They can also be set to the smallest and largest possible values using:

Minimum <= interval <= Maximum

If only the interval bounds for some array members should be updated, only the interval itself needs to be indexed:

# bound infinite values to be exactly themselves
Lower(data) <= interval[np.isinf(data)] <= Upper(data)

Common lower and upper bounds

The following common lower and upper bounds are provided for ease of use:

Interval operations

Two intervals can be

or converted into a single-member union of intervals using Interval.into_union.

Methods:

  • non_empty_width

    Binary width of the interval.

  • empty

    Create an empty interval that contains no values.

  • empty_like

    Create an empty interval that contains no values and has the same dtype and size as a.

  • singleton

    Create a singleton interval that has the same dtype and size as a and contains, for each element in a, only this singular value.

  • full

    Create a full interval that contains all possible values of dtype.

  • full_like

    Create a full interval that contains all possible values and has the same dtype and size as a.

  • preserve_inf

    Preserve all infinite values in a exactly.

  • preserve_signed_nan

    Preserve all NaN values in a, preserving their sign bit.

  • preserve_any_nan

    Preserve all NaN values in a, ignoring their sign bit.

  • preserve_finite

    Preserve all finite values in a as finite values.

  • preserve_non_nan

    Preserve all non-NaN values in a as non-NaN values.

  • intersect

    Computes the intersection with the other interval.

  • union

    Computes the union with the other interval (union).

  • into_union

    Convert this interval into a single-member union of exactly this one interval.

  • preserve_only_where

    Preserve safe intervals only at the data points where the where

dtype property

dtype: dtype[T]

Dtype T of the interval.

n property

n: N

Size N of the interval.

non_empty_width

non_empty_width() -> ndarray[
    tuple[N], dtype[unsignedinteger]
]

Binary width of the interval.

The interval must not have any empty entries.

Single-element intervals have width zero, full intervals have maximum width.

Returns:

empty staticmethod

empty(dtype: dtype[T], n: Ni) -> Interval[T, Ni]

Create an empty interval that contains no values.

Parameters:
  • dtype (dtype[T]) –

    The dtype of the interval

  • n (Ni) –

    The size of the interval

Returns:

empty_like staticmethod

empty_like(
    a: ndarray[tuple[int, ...], dtype[T]],
) -> Interval[T, int]

Create an empty interval that contains no values and has the same dtype and size as a.

Parameters:
Returns:

singleton staticmethod

singleton(
    a: ndarray[tuple[int, ...], dtype[T]],
) -> Interval[T, int]

Create a singleton interval that has the same dtype and size as a and contains, for each element in a, only this singular value.

Parameters:
Returns:

full staticmethod

full(dtype: dtype[T], n: Ni) -> Interval[T, Ni]

Create a full interval that contains all possible values of dtype.

Parameters:
  • dtype (dtype[T]) –

    The dtype of the interval

  • n (Ni) –

    The size of the interval

Returns:

full_like staticmethod

full_like(
    a: ndarray[tuple[int, ...], dtype[T]],
) -> Interval[T, int]

Create a full interval that contains all possible values and has the same dtype and size as a.

Parameters:
Returns:

preserve_inf

preserve_inf(a: ndarray[tuple[N], dtype[T]]) -> Self

Preserve all infinite values in a exactly.

Specifically, set their lower and upper bounds in this interval to their values.

Equivalent to

Lower(a) <= self[np.isinf(a)] <= Upper(a)
Parameters:
  • a (ndarray[tuple[N], dtype[T]]) –

    The arrays whose infinite values this interval should preserve

Returns:
  • self( Self ) –

    The modified self.

preserve_signed_nan

preserve_signed_nan(
    a: ndarray[tuple[N], dtype[T]], *, equal_nan: bool
) -> Self

Preserve all NaN values in a, preserving their sign bit.

  • If equal_nan is True, the intervals corresponding to the NaN values will include all possible NaN values with the same sign bit.
  • If equal_nan is False, all NaN values are preserved exactly.
Parameters:
  • a (ndarray[tuple[N], dtype[T]]) –

    The arrays whose NaN values this interval should preserve

  • equal_nan (bool) –

    Whether any NaN values matches another NaN value or if NaN values should be preserved exactly

Returns:
  • self( Self ) –

    The modified self.

preserve_any_nan

preserve_any_nan(
    a: ndarray[tuple[N], dtype[T]], *, equal_nan: bool
) -> IntervalUnion[T, N, int]

Preserve all NaN values in a, ignoring their sign bit.

  • If equal_nan is True, the intervals corresponding to the NaN values will include all possible NaN values, irrespective of their sign bit.
  • If equal_nan is False, all NaN values are preserved exactly.

Since there are two disjoint value regions of NaNs (positive and negative), this method returns a union of intervals.

Parameters:
  • a (ndarray[tuple[N], dtype[T]]) –

    The arrays whose NaN values this interval should preserve

  • equal_nan (bool) –

    Whether any NaN values matches another NaN value or if NaN values should be preserved exactly

Returns:
  • union( IntervalUnion[T, N, int] ) –

    The union of the existing intervals for non-NaN values and the NaN-preserving intervals for NaN values.

preserve_finite

preserve_finite(a: ndarray[tuple[N], dtype[T]]) -> Self

Preserve all finite values in a as finite values.

Specifically, set their lower and upper bounds to exclude non-finite values.

Parameters:
  • a (ndarray[tuple[N], dtype[T]]) –

    The arrays whose non-finite values this interval should preserve as non-finite.

Returns:
  • self( Self ) –

    The modified self.

preserve_non_nan

preserve_non_nan(a: ndarray[tuple[N], dtype[T]]) -> Self

Preserve all non-NaN values in a as non-NaN values.

Specifically, set their lower and upper bounds to exclude NaN values.

Parameters:
  • a (ndarray[tuple[N], dtype[T]]) –

    The arrays whose non-NaN values this interval should preserve as non-NaN.

Returns:
  • self( Self ) –

    The modified self.

intersect

intersect(other: Interval[T, N]) -> Interval[T, N]

Computes the intersection with the other interval.

Parameters:
  • other (Interval[T, N]) –

    The other interval to intersect with

Returns:
  • intersection( Interval[T, N] ) –

    The intersection of self and other.

union

union(
    other: Interval[T, N] | IntervalUnion[T, N, int],
) -> IntervalUnion[T, N, int]

Computes the union with the other interval (union).

Parameters:
Returns:

into_union

into_union() -> IntervalUnion[T, N, Literal[1]]

Convert this interval into a single-member union of exactly this one interval.

Returns:

preserve_only_where

preserve_only_where(
    where: Literal[True] | ndarray[tuple[N], dtype[bool]],
) -> Self

Preserve safe intervals only at the data points where the where condition is True.

This method must only be used for pointwise safe intervals.

Parameters:
Returns:
  • self( Self ) –

    The modified self.

Minimum module-attribute

Minimum = _Minimum()

The smallest representable value

Maximum module-attribute

Maximum = _Maximum()

The largest representable value

Lower

Lower(lower: ndarray[tuple[int, ...], dtype[number]])

Array wrapper to override an Interval's lower bound using comparison syntax.

Lower(lower_bound) <= interval
Parameters:

Upper

Upper(upper: ndarray[tuple[int, ...], dtype[number]])

Array wrapper to override an Interval's upper bound using comparison syntax.

interval <= Upper(upper_bound)
Parameters:

IntervalUnion

IntervalUnion(
    *,
    _lower: ndarray[tuple[U, N], dtype[T]],
    _upper: ndarray[tuple[U, N], dtype[T]],
)

Bases: Generic[T, N, U]

flowchart LR compression_safeguards.utils.intervals.IntervalUnion[IntervalUnion] click compression_safeguards.utils.intervals.IntervalUnion href "" "compression_safeguards.utils.intervals.IntervalUnion"

Union of U intervals, each over a N-sized ndarray of data type T.

Methods:

  • non_empty_width

    Binary width of the interval union.

  • empty

    Create an empty interval union that contains no values.

  • intersect

    Computes the intersection with the other interval union.

  • union

    Computes the union with the other interval (union).

  • preserve_only_where

    Preserve safe intervals only at the data points where the where

  • contains

    Check if this interval union contains the elements of the other array.

  • pick

    Pick a member of the interval union that minimises the cost of correcting the approximation to be a member of the interval union.

dtype property

dtype: dtype[T]

Dtype T of the interval union.

n property

n: N

Size N of the interval union.

u property

u: U

Number of intervals U in the interval union.

non_empty_width

non_empty_width() -> ndarray[
    tuple[N], dtype[unsignedinteger]
]

Binary width of the interval union.

The interval union must not have any empty entries.

Single-element intervals have width zero, full intervals have maximum width.

Returns:

empty staticmethod

empty(
    dtype: dtype[T], n: Ni, u: Ui
) -> IntervalUnion[T, Ni, Ui]

Create an empty interval union that contains no values.

Parameters:
  • dtype (dtype[T]) –

    The dtype of the intervals

  • n (Ni) –

    The size of the intervals

  • u (Ui) –

    The number of intervals in the union

Returns:

intersect

intersect(
    other: IntervalUnion[T, N, int],
) -> IntervalUnion[T, N, int]

Computes the intersection with the other interval union.

Parameters:
Returns:

union

union(
    other: Interval[T, N] | IntervalUnion[T, N, int],
) -> IntervalUnion[T, N, int]

Computes the union with the other interval (union).

Parameters:
Returns:

preserve_only_where

preserve_only_where(
    where: Literal[True] | ndarray[tuple[N], dtype[bool]],
) -> IntervalUnion[T, N, int]

Preserve safe intervals only at the data points where the where condition is True.

This method must only be used for pointwise safe intervals.

Parameters:
Returns:
  • self( IntervalUnion[T, N, int] ) –

    The interval union where only safe intervals at data points where the condition is True are preserved.

contains

contains(
    other: ndarray[S, dtype[T]],
) -> ndarray[S, dtype[bool]]

Check if this interval union contains the elements of the other array.

Parameters:
  • other (ndarray[S, dtype[T]]) –

    The array whose elements' membership in interval union should be checked

Returns:

pick

pick(
    approximation: ndarray[S, dtype[T]],
) -> ndarray[S, dtype[T]]

Pick a member of the interval union that minimises the cost of correcting the approximation to be a member of the interval union.

The metric for minimising the correction cost is unspecified and may be approximate.

Parameters:
  • approximation (ndarray[S, dtype[T]]) –

    An approximation of a member of the interval union

Returns: