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:
ABCAbstract 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
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:
VSAModelMAP (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
- 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
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:
VSAModelFHRR (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
- 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
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:
VSAModelHRR (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
- 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
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:
VSAModelBSC (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
- 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
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:
VSAModelBSDC (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
- 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:
VSAModelGHRR (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 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
- 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:
VSAModelVTB (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
- 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¶
VSA - Main API - Main VSA API
Choosing a VSA Model - Model selection guide
Theory Guide: Hyperdimensional Computing & Vector Symbolic Architectures - Mathematical foundations