Components Module
The pyhdc.components module contains the low-level building blocks used
internally by all encodings. Most users do not need to import these directly,
they are assembled automatically by the encoding classes via EncodingSpec.
Use the components module when:
Writing a custom encoding subclass
Applying a specific operation outside an encoding context
Using
remap_to_unitfor post-processing
pyhdc.components.similarity
- pyhdc.components.similarity.CosineSimilarity(*hypervectors: ndarray | torch.Tensor, axis: int | None = None, mode: str = 'pairwise')[source]
CosineSimilarity Cosine Similarity of hypervectors
cos(theta) = ( A dot B ) / ( norm(A) * norm(B) )
Hypervectors are dimension-first (axis 0 is always the dimension
D). Supports these calling conventions:(a, b) where a and b are 1D: returns a scalar in [-1, 1] (a, b) batches: per-pair scores (trailing axes broadcast) (arr,) where arr is (D, N): sim(col_0, col_i) for i in 1..N-1 (arr,) where arr is (D, N, M, ...): requires ``axis`` (split index 0 vs the rest along that batch axis)With
mode="cross"and two batchesA=(D, P),B=(D, M), returns the full(P, M)cross-similarity matrix via a single matmul of the normalized operands (an all-zero column is treated as orthogonal, scoring 0 rather than nan).- Parameters:
*hypervectors – Two hypervectors, or a single batch array
axis – For a single
(D, N, M, ...)batch, the batch axis to split onmode –
"pairwise"(default) or"cross"
- Returns:
Scalar similarity, or an array of similarities over the trailing axes
Cosine similarity between two vectors or batches.
With
mode="cross"and two batchesA=(D, P),B=(D, M), returns the full(P, M)cross-similarity matrix.- Returns:
float,ndarray, orTensorin [-1, 1]. Operates column-wise over axis 0 of a(D, N)batch. See the batched calling conventions.
- pyhdc.components.similarity.HammingDistance(*hypervectors: ndarray | torch.Tensor, axis: int | None = None, mode: str = 'pairwise')[source]
HammingDistance Hamming Distance of hypervectors
Counts the number of elements where A[i] != B[i], normalized to the hypervector dimension and mapped to [-1, 1] where 1 is identical, -1 is completely different, and 0 is half-matching.
Hypervectors are dimension-first (axis 0 is always the dimension
D). Supports these calling conventions:(a, b) where a and b are 1D: returns a scalar in [-1, 1] (a, b) batches: per-pair scores (trailing axes broadcast) (arr,) where arr is (D, N): sim(col_0, col_i) for i in 1..N-1 (arr,) where arr is (D, N, M, ...): requires ``axis``
With
mode="cross"and two binary{0, 1}batchesA=(D, P),B=(D, M), returns the full(P, M)cross-similarity matrix.- Parameters:
*hypervectors – Two hypervectors, or a single batch array
axis – For a single
(D, N, M, ...)batch, the batch axis to split onmode –
"pairwise"(default) or"cross"
- Returns:
Scalar similarity, or an array of similarities over the trailing axes
Normalised Hamming distance, mapped to [-1, 1].
Appropriate for dense binary vectors (BSC encoding).
With
mode="cross"and two batchesA=(D, P),B=(D, M), returns the full(P, M)cross-similarity matrix.- Returns:
Value in [-1, 1]. (Was [0, 1] in v1.0.x.)
- pyhdc.components.similarity.Overlap(*hypervectors: ndarray | torch.Tensor, axis: int | None = None, mode: str = 'pairwise')[source]
Overlap similarity for sparse binary vectors, normalized by nonzeros in B.
Counts the elements where both A[i] and B[i] are 1, normalized to the number of nonzero elements in the reference (second) hypervector B and mapped to [-1, 1] where 1 is identical, -1 is no overlap, and 0 is 50% overlap. Normalizing against B means the best results come from passing the bundled hypervector as A and the reference as B.
Hypervectors are dimension-first (axis 0 is always the dimension
D). Supports these calling conventions:(a, b) where a and b are 1D: returns a scalar in [-1, 1] (a, b) batches: per-pair scores (trailing axes broadcast) (arr,) where arr is (D, N): sim(col_0, col_i) for i in 1..N-1 (arr,) where arr is (D, N, M, ...): requires ``axis``
With
mode="cross"and two sparse binary{0, 1}batchesA=(D, P)(prototypes),B=(D, M)(codebook), returns the full(P, M)matrix. The normalization stays asymmetric, each columnmis divided by the nonzero count ofB[:, m](the second argument). So pass the bundled vectors as A and the reference codebook as B.- Parameters:
*hypervectors – Two hypervectors, or a single batch array
axis – For a single
(D, N, M, ...)batch, the batch axis to split onmode –
"pairwise"(default) or"cross"
- Returns:
Scalar similarity, or an array of similarities over the trailing axes
Normalised overlap (set intersection), mapped to [-1, 1].
Appropriate for sparse binary vectors (BSDC family).
With
mode="cross", returns the full(P, M)matrix. Normalization stays asymmetric (each columnmdivided by the nonzero count ofB[:, m]), so pass the bundled vectors asAand the reference codebook asB.- Returns:
Value in [-1, 1]. (Was [0, 1] in v1.0.x.)
- pyhdc.components.similarity.AngleDistance(*hypervectors: ndarray | torch.Tensor, axis: int | None = None, mode: str = 'pairwise')[source]
AngleDistance Angle Distance of phase hypervectors
Calculates the average angular distance of two complex hypervectors of unit length, normalized to the hypervector dimension so it is in [-1, 1].
Hypervectors are dimension-first (axis 0 is always the dimension
D). Supports these calling conventions:(a, b) where a and b are 1D: returns a scalar in [-1, 1] (a, b) batches: per-pair scores (trailing axes broadcast) (arr,) where arr is (D, N): sim(col_0, col_i) for i in 1..N-1 (arr,) where arr is (D, N, M, ...): requires ``axis``
With
mode="cross"and two phase batchesA=(D, P),B=(D, M), returns the full(P, M)matrix usingcos(x - y) = cos x cos y + sin x sin yso the reduction overDis two matmuls and no(D, P, M)tensor is built.- Parameters:
*hypervectors – Two hypervectors, or a single batch array
axis – For a single
(D, N, M, ...)batch, the batch axis to split onmode –
"pairwise"(default) or"cross"
- Returns:
Scalar similarity, or an array of similarities over the trailing axes
Cosine of element-wise angle differences.
Appropriate for phase/angle encodings (FHRR).
With
mode="cross"and two batchesA=(D, P),B=(D, M), returns the full(P, M)cross-similarity matrix.- Returns:
Value in [-1, 1].
- pyhdc.components.similarity.remap_to_unit(sim: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Remap similarity from [-1, 1] to [0, 1].
Maps the standard [-1, 1] similarity range to [0, 1], where 0.5 is orthogonal, 1.0 is identical, and 0.0 is completely opposite. Works on scalars, numpy arrays, and torch tensors.
Pass to an encoding via the
similarity_remapparameter:enc = BSC(dimension=10_000, similarity_remap=remap_to_unit)
- Parameters:
sim – Similarity value(s) in [-1, 1]
- Returns:
Remapped value(s) in [0, 1]
Map a similarity value from [-1, 1] to [0, 1]:
(sim + 1) / 2.- Parameters:
sim – Scalar,
ndarray, orTensor.- Returns:
Same type as input, values in [0, 1].
pyhdc.components.binding
- pyhdc.components.binding.ElementMultiplication(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Element-wise multiplication binding.
Binds hypervectors by multiplying corresponding elements. Commonly used with MAP encodings (bipolar values). Operands broadcast over the trailing batch axes, so a single
(D,)key binds against every column of a(D, N)batch, and two(D, N)batches bind per column.- Parameters:
*hypervectors – Variable number of hypervectors to bind, or single 2D batch
- Returns:
Bound hypervector
Example
>>> v1 = np.array([1, -1, 1, -1]) >>> v2 = np.array([1, 1, -1, -1]) >>> result = ElementMultiplication(v1, v2) >>> # result: [1, -1, -1, 1]
Element-wise product of bipolar vectors. Self-inverse. Used by MAP family.
- pyhdc.components.binding.CircularConvolution(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Circular convolution binding.
Binds hypervectors using circular convolution in the frequency domain. Used in Holographic Reduced Representations (HRR).
- Parameters:
*hypervectors – Variable number of hypervectors to bind, or single 2D batch
- Returns:
Bound hypervector
Note
Binding is performed iteratively for more than 2 vectors: bind(A, B, C) = bind(bind(A, B), C)
Circular convolution via FFT. Used by HRR family for binding.
- pyhdc.components.binding.CircularCorrelation(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Circular correlation (unbinding operation for circular convolution).
Unbinds hypervectors by performing circular correlation, which is the approximate inverse of circular convolution.
- Parameters:
*hypervectors – Variable number of hypervectors, or single 2D batch
- Returns:
Unbound hypervector
Note
For unbinding bind(A, B) with B, compute: correlate(bind(A, B), B) ≈ A
Circular correlation via FFT. Used by HRR family for unbinding.
- pyhdc.components.binding.ExclusiveOr(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
XOR binding for binary hypervectors.
Binds binary hypervectors using exclusive OR. Used with Binary Spatter Codes (BSC) and other binary encodings. XOR is its own inverse. Operands broadcast over the trailing batch axes (a single key binds against each column of a batch, two batches bind per column).
- Parameters:
*hypervectors – Variable number of binary hypervectors, or single 2D batch
- Returns:
Bound binary hypervector
Example
>>> v1 = np.array([1, 0, 1, 0]) >>> v2 = np.array([1, 1, 0, 0]) >>> result = ExclusiveOr(v1, v2) >>> # result: [0, 1, 1, 0]
Element-wise XOR. Exactly self-inverse. Used by BSC.
- pyhdc.components.binding.Shifting(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Binding by circular shifting.
Binds sparse binary hypervectors by rotating positions based on a hash of the previous vector. Used with Binary Sparse Distributed Codes (BSDC).
- Parameters:
*hypervectors – Variable number of sparse binary hypervectors, or single 2D batch
- Returns:
Bound hypervector
Circular shift by one position. Used by BSDC_S, BSDC_THIN for binding.
- pyhdc.components.binding.InverseShifting(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Unbinding operation for shift-based binding.
Reverses the circular shifts applied during binding.
- Parameters:
*hypervectors – Variable number of hypervectors, or single 2D batch
- Returns:
Unbound hypervector
Circular shift in the reverse direction. Used for unbinding in BSDC_S.
- pyhdc.components.binding.SegmentShifting(*hypervectors: ndarray | torch.Tensor, probability: float | None = None) ndarray | torch.Tensor[source]
Segment-based circular shifting for binding.
Divides hypervectors into segments and applies different rotations to each segment based on the content of previous vectors.
- Parameters:
*hypervectors – Variable number of sparse binary hypervectors, or single 2D batch
probability – Probability parameter controlling number of segments
- Returns:
Bound hypervector
Per-segment circular shift. Used by BSDC_SEG for binding.
- pyhdc.components.binding.InverseSegmentShifting(*hypervectors: ndarray | torch.Tensor, probability: float | None = None) ndarray | torch.Tensor[source]
Unbinding operation for segment-based shifting.
- Parameters:
*hypervectors – Variable number of hypervectors, or single 2D batch
probability – Probability parameter (must match binding)
- Returns:
Unbound hypervector
Per-segment inverse shift. Used by BSDC_SEG for unbinding.
- pyhdc.components.binding.AdditiveContextDependentThinning(*hypervectors: ndarray | torch.Tensor, probability: float | None = None, seed: int | None = None) ndarray | torch.Tensor[source]
Context-dependent thinning for sparse hypervectors.
Binds sparse vectors while controlling density through selective thinning based on context. Used with BSDC encodings.
- Parameters:
*hypervectors – Variable number of sparse binary hypervectors, or single 2D batch
probability – Probability parameter for thinning
seed – Random seed for reproducibility
- Returns:
Bound and thinned hypervector
Note
This requires the Disjunction operation from bundling module
CDT binding. Not invertible. Used by BSDC_CDT.
- pyhdc.components.binding.VectorDerivedTransformation(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Vector-Derived Transformation Binding.
Binds vectors using the equation: B_v(y, x) = V_y * x where V_y is a matrix derived from vector y.
For multiple vectors [x1, x2, x3, …, xn]: B_v(x1, x2, x3, …, xn) = V_xn * V_x(n-1) * … * V_x2 * x1
- Parameters:
*hypervectors – Variable number of hypervectors to bind, or single 2D batch
- Returns:
Bound hypervector
Note
Requires hypervector dimension to be a perfect fourth power (d = k^4)
Matrix derived from key vector, applied to value. Used by VTB for binding.
- pyhdc.components.binding.TransposeVectorDerivedTransformation(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Pseudo-inverse for Vector-Derived Transformation (unbinding).
Unbinds vectors using: B+_v(y, x) = V_y^T * x where V_y^T is the transpose of the V_y matrix.
- Parameters:
*hypervectors – Variable number of hypervectors, or single 2D batch
- Returns:
Unbound hypervector
Transpose of VDT matrix. Used by VTB for unbinding.
- pyhdc.components.binding.MatrixMultiplication(*hypervectors: ndarray | torch.Tensor, matrices: List[ndarray | torch.Tensor] | None = None, seed: int | None = None) Tuple[ndarray | torch.Tensor, List[ndarray | torch.Tensor]][source]
Matrix-based binding using random orthogonal matrices.
Binds hypervectors by transforming them with random matrices. Returns both the bound result and the matrices for later unbinding.
- Parameters:
*hypervectors – Variable number of hypervectors to bind (single (D,) each)
matrices – Optional pre-generated matrices. If None, generates new ones.
seed – Random seed for reproducible matrix generation
- Returns:
Tuple of (bound hypervector, list of matrices)
Note
Requires N-1 matrices to bind N hypervectors. Matrix binding is not batch-safe; use batch_dim= at the Encoding layer to loop over a batch.
Random matrix multiplication. Used by MBAT for binding. Returns
(result, matrices); matrices must be saved for unbinding.
- pyhdc.components.binding.InverseMatrixMultiplication(*hypervectors: ndarray | torch.Tensor, matrices: List[ndarray | torch.Tensor]) ndarray | torch.Tensor[source]
Unbinding operation for matrix-based binding.
Recovers the original hypervector using the stored matrices.
- Parameters:
*hypervectors – Variable number of hypervectors (bound result + unbinding keys)
matrices – List of matrices used during binding
- Returns:
Unbound hypervector
Note
Not batch-safe; use batch_dim= at the Encoding layer to loop over a batch.
Matrix inverse multiplication. Used by MBAT for unbinding.
- pyhdc.components.binding.ElementAngleAddition(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Binding by adding phase angles.
Used with Fourier Holographic Reduced Representations (FHRR) where hypervector elements represent phase angles. Operands broadcast over the trailing batch axes.
- Parameters:
*hypervectors – Variable number of phase hypervectors, or single 2D batch
- Returns:
Bound hypervector with phases in [0, 2*pi)
Element-wise modular angle addition. Used by FHRR for binding.
- pyhdc.components.binding.ElementAngleSubtraction(*hypervectors: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Unbinding by subtracting phase angles.
Inverse operation for ElementAngleAddition. Operands broadcast over the trailing batch axes.
- Parameters:
*hypervectors – Variable number of phase hypervectors, or single 2D batch
- Returns:
Unbound hypervector with phases in [0, 2*pi)
Element-wise modular angle subtraction. Used by FHRR for unbinding.
- pyhdc.components.binding.multibind(data, axis=-1)[source]
Multiplicative bind: product over a stacked batch axis (defaults to the last).
Binds a set of hypervectors element-wise, e.g.
(D, N) -> (D,).Multiplicative bind of a stacked
(D, N)set into a single(D,)vector (product over the batch axis). Element-wise binding for bipolar/MAP families, for non-multiplicative binders useEncoding.bind.- Parameters:
axis – Batch axis to reduce. Default
-1.
pyhdc.components.bundling
- pyhdc.components.bundling.ElementAddition(*hypervectors: ndarray | torch.Tensor, random_choice_range: float | None = None, axis: None | int | Tuple[int, ...] = None) Tuple[ndarray | torch.Tensor, Dict[str, Any]][source]
Element-wise addition bundling.
Bundles hypervectors by summing corresponding elements. The simplest bundling operation that preserves information from all inputs.
When random_choice_range is set, coordinates whose |sum| falls within rho * sqrt(N) are replaced by independent fair draws from {-1, +1} (band randomization for MAP_I bipolar integer encoding). Defaulting random_choice_range to 0.0 limits this to exact zero-sums only.
- Parameters:
*hypervectors – Variable number of hypervectors to bundle, or single 2D batch
random_choice_range – Optional float (rho). Coordinates with |sum| <= rho * sqrt(N) are randomly assigned. Defaults to 0.0 (zero-ties only).
axis – Batch axis (or axes) to fold. Defaults to the last batch axis, so a
(D, N)batch collapses to(D,)and a(D, N, M)batch to(D, N).
- Returns:
Tuple of (bundled hypervector, metadata dict). Metadata contains “random_zone_count”.
Example
>>> v1 = np.array([1, -1, 1, -1]) >>> v2 = np.array([1, 1, -1, -1]) >>> result, _ = ElementAddition(v1, v2) >>> # result: [2, 0, 0, -2]
Element-wise sum; no normalisation.
- pyhdc.components.bundling.ElementAdditionCut(*hypervectors: ndarray | torch.Tensor, min_val: float = -1.0, max_val: float = 1.0, random_choice_range: float | None = None, axis: None | int | Tuple[int, ...] = None) Tuple[ndarray | torch.Tensor, Dict[str, Any]][source]
Element-wise addition with clipping.
Bundles hypervectors by summing elements and clipping the result to [min_val, max_val] range. Prevents unbounded growth in element values.
When random_choice_range is set, coordinates whose |sum| falls within rho * sqrt(N) * element_std (where element_std = 1/sqrt(3) for Uniform[-1,1]) are replaced by independent fair draws from Uniform[min_val, max_val] (band randomization for MAP_C continuous encoding). Defaulting random_choice_range to 0.0 limits this to exact zero-sums only.
- Parameters:
*hypervectors – Variable number of hypervectors to bundle, or single 2D batch
min_val – Minimum element value after bundling
max_val – Maximum element value after bundling
random_choice_range – Optional float (rho). Coordinates with |sum| <= rho * sqrt(N/3) are randomly assigned. Defaults to 0.0 (zero-ties only).
axis – Batch axis (or axes) to fold (defaults to the last batch axis).
- Returns:
Tuple of (bundled and clipped hypervector, metadata dict). Metadata contains “random_zone_count”.
Element-wise sum then clip to [-1, 1]. Used by MAP_C.
- pyhdc.components.bundling.ElementAdditionBits(*hypervectors: ndarray | torch.Tensor, min_val: int = -1, max_val: int = 1, axis: None | int | Tuple[int, ...] = None) ndarray | torch.Tensor[source]
Element-wise addition with a single saturating clip at the end.
Bundles by summing all vectors, then clipping the total once to
[min_val, max_val]. The sum is accumulated in a wide (int64) integer so it cannot overflow the element dtype before the clip, and the clip saturates at the bounds (no wraparound). Summation is order-independent, so a tuple of axes is supported.- Parameters:
*hypervectors – Variable number of hypervectors to bundle, or single batch
min_val – Lower saturation bound applied once to the final sum
max_val – Upper saturation bound applied once to the final sum
axis – Batch axis (or axes) to fold (defaults to the last batch axis).
- Returns:
Bundled hypervector, summed then clipped to
[min_val, max_val]
Element-wise sum in a wide accumulator, then a single saturating clip to the integer bit-width range. Used by MAP_I_Bits.
- pyhdc.components.bundling.ElementAdditionBinaryThreshold(*hypervectors: ndarray | torch.Tensor, min_val: float = 0.0, max_val: float = 1.0, random_choice_range: float | None = None, axis: None | int | Tuple[int, ...] = None) Tuple[ndarray | torch.Tensor, Dict[str, Any]][source]
Element-wise addition with binary thresholding.
Bundles binary hypervectors by majority voting. Elements that appear in more than half of the input vectors are set to max_val, others to min_val.
- Parameters:
*hypervectors – Variable number of hypervectors to bundle, or single 2D batch
min_val – Value for elements below threshold
max_val – Value for elements at or above threshold
random_choice_range – Optional float [0.0, 1.0] specifying the fraction of total vectors that defines the random choice zone around the threshold. Elements with sums outside this range are deterministically assigned, while elements within the range are randomly assigned.
axis – Batch axis (or axes) to fold (defaults to the last batch axis).
- Returns:
Tuple of (bundled binary hypervector, metadata dict). The metadata contains “random_zone_count” (the number of elements in the random choice zone). The “operation” key is added by the encoding wrapper, not this function.
Example
>>> v1 = np.array([1, 0, 1, 0]) >>> v2 = np.array([1, 1, 0, 0]) >>> v3 = np.array([1, 0, 0, 1]) >>> result, metadata = ElementAdditionBinaryThreshold(v1, v2, v3) >>> # result: [1, 0, 0, 0] (1 appears in 3/3, 2/3, 1/3, 1/3 positions)
Majority-vote threshold. Used by BSC.
- pyhdc.components.bundling.ElementAdditionBipolarThreshold(*hypervectors: ndarray | torch.Tensor, min_val: float = -1.0, max_val: float = 1.0, random_choice_range: float | None = None, axis: None | int | Tuple[int, ...] = None) Tuple[ndarray | torch.Tensor, Dict[str, Any]][source]
Element-wise addition with bipolar thresholding.
Bundles bipolar hypervectors {-1, +1} by thresholding at zero. Positive sums become max_val, negative sums become min_val.
Coordinates whose |sum| falls within random_choice_range * sqrt(N) of zero (the band) are replaced by independent fair draws from {min_val, max_val}. Defaulting random_choice_range to 0.0 limits this to exact ties only, preserving the standard majority-vote behavior.
- Parameters:
*hypervectors – Variable number of hypervectors to bundle, or single 2D batch
min_val – Value for elements with negative sum
max_val – Value for elements with non-negative sum
random_choice_range – Optional float (rho). Coordinates with |sum| <= rho * sqrt(N) are randomly assigned. Defaults to 0.0 (ties only).
axis – Batch axis (or axes) to fold (defaults to the last batch axis).
- Returns:
Tuple of (bundled bipolar hypervector, metadata dict). Metadata contains “random_zone_count”.
Sum then sign function. Result in {-1, +1}.
- pyhdc.components.bundling.ElementAdditionNormalized(*hypervectors: ndarray | torch.Tensor, random_choice_range: float | None = None, axis: None | int | Tuple[int, ...] = None) Tuple[ndarray | torch.Tensor, Dict[str, Any]][source]
Element-wise addition with normalization to unit length.
Bundles hypervectors by summing elements and normalizing the result to have magnitude 1. Used in HRR and related encodings.
HRR elements are N(0, 1/D) per Schlegel et al. (2022), so the pre-aggregate T_k = sum of N iid N(0, 1/D) values has std sqrt(N/D). When random_choice_range (rho) is set, coordinates whose |T_k| <= rho * sqrt(N/D) are replaced by independent N(0, 1/D) draws before normalization (band randomization). This keeps fresh draws at the same scale as individual input elements, consistent with the GU/GB theory.
- Parameters:
*hypervectors – Variable number of hypervectors to bundle, or single 2D batch
random_choice_range – Optional float (rho). Coordinates with |sum| <= rho * sqrt(N/D) are randomly replaced. Defaults to 0.0.
axis – Batch axis (or axes) to fold (defaults to the last batch axis).
- Returns:
Tuple of (bundled and normalized hypervector, metadata dict). Metadata contains “random_zone_count”.
Note
Each output hypervector is normalized independently along axis 0 (
||result|| = 1per column for a batched result).Sum then L2 normalise. Used by HRR, VTB, MBAT.
- pyhdc.components.bundling.ElementAdditionConstantNormalized(*hypervectors: ndarray | torch.Tensor, axis: None | int | Tuple[int, ...] = None) ndarray | torch.Tensor[source]
Element-wise addition with approximate constant normalization.
Bundles hypervectors by summing elements and dividing by sqrt(M) where M is the number of vectors bundled. Provides approximate unit length without computing the full norm (faster).
- Parameters:
*hypervectors – Variable number of hypervectors to bundle, or single 2D batch
axis – Batch axis (or axes) to fold (defaults to the last batch axis).
- Returns:
Bundled and approximately normalized hypervector
Note
Result will have ||result|| ~= 1 (approximate)
Sum then divide by √M. Used by HRR_ConstNorm.
- pyhdc.components.bundling.AnglesOfElementAddition(*hypervectors: ndarray | torch.Tensor, random_choice_range: float | None = None, axis: None | int | Tuple[int, ...] = None) Tuple[ndarray | torch.Tensor, Dict[str, Any]][source]
Bundling by adding phase angles (for FHRR).
Bundles phase-encoded hypervectors by computing the mean angle. Converts angles to complex numbers, sums them, and extracts the resulting phase. Used with Fourier Holographic Reduced Representations.
When random_choice_range is set, coordinates whose phasor magnitude |sum| falls within rho * sqrt(N/2) are replaced by independent fair draws from Uniform[-pi, pi] (band randomization for FHRR). The Rayleigh sigma of the neutral phasor sum magnitude is sqrt(N/2). Defaulting random_choice_range to 0.0 limits this to near-zero magnitude sums only.
- Parameters:
*hypervectors – Variable number of phase hypervectors, or single 2D batch
random_choice_range – Optional float (rho). Coordinates with phasor magnitude <= rho * sqrt(N/2) are randomly assigned. Defaults to 0.0.
axis – Batch axis (or axes) to fold (defaults to the last batch axis).
- Returns:
Tuple of (bundled phase hypervector, metadata dict). Metadata contains “random_zone_count”.
Note
Input values should be angles in radians. Output is also in radians.
Phasor resultant angle. Used by FHRR.
- pyhdc.components.bundling.Disjunction(*hypervectors: ndarray | torch.Tensor, axis: None | int | Tuple[int, ...] = None) ndarray | torch.Tensor[source]
Bitwise OR bundling for sparse binary vectors.
Bundles sparse binary hypervectors using bitwise OR. An element is 1 in the result if it is 1 in any input vector. Preserves sparsity better than addition for Binary Sparse Distributed Codes.
- Parameters:
*hypervectors – Variable number of sparse binary hypervectors, or single 2D batch
axis – Batch axis (or axes) to fold (defaults to the last batch axis).
- Returns:
Bundled sparse binary hypervector
Example
>>> v1 = np.array([1, 0, 1, 0]) >>> v2 = np.array([0, 1, 0, 0]) >>> result = Disjunction(v1, v2) >>> # result: [1, 1, 1, 0]
Bitwise OR. Used by BSDC family (without thinning).
- pyhdc.components.bundling.DisjunctionThinned(*hypervectors: ndarray | torch.Tensor, density: float = 0.5, axis: None | int | Tuple[int, ...] = None) ndarray | torch.Tensor[source]
Bitwise OR bundling with random thinning to maintain density.
Bundles sparse binary hypervectors using bitwise OR, then randomly zeros bits to keep the fraction of 1-bits at most density. For a batched result each output hypervector (column over the surviving batch axes) is thinned independently to
ceil(D * density)set bits.- Parameters:
*hypervectors – Variable number of sparse binary hypervectors, or single 2D batch
density – Maximum output density (fraction of 1-bits), defaults to 0.5
axis – Single batch axis to fold (defaults to the last batch axis). Thinning is per-column, so a tuple of axes is not supported.
- Returns:
Bundled and thinned sparse binary hypervector
Example
>>> v1 = np.array([1, 0, 1, 0]) >>> v2 = np.array([0, 1, 1, 0]) >>> result = DisjunctionThinned(v1, v2, density=0.25) >>> # result has at most 1 nonzero element (25% of 4)
Bitwise OR then random thinning to a maximum density. Used by BSDC_THIN.
- Parameters:
density – Maximum output density (fraction of 1-bits) after thinning (float, default 0.5).
- pyhdc.components.bundling.multiset(data, axis=-1)[source]
Additive multiset: sum a stacked batch axis (defaults to the last axis).
The additive bundling of a set of hypervectors, e.g.
(D, N) -> (D,).Additive multiset: sum a stacked
(D, N)set into a single(D,)vector over the batch axis. For family-specific bundling (threshold, normalize, thin) useEncoding.bundle.- Parameters:
axis – Batch axis to reduce. Default
-1.
- pyhdc.components.bundling.multibundle(data, axis=-1)
Additive multiset: sum a stacked batch axis (defaults to the last axis).
The additive bundling of a set of hypervectors, e.g.
(D, N) -> (D,).Alias of
multiset()under its conventional HDC name.
- pyhdc.components.bundling.randsel(data, p=None)[source]
Random-selection bundling of a
(D, N)batch into a single(D,)vector.Each coordinate is copied from one of the
Ninput columns, chosen independently at random (uniformly, or per the probability weightspover theNcolumns).- Parameters:
data – A
(D, N)array (numpy or torch) whose columns are the inputs to select among.p – Optional length-
Nweights over the columns (default uniform). Weights are normalized to a probability distribution, so they need not sum to 1.
- Returns:
A
(D,)array of the same backend/dtype asdata.
Random-selection bundling: reduce a
(D, N)batch to(D,)by copying each coordinate from one randomly chosen input column.- Parameters:
p – Optional length-
Nweights over the columns (default uniform). Normalized internally, so they need not sum to 1.
- pyhdc.components.bundling.multirandsel(data, count, p=None)[source]
Produce
countindependentrandsel()draws as a(D, count)array.Produce
countindependentrandsel()draws as a(D, count)array.- Parameters:
count – Number of independent random-selection draws.
p – Optional column weights (see
randsel()).
pyhdc.components.elements
Element generators control how individual hypervector values are drawn.
Each function has signature (size, dtype) -> ndarray.
- pyhdc.components.elements.UniformBipolar(dimensions: int, dtype: type = <class 'numpy.float32'>) ndarray[source]
UniformBipolar X∈R, X_i ~ U(-1,1)
Uniform distribution of real numbers between -1 and 1
- Parameters:
dimensions (int) – number of dimensions in the vector
- Returns:
hypervector
- Return type:
np.ndarray
Uniform random from {-1, +1}.
- pyhdc.components.elements.UniformAngles(dimensions: int, dtype: type = <class 'numpy.float32'>) ndarray[source]
UniformAngles θ∈R, θ_i ~ U(-pi, pi)
Uniformly distributed angles from -pi to pi. Useful for a complex hypervector representation X∈C, X_i = e^(i*θ). In this case, the complex vector is assumed to be on the unit circle (length one) so we only need to store the real angle, θ, and the hypervector X can be computed as needed from the hypervector θ.
- Parameters:
dimensions (int) – number of dimensions in the vector
- Returns:
hypervector
- Return type:
np.ndarray
Uniform random in [-π, π).
- pyhdc.components.elements.NormalReal(dimensions: int, dtype: type = <class 'numpy.float32'>) ndarray[source]
NormalReal X∈R, X_i ~ N(0, 1/d)
Normal distribution of real numbers with mean 0 and variance 1/d, where d is the dimension of the hypervector
- Parameters:
dimensions (int) – number of dimensions in the vector
- Returns:
hypervector
- Return type:
np.ndarray
Standard normal N(0, 1).
- pyhdc.components.elements.BernoulliBinary(dimensions: int, dtype: type = <class 'numpy.int32'>) ndarray[source]
BernoulliBinary X∈{0,1}, X_i ~ B(0.5)
Bernoulli distribution of binary numbers, either 0 or 1
- Parameters:
dimensions (int) – number of dimensions in the vector
- Returns:
hypervector
- Return type:
np.ndarray
Bernoulli(p=0.5) → {0, 1}.
- pyhdc.components.elements.BernoulliBipolar(dimensions: int, dtype: type = <class 'numpy.int32'>) ndarray[source]
BernoulliBipolar X∈Z, X_i ~ B(0.5)*2 - 1
Bernoulli distribution of bipolar numbers, either -1 or 1
- Parameters:
dimensions (int) – number of dimensions in the vector
- Returns:
hypervector
- Return type:
np.ndarray
Bernoulli(p=0.5) → {-1, +1}.
- pyhdc.components.elements.BernoulliSparse(dimensions: int, dtype: type = <class 'numpy.int32'>, probability: float = None) ndarray[source]
BernoulliSparse X∈{0,1}, X_i ~ B(p << 1)
Bernoulli distribution of binary numbers, either 0 or 1 with variable probability. If undefined probability is given as p = 1/sqrt(dimensions), which creates a sparsely populated array
- Parameters:
- Returns:
hypervector
- Return type:
np.ndarray
k-sparse binary: exactly k elements are 1, rest 0.
- Parameters:
k – Number of 1s. Default: determined by the encoding.
- pyhdc.components.elements.SparseSegmented(dimensions: int, dtype: type = <class 'numpy.int32'>, probability: float = None) ndarray[source]
SparseSegmented X∈{0,1}, X_i ~ B(p << 1)
Sparsely segmented binary numbers, either 0 or 1 with variable probability. If undefined probability is given as p = 1/sqrt(dimensions). Hypervector is split into s, dimensions * probability, segments. Each segment populated with exactly 1 non-zero element uniformly distributed throughout the segment.
NOTE: Since s = dimensions * probability is not garunteed to evenly divide into the hypervector dimensions, the segment, s, is rounded up and the final hypervector trimmed. This means the non-zero value in the last segment may be trimmed and not be present in the final hypervector.
- Parameters:
- Returns:
hypervector
- Return type:
np.ndarray
Segment-wise sparse binary: k ones per segment.
- Parameters:
segment_size – Number of elements per segment.
k – Number of 1s per segment.
pyhdc.components.thinning
pyhdc.components.unary
Added in 2.1.0. Unary components back the four single-operand operations
(permute(), inverse(), negative(), normalize())
exposed on Hypervector, on each encoding, and at module level.
Each function takes raw array data, operates dimension-first (axis 0 is the
hypervector dimension D, trailing axes are the batch) and runs on both
numpy and torch backends.
An encoding wires these into its EncodingSpec through the permute_fn,
inverse_fn, normalize_fn, and negative_fn fields. permute_fn
defaults to CyclicShift() when left unset, so every encoding has a
permutation. The other three default to RaiseNotImplementedError: an
encoding that does not assign inverse_fn / normalize_fn / negative_fn
raises NotImplementedError when that operation is called. See
Encoding Classes for the per-family support of each operation.
- pyhdc.components.unary.CyclicShift(data: ndarray | torch.Tensor, shift: int = 1) ndarray | torch.Tensor[source]
Cyclic-shift permutation along axis 0 (the dimension); broadcasts over any trailing batch axes. Encoding-agnostic, so it is the default
permute.Cyclic-shift permutation along axis 0, broadcasts over trailing batch axes. Encoding-agnostic, so it is the default
permute_fnfor all 15 encodings. Implemented asnp.roll(data, shift, axis=0)(torch:torch.roll(data, shift, dims=0)). A negativeshiftis the exact inverse of the positive shift.- Parameters:
shift – Number of positions to shift. Default
1.
- pyhdc.components.unary.IdentityInverse(data: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Inverse for self-inverse binding (MAP bipolar multiply, BSC XOR): the element is its own inverse. Exact for bipolar/binary values.
Returns
dataunchanged. The binding inverse for self-inverse schemes where each element is its own inverse: MAP bipolar multiply and BSC XOR.
- pyhdc.components.unary.ReverseInverse(data: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Exact involution inverse of circular convolution (HRR): keep index 0 and reverse the remaining coordinates along axis 0.
Exact involution inverse of circular convolution, used by the HRR family. Keeps index 0 and reverses the remaining coordinates along axis 0:
np.concatenate([data[:1], np.flip(data[1:], axis=0)], axis=0)(torch:torch.cat([data[:1], torch.flip(data[1:], dims=[0])], dim=0)).
- pyhdc.components.unary.PhaseNegate(data: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Inverse for FHRR angle binding: negate the phase (mod 2*pi).
FHRR binding inverse: negate the phase modulo 2π,
np.mod(-data, 2*pi).
- pyhdc.components.unary.Negate(data: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Additive (bundling) inverse: element-wise negation.
Additive (bundling) inverse: element-wise negation
-data.
- pyhdc.components.unary.L2Normalize(data: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Normalize each hypervector to unit L2 length along axis 0.
Normalise each hypervector to unit L2 length along axis 0,
data / np.linalg.norm(data, axis=0, keepdims=True). The canonical form for HRR, VTB, and MBAT.
- pyhdc.components.unary.WrapPhase(data: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Normalize FHRR phases to the canonical range [-pi, pi).
Normalise FHRR phases to the entry distribution range
[-pi, pi),np.mod(data + pi, 2*pi) - pi.
- pyhdc.components.unary.SignNormalize(data: ndarray | torch.Tensor) ndarray | torch.Tensor[source]
Normalize MAP hypervectors back to bipolar {-1, 0, +1} by sign.
Normalise MAP hypervectors back to bipolar
{-1, 0, +1}by sign,np.sign(data).
The table maps each unary operation to the component that backs it and the encoding families that use it.
Operation |
Component |
Used by |
|---|---|---|
|
All 15 encodings (default fallback) |
|
|
MAP_I, MAP_I_Bits, MAP_B, BSC |
|
|
HRR, HRR_NoNorm, HRR_ConstNorm |
|
|
FHRR |
|
|
MAP_C, MAP_I, MAP_I_Bits, MAP_B, HRR, HRR_NoNorm, HRR_ConstNorm, VTB, MBAT |
|
|
HRR, HRR_NoNorm, HRR_ConstNorm, VTB, MBAT |
|
|
FHRR |
|
|
MAP_C, MAP_I, MAP_I_Bits, MAP_B |
pyhdc.components.basis
Family-aware basis builders that produce a (D, count) codebook
array in an encoding’s value domain and backend. The codebook encoders
(Level, Thermometer, Circular, etc.)
hold one of these as their basis. Each builder has signature
fn(encoding, count, dimension=None) -> (D, count) array.
- pyhdc.components.basis.empty(encoding, count, dimension=None)[source]
countall-zero hypervectors as a(D, count)array.countall-zero hypervectors as a(D, count)array.
- pyhdc.components.basis.random(encoding, count, dimension=None)[source]
countindependent random hypervectors as a(D, count)codebook.countindependent random hypervectors as a(D, count)codebook.
- pyhdc.components.basis.identity(encoding, count, dimension=None)[source]
countcopies of the binding-identity element as a(D, count)codebook.The binding-identity
esatisfiesbind(x, e) == x, such that every column ise. Defined for the MAP, HRR, FHRR, and BSC families, raisesNotImplementedErrorfor VTB, MBAT, and the BSDC family (no neutral binding element).countcopies of the binding-identity elemente(wherebind(x, e) == x). Defined for the MAP, HRR, FHRR, and BSC families. RaisesNotImplementedErrorfor VTB, MBAT, and the BSDC family.
- pyhdc.components.basis.level(encoding, count, dimension=None)[source]
A linear level codebook: adjacent columns correlated, ends near-orthogonal.
Built family-agnostically from two random endpoint draws
baseandaltplus a per-coordinate uniform thresholdu. Columnikeepsbasewhereu >= i / (count - 1)andaltelsewhere, so each coordinate flips frombasetoaltexactly once (at its own threshold). Similarity therefore decays monotonically with|i - j|. Column 0 isbaseand the last column isalt(two independent draws, so near-orthogonal).A linear level codebook: adjacent columns correlated, ends near-orthogonal. Family-agnostic.
- pyhdc.components.basis.circular(encoding, count, dimension=None)[source]
A circular (ring) level codebook: similarity wraps, so level 0 ~ level L-1.
Like
level(), but each coordinate is assigned a random start phasepin[0, count)and takesbaseover a half-ring arc andaltover the other half. Similarity depends on ring distancemin(|i - j|, count - |i - j|), so the first and last columns are adjacent and the diametrically opposite column is the similarity minimum (near-orthogonal, around 0).A circular (ring) level codebook: similarity wraps, so level 0 ~ level L-1. Family-agnostic.
- pyhdc.components.basis.thermometer(encoding, count, dimension=None)[source]
A deterministic thermometer (cumulative unary) codebook. Discrete families only.
Column
isets its firstround(i / (count - 1) * D)coordinates to the high endpoint and the rest to the low endpoint, so each column’s high-set is a strict superset of the previous column’s (nested). Column 0 is the constant all-low vector and the last column the constant all-high vector (so the two ends are anti-correlated, not orthogonal). Distinct fromlevel(), whose endpoints are two independent random draws.- Raises:
NotImplementedError – For continuous and phase families (via
family_endpoints()).
A deterministic thermometer (cumulative unary) codebook. Discrete families only, raises
NotImplementedErrorfor continuous and phase families.
- pyhdc.components.basis.family_endpoints(encoding)[source]
Return the
(low, high)element endpoints forencoding’s value domain.- Parameters:
encoding – An
Encodinginstance.- Returns:
A
(low, high)tuple of scalars in the family’s domain.- Raises:
NotImplementedError – If the family is continuous or phase-valued and has no discrete endpoint pair (MAP_C, HRR family, VTB, MBAT, FHRR).
Return the
(low, high)element endpoints for an encoding’s value domain. Defined for the discrete (bipolar, binary, sparse) families, raisesNotImplementedErrorfor MAP_C, the HRR family, VTB, MBAT, and FHRR.
- pyhdc.components.basis.binding_identity(encoding, dimension=None)[source]
Return the binding-identity element
e(wherebind(x, e) == x) as(D,).The neutral element of the encoding’s binding rule, in the encoding’s value domain and backend:
element-wise multiply (MAP) -> all ones
XOR (BSC) -> all zeros
circular convolution (HRR family) -> the impulse
[1, 0, ..., 0]angle addition (FHRR) -> zero phase (all zeros)
- Parameters:
encoding – An
Encodinginstance.dimension – Hypervector dimension (defaults to
encoding.dimension).
- Returns:
A
(D,)array (numpy or torch) holding the binding-identity element.- Raises:
NotImplementedError – For binding rules with no neutral element (VTB, MBAT, and the BSDC family).
Return the binding-identity element
eas a(D,)array (all-ones for MAP multiply, all-zeros for BSC XOR and FHRR angle addition, the impulse[1, 0, ...]for HRR convolution). RaisesNotImplementedErrorfor VTB, MBAT, and the BSDC family.
pyhdc.components.quantization
Maps continuous element values to a bipolar form, dimension-first, on both backends.