Hypervector

class pyhdc.Hypervector(data: ArrayLike, encoding: Encoding, backend: Backend | None = None, metadata: Dict[str, Any] | None = None)[source]

Bases: object

A hypervector representation supporting multiple backends.

Similar to numpy’s ndarray, this class can represent a single hypervector or an array of hypervectors, and supports both numpy and PyTorch backends.

data

The underlying array (numpy.ndarray or torch.Tensor)

encoding

The encoding scheme used for operations

backend

The backend being used (‘numpy’ or ‘torch’)

bind(*others: Hypervector, batch_dim: int | None = None) Hypervector[source]

Bind this hypervector with others.

Note: Batching via batch_dim is available at the Encoding class level, not at the instance method level (which always operates on single instances).

Parameters:
  • *others – Other hypervectors to bind

  • batch_dim – Passed through to Encoding.bind (instance methods don’t use batching)

Returns:

A new bound hypervector

bundle(*others: Hypervector, axis: None | int | Tuple[int, ...] = None, batch_dim: int | None = None) Hypervector[source]

Bundle this hypervector with others.

Note: Batching via batch_dim is available at the Encoding class level, not at the instance method level (which always operates on single instances).

Parameters:
  • *others – Other hypervectors to bundle

  • axis – Batch axis (or axes) to fold when bundling a single batched hypervector (defaults to the last batch axis)

  • batch_dim – Passed through to Encoding.bundle (instance methods don’t use batching)

Returns:

A new bundled hypervector

cpu() Hypervector[source]

Move to CPU.

cuda(device: int | None = None) Hypervector[source]

Move to CUDA device.

property device: Device | None

Get the device (for PyTorch backend).

property dtype: Any

Get the data type.

get_metadata() Dict[str, Any][source]

Get operational metadata for this hypervector.

Returns:

Dictionary containing metadata from the operation that created this hypervector. Empty dict if no metadata available.

inverse() Hypervector[source]

Return the binding inverse of this hypervector.

property ndim: int

Get the number of dimensions.

negative() Hypervector[source]

Return the bundling (additive) inverse of this hypervector.

normalize() Hypervector[source]

Normalize this hypervector to its encoding’s entry space.

permute(shift: int = 1) Hypervector[source]

Permute (cyclic-shift) this hypervector along the dimension axis.

select(indices) Hypervector[source]

Select hypervectors along the batch axis (axis 1).

Hypervectors are dimension-first (D, N); select keeps the columns at the given indices.

Parameters:

indices – Integer (non-negative) indices of the hypervectors to keep, as a sequence, numpy array, or tensor.

Returns:

A new Hypervector of shape (D, len(indices)) with the selected columns, preserving encoding, backend, and metadata.

property shape: Tuple[int, ...]

Get the shape of the hypervector.

similarity(other: 'Hypervector' | None = None, *, axis: int | None = None) float | np.ndarray | 'torch.Tensor'[source]

Compute similarity with another hypervector, or within a batch.

Parameters:
  • other – Another hypervector to compare with. If omitted, self must be a (D, N) batch and the similarity of column 0 against each remaining column is returned.

  • axis – For a single (D, N, M, ...) batch (other omitted), the batch axis along which to split column 0 against the rest.

Returns:

Similarity score(s)

thin() Hypervector[source]

Apply thinning operation.

Returns:

A new thinned hypervector

to(device: Device) Hypervector[source]

Move to specified device (PyTorch only).

to_numpy() Hypervector[source]

Convert to numpy backend.

to_torch(device: Device | None = None) Hypervector[source]

Convert to PyTorch backend.

unbind(*others: Hypervector, batch_dim: int | None = None) Hypervector[source]

Unbind this hypervector from others.

Note: Batching via batch_dim is available at the Encoding class level, not at the instance method level (which always operates on single instances).

Parameters:
  • *others – Other hypervectors to unbind

  • batch_dim – Passed through to Encoding.unbind (instance methods don’t use batching)

Returns:

A new unbound hypervector

Reference summary

Constructor

Hypervector(data, encoding, backend=None, metadata=None)

Normally you do not construct Hypervector directly: use encoding.generate(), encoding.zeros(), or encoding.from_array().

Properties

Property

Type

Description

.data

ndarray or Tensor

Underlying NumPy array or PyTorch tensor (read-only)

.encoding

Encoding

The encoding that produced this hypervector

.backend

str

"numpy" or "torch"

.shape

tuple

Shape of the underlying array (e.g., (10000,) or (10000, 100))

.ndim

int

Number of dimensions (1 for a single HV, 2 for a batch)

.dtype

dtype

Data type of the underlying array (e.g., float32, int8)

.device

str or None

PyTorch device string (e.g., "cuda:0"); None for NumPy backend

Similarity

Hypervector.similarity(other=None)[source]

Compute similarity to another hypervector (or batch), or within a single batch when other is omitted.

Delegates to the encoding’s similarity function. Returns values in [-1, 1].

Parameters:

other – A Hypervector of the same encoding and backend. If omitted, self must be a (D, N) batch and the similarity of column 0 against each remaining column is returned.

Returns:

float, ndarray, or Tensor depending on input shapes. See batched calling conventions.

Batch selection

Hypervector.select(indices)[source]

Select hypervectors (columns) from a (D, N) batch by index along the batch axis. Returns a (D, len(indices)) batch. Works on NumPy and PyTorch (list or array indices are accepted).

codebook = enc.generate(size=(10_000, 100))   # (10000, 100)
subset   = codebook.select([0, 2, 4])         # (10000, 3)

Bundle and bind

Hypervector.bundle(*others, axis=None, batch_dim=None)[source]

Bundle this hypervector with one or more others. A batched operand is reduced automatically, axis= selects which batch axis to collapse.

Parameters:
  • others – Additional Hypervector objects.

  • axis – Batch axis (or tuple of axes) to reduce. Axis 0 cannot be reduced.

  • batch_dim – Deprecated as of 2.1.0, emits DeprecationWarning and will be removed in a future release. Pass a batched operand or use axis=.

Returns:

Hypervector

Hypervector.bind(*others, batch_dim=None)[source]

Bind this hypervector with one or more others. Batched operands are handled automatically: element-wise binders broadcast, others are applied per column.

Parameters:
  • others – Additional Hypervector objects.

  • batch_dim – Deprecated as of 2.1.0, emits DeprecationWarning and will be removed in a future release. Pass a batched operand instead.

Returns:

Hypervector

Hypervector.unbind(*others, batch_dim=None)[source]

Unbind to recover a component. Batched operands are handled automatically.

Parameters:

batch_dim – Deprecated as of 2.1.0, emits DeprecationWarning and will be removed in a future release. Pass a batched operand instead.

Raises:

NotImplementedError – For encodings that do not support unbinding (e.g., BSDC_CDT).

Returns:

Hypervector

Hypervector.thin()[source]

Apply the encoding’s thinning operation (sparse binary encodings only). For encodings that do not thin, returns self unchanged.

Returns:

Hypervector

Unary operations

These four operate dimension-first. Axis 0 is always the dimension D, and each operation broadcasts over the trailing batch axes of a (D, N) or (D, N, M) input. Each delegates to the encoding (self._encoding.<op>) and returns a new Hypervector. Whether an operation is defined depends on the encoding family. The per-family behavior is listed below and resolved through the encoding’s EncodingSpec.

Hypervector.permute(shift=1)[source]

Cyclic-shift permutation along axis 0 (the dimension). A positive shift rolls coordinates forward, a negative shift rolls them back and is the exact inverse of the positive shift. Every encoding defines permute: when an encoding does not supply its own permute_fn, the shared CyclicShift component is used, so all families support it by default.

Parameters:

shift – Integer number of positions to roll. Default 1.

Returns:

Hypervector

Hypervector.inverse()[source]

The binding inverse: the element that unbinds what binding produced. The mechanism is family-specific (IdentityInverse for self-inverse binding, ReverseInverse for circular convolution, PhaseNegate for FHRR).

Raises:

NotImplementedError – For encodings whose EncodingSpec leaves inverse_fn at its default: MAP_C, VTB, MBAT, BSDC_CDT, BSDC_S, BSDC_SEG, and BSDC_THIN.

Returns:

Hypervector

Hypervector.normalize()[source]

Normalize to the entry distribution for the encoding. The mechanism is family-specific (SignNormalize to bipolar {-1, 0, +1} for MAP, L2Normalize to unit L2 length along axis 0 for HRR/VTB/MBAT, WrapPhase to [-pi, pi) for FHRR).

Raises:

NotImplementedError – For encodings whose EncodingSpec leaves normalize_fn at its default: BSC and all four BSDC variants (BSDC_CDT, BSDC_S, BSDC_SEG, BSDC_THIN).

Returns:

Hypervector

Hypervector.negative()[source]

The bundling (additive) inverse: element-wise negation for the additive families (Negate).

Raises:

NotImplementedError – For encodings whose EncodingSpec leaves negative_fn at its default: FHRR, BSC, and all four BSDC variants (BSDC_CDT, BSDC_S, BSDC_SEG, BSDC_THIN).

Returns:

Hypervector

Backend and device conversion

Hypervector.to_numpy()[source]

Convert to NumPy backend. Copies data if currently on PyTorch.

Returns:

Hypervector

Hypervector.to_torch(device=None)[source]

Convert to PyTorch backend.

Parameters:

device – Target device string ("cpu", "cuda", etc.). None means CPU.

Returns:

Hypervector

Hypervector.to(device)[source]

Move to a specific device. Equivalent to .to_torch(device) when on NumPy, or .data.to(device) when already on PyTorch.

Parameters:

device – Device string or torch.device.

Returns:

Hypervector

Hypervector.cpu()[source]

Move to CPU. Equivalent to .to("cpu").

Returns:

Hypervector

Hypervector.cuda(device=None)[source]

Move to CUDA. Equivalent to .to("cuda") or .to("cuda:<device>").

Parameters:

device – Optional CUDA device index (int).

Returns:

Hypervector

Metadata

Hypervector.get_metadata()[source]

Return the metadata dictionary attached to this hypervector.

Most hypervectors have an empty metadata dict. MBAT binding stores the random matrices here, keyed by "matrices".

Returns:

Dict[str, Any]

Special methods

Hypervector.__getitem__(key)[source]

Index or slice a batch hypervector.

batch = enc.generate(size=(10_000, 100))   # (10000, 100)
hv0   = batch[:, 0]        # shape (10000,): first hypervector (column 0)
first5 = batch[:, :5]      # shape (10000, 5): first five hypervectors

Operators route through the encoding, so each one raises per family exactly as the underlying method does. For +, *, and / a non-Hypervector right-hand operand returns NotImplemented, which Python turns into a TypeError. There are no reflected dunders, so other + hv with a non-hypervector other also raises TypeError.

a = enc.generate(size=10_000)
b = enc.generate(size=10_000)

bundled = a + b       # a.bundle(b)
bound   = a * b       # a.bind(b)
recov   = bound / b   # bound.unbind(b)
inv     = ~a          # a.inverse()
rolled  = a >> 3      # a.permute(shift=3)
back    = rolled << 3 # a.permute(shift=-3), inverse of >> 3
Hypervector.__add__(other)[source]

Bundle. Routes to self.bundle(other). other must be a Hypervector, any other type returns NotImplemented. Defined for all encodings.

Hypervector.__mul__(other)[source]

Bind. Routes to self.bind(other). other must be a Hypervector, any other type returns NotImplemented. Defined for all encodings. On a batched (ndim > 1) operand the non-element-wise binders (HRR convolution, shifting, matrix, VTB, BSDC_CDT) are applied per column, returning one batched result.

Hypervector.__truediv__(other)[source]

Unbind. Routes to self.unbind(other). other must be a Hypervector, any other type returns NotImplemented.

Raises:

NotImplementedError – For BSDC_CDT (its unbinding_fn is the default raising stub).

Hypervector.__invert__()[source]

Inverse. Routes to self.inverse().

Raises:

NotImplementedError – For MAP_C, VTB, MBAT, BSDC_CDT, BSDC_S, BSDC_SEG, and BSDC_THIN (see Hypervector.inverse()).

Hypervector.__rshift__(shift)[source]

Permute forward. Routes to self.permute(shift=int(shift)). shift must be integral (Python int or any numbers.Integral such as a NumPy integer) and must not be a bool; a bool, float, or other type returns NotImplemented (Python raises TypeError). Defined for all encodings.

Hypervector.__lshift__(shift)[source]

Permute backward. Routes to self.permute(shift=-int(shift)) and is the exact inverse of >> by the same amount. Same shift rule as Hypervector.__rshift__(): integral and not bool, else NotImplemented. Defined for all encodings.

Hypervector.__len__()[source]

Return shape[0], which is the hypervector dimension D (axis 0), not the batch count, since batches are dimension-first (D, N).

Hypervector.__repr__()[source]

Human-readable summary: shape, dtype, backend.