API Reference

This page contains the complete API reference for HyperdimensionalComputing.jl.

Types

HyperdimensionalComputing.AbstractHVType
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
100

See 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.
source
HyperdimensionalComputing.BinaryHVType
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
true

Binding is self-inverse:

julia> x = BinaryHV(; D = 8, rng = Xoshiro(1)); y = BinaryHV(; D = 8, rng = Xoshiro(2));

julia> x * y * y == x
true

See 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.
source
HyperdimensionalComputing.BipolarHVType
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
true

Random 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.0028

See 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.
source
HyperdimensionalComputing.TernaryHVType
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
true

Bundling 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
  1

See 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.
source
HyperdimensionalComputing.GradedHVType
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
true

Binding 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.5

See also

AbstractHV, GradedBipolarHV, bundle, bind, similarity

source
HyperdimensionalComputing.GradedBipolarHVType
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
true

Binding 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.0

See also

AbstractHV, GradedHV, bundle, bind, similarity

source
HyperdimensionalComputing.RealHVType
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
true

The 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.326904027046626

See also

AbstractHV, bundle, bind, similarity

source
HyperdimensionalComputing.FHRRType
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
true

Fractional 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)
true

See 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.
source

Operations

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

Bundling is m-way, not pairwise

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

bind, similarity

source
Base.bindFunction
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

bundle, unbind, similarity

source
HyperdimensionalComputing.unbindFunction
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.

Warning

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

bind, bundle, similarity

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

source
HyperdimensionalComputing.shiftFunction
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.

source
HyperdimensionalComputing.normalizeFunction
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
 -12
source
HyperdimensionalComputing.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

source
normalize!(hv::FHRR)

A Fourier Holographic Reduced Representation is normalized by setting the norm of each complex element to 1.

source
HyperdimensionalComputing.perturbateFunction
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
 1
source

Inference

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

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

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

source
HyperdimensionalComputing.δFunction
δ(u::AbstractHV, v::AbstractHV; [method])
δ(u::AbstractHV; [method])
δ(hvs::AbstractVector{<:AbstractHV}; [method])

Alias for similarity. See similarity for the main documentation.

source
HyperdimensionalComputing.similaritymetricFunction
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
:jaccard

See also

similarity, chancesimilarity

source
HyperdimensionalComputing.chancesimilarityFunction
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.

Note

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

See also

similarity, similaritymetric

source
HyperdimensionalComputing.nearest_neighborFunction
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).

source

Combinators

Combinators take hypervectors and return a hypervector: they compose the primitive operations into structured representations.

HyperdimensionalComputing.multisetFunction
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
 0

Extended 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
source
HyperdimensionalComputing.multibindFunction
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
 1

Extended 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
source
HyperdimensionalComputing.bundlesequenceFunction
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
 0

Extended 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
source
HyperdimensionalComputing.bindsequenceFunction
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
 1

Extended 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
source
HyperdimensionalComputing.hashtableFunction
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 hypervectors
  • values::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
 0

Extended 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

source
HyperdimensionalComputing.crossproductFunction
crossproduct(U::T, V::T) where {T <: AbstractVector{<:AbstractHV}}

Cross product between two sets of hypervectors.

Arguments

  • U::AbstractVector{<:AbstractHV}: Hypervectors
  • V::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
 0

Extended 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

source
HyperdimensionalComputing.ngramsFunction
ngrams(vs::AbstractVector{<:AbstractHV}, n::Int = 3)

Creates a hypervector with the n-gram statistics of the input.

Arguments

  • vs::AbstractVector{<:AbstractHV}: Hypervector collection
  • n::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
 1

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

Note
  • For n = 1 use multiset() instead
  • For n = m use bindsequence() instead

See also

  • multiset: Multiset encoding, equivalent to ngram(vs, 1)
  • bindsequence: Bind-sequence encoding, equivalent to ngram(vs, length(vs))

References

source
HyperdimensionalComputing.graphFunction
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 hypervectors
  • target::AbstractVector{<:AbstractHV}: Set of target node hypervectors
  • directed::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
 1

Extended 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

source

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.encodeFunction
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
100

Sequence 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
true

See also

AbstractEncoding, KMer, NGram, Sequence, BagOfSymbols

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

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

source
HyperdimensionalComputing.decodeFunction
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.

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

source
HyperdimensionalComputing.AbstractEncodingType
AbstractEncoding

Supertype 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]])
end
source
HyperdimensionalComputing.NGramType
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)
true
source
HyperdimensionalComputing.KMerType
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"]])
true
source

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

source
HyperdimensionalComputing.LevelEncoderType
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 perturbate a fraction bandwidth of 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 (FHRR only, the default for FHRR): 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))
true

Fractional 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
true

See also

encode, decode, AbstractEncoder, perturbate

source
HyperdimensionalComputing.RandomProjectionType
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.

Standardize your features first

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 typeMap from z = R * x
BipolarHVz > 0 ↦ +1, else -1
BinaryHVz .> 0
TernaryHVsign.(z) .* (abs.(z) .> θ) (θ scalar or per-component vector)
RealHVβ .* z
GradedHVlogistic.(β .* z)
GradedBipolarHVtanh.(β .* z)
FHRRexp.(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))
true

The 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:1

See also

encode, decode, rethreshold, AbstractEncoder, LevelEncoder

source
HyperdimensionalComputing.rethresholdFunction
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.

source

Package extensions

HyperdimensionalComputing.jl has a couple of package extensions to interact with commonly used Julia packages:

UnicodePlots.jl

HyperdimensionalComputing.unicodeheatmapFunction
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.

source