How to Bundle Hypervectors

Bundling combines multiple hypervectors into one that is similar to all inputs. Four equivalent ways to bundle are provided.

Four bundling methods

1. Instance method: bundle one hypervector with others:

import pyhdc

enc = pyhdc.MAP_C(dimension=10_000)
a, b, c = enc.generate(), enc.generate(), enc.generate()

result = a.bundle(b, c)   # result is similar to a, b, and c

2. Encoding method: bundle via the encoding object:

result = enc.bundle(a, b, c)

You can also pass a list:

hvs    = [enc.generate() for _ in range(10)]
result = enc.bundle(*hvs)

3. Convenience function: module-level shortcut:

result = pyhdc.bundle(a, b, c)

4. Batched bundling: bundle multiple groups at once:

# Bundle [[a,b], [c,d]] -> returns [bundle(a,b), bundle(c,d)]
results = enc.bundle([a, b], [c, d])   # list of two Hypervectors

Collapse a whole batch to one prototype

A batch of N hypervectors is a (D, N) array, where each column is one hypervector. Passing such a batch to bundle folds over the N columns and returns a single (D,) prototype:

import pyhdc

enc   = pyhdc.MAP_C(dimension=10_000)
batch = enc.generate(size=(10_000, 50))   # 50 vectors as columns (shape: (10000, 50))
# collapse the 50 columns into one prototype
result = enc.bundle(batch)
print(result.shape)   # (10000,)

Zero vector as the bundle identity

The zero hypervector acts as the additive identity for bundling; bundling anything with zero leaves it unchanged:

zero   = enc.zeros()
result = enc.bundle(a, zero)
print(result.similarity(a))   # ~= 1.0

This is useful when building bundles iteratively:

accumulator = enc.zeros()
for hv in hvs:
    accumulator = enc.bundle(accumulator, hv)

Capacity limits

Bundling is lossy: each bundle adds noise to every component. The more hypervectors you bundle, the harder it is to distinguish individual members via similarity.

Approximate rule of thumb: bundling more than \(O(N \times ln(M))\) vectors into a single hypervector of dimension \(D\) causes the similarity to each component to drop below a useful threshold.

Encoding-specific notes

Different encoding families use different bundling implementations, but the interface is always the same:

Encoding

Bundling behaviour

MAP_C

Element-wise addition then clip to [-1,1]; ties broken randomly (random_choice_range parameter)

MAP_I, MAP_B

Element-wise addition with integer clipping

HRR

Element-wise addition followed by L2 normalisation

HRR_NoNorm

Element-wise addition without normalisation (vectors grow in magnitude)

FHRR

Sum phasors, extract resultant angle

BSC

Majority-vote threshold: each element is 1 if more than half the inputs are 1

BSDC family

Bitwise OR; BSDC_THIN applies random thinning after OR to maintain density