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_unit for post-processing

pyhdc.components.similarity

pyhdc.components.similarity.CosineSimilarity(*hypervectors: ndarray | torch.Tensor, axis: int | None = None)[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)
Parameters:
  • *hypervectors – Two hypervectors, or a single batch array

  • axis – For a single (D, N, M, ...) batch, the batch axis to split on

Returns:

Scalar similarity, or an array of similarities over the trailing axes

Cosine similarity between two vectors or batches.

Returns:

float, ndarray, or Tensor in [-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)[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``
Parameters:
  • *hypervectors – Two hypervectors, or a single batch array

  • axis – For a single (D, N, M, ...) batch, the batch axis to split on

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).

Returns:

Value in [-1, 1]. (Was [0, 1] in v1.0.x.)

pyhdc.components.similarity.Overlap(*hypervectors: ndarray | torch.Tensor, axis: int | None = None)[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``
Parameters:
  • *hypervectors – Two hypervectors, or a single batch array

  • axis – For a single (D, N, M, ...) batch, the batch axis to split on

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).

Returns:

Value in [-1, 1]. (Was [0, 1] in v1.0.x.)

pyhdc.components.similarity.AngleDistance(*hypervectors: ndarray | torch.Tensor, axis: int | None = None)[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``
Parameters:
  • *hypervectors – Two hypervectors, or a single batch array

  • axis – For a single (D, N, M, ...) batch, the batch axis to split on

Returns:

Scalar similarity, or an array of similarities over the trailing axes

Cosine of element-wise angle differences.

Appropriate for phase/angle encodings (FHRR).

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_remap parameter:

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, or Tensor.

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.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|| = 1 per 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.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:
  • dimensions (int) – number of dimensions in the vector

  • probability (float, optional) – probability of the Bernoulli distribution, defaults to 1/sqrt(d)

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:
  • dimensions (int) – number of dimensions in the vector

  • probability (float, optional) – probability of the Bernoulli distribution, defaults to 1/sqrt(d)

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.thinning.NoThin(hypervector: ndarray) ndarray[source]

No-op thinning function. Returns the input unchanged. Used by all encodings that do not perform 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_fn for all 15 encodings. Implemented as np.roll(data, shift, axis=0) (torch: torch.roll(data, shift, dims=0)). A negative shift is 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 data unchanged. 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

permute

CyclicShift()

All 15 encodings (default fallback)

inverse

IdentityInverse()

MAP_I, MAP_I_Bits, MAP_B, BSC

inverse

ReverseInverse()

HRR, HRR_NoNorm, HRR_ConstNorm

inverse

PhaseNegate()

FHRR

negative

Negate()

MAP_C, MAP_I, MAP_I_Bits, MAP_B, HRR, HRR_NoNorm, HRR_ConstNorm, VTB, MBAT

normalize

L2Normalize()

HRR, HRR_NoNorm, HRR_ConstNorm, VTB, MBAT

normalize

WrapPhase()

FHRR

normalize

SignNormalize()

MAP_C, MAP_I, MAP_I_Bits, MAP_B