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: .. code-block:: python 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: .. code-block:: python result = enc.bundle(a, b, c) You can also pass a list: .. code-block:: python hvs = [enc.generate() for _ in range(10)] result = enc.bundle(*hvs) **3. Convenience function**: module-level shortcut: .. code-block:: python result = pyhdc.bundle(a, b, c) **4. Batched bundling**: bundle multiple groups at once: .. code-block:: python # 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: .. code-block:: python 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: .. code-block:: python zero = enc.zeros() result = enc.bundle(a, zero) print(result.similarity(a)) # ~= 1.0 This is useful when building bundles iteratively: .. code-block:: python 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 :math:`O(N \times ln(M))` vectors into a single hypervector of dimension :math:`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: .. list-table:: :header-rows: 1 :widths: 20 80 * - 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