Models

All VSA model implementations in HoloVec.

Base Model

All models inherit from the VSAModel base class.

class holovec.models.VSAModel(space: VectorSpace, backend: Backend | None = None)[source]

Bases: ABC

Abstract base class for VSA models.

A VSA model defines the core operations: - bind: Associate two vectors (creates dissimilar result) - unbind: Recover one vector given the other and their binding - bundle: Combine multiple vectors (preserves similarity) - permute: Reorder vector to represent position/sequence

Different models have different algebraic properties: - Self-inverse binding: bind(a, b) = unbind(a, b) - Exact vs approximate inverse - Commutativity of binding

Initialize VSA model.

Parameters:
  • space – Vector space defining the representation

  • backend – Computational backend (defaults to space’s backend)

__init__(space: VectorSpace, backend: Backend | None = None)[source]

Initialize VSA model.

Parameters:
  • space – Vector space defining the representation

  • backend – Computational backend (defaults to space’s backend)

abstractmethod bind(a: Any, b: Any) Any[source]

Bind two vectors to create an association.

Binding creates a new vector that is dissimilar to both inputs but preserves structured similarity (similar inputs → similar bindings).

Parameters:
  • a – First vector

  • b – Second vector

Returns:

Bound vector representing the association of a and b

abstractmethod unbind(a: Any, b: Any) Any[source]

Unbind to recover one vector given the other.

For self-inverse models: unbind(a, b) = bind(a, b) For others: approximately recovers a from bind(a, b) and b

Parameters:
  • a – Bound vector or first operand

  • b – Second operand

Returns:

Recovered vector (exact or approximate depending on model)

abstractmethod bundle(vectors: Sequence[Any]) Any[source]

Bundle (superpose) multiple vectors.

Bundling combines vectors while preserving similarity to all inputs. The result is similar to each input vector.

Parameters:

vectors – Sequence of vectors to bundle

Returns:

Bundled vector representing the superposition

Raises:

ValueError – If vectors is empty

abstractmethod permute(vec: Any, k: int = 1) Any[source]

Permute vector to represent position or sequence.

Permutation reorders coordinates and is used to encode position or create sequences. It’s invertible and preserves similarity.

Parameters:
  • vec – Vector to permute

  • k – Number of positions to shift (default: 1)

Returns:

Permuted vector

unpermute(vec: Any, k: int = 1) Any[source]

Inverse permutation.

Parameters:
  • vec – Vector to unpermute

  • k – Number of positions to shift back (default: 1)

Returns:

Unpermuted vector

similarity(a: Any, b: Any) float[source]

Compute similarity between two vectors.

Delegates to the vector space’s similarity metric.

Parameters:
  • a – First vector

  • b – Second vector

Returns:

Similarity score (space-dependent metric)

normalize(vec: Any) Any[source]

Normalize vector according to space conventions.

Parameters:

vec – Vector to normalize

Returns:

Normalized vector

random(seed: int | None = None) Any[source]

Generate a random vector from the space.

Parameters:

seed – Optional random seed

Returns:

Random vector

random_sequence(n: int, seed: int | None = None) List[Any][source]

Generate n random vectors.

Parameters:
  • n – Number of vectors to generate

  • seed – Optional base seed (each vector gets seed + i)

Returns:

List of random vectors

bind_multiple(vectors: Sequence[Any]) Any[source]

Bind multiple vectors sequentially.

For n vectors: bind(bind(bind(v1, v2), v3), …)

Parameters:

vectors – Sequence of vectors to bind

Returns:

Result of sequential binding

Raises:

ValueError – If fewer than 2 vectors provided

abstract property is_self_inverse: bool

Whether binding is self-inverse (bind = unbind).

abstract property is_commutative: bool

Whether binding is commutative (bind(a, b) = bind(b, a)).

abstract property is_exact_inverse: bool

Whether unbinding gives exact recovery (no approximation error).

abstract property model_name: str

Return the model name (e.g., ‘MAP’, ‘FHRR’, ‘HRR’).

MAP Model

Multiply-Add-Permute: Fast, self-inverse, hardware-friendly.

class holovec.models.MAPModel(dimension: int = 10000, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Bases: VSAModel

MAP (Multiply-Add-Permute) model.

Binding: element-wise multiplication Unbinding: element-wise multiplication (self-inverse) Bundling: element-wise addition + normalization Permutation: circular shift

Best used with BipolarSpace or RealSpace.

Initialize MAP model.

Parameters:
  • dimension – Dimensionality of hypervectors

  • space – Vector space (defaults to BipolarSpace)

  • backend – Computational backend

  • seed – Random seed for space

__init__(dimension: int = 10000, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Initialize MAP model.

Parameters:
  • dimension – Dimensionality of hypervectors

  • space – Vector space (defaults to BipolarSpace)

  • backend – Computational backend

  • seed – Random seed for space

property model_name: str

Return the model name (e.g., ‘MAP’, ‘FHRR’, ‘HRR’).

property is_self_inverse: bool

Whether binding is self-inverse (bind = unbind).

property is_commutative: bool

Whether binding is commutative (bind(a, b) = bind(b, a)).

property is_exact_inverse: bool

Whether unbinding gives exact recovery (no approximation error).

bind(a: Any, b: Any) Any[source]

Bind using element-wise multiplication.

For bipolar: XOR when represented as {0,1} For real: Hadamard product

Parameters:
  • a – First vector

  • b – Second vector

Returns:

Bound vector c = a ⊙ b

unbind(a: Any, b: Any) Any[source]

Unbind using element-wise multiplication (self-inverse).

Since binding is self-inverse: unbind(c, b) = c ⊙ b

Parameters:
  • a – Bound vector (or first operand)

  • b – Second operand

Returns:

Unbound vector (exact for bipolar, approximate for continuous)

bundle(vectors: Sequence[Any]) Any[source]

Bundle using element-wise addition.

For bipolar: majority vote after summing For real: sum and normalize

Parameters:

vectors – Sequence of vectors to bundle

Returns:

Bundled vector

Raises:

ValueError – If vectors is empty

permute(vec: Any, k: int = 1) Any[source]

Permute using circular shift.

Shifts vector elements by k positions to the right. Negative k shifts left.

Parameters:
  • vec – Vector to permute

  • k – Number of positions to shift

Returns:

Permuted vector

bind_multiple(vectors: Sequence[Any]) Any

Bind multiple vectors sequentially.

For n vectors: bind(bind(bind(v1, v2), v3), …)

Parameters:

vectors – Sequence of vectors to bind

Returns:

Result of sequential binding

Raises:

ValueError – If fewer than 2 vectors provided

normalize(vec: Any) Any

Normalize vector according to space conventions.

Parameters:

vec – Vector to normalize

Returns:

Normalized vector

random(seed: int | None = None) Any

Generate a random vector from the space.

Parameters:

seed – Optional random seed

Returns:

Random vector

random_sequence(n: int, seed: int | None = None) List[Any]

Generate n random vectors.

Parameters:
  • n – Number of vectors to generate

  • seed – Optional base seed (each vector gets seed + i)

Returns:

List of random vectors

similarity(a: Any, b: Any) float

Compute similarity between two vectors.

Delegates to the vector space’s similarity metric.

Parameters:
  • a – First vector

  • b – Second vector

Returns:

Similarity score (space-dependent metric)

unpermute(vec: Any, k: int = 1) Any

Inverse permutation.

Parameters:
  • vec – Vector to unpermute

  • k – Number of positions to shift back (default: 1)

Returns:

Unpermuted vector

Key Properties:

  • Space: Bipolar ({-1, +1})

  • Binding: Element-wise multiplication

  • Unbinding: Self-inverse (multiply again)

  • Best For: Hardware implementations, speed, simplicity

FHRR Model

Fourier Holographic Reduced Representations: Exact inverse, best capacity.

class holovec.models.FHRRModel(dimension: int = 512, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Bases: VSAModel

FHRR (Fourier HRR) model using complex phasors.

Binding: element-wise complex multiplication (phase addition) Unbinding: element-wise multiplication with conjugate (phase subtraction) Bundling: element-wise addition + normalization to unit magnitude Permutation: circular shift (can also use phase rotation)

Uses ComplexSpace with unit-magnitude phasors.

Initialize FHRR model.

Parameters:
  • dimension – Dimensionality of hypervectors (can be smaller than MAP due to better capacity)

  • space – Vector space (defaults to ComplexSpace)

  • backend – Computational backend

  • seed – Random seed for space

__init__(dimension: int = 512, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Initialize FHRR model.

Parameters:
  • dimension – Dimensionality of hypervectors (can be smaller than MAP due to better capacity)

  • space – Vector space (defaults to ComplexSpace)

  • backend – Computational backend

  • seed – Random seed for space

property model_name: str

Return the model name (e.g., ‘MAP’, ‘FHRR’, ‘HRR’).

property is_self_inverse: bool

Whether binding is self-inverse (bind = unbind).

property is_commutative: bool

Whether binding is commutative (bind(a, b) = bind(b, a)).

property is_exact_inverse: bool

Whether unbinding gives exact recovery (no approximation error).

bind(a: Any, b: Any) Any[source]

Bind using element-wise complex multiplication.

For unit phasors: (a * b)[i] = a[i] * b[i] This adds phase angles: ∠(a*b) = ∠a + ∠b

Parameters:
  • a – First vector (unit phasors)

  • b – Second vector (unit phasors)

Returns:

Bound vector c = a ⊙ b (element-wise product)

unbind(a: Any, b: Any) Any[source]

Unbind using element-wise multiplication with conjugate.

To recover original from c = a ⊙ b: unbind(c, b) = c ⊙ b* = (a ⊙ b) ⊙ b* = a ⊙ (b ⊙ b*) = a ⊙ 1 = a

Parameters:
  • a – Bound vector (or first operand)

  • b – Second operand

Returns:

Unbound vector (exact recovery)

bundle(vectors: Sequence[Any]) Any[source]

Bundle using element-wise addition.

Sum phasors and normalize back to unit magnitude. The result points in the “average” direction of inputs.

Parameters:

vectors – Sequence of vectors to bundle

Returns:

Bundled vector (normalized to unit magnitude)

Raises:

ValueError – If vectors is empty

permute(vec: Any, k: int = 1) Any[source]

Permute using circular shift.

For FHRR, permutation can be done as: 1. Circular shift (coordinate permutation) 2. Phase rotation (multiply by exp(i*2πk/D))

We use circular shift for consistency with other models.

Parameters:
  • vec – Vector to permute

  • k – Number of positions to shift

Returns:

Permuted vector

fractional_power(vec: Any, exponent: float) Any[source]

Raise phasor to a fractional power.

For unit phasor z = exp(iθ): z^α = exp(iαθ) This is useful for encoding continuous values.

Parameters:
  • vec – Vector of unit phasors

  • exponent – Power to raise to

Returns:

Vector with phases scaled by exponent

Example

>>> base = model.random()
>>> # Encode value 2.5 using fractional power
>>> encoded = model.fractional_power(base, 2.5)
bind_multiple(vectors: Sequence[Any]) Any

Bind multiple vectors sequentially.

For n vectors: bind(bind(bind(v1, v2), v3), …)

Parameters:

vectors – Sequence of vectors to bind

Returns:

Result of sequential binding

Raises:

ValueError – If fewer than 2 vectors provided

normalize(vec: Any) Any

Normalize vector according to space conventions.

Parameters:

vec – Vector to normalize

Returns:

Normalized vector

random(seed: int | None = None) Any

Generate a random vector from the space.

Parameters:

seed – Optional random seed

Returns:

Random vector

random_sequence(n: int, seed: int | None = None) List[Any]

Generate n random vectors.

Parameters:
  • n – Number of vectors to generate

  • seed – Optional base seed (each vector gets seed + i)

Returns:

List of random vectors

similarity(a: Any, b: Any) float

Compute similarity between two vectors.

Delegates to the vector space’s similarity metric.

Parameters:
  • a – First vector

  • b – Second vector

Returns:

Similarity score (space-dependent metric)

unpermute(vec: Any, k: int = 1) Any

Inverse permutation.

Parameters:
  • vec – Vector to unpermute

  • k – Number of positions to shift back (default: 1)

Returns:

Unpermuted vector

Key Properties:

  • Space: Complex (unit phasors)

  • Binding: Element-wise multiplication

  • Unbinding: Exact inverse (complex conjugate)

  • Best For: High capacity, accurate retrieval

HRR Model

Holographic Reduced Representations: Circular convolution, general purpose.

class holovec.models.HRRModel(dimension: int = 10000, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Bases: VSAModel

HRR (Holographic Reduced Representations) model.

Binding: circular convolution (via FFT) Unbinding: circular correlation (via FFT) Bundling: element-wise addition + normalization Permutation: circular shift

Uses RealSpace with Gaussian distribution N(0, 1/D).

Initialize HRR model.

Parameters:
  • dimension – Dimensionality of hypervectors (recommend 1000-10000)

  • space – Vector space (defaults to RealSpace)

  • backend – Computational backend

  • seed – Random seed for space

__init__(dimension: int = 10000, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Initialize HRR model.

Parameters:
  • dimension – Dimensionality of hypervectors (recommend 1000-10000)

  • space – Vector space (defaults to RealSpace)

  • backend – Computational backend

  • seed – Random seed for space

property model_name: str

Return the model name (e.g., ‘MAP’, ‘FHRR’, ‘HRR’).

property is_self_inverse: bool

Whether binding is self-inverse (bind = unbind).

property is_commutative: bool

Whether binding is commutative (bind(a, b) = bind(b, a)).

property is_exact_inverse: bool

Whether unbinding gives exact recovery (no approximation error).

bind(a: Any, b: Any) Any[source]

Bind using circular convolution.

Implemented via FFT: conv(a, b) = IFFT(FFT(a) * FFT(b))

Parameters:
  • a – First vector

  • b – Second vector

Returns:

Bound vector c = a ⊛ b (circular convolution)

unbind(a: Any, b: Any) Any[source]

Unbind using circular correlation (approximate inverse of convolution).

This is the classic HRR unbinding operation that uses circular correlation to approximately recover the original vector from a bound pair.

Parameters:
  • a – Bound vector c = x ⊛ b (result of circular convolution)

  • b – Key vector (second operand in binding)

Returns:

Approximate recovery of x (original vector), normalized to unit length

Notes

Mathematical Foundation:

HRR binding via circular convolution:

c = x ⊛ b

In frequency domain (Fourier):

C(ω) = X(ω) · B(ω)

Unbinding via circular correlation:

x̂ = c ⋆ b = IFFT(C(ω) · B*(ω))

Where B*(ω) is the complex conjugate of B(ω).

Substituting C(ω) = X(ω) · B(ω):
x̂ = IFFT(X(ω) · B(ω) · B*(ω))

= IFFT(X(ω) · |B(ω)|²)

For random vectors with approximately uniform power spectrum (|B(ω)|² ≈ 1), this gives x̂ ≈ x.

Approximation Quality:

Recovery similarity depends on: - Dimension D: Higher D → better recovery - Noise level: Clean binding → better unbind - Bundle size: More items → more interference

Empirical performance (D=10000): - Clean unbind: similarity ≈ 0.65-0.75 (approximate inverse) - After bundling 2 items: similarity ≈ 0.57 - After bundling 10 items: similarity ≈ 0.30 - After bundling 100 items: similarity decreases further

References

  • Plate (1995): “Holographic Reduced Representations”

  • Plate (2003): “Holographic Reduced Representations” (full book)

Examples

>>> model = VSA.create('HRR', dim=10000)
>>> x = model.random(seed=1)
>>> b = model.random(seed=2)
>>> c = model.bind(x, b)
>>> x_recovered = model.unbind(c, b)
>>> similarity = model.similarity(x, x_recovered)
>>> print(f"Recovery similarity: {similarity:.3f}")  # ~0.99
bundle(vectors: Sequence[Any]) Any[source]

Bundle using element-wise addition (superposition).

For HRR, bundling is simple vector addition without normalization. This preserves the magnitude relationships needed for proper unbinding.

Parameters:

vectors – Sequence of vectors to bundle

Returns:

Bundled vector (unnormalized sum)

Raises:

ValueError – If vectors is empty

Notes

Unlike some VSA models, HRR does NOT normalize after bundling. Normalization would interfere with the circular correlation unbinding operation. The unbind() method handles normalization of its output.

permute(vec: Any, k: int = 1) Any[source]

Permute using circular shift.

Shifts vector elements by k positions to the right. Negative k shifts left.

Parameters:
  • vec – Vector to permute

  • k – Number of positions to shift

Returns:

Permuted vector

bind_multiple(vectors: Sequence[Any]) Any

Bind multiple vectors sequentially.

For n vectors: bind(bind(bind(v1, v2), v3), …)

Parameters:

vectors – Sequence of vectors to bind

Returns:

Result of sequential binding

Raises:

ValueError – If fewer than 2 vectors provided

normalize(vec: Any) Any

Normalize vector according to space conventions.

Parameters:

vec – Vector to normalize

Returns:

Normalized vector

random(seed: int | None = None) Any

Generate a random vector from the space.

Parameters:

seed – Optional random seed

Returns:

Random vector

random_sequence(n: int, seed: int | None = None) List[Any]

Generate n random vectors.

Parameters:
  • n – Number of vectors to generate

  • seed – Optional base seed (each vector gets seed + i)

Returns:

List of random vectors

similarity(a: Any, b: Any) float

Compute similarity between two vectors.

Delegates to the vector space’s similarity metric.

Parameters:
  • a – First vector

  • b – Second vector

Returns:

Similarity score (space-dependent metric)

unpermute(vec: Any, k: int = 1) Any

Inverse permutation.

Parameters:
  • vec – Vector to unpermute

  • k – Number of positions to shift back (default: 1)

Returns:

Unpermuted vector

Key Properties:

  • Space: Real (Gaussian)

  • Binding: Circular convolution

  • Unbinding: Circular correlation (approximate inverse)

  • Best For: General purpose, proven track record

BSC Model

Binary Spatter Codes: Memory-efficient, sparse binary.

class holovec.models.BSCModel(dimension: int = 10000, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Bases: VSAModel

BSC (Binary Spatter Codes) model.

Binding: XOR Unbinding: XOR (self-inverse) Bundling: element-wise addition + majority vote Permutation: circular shift

Uses BinarySpace with values in {0, 1}.

Initialize BSC model.

Parameters:
  • dimension – Dimensionality of hypervectors

  • space – Vector space (defaults to BinarySpace)

  • backend – Computational backend

  • seed – Random seed for space

__init__(dimension: int = 10000, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Initialize BSC model.

Parameters:
  • dimension – Dimensionality of hypervectors

  • space – Vector space (defaults to BinarySpace)

  • backend – Computational backend

  • seed – Random seed for space

property model_name: str

Return the model name (e.g., ‘MAP’, ‘FHRR’, ‘HRR’).

property is_self_inverse: bool

Whether binding is self-inverse (bind = unbind).

property is_commutative: bool

Whether binding is commutative (bind(a, b) = bind(b, a)).

property is_exact_inverse: bool

Whether unbinding gives exact recovery (no approximation error).

bind(a: Any, b: Any) Any[source]

Bind using XOR.

For binary vectors: a XOR b Property: a XOR b XOR b = a (self-inverse)

Parameters:
  • a – First vector (binary {0, 1})

  • b – Second vector (binary {0, 1})

Returns:

Bound vector c = a XOR b

unbind(a: Any, b: Any) Any[source]

Unbind using XOR (self-inverse).

Since XOR is self-inverse: unbind(c, b) = c XOR b

Parameters:
  • a – Bound vector (or first operand)

  • b – Second operand

Returns:

Unbound vector (exact recovery)

bundle(vectors: Sequence[Any]) Any[source]

Bundle using element-wise addition + majority vote.

Sum all binary vectors element-wise, then threshold at n/2 where n is the number of vectors.

Parameters:

vectors – Sequence of vectors to bundle

Returns:

Bundled vector (binary {0, 1})

Raises:

ValueError – If vectors is empty

permute(vec: Any, k: int = 1) Any[source]

Permute using circular shift.

Shifts vector elements by k positions to the right. Negative k shifts left.

Parameters:
  • vec – Vector to permute

  • k – Number of positions to shift

Returns:

Permuted vector

to_bipolar(vec: Any) Any[source]

Convert binary {0, 1} to bipolar {-1, +1}.

Transformation: x → 2x - 1

Parameters:

vec – Binary vector

Returns:

Bipolar vector

from_bipolar(vec: Any) Any[source]

Convert bipolar {-1, +1} to binary {0, 1}.

Transformation: x → (x + 1) / 2

Parameters:

vec – Bipolar vector

Returns:

Binary vector

bind_multiple(vectors: Sequence[Any]) Any

Bind multiple vectors sequentially.

For n vectors: bind(bind(bind(v1, v2), v3), …)

Parameters:

vectors – Sequence of vectors to bind

Returns:

Result of sequential binding

Raises:

ValueError – If fewer than 2 vectors provided

normalize(vec: Any) Any

Normalize vector according to space conventions.

Parameters:

vec – Vector to normalize

Returns:

Normalized vector

random(seed: int | None = None) Any

Generate a random vector from the space.

Parameters:

seed – Optional random seed

Returns:

Random vector

random_sequence(n: int, seed: int | None = None) List[Any]

Generate n random vectors.

Parameters:
  • n – Number of vectors to generate

  • seed – Optional base seed (each vector gets seed + i)

Returns:

List of random vectors

similarity(a: Any, b: Any) float

Compute similarity between two vectors.

Delegates to the vector space’s similarity metric.

Parameters:
  • a – First vector

  • b – Second vector

Returns:

Similarity score (space-dependent metric)

unpermute(vec: Any, k: int = 1) Any

Inverse permutation.

Parameters:
  • vec – Vector to unpermute

  • k – Number of positions to shift back (default: 1)

Returns:

Unpermuted vector

Key Properties:

  • Space: Binary ({0, 1})

  • Binding: XOR

  • Unbinding: Self-inverse (XOR again)

  • Best For: Memory efficiency, binary operations

BSDC, GHRR, VTB Models

Additional specialized models:

class holovec.models.BSDCModel(dimension: int = 10000, sparsity: float | None = None, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Bases: VSAModel

BSDC (Binary Sparse Distributed Codes) model.

Binding: XOR (element-wise, self-inverse) Unbinding: XOR (same as binding, self-inverse) Bundling: Majority voting with sparsity preservation Permutation: circular shift

Uses SparseSpace with optimal sparsity p = 1/√D.

Initialize BSDC model.

Parameters:
  • dimension – Dimensionality of hypervectors (typically > 1000)

  • sparsity – Fraction of 1s (default: 1/√D which is optimal)

  • space – Vector space (defaults to SparseSpace with optimal sparsity)

  • backend – Computational backend

  • seed – Random seed for space

__init__(dimension: int = 10000, sparsity: float | None = None, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None)[source]

Initialize BSDC model.

Parameters:
  • dimension – Dimensionality of hypervectors (typically > 1000)

  • sparsity – Fraction of 1s (default: 1/√D which is optimal)

  • space – Vector space (defaults to SparseSpace with optimal sparsity)

  • backend – Computational backend

  • seed – Random seed for space

property model_name: str

Return the model name (e.g., ‘MAP’, ‘FHRR’, ‘HRR’).

property is_self_inverse: bool

Whether binding is self-inverse (bind = unbind).

property is_commutative: bool

Whether binding is commutative (bind(a, b) = bind(b, a)).

property is_exact_inverse: bool

Whether unbinding gives exact recovery (no approximation error).

bind(a: Any, b: Any) Any[source]

Bind using XOR.

For sparse binary codes, XOR preserves sparsity on average. Expected sparsity of result: p(1-p) + (1-p)p = 2p(1-p)

For optimal p = 1/√D, result sparsity ≈ 2/√D (slightly increased).

Parameters:
  • a – First hypervector

  • b – Second hypervector

Returns:

Bound hypervector c = a XOR b

unbind(a: Any, b: Any) Any[source]

Unbind using XOR (self-inverse).

Since XOR is self-inverse: unbind(bind(a, b), b) = a

Parameters:
  • a – Bound hypervector (or first operand)

  • b – Second operand

Returns:

Unbound hypervector (exact recovery)

bundle(vectors: Sequence[Any], maintain_sparsity: bool = True) Any[source]

Bundle using majority voting.

For sparse codes, bundling requires careful handling to maintain sparsity: 1. Sum all vectors element-wise 2. Apply threshold to get binary result 3. Optionally re-sparsify to maintain target sparsity

Parameters:
  • vectors – Sequence of hypervectors to bundle

  • maintain_sparsity – If True, enforce target sparsity (default: True)

Returns:

Bundled hypervector

Raises:

ValueError – If vectors is empty

permute(vec: Any, k: int = 1) Any[source]

Permute using circular shift.

Shifts vector elements by k positions. For sparse codes, this maintains sparsity perfectly.

Parameters:
  • vec – Hypervector to permute

  • k – Number of positions to shift (default: 1)

Returns:

Permuted hypervector

measure_sparsity(vec: Any) float[source]

Measure actual sparsity of a vector.

Parameters:

vec – Hypervector to measure

Returns:

Fraction of 1s in the vector

rehash(vec: Any) Any[source]

Rehash vector to restore optimal sparsity.

Useful after multiple operations that may have changed sparsity. Randomly selects positions to maintain target sparsity while preserving as much similarity as possible.

Parameters:

vec – Hypervector to rehash

Returns:

Rehashed hypervector with target sparsity

encode_sequence(items: Sequence[Any], use_ngrams: bool = False, n: int = 2) Any[source]

Encode sequence of items.

Two strategies: 1. Position binding: item_i ⊗ ρⁱ(position) 2. N-grams: Bundle all n-grams in sequence

Parameters:
  • items – Sequence of hypervectors

  • use_ngrams – If True, use n-gram encoding (default: False)

  • n – N-gram size (default: 2 for bigrams)

Returns:

Sequence hypervector

Raises:

ValueError – If items is empty

class holovec.models.GHRRModel(dimension: int = 100, matrix_size: int = 3, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None, diagonality: float | None = None)[source]

Bases: VSAModel

GHRR (Generalized Holographic Reduced Representations) model.

Binding: element-wise matrix multiplication (phase addition per matrix) Unbinding: element-wise multiplication with conjugate transpose Bundling: element-wise addition + normalization Permutation: circular shift (or use non-commutativity instead)

Uses MatrixSpace with m×m unitary matrices.

Initialize GHRR model.

Parameters:
  • dimension – Number of matrices in hypervector (can be smaller than scalar models due to better capacity)

  • matrix_size – Size m of each m×m matrix (default: 3) Larger m → more non-commutative, better for complex structures m=1 recovers FHRR

  • space – Vector space (defaults to MatrixSpace)

  • backend – Computational backend

  • seed – Random seed for space

  • diagonality – Control commutativity in [0, 1] None: Random (default) 0.0: Maximally non-commutative 1.0: Fully commutative (FHRR-like)

__init__(dimension: int = 100, matrix_size: int = 3, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None, diagonality: float | None = None)[source]

Initialize GHRR model.

Parameters:
  • dimension – Number of matrices in hypervector (can be smaller than scalar models due to better capacity)

  • matrix_size – Size m of each m×m matrix (default: 3) Larger m → more non-commutative, better for complex structures m=1 recovers FHRR

  • space – Vector space (defaults to MatrixSpace)

  • backend – Computational backend

  • seed – Random seed for space

  • diagonality – Control commutativity in [0, 1] None: Random (default) 0.0: Maximally non-commutative 1.0: Fully commutative (FHRR-like)

property model_name: str

Return the model name (e.g., ‘MAP’, ‘FHRR’, ‘HRR’).

property is_self_inverse: bool

Whether binding is self-inverse (bind = unbind).

property is_commutative: bool

Whether binding is commutative (bind(a, b) = bind(b, a)).

property is_exact_inverse: bool

Whether unbinding gives exact recovery (no approximation error).

property commutativity_degree: float

Degree of commutativity in [0, 1].

For GHRR, this depends on the diagonality of Q matrices. More diagonal → more commutative.

Returns:

0.0 if maximally non-commutative, 1.0 if fully commutative

bind(a: Any, b: Any) Any[source]

Bind using element-wise matrix multiplication.

For matrices at position j: (a ⊗ b)_j = a_j @ b_j

This is non-commutative: a ⊗ b ≠ b ⊗ a in general.

Parameters:
  • a – First hypervector (D, m, m)

  • b – Second hypervector (D, m, m)

Returns:

Bound hypervector c where c_j = a_j @ b_j for all j

unbind(a: Any, b: Any) Any[source]

Unbind using element-wise multiplication with conjugate transpose.

To recover original from c = a ⊗ b: unbind(c, b) = c_j @ b_j† for all j

This provides exact recovery: unbind(bind(a, b), b) = a

Parameters:
  • a – Bound hypervector (or first operand)

  • b – Second operand

Returns:

Unbound hypervector (exact recovery)

bundle(vectors: Sequence[Any]) Any[source]

Bundle using element-wise addition.

Sum all hypervectors element-wise. Each element is an m×m matrix.

For GHRR: (a + b)_j = a_j + b_j (matrix addition)

Parameters:

vectors – Sequence of hypervectors to bundle

Returns:

Bundled hypervector

Raises:

ValueError – If vectors is empty

permute(vec: Any, k: int = 1) Any[source]

Permute using circular shift.

For GHRR, permutation is less critical since non-commutativity can encode order. But still useful for some applications.

Parameters:
  • vec – Hypervector to permute (D, m, m)

  • k – Number of positions to shift

Returns:

Permuted hypervector

test_non_commutativity(a: Any, b: Any) float[source]

Test degree of non-commutativity for two hypervectors.

Computes: δ(a ⊗ b, b ⊗ a)

A similarity of 1.0 means commutative, close to 0 means non-commutative.

Parameters:
  • a – First hypervector

  • b – Second hypervector

Returns:

Similarity between a⊗b and b⊗a

compute_diagonality(vec: Any) float[source]

Compute average diagonality of matrices in hypervector.

Diagonality metric: Σ|Q_jj| / ΣΣ|Q_jk|

Parameters:

vec – Hypervector (D, m, m)

Returns:

Diagonality in [0, 1]

class holovec.models.VTBModel(dimension: int = 10000, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None, n_bases: int = 4, shifts: List[int] | None = None, temperature: float = 100.0)[source]

Bases: VSAModel

VTB (Vector-derived Transformation Binding) model.

Binding (MBAT-style): c = Σ_k w_k(a) · roll(b, s_k) Unbinding (approximate): b̂ = Σ_k w_k(a) · roll(c, -s_k) Bundling: element-wise addition + normalization Permutation: circular shift

Uses RealSpace with L2-normalized real-valued vectors.

Initialize VTB model.

Parameters:
  • dimension – Dimensionality of hypervectors

  • space – Vector space (defaults to RealSpace)

  • backend – Computational backend

  • seed – Random seed for space

__init__(dimension: int = 10000, space: VectorSpace | None = None, backend: Backend | None = None, seed: int | None = None, n_bases: int = 4, shifts: List[int] | None = None, temperature: float = 100.0)[source]

Initialize VTB model.

Parameters:
  • dimension – Dimensionality of hypervectors

  • space – Vector space (defaults to RealSpace)

  • backend – Computational backend

  • seed – Random seed for space

property model_name: str

Return the model name (e.g., ‘MAP’, ‘FHRR’, ‘HRR’).

property is_self_inverse: bool

Whether binding is self-inverse (bind = unbind).

property is_commutative: bool

Whether binding is commutative (bind(a, b) = bind(b, a)).

property is_exact_inverse: bool

Whether unbinding gives exact recovery (no approximation error).

bind(a: Any, b: Any) Any[source]

Bind using MBAT-style weighted basis transforms.

c = Σ_k w_k(a) · roll(b, s_k)

unbind(c: Any, b: Any) Any[source]

Approximate unbinding using weighted inverse transforms.

IMPORTANT: Due to non-commutativity, this recovers b from c = bind(a, b). You must pass the FIRST argument of bind (a) as the second argument here.

For c = bind(a, b):
  • unbind(c, a) → recovers b (correct usage)

  • unbind(c, b) → does NOT recover a

b̂ = Σ_k w_k(b) · roll(c, -s_k)

bundle(vectors: Sequence[Any]) Any[source]

Bundle using element-wise addition.

Sum all hypervectors element-wise and normalize.

Parameters:

vectors – Sequence of hypervectors to bundle

Returns:

Bundled hypervector

Raises:

ValueError – If vectors is empty

permute(vec: Any, k: int = 1) Any[source]

Permute using circular shift.

Shifts vector elements by k positions. Combined with binding, this can encode position in sequences.

Parameters:
  • vec – Hypervector to permute

  • k – Number of positions to shift (default: 1)

Returns:

Permuted hypervector

test_non_commutativity(a: Any, b: Any) float[source]

Test degree of non-commutativity for two hypervectors.

Computes: similarity(a ⊗ b, b ⊗ a)

A similarity of 1.0 means commutative, close to 0 means non-commutative.

Parameters:
  • a – First hypervector

  • b – Second hypervector

Returns:

Similarity between a⊗b and b⊗a (should be low for VTB)

bind_sequence(items: Sequence[Any], use_permute: bool = True) Any[source]

Bind a sequence of items with positional encoding.

Two strategies: 1. With permutation: c = a₁ ⊗ ρ⁰(pos) + a₂ ⊗ ρ¹(pos) + … 2. Without permutation: c = (…((a₁ ⊗ a₂) ⊗ a₃)…) (nested binding)

Parameters:
  • items – Sequence of hypervectors to bind

  • use_permute – If True, use permutation strategy; else nested binding

Returns:

Sequence hypervector

Raises:

ValueError – If items is empty

See Also