API Reference
This page contains the complete API reference for HyperdimensionalComputing.jl.
Types
HyperdimensionalComputing.AbstractHV — Type
AbstractHV{T} <: AbstractVector{T}Abstract supertype of all hypervector types: BinaryHV, BipolarHV, TernaryHV, RealHV, GradedHV, GradedBipolarHV and FHRR.
A hypervector is a high-dimensional vector (10,000 dimensions by default) that carries information holographically: meaning is distributed over the whole vector rather than located in individual elements. Hypervectors are composed with bundle (+), bind (*) and shift (ρ), and compared with similarity.
Constructors and encode
All concrete hypervector types HV <: AbstractHV share the same constructor interface, and each constructor form has exactly one meaning:
HV(; D = 10_000, seed = nothing, rng = default_rng()) # fresh random hypervector
HV(v::AbstractVector{<:Real}) # wrap element data, validated per type
HV(x) # token shorthand for `encode(HV, x)`encode is the canonical way to turn raw data into hypervectors — HV(x) is shorthand for its token path only. HV(n::Number) throws, because a number is ambiguous between a token and the dimensionality (use D = n, or encode(HV, n) for number tokens); an array that is not valid element data for the type throws instead of silently token-encoding. Tuples of reals read as data, like vectors.
Some types extend this interface with type-specific keywords, e.g. distr for RealHV, GradedHV and GradedBipolarHV.
Indexing
hv[i] with an integer returns the element value. Non-scalar indexing — hv[1:3], hv[[1, 4]], logical masks — returns a plain Vector of element values, not a new hypervector: information in a hypervector is distributed over all D dimensions, so a slice is not itself a meaningful hypervector. Hypervectors are immutable; there is no setindex!. Equality (==/isequal) holds only between hypervectors of the same type — a BinaryHV never equals a BipolarHV — while comparison against plain vectors is elementwise.
Examples
julia> BinaryHV(:cat) == BinaryHV(:cat) # encoding the same object twice
true
julia> BinaryHV(:cat) == BinaryHV(:dog) # different objects, different vectors
false
julia> length(BinaryHV(:cat; D = 100)) # dimensionality is set with the keyword D
100See also
encode, bundle, bind, similarity
Extended help
References
- Kanerva, P. (2009). Hyperdimensional Computing: An Introduction to Computing in Distributed Representation with High-Dimensional Random Vectors. Cognitive Computation, 1(2), 139–159.
HyperdimensionalComputing.BinaryHV — Type
BinaryHV(; D = 10_000, seed = nothing, rng = default_rng())
BinaryHV(x)
BinaryHV(v::AbstractVector{<:Real})A binary hypervector implementing the Binary Spatter Code (BSC) vector symbolic architecture (Kanerva, 1994–1997). Elements are {false,true}, stored compactly as a BitVector.
Under BSC, bind is elementwise XOR and self-inverse (x * x is the identity element), bundle is a majority vote across inputs with deterministic tie-breaking, and similarity defaults to Jaccard.
HV(x) is shorthand for encode(HV, x), the deterministic token path; a Number argument throws — use D = n for dimensionality, or encode for number tokens. See AbstractHV for the full convention.
Indexing with a scalar returns a single element; indexing with a range or vector returns a plain Vector, not a hypervector.
Examples
julia> BinaryHV(; D = 8, rng = Xoshiro(42))
8-element BinaryHV with 3 true and 5 false:
0
0
0
0
1
1
1
0
julia> BinaryHV("apple") == BinaryHV("apple") # deterministic from hash
trueBinding is self-inverse:
julia> x = BinaryHV(; D = 8, rng = Xoshiro(1)); y = BinaryHV(; D = 8, rng = Xoshiro(2));
julia> x * y * y == x
trueSee also
AbstractHV, bundle, bind, similarity
Extended help
References
- Kanerva, P. (1994). The Spatter Code for Encoding Concepts at Many Levels. ICANN, 226–229.
- Kanerva, P. (1995). A Family of Binary Spatter Codes. ICANN, 517–522.
- Kanerva, P. (1996). Binary Spatter-Coding of Ordered K-tuples. ICANN, LNCS 1112, 869–873.
- Kanerva, P. (1997). Fully Distributed Representation. RWC, 358–365.
HyperdimensionalComputing.BipolarHV — Type
BipolarHV(; D = 10_000, seed = nothing, rng = default_rng())
BipolarHV(x)
BipolarHV(v::AbstractVector{<:Real})
BipolarHV(v::AbstractVector{Bool})A bipolar hypervector in the style of the Multiply-Add-Permute (MAP) vector symbolic architecture (Gayler, 1998). Elements are ±1, stored compactly as a BitVector with bit true ↦ -1 and false ↦ +1, so that XOR on the stored bits is exactly the elementwise ±1 product.
Constructing from a real vector requires every element to be exactly ±1; a zero element throws an ArgumentError, since a bipolar hypervector has no zero state — use TernaryHV for elements in {-1, 0, +1} — and anything else is rejected rather than coerced. A Bool vector is the exception: it is interpreted as the raw stored bits (true ↦ -1), not as values.
Under this architecture, bind is the elementwise product (XOR on the stored bits) and self-inverse — x * x is the all-+1 identity — bundle is a majority vote across inputs with deterministic tie-breaking, and similarity defaults to cosine.
HV(x) is shorthand for encode(HV, x), the deterministic token path; a Number argument throws — use D = n for dimensionality, or encode for number tokens. See AbstractHV for the full convention.
Indexing with a scalar returns a single element; indexing with a range or vector returns a plain Vector, not a hypervector.
Examples
julia> BipolarHV(; D = 8, rng = Xoshiro(42))
8-element BipolarHV with 5 positives and 3 negatives:
1
1
1
1
-1
-1
-1
1
julia> BipolarHV("apple") == BipolarHV("apple") # deterministic from hash
trueRandom hypervectors are quasi-orthogonal at the default D = 10_000:
julia> x = BipolarHV(; rng = Xoshiro(1)); y = BipolarHV(; rng = Xoshiro(2));
julia> similarity(x, y)
-0.0028See also
AbstractHV, bundle, bind, similarity
Extended help
References
- Gayler, R. W. (1998). Multiplicative Binding, Representation Operators & Analogy. In Advances in Analogy Research: Integration of Theory and Data from the Cognitive, Computational, and Neural Sciences, 1–4.
HyperdimensionalComputing.TernaryHV — Type
TernaryHV(; D = 10_000, seed = nothing, rng = default_rng())
TernaryHV(x)
TernaryHV(v::AbstractVector{<:Real})
TernaryHV{T}(...)A ternary hypervector implementing the Multiply-Add-Permute (MAP) vector symbolic architecture (Gayler, 1998). Elements are integers, stored as a Vector{T} with T <: Integer; the random constructors generate only ±1 entries, and zeros arise from operations such as unnormalized bundling. All constructor forms also exist with an explicit element type, TernaryHV{T}(...).
Under MAP, bind is elementwise multiplication and self-inverse, bundle is elementwise addition without normalization by default (so counts accumulate; normalize clamps the result back to {-1, 0, +1}), and similarity defaults to cosine.
HV(x) is shorthand for encode(HV, x), the deterministic token path; a Number argument throws — use D = n for dimensionality, or encode for number tokens. See AbstractHV for the full convention.
Indexing with a scalar returns a single element; indexing with a range or vector returns a plain Vector, not a hypervector.
Examples
julia> TernaryHV(; D = 8, rng = Xoshiro(42))
8-element TernaryHV{Int64} with 4 positives, 0 zeros, and 4 negatives:
1
1
-1
-1
-1
-1
1
1
julia> TernaryHV("apple") == TernaryHV("apple") # deterministic from hash
trueBundling accumulates counts; normalize clamps back to {-1, 0, +1}:
julia> x = TernaryHV(; D = 8, rng = Xoshiro(1)); y = TernaryHV(; D = 8, rng = Xoshiro(2));
julia> x + y
8-element TernaryHV{Int64} with 3 positives, 2 zeros, and 3 negatives:
-2
0
-2
-2
0
2
2
2
julia> normalize(x + y)
8-element TernaryHV{Int64} with 3 positives, 2 zeros, and 3 negatives:
-1
0
-1
-1
0
1
1
1See also
AbstractHV, bundle, bind, similarity
Extended help
References
- Gayler, R. W. (1998). Multiplicative Binding, Representation Operators & Analogy. In Advances in Analogy Research: Integration of Theory and Data from the Cognitive, Computational, and Neural Sciences, 1–4.
HyperdimensionalComputing.GradedHV — Type
GradedHV(; D = 10_000, distr = Beta(1, 1), seed = nothing, rng = default_rng())
GradedHV(x)
GradedHV(v::AbstractVector{<:Real}[, distr])A graded hypervector with elements in the fuzzy-membership interval [0, 1]. Elements are drawn from a distribution with support in [0, 1] (uniform Beta(1, 1) by default, via the distr keyword); values passed as data are clamped to [0, 1].
Operations follow fuzzy logic: bind is the fuzzy XOR (1 - x) * y + x * (1 - y), bundle uses the three-valued π aggregation, and similarity defaults to Jaccard.
HV(x) is shorthand for encode(HV, x), the deterministic token path; a Number argument throws — use D = n for dimensionality, or encode for number tokens. See AbstractHV for the full convention.
Indexing with a scalar returns a single element; indexing with a range or vector returns a plain Vector, not a hypervector.
Examples
julia> GradedHV(; D = 8, rng = Xoshiro(42))
8-element GradedHV{Float64} with μ ± σ = 0.532 ± 0.247:
0.8023279156644033
0.6042216741680727
0.5612409791764235
0.8514212832811604
0.5873457677614401
0.4663593857124599
0.13521235508492413
0.24655411787892703
julia> GradedHV("apple") == GradedHV("apple") # deterministic from hash
trueBinding is fuzzy XOR, so binding with certainty (1.0) negates the membership:
julia> GradedHV([1.0, 0.0, 0.5]) * GradedHV([1.0, 1.0, 1.0])
3-element GradedHV{Float64} with μ ± σ = 0.5 ± 0.5:
0.0
1.0
0.5See also
HyperdimensionalComputing.GradedBipolarHV — Type
GradedBipolarHV(; D = 10_000, distr = 2Beta(1, 1) - 1, seed = nothing, rng = default_rng())
GradedBipolarHV(x)
GradedBipolarHV(v::AbstractVector{<:Real}[, distr])A graded bipolar hypervector with elements in [-1, 1], the bipolar counterpart of GradedHV. Elements are drawn from a distribution with support in [-1, 1] (the scaled uniform 2Beta(1, 1) - 1 by default, via the distr keyword); values passed as data are clamped to [-1, 1].
Operations are the fuzzy-logic operations of GradedHV mapped to the bipolar interval: bind is fuzzy XOR and bundle the three-valued π aggregation, both applied after rescaling [-1, 1] to [0, 1] and mapping back; similarity defaults to cosine.
HV(x) is shorthand for encode(HV, x), the deterministic token path; a Number argument throws — use D = n for dimensionality, or encode for number tokens. See AbstractHV for the full convention.
Indexing with a scalar returns a single element; indexing with a range or vector returns a plain Vector, not a hypervector.
Examples
julia> GradedBipolarHV(; D = 8, rng = Xoshiro(42))
8-element GradedBipolarHV{Float64} with μ ± σ = 0.064 ± 0.494:
0.6046558313288066
0.20844334833614542
0.12248195835284692
0.7028425665623208
0.1746915355228802
-0.06728122857508023
-0.7295752898301517
-0.506891764242146
julia> GradedBipolarHV("apple") == GradedBipolarHV("apple") # deterministic from hash
trueBinding with full certainty (1.0) mirrors a value across the interval:
julia> GradedBipolarHV([-1.0, 0.0, 1.0]) * GradedBipolarHV([1.0, 1.0, 1.0])
3-element GradedBipolarHV{Float64} with μ ± σ = 0.0 ± 1.0:
1.0
0.0
-1.0See also
HyperdimensionalComputing.RealHV — Type
RealHV(; D = 10_000, distr = Normal(), seed = nothing, rng = default_rng())
RealHV(x)
RealHV(v::AbstractVector{<:Real}[, distr])A real-valued hypervector (continuous Multiply-Add-Permute architecture). Elements are drawn from a configurable distribution distr (standard normal by default), which the vector carries along so that normalize! can rescale a result back to the original spread.
Under this architecture, bind is elementwise multiplication, bundle is elementwise addition rescaled by √m for m inputs, and similarity defaults to cosine. Real-valued MAP binding is not exactly invertible, so unbind throws for this type: recover bound information with similarity against candidate hypervectors, or use FHRR or BipolarHV if you need exact unbinding.
HV(x) is shorthand for encode(HV, x), the deterministic token path; a Number argument throws — use D = n for dimensionality, or encode for number tokens. See AbstractHV for the full convention.
Indexing with a scalar returns a single element; indexing with a range or vector returns a plain Vector, not a hypervector.
Examples
julia> RealHV(; D = 8, rng = Xoshiro(42))
8-element RealHV{Float64} with μ ± σ = -0.222 ± 0.736:
-0.36335748145177754
0.2517372155742292
-0.31498797116895605
-0.31125240132442067
0.8163067649323273
0.47673837983187795
-0.8595553820616212
-1.4692882055065464
julia> RealHV("apple") == RealHV("apple") # deterministic from hash
trueThe distr keyword controls the element distribution:
julia> RealHV(; D = 8, distr = Normal(0, 5), rng = Xoshiro(1))
8-element RealHV{Float64} with μ ± σ = 0.214 ± 4.17:
0.30966370157040063
1.392029070820001
-2.9791220768202606
0.2332969478669087
5.428970107716381
-7.88282461292992
0.8796999565053736
4.326904027046626See also
HyperdimensionalComputing.FHRR — Type
FHRR(; D = 10_000, T = Float64, seed = nothing, rng = default_rng())
FHRR(x)
FHRR(v::AbstractVector{<:Complex})A Fourier Holographic Reduced Representation hypervector (Plate, 1995). Elements are complex numbers on the unit circle, e^(iθ) with random phase θ, stored as a Vector{Complex{T}} (T = Float64 by default, via the T keyword).
Under FHRR, bind is elementwise complex multiplication (phases add), inverted by unbind (elementwise division), bundle is phasor addition renormalized to unit modulus, and similarity is the normalized real part of the complex dot product. In addition, hv ^ x raises every phase to the power x, which enables fractional-power (level) encoding of continuous values.
HV(x) is shorthand for encode(HV, x), the deterministic token path; a Number argument throws — use D = n for dimensionality, or encode for number tokens. See AbstractHV for the full convention.
Indexing with a scalar returns a single element; indexing with a range or vector returns a plain Vector, not a hypervector.
Examples
julia> FHRR(; D = 4, rng = Xoshiro(42))
4-element FHRR{ComplexF64}:
-0.6875407989187119 - 0.7261457497102214im
-0.9517124499338168 + 0.3069908999318585im
-0.9899412825080958 + 0.14147882239482543im
-0.2902555218408553 - 0.9569491794452267im
julia> FHRR("apple") == FHRR("apple") # deterministic from hash
trueFractional powers encode continuous values: nearby exponents stay similar.
julia> x = FHRR(; rng = Xoshiro(1));
julia> similarity(x^1.0, x^1.05) > similarity(x^1.0, x^2.0)
trueSee also
AbstractHV, bundle, bind, unbind, similarity
Extended help
References
- Plate, T. A. (1995). Holographic Reduced Representations. IEEE Transactions on Neural Networks, 6(3), 623–641.
Operations
HyperdimensionalComputing.bundle — Function
bundle(hvs; kwargs...)Bundle (superpose) a collection of hypervectors into a single hypervector that is similar to every input. Overloaded as the + operator.
The aggregation rule depends on the hypervector type: majority vote with deterministic tie-breaking (BinaryHV, BipolarHV), elementwise addition (TernaryHV, RealHV), fuzzy aggregation (GradedHV, GradedBipolarHV) or phasor addition (FHRR).
bundle combines all its inputs in one go, and for most types the result depends on how many there are – a majority vote over m inputs, a 1/√m rescaling, a renormalization. Bundling is therefore not associative for BinaryHV, BipolarHV, RealHV and FHRR (it is for TernaryHV and the graded types, whose rules happen to be associative).
Three spellings do the right thing, because each reaches bundle with every input at once: bundle(hvs), sum(hvs), and chained x + y + z (Julia parses a chain of + as a single variadic call).
Folding pairwise does not: (x + y) + z, reduce(+, hvs) and foldl(+, hvs) bundle a bundle. The result is heavily biased towards the last inputs and loses the defining property that a bundle is equally similar to each of its parts.
See also
Base.bind — Function
bind(hv1, hv2)
bind(hvs::AbstractVector{<:AbstractHV})Bind (associate) hypervectors into a single hypervector that is dissimilar to its inputs while preserving distances. Overloaded as the * operator and inverted by unbind (/) — except for RealHV, whose binding is not exactly invertible.
The binding rule depends on the hypervector type: XOR of the stored bits, which is self-inverse (BinaryHV, BipolarHV), elementwise multiplication (TernaryHV, RealHV), fuzzy XOR (GradedHV, GradedBipolarHV) or complex multiplication (FHRR).
See also
HyperdimensionalComputing.unbind — Function
unbind(hv1, hv2)Unbind hv2 from hv1, inverting bind: unbind(bind(x, y), y) recovers x. Overloaded as the / operator.
For the XOR- and multiplication-based types (BinaryHV, BipolarHV, TernaryHV) binding is self-inverse, so unbind is simply bind; the same fallback gives approximate fuzzy unbinding for GradedHV and GradedBipolarHV. FHRR unbinds exactly via elementwise complex division.
Real-valued MAP binding is not exactly invertible, so unbind throws for RealHV. Recover bound information with similarity against candidate hypervectors, or use FHRR or BipolarHV if you need exact unbinding.
See also
HyperdimensionalComputing.shift! — Function
shift!(hv::AbstractHV, k::Int)Permutes hypervector in-place by a specified number of shifts.
This operations is used to assign an order to hypervectors.
HyperdimensionalComputing.shift — Function
shift(hv::AbstractHV, k::Int)Permutes hypervector in-place by a specified number of shifts.
This operations is used to assign an order to hypervectors.
HyperdimensionalComputing.ρ — Function
ρ(hv::AbstractHV, k::Int = 1)Alias of shift.
HyperdimensionalComputing.ρ! — Function
ρ!(hv::AbstractHV, k::Int = 1)Alias of shift!.
HyperdimensionalComputing.normalize — Function
normalize(hv::AbstractHV)Return a copy of the normalized version of the input hypervector.
Example
julia> v = bundle([encode(TernaryHV, i; D = 8) for i in 1:100])
8-element TernaryHV{Int64} with 4 positives, 0 zeros, and 4 negatives:
12
-2
-16
12
-4
6
12
-12
julia> normalize(v)
8-element TernaryHV{Int64} with 4 positives, 0 zeros, and 4 negatives:
1
-1
-1
1
-1
1
1
-1
julia> v
8-element TernaryHV{Int64} with 4 positives, 0 zeros, and 4 negatives:
12
-2
-16
12
-4
6
12
-12HyperdimensionalComputing.normalize! — Function
normalize!(hv::AbstractHV)Normalize the input hypervector.
Examples
```julia-repl julia> v = bundle([encode(TernaryHV, i; D = 8) for i in 1:100]) 8-element TernaryHV{Int64} with 4 positives, 0 zeros, and 4 negatives: 12 -2 -16 12 -4 6 12 -12
julia> normalize!(v) 8-element TernaryHV{Int64} with 4 positives, 0 zeros, and 4 negatives: 1 -1 -1 1 -1 1 1 -1
julia> v 8-element TernaryHV{Int64} with 4 positives, 0 zeros, and 4 negatives: 1 -1 -1 1 -1 1 1 -1
normalize!(hv::FHRR)A Fourier Holographic Reduced Representation is normalized by setting the norm of each complex element to 1.
HyperdimensionalComputing.perturbate — Function
perturbate(hv::AbstractHV, args...; rng::AbstractRNG = Random.GLOBAL_RNG)Perturbate hypervectors by randomly flipping values.
Examples
julia> v = BinaryHV(ones(10))
10-element BinaryHV with 10 true and 0 false:
1
1
1
1
1
1
1
1
1
1
julia> perturbate(v, 1)
10-element BinaryHV with 9 true and 1 false:
1
1
1
1
1
0
1
1
1
1
julia> perturbate(v, 0.5)
10-element BinaryHV with 5 true and 5 false:
0
1
1
0
1
0
0
1
0
1
julia> perturbate(v, [1,2,3])
10-element BinaryHV with 7 true and 3 false:
0
0
0
1
1
1
1
1
1
1HyperdimensionalComputing.perturbate! — Function
perturbate!(hv::AbstractHV, args...; rng::AbstractRNG = Random.GLOBAL_RNG)Perturbate hypervectors by randomly flipping values.
Refer to perturbate for example use cases.
Inference
HyperdimensionalComputing.similarity — Function
similarity(u::AbstractVector, v::AbstractVector; method::Symbol)Computes similarity between two (hyper)vectors using a method ∈ [:cosine, :jaccard, :hamming]. When no method is given, a default is used (cosine for vectors that can have negative elements and Jaccard for those that only have positive elements).
similarity(hvs::AbstractVector{<:AbstractHV}; [method])Computes the similarity matrix for a vector of hypervectors using the similarity metrics defined by the pairwise version of similarity.
similarity(u::AbstractHV; [method])Create a function that computes the similarity between its argument and uusingsimilarity, i.e. a function equivalent tov -> similarity(u, v)`.
HyperdimensionalComputing.δ — Function
δ(u::AbstractHV, v::AbstractHV; [method])
δ(u::AbstractHV; [method])
δ(hvs::AbstractVector{<:AbstractHV}; [method])Alias for similarity. See similarity for the main documentation.
HyperdimensionalComputing.similaritymetric — Function
similaritymetric(HV)
similaritymetric(hv::AbstractHV)Which metric similarity uses for hypervectors of type HV, as a Symbol.
:jaccard for BinaryHV and GradedHV, whose elements are non-negative, and :cosine for the types that can take negative values – BipolarHV, TernaryHV, RealHV, GradedBipolarHV and FHRR. (For FHRR the normalized real part of the Hermitian inner product is the cosine similarity, since every element has unit modulus.)
Use together with chancesimilarity, which tells you what an unrelated pair scores under that metric – the number you need to judge whether a given similarity is large.
Examples
julia> similaritymetric(BinaryHV), similaritymetric(BipolarHV)
(:jaccard, :cosine)
julia> similaritymetric(BinaryHV(; D = 10)) # also works on an instance
:jaccardSee also
HyperdimensionalComputing.chancesimilarity — Function
chancesimilarity(HV)
chancesimilarity(hv::AbstractHV)The expected similarity between two independent random hypervectors of type HV: the value that means "unrelated".
This is the baseline you need to interpret a similarity score, and it is not always zero. Under cosine (see similaritymetric) unrelated hypervectors score 0.0, but under Jaccard they score 1/3 – so a similarity of 0.35 is strong evidence of a relationship for a BipolarHV and no evidence at all for a BinaryHV.
The value assumes hypervectors built with the type's default element distribution. Passing a custom distr to RealHV, GradedHV or GradedBipolarHV can shift the baseline: a distribution that is not centred makes random vectors point in a common direction, raising the chance level above zero.
Examples
julia> chancesimilarity(BipolarHV)
0.0
julia> chancesimilarity(BinaryHV) # Jaccard: unrelated is 1/3, not 0
0.3333333333333333See also
HyperdimensionalComputing.nearest_neighbor — Function
nearest_neighbor(u::AbstractHV, collection[, k::Int]; kwargs...)Returns the element of collection that is most similar to u.
Function outputs (τ, i, xi) with τ the highest similarity value, i the index (or key if collection is a dictionary) of the closest neighbor and xi the closest vector. kwargs is an optional argument for the similarity search.
If a number k is given, the k closest neighbor are returned, as a sorted list of (τ, i).
Combinators
Combinators take hypervectors and return a hypervector: they compose the primitive operations into structured representations.
HyperdimensionalComputing.multiset — Function
multiset(vs::AbstractVector{<:T})::T where {T <: AbstractHV}Multiset of input hypervectors, bundles all the input hypervectors together.
Arguments
vs::AbstractVector{<:AbstractHV}: Hypervectors
Example
julia> vs = BinaryHV.('a':'j'; D = 10) # a hypervector for each character
10-element Vector{BinaryHV}:
10-element BinaryHV with 5 true and 5 false
10-element BinaryHV with 6 true and 4 false
10-element BinaryHV with 3 true and 7 false
10-element BinaryHV with 6 true and 4 false
10-element BinaryHV with 3 true and 7 false
10-element BinaryHV with 6 true and 4 false
10-element BinaryHV with 4 true and 6 false
10-element BinaryHV with 3 true and 7 false
10-element BinaryHV with 5 true and 5 false
10-element BinaryHV with 3 true and 7 false
julia> multiset(vs)
10-element BinaryHV with 3 true and 7 false:
1
0
0
0
0
0
1
1
0
0Extended help
This encoding is based on the following mathematical notation:
\[\bigoplus_{i=1}^{m} V_i\]
where $V$ is the hypervector collection, $m$ is the size of the hypervector collection, $i$ is the position of the entry in the collection, and $\oplus$ is the bundling operation.
References
See also
multibind: Multibind encoding, binding-variant of this encoder
HyperdimensionalComputing.multibind — Function
multibind(vs::AbstractVector{<:AbstractHV})Binding of multiple hypervectors, binds all the input hypervectors together.
Arguments
vs::AbstractVector{<:AbstractHV}: Hypervectors
Examples
julia> vs = BinaryHV.('a':'j'; D = 10); # a hypervector for each character
julia> multibind(vs)
10-element BinaryHV with 4 true and 6 false:
1
0
0
0
0
0
1
0
1
1Extended help
This encoding is based on the following mathematical notation:
\[\bigotimes_{i=1}^{m} V_i\]
where $V$ is the hypervector collection, $m$ is the size of the hypervector collection, $i$ is the position of the entry in the collection, and $\otimes$ is the binding operation.
References
See also
multiset: Multiset encoding, bundling-variant of this encoder
HyperdimensionalComputing.bundlesequence — Function
bundlesequence(vs::AbstractVector{<:AbstractHV})Bundling-based sequence. The first value is not permuted, the last value is permuted n-1 times.
Arguments
vs::AbstractVector{<:AbstractHV}: Hypervector sequence
Examples
julia> vs = BinaryHV.('a':'j'; D = 10); # a hypervector for each character
julia> bundlesequence(vs)
10-element BinaryHV with 4 true and 6 false:
0
0
0
1
1
0
1
1
0
0Extended help
This encoding is based on the following mathematical notation:
\[\bigoplus_{i=1}^{m} \rho(V_i, i-1)\]
where $V$ is the hypervector collection, $m$ is the size of the hypervector collection, $i$ is the position of the entry in the collection, and $\oplus$ and $\rho$ are the bundling and shift operations.
References
See also
bindsequence: Binding-sequence encoding, binding-variant of this encoder
HyperdimensionalComputing.bindsequence — Function
bindsequence(vs::AbstractVector{<:AbstractHV})Binding-based sequence. The first value is not permuted, the last value is permuted n-1 times.
Arguments
vs::AbstractVector{<:AbstractHV}: Hypervector sequence
Examples
julia> vs = BinaryHV.('a':'j'; D = 10); # a hypervector for each character
julia> bindsequence(vs)
10-element BinaryHV with 6 true and 4 false:
1
0
0
1
1
0
0
1
1
1Extended help
This encoding is based on the following mathematical notation:
\[\bigotimes_{i=1}^{m} \rho(V_i, i-1)\]
where $V$ is the hypervector collection, $m$ is the size of the hypervector collection, $i$ is the position of the entry in the collection, and $\otimes$ and $\rho$ are the binding and shift operations.
References
See also
bundlesequence: Bundle-sequence encoding, bundling-variant of this encoder
HyperdimensionalComputing.hashtable — Function
hashtable(keys::T, values::T) where {T <: AbstractVector{<:AbstractHV}}Hash table from keys-values hypervector pairs. Keys and values must be the same length in order to encode as hypervector.
Arguments
keys::AbstractVector{<:AbstractHV}: Keys hypervectorsvalues::AbstractVector{<:AbstractHV}: Values hypervectors
Example
julia> ks = BinaryHV.([:name, :age, :city]; D = 10); # key hypervectors
julia> vs = BinaryHV.(["Alice", "42", "Ghent"]; D = 10); # value hypervectors
julia> hashtable(ks, vs)
10-element BinaryHV with 3 true and 7 false:
0
0
0
1
1
0
0
0
1
0Extended help
This encoding is based on the following mathematical notation:
\[\bigoplus_{i=1}^{m} K_i \otimes V_i\]
where $K$ and $V$ are the key and value hypervector collections, $m$ is the size of the hypervector collection, $i$ is the position of the entry in the collection, and $\otimes$ and $\oplus$ are the binding and bundling operations.
References
HyperdimensionalComputing.crossproduct — Function
crossproduct(U::T, V::T) where {T <: AbstractVector{<:AbstractHV}}Cross product between two sets of hypervectors.
Arguments
U::AbstractVector{<:AbstractHV}: HypervectorsV::AbstractVector{<:AbstractHV}: Hypervectors
Examples
julia> us = BinaryHV.('a':'e'; D = 10);
julia> vs = BinaryHV.('v':'z'; D = 10);
julia> crossproduct(us, vs)
10-element BinaryHV with 5 true and 5 false:
0
1
0
1
0
0
1
1
1
0Extended help
This encoding strategy first creates a multiset from both input hypervector sets, which are then bound together to generate all cross products, i.e.
\[U_1 \times V_1 + U_1 \times V_2 + ... + U_1 \times V_m + ... + U_n \times V_m\]
This encoding is based on the following formula:
\[\bigoplus_{i=1}^{m} U_i \ \otimes \ \bigoplus_{i=1}^{n} V_i\]
where $U$ and $V$ are collections of hypervectors, $m$ and $n$ are the sizes of the U and V collections, $i$ is the position in the hypervector collection, and $\oplus$ and $\otimes$ are the bundling and binding operations.
References
HyperdimensionalComputing.ngrams — Function
ngrams(vs::AbstractVector{<:AbstractHV}, n::Int = 3)Creates a hypervector with the n-gram statistics of the input.
Arguments
vs::AbstractVector{<:AbstractHV}: Hypervector collectionn::Int = 3: n-gram size
Examples
julia> vs = BinaryHV.('a':'j'; D = 10); # a hypervector for each character
julia> ngrams(vs)
10-element BinaryHV with 5 true and 5 false:
1
0
0
1
0
1
0
0
1
1Extended help
This encoding is defined by the following mathematical notation:
\[\bigoplus_{i=1}^{m-n}\bigotimes_{j=1}^{n-1}\rho^{n-j-1}(V_{i+j})\]
where $V$ is the collection of hypervectors, $m$ is the number of hypervectors in the collection $V$, $n$ is the window size, $i$ is the position in the sequence, $j$ is the position in the n-gram, and $\oplus$, $\otimes$ and $\rho$ are the bundling, binding and shift operations.
See also
multiset: Multiset encoding, equivalent tongram(vs, 1)bindsequence: Bind-sequence encoding, equivalent tongram(vs, length(vs))
References
HyperdimensionalComputing.graph — Function
graph(source::T, target::T, directed::Bool = false)Graph for source-target pairs. Can be directed or undirected.
Arguments
source::AbstractVector{<:AbstractHV}: Set of source node hypervectorstarget::AbstractVector{<:AbstractHV}: Set of target node hypervectorsdirected::Bool = false: Whether the graph is directed or not
Example
julia> V = [BinaryHV(i; D = 10) for i in 1:7];
julia> E = [1 2; 1 3; 1 4; 2 3; 2 4; 3 4; 4 5; 5 6; 6 7]; # Lollipop graph
julia> graph(V[E[:, 1]], V[E[:, 2]])
10-element BinaryHV with 7 true and 3 false:
1
1
0
1
1
1
0
0
1
1Extended help
This encoding is based on the following mathematical notation:
Undirected graphs
\[\bigoplus_{i=1}^{E} V_i \otimes V_j\]
Directed graphs
\[\bigoplus_{i=1}^{E} V_i \otimes \rho(V_j)\]
where $V$ is the node hypervector, $i$ and $j$ refer to the source and target nodes, $E$ is the set of edges between nodes in the graph, and $\otimes$, $\oplus$ and $\rho$ are the binding, bundling and shift operations.
See also
hashtable: Hash table encoding, underlying encoding strategy of this encoder.
References
Encoders
Encoders take raw data and return a hypervector. encode is the canonical entry point: without a strategy it is the deterministic token path, and with an AbstractEncoding strategy it composes the token path with the combinators above.
HyperdimensionalComputing.encode — Function
encode(HV::Type{<:AbstractHV}, x; D = 10_000, kwargs...)
encode(HV::Type{<:AbstractHV}, x, strategy::AbstractEncoding; D = 10_000, kwargs...)Encode raw data x as a D-dimensional hypervector of type HV.
Without a strategy, this is the token path: one object, one hash, one hypervector. x is hashed and the hash seeds the hypervector, so encoding the same object twice yields the same hypervector, and distinct objects give quasi-orthogonal hypervectors. This holds for any x, including strings and collections: encode(HV, "ACGT") hashes the whole string as a single token.
To encode a string (or any iterable of symbols) as a sequence, say so with a strategy: KMer, NGram, Sequence or BagOfSymbols. Strategies are thin compositions of the token path with the combinators in encoding.jl (multiset, ngrams, bundlesequence).
HV(x) is shorthand for encode(HV, x) for token-like x; every non-trivial encoding goes through encode. Extra keyword arguments (distr, T, ...) are forwarded to the HV constructor.
Examples
julia> encode(BipolarHV, "cat") == encode(BipolarHV, "cat") # deterministic
true
julia> encode(BipolarHV, "cat") == BipolarHV("cat") # HV(x) is sugar
true
julia> length(encode(BinaryHV, 42; D = 100)) # numbers are fine as encode tokens
100Sequence strategies compose the token path with the combinators:
julia> kmer = encode(BinaryHV, "ACGTAC", KMer(3); D = 64);
julia> kmer == multiset([encode(BinaryHV, s; D = 64) for s in ["ACG", "CGT", "GTA", "TAC"]])
true
julia> kmer != encode(BinaryHV, "ACGTAC", NGram(3); D = 64) # a different encoding
trueSee also
encode(lvl::LevelEncoder, x::Number; testbound = false)Encode the number x as a hypervector using the encoder's shared level set: the level whose value is nearest to x for a ladder encoder, or the continuous base^(β * x) for a fractional power (FHRR) encoder. Out-of-range values snap to the nearest level by default; pass testbound = true to throw a DomainError instead. See LevelEncoder.
encode(rp::RandomProjection, x::AbstractVector{<:Real})
encode(rp::RandomProjection, X::AbstractMatrix{<:Real})Encode the feature vector x (length d) as a hypervector: project through the encoder's fixed matrix (z = R * x) and apply the output type's nonlinearity. A d × n matrix is encoded per column, returning a vector of n hypervectors — all comparable, having passed through the same R. See RandomProjection.
HyperdimensionalComputing.decode — Function
decode(lvl::LevelEncoder, hv::AbstractHV; method = :nearest)Decode a hypervector back to the numeric value of the most similar level in the encoder's shared level set (nearest-neighbour by similarity — robust, works for noisy hypervectors such as bundles, but quantized to the encoder's value grid).
For a fractional power (FHRR) encoder, method = :analytic instead inverts the phases directly (mean(real(log(hv) / log(base)) / β)), giving a continuous, grid-free estimate — but it assumes a clean encoded vector and degrades on noisy ones; the default :nearest is the robust choice. See LevelEncoder.
decode(rp::RandomProjection, hv::AbstractHV, references; method = :nearest)Clean up hv against a set of references via nearest_neighbor — returning its (similarity, index, neighbor) (index becomes the key when references is a Dict).
This is clean-up, not inversion: the projection nonlinearity (sign, threshold, tanh, ...) discards magnitudes, so a random projection has no analytic inverse and method = :analytic is deliberately not offered (unlike LevelEncoder for FHRR). Calling decode without references throws: recovering anything from a lossy encoding needs a codebook to search.
HyperdimensionalComputing.AbstractEncoding — Type
AbstractEncodingSupertype of sequence-encoding strategies for encode: KMer, NGram, Sequence and BagOfSymbols.
Extending
Adding a new strategy requires only a struct and one encode method:
struct EveryOther <: AbstractEncoding end
function HyperdimensionalComputing.encode(
HV::Type{<:AbstractHV}, x, ::EveryOther; kwargs...
)
return multiset([encode(HV, s; kwargs...) for s in collect(x)[1:2:end]])
endHyperdimensionalComputing.BagOfSymbols — Type
BagOfSymbols()Sequence-encoding strategy: encode each symbol to a hypervector and bundle them orderlessly with multiset – the position-free counterpart of Sequence (and the n = 1 corner of NGram).
HyperdimensionalComputing.Sequence — Type
Sequence()Sequence-encoding strategy: encode each symbol to a hypervector and superpose them position-aware via bundlesequence (symbol i is shifted i - 1 times). Similar sequences map to similar hypervectors; use KMer or NGram for local-window statistics instead.
HyperdimensionalComputing.NGram — Type
NGram(n)Sequence-encoding strategy: encode each symbol to a hypervector, compose every window of n consecutive symbols by shift-binding, and bundle the windows – i.e. the existing ngrams combinator applied to token-encoded symbols. See KMer for how this differs from k-mer hashing.
Examples
julia> hv = encode(BinaryHV, "ACGT", NGram(2); D = 64);
julia> hv == ngrams([encode(BinaryHV, c; D = 64) for c in "ACGT"], 2)
trueHyperdimensionalComputing.KMer — Type
KMer(k)Sequence-encoding strategy: slide a window of length k over the sequence, treat every k-mer substring as one atomic token, hash it, and bundle the results with multiset. This is the standard genomics/text encoding (k-mer profile) and resolves issue #53.
Not the same operation as NGram: KMer hashes each window as a whole, so "AC" and "CA" get unrelated hypervectors; NGram encodes the symbols and composes windows by shift-binding, so windows that share symbols share structure. The two produce different hypervectors with different properties – pick deliberately.
Examples
julia> hv = encode(BinaryHV, "ACGT", KMer(2); D = 64);
julia> hv == multiset([encode(BinaryHV, s; D = 64) for s in ["AC", "CG", "GT"]])
trueStateful encoders hold hypervector state that is built once at construction — a level set, a projection matrix — so that separately encoded values remain mutually comparable. They are passed as the first argument of encode, and support the inverse map decode.
HyperdimensionalComputing.AbstractEncoder — Type
AbstractEncoder{HV <: AbstractHV}Supertype of stateful encoders: objects that hold hypervector state built once at construction (a level set, a projection matrix, ...) and are then used through encode and its inverse decode. Where an AbstractEncoding strategy is a pure recipe (encode(HV, x, strategy)), an AbstractEncoder instance is the shared state: encoding a value and decoding a hypervector are only consistent against the same state, so the state lives in the object, not in the call. Instances slot in as the first argument of encode.
Currently implemented: LevelEncoder (scalars) and RandomProjection (feature vectors).
HyperdimensionalComputing.LevelEncoder — Type
LevelEncoder{HV} <: AbstractEncoder{HV}Encoder for numeric values: maps a number to a hypervector such that close values get similar hypervectors and distant values get quasi-orthogonal ones, via a set of level-correlated hypervectors built once at construction and shared by every encode/decode call.
Two mechanisms, selected by dispatch on the hypervector type:
- Ladder (every hypervector type): start from a random base hypervector and repeatedly
perturbatea fractionbandwidthof the positions to obtain successive levels. Adjacent levels are similar; the first and last are quasi-orthogonal. Values are quantized to the nearest level. - Fractional power encoding (
FHRRonly, the default forFHRR):encode(lvl, x) = base^(β * x)using complex exponentiation — continuous, no quantization.βplays the same bandwidth role as the ladder's flip fraction: smaller values give slower similarity decay.
Constructors
LevelEncoder(HV, values; D = 10_000, bandwidth = 2/length(values), seed, rng)
LevelEncoder(HV, range, n; D = 10_000, bandwidth = 2/n, seed, rng)
LevelEncoder(FHRR, values; D = 10_000, β = 1/(max - min), seed, rng)
LevelEncoder(levels::AbstractVector{<:AbstractHV}, values)The first two build a ladder: over the given values (any vector or range of numbers), or n evenly spaced levels over range (anything minimum/maximum accept: a range, a vector, a 2-tuple). For FHRR the two-argument form builds a fractional power encoder whose values serve as the decoding grid; ask for a ladder explicitly by passing a level count n. The last form wraps precomputed level hypervectors with their values. Passing seed makes the whole encoder deterministic.
Examples
julia> lvl = LevelEncoder(BipolarHV, (0, 1), 20; seed = 42)
LevelEncoder{BipolarHV}: 20 levels over [0.0, 1.0] (ladder, bandwidth = 0.1)
julia> decode(lvl, encode(lvl, 0.25)) # round-trips within one grid step
0.2631578947368421
julia> similarity(encode(lvl, 0.3), encode(lvl, 0.35)) >
similarity(encode(lvl, 0.3), encode(lvl, 0.9))
trueFractional power encoding for FHRR is continuous:
julia> fpe = LevelEncoder(FHRR, 0:0.1:10; seed = 1)
LevelEncoder{FHRR}: 101 levels over [0.0, 10.0] (fractional power, β = 0.1)
julia> decode(fpe, encode(fpe, 3.7); method = :analytic) ≈ 3.7
trueSee also
HyperdimensionalComputing.RandomProjection — Type
RandomProjection{HV, T} <: AbstractEncoder{HV}Encoder for fixed-length real feature vectors (an RGB triple, an embedding): x ∈ ℝᵈ is projected as z = R * x through a D × d projection matrix drawn once at construction, then mapped into the hypervector domain by a per-type nonlinearity. Nearby feature vectors get similar hypervectors; the Johnson–Lindenstrauss lemma guarantees the projection approximately preserves distances (Kleyko et al., §3.2.3). Not for sequences (use KMer / NGram) and not for scalars (use LevelEncoder).
R is the shared state: two hypervectors are comparable only when encoded through the same R, which is why this is a stateful AbstractEncoder — exactly like LevelEncoder's level set. The struct is immutable and has no fit method; re-thresholding returns a new encoder via rethreshold.
R * x is dominated by whichever feature has the largest scale. RGB channels share a scale; embedding dimensions and mixed tabular features generally do not. Center and scale each feature (z-scores) before encoding, or the projection silently encodes only the loudest feature.
Nonlinearities (dispatched on the output type)
| Output type | Map from z = R * x |
|---|---|
BipolarHV | z > 0 ↦ +1, else -1 |
BinaryHV | z .> 0 |
TernaryHV | sign.(z) .* (abs.(z) .> θ) (θ scalar or per-component vector) |
RealHV | β .* z |
GradedHV | logistic.(β .* z) |
GradedBipolarHV | tanh.(β .* z) |
FHRR | exp.(im * β .* z) (shared phase_encode helper) |
The sign-like maps are scale-invariant; for the others β (default 1/√d) scales z to order one for standardized features, and can be tuned.
FHRR = random Fourier features
For FHRR with a :gaussian matrix this is exactly the Rahimi–Recht random Fourier feature map: similarity(encode(rp, x), encode(rp, y)) approximates the Gaussian kernel exp(-β² ‖x - y‖² / 2) with bandwidth β — the same phase-encoding math as LevelEncoder's fractional power path, and the strongest bridge between hyperdimensional computing and kernel methods.
Constructors
RandomProjection(HV, d::Int; D = 10_000, matrix = :gaussian, θ = 0, β = 1/√d, seed, rng)
RandomProjection(HV, R::AbstractMatrix; θ = 0, β = 1/√size(R, 2))
RandomProjection(TernaryHV, X::AbstractMatrix; target_sparsity, D = 10_000, matrix, seed, rng)The first draws a fresh D × d matrix: :gaussian (N(0,1), default), :bipolar ({-1, +1}) or :sparse_ternary ({-1, 0, +1} with nonzero density 1/√d, Li–Hastie–Church very sparse projections — the HDC-idiomatic, scalable choice). All three satisfy Johnson–Lindenstrauss.
The second wraps a supplied matrix (d and D are read off its size), for reproducible, saved or structured projections.
The third is the data-driven ternary constructor: it reads the d × n data matrix X (columns are observations) once at construction and solves for the global scalar θ such that encoded training columns have a fraction target_sparsity of zero elements. This is construction from data, not fitting: the returned encoder is as immutable as any other. (For TernaryHV the positional matrix is interpreted as data X when target_sparsity is given, and as a supplied projection matrix otherwise.)
Examples
julia> rp = RandomProjection(BipolarHV, 3; seed = 42)
RandomProjection{BipolarHV}: 3 features → 10000-dimensional BipolarHV
julia> x = [0.9, -0.2, 0.4];
julia> encode(rp, x) == encode(rp, x) # same R, comparable and deterministic
true
julia> similarity(encode(rp, x), encode(rp, x .+ 0.05)) >
similarity(encode(rp, x), encode(rp, -x))
trueThe FHRR similarity approximates a Gaussian kernel:
julia> rff = RandomProjection(FHRR, 3; β = 0.5, seed = 1)
RandomProjection{FHRR}: 3 features → 10000-dimensional FHRR (β = 0.5)
julia> y = [0.7, -0.2, 0.4]; # ‖x - y‖ = 0.2
julia> similarity(encode(rff, x), encode(rff, y)) ≈ exp(-(0.5 * 0.2)^2 / 2) atol = 0.02
ERROR: ParseError:
# Error @ none:1:69
similarity(encode(rff, x), encode(rff, y)) ≈ exp(-(0.5 * 0.2)^2 / 2) atol = 0.02
# └──────────┘ ── extra tokens after end of expression
Stacktrace:
[1] top-level scope
@ none:1See also
HyperdimensionalComputing.rethreshold — Function
rethreshold(rp::RandomProjection, θ)Return a new RandomProjection with threshold θ (a scalar or a length-D vector), sharing the original's projection matrix — encodings from both encoders remain comparable. This is the immutable counterpart of mutating the threshold.
Package extensions
HyperdimensionalComputing.jl has a couple of package extensions to interact with commonly used Julia packages:
UnicodePlots.jl
HyperdimensionalComputing.unicodeheatmap — Function
unicodeheatmap(hv::AbstractHV)Render a hypervector as a square unicode heatmap of its leading ⌊√D⌋² elements (phases for FHRR).
Only available when UnicodePlots is loaded (using UnicodePlots); implemented in the UnicodePlotting package extension.
See also unicodehistogram.
HyperdimensionalComputing.unicodehistogram — Function
unicodehistogram(hv::AbstractHV)Render the distribution of a hypervector's elements as a unicode histogram (a bar plot of counts for the discrete types BinaryHV, BipolarHV and TernaryHV; phases for FHRR).
Only available when UnicodePlots is loaded (using UnicodePlots); implemented in the UnicodePlotting package extension.
See also unicodeheatmap.