Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/functional.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ Encodings

multiset
multibind
sequence
distinct_sequence
bundle_sequence
bind_sequence
hash_table
cross_product
ngrams
Expand Down
4 changes: 2 additions & 2 deletions docs/structures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ This module provides class-based implementations of HDC data structures.
Memory
Multiset
HashTable
Sequence
DistinctSequence
BundleSequence
BindSequence
Graph
Tree
FiniteStateAutomata
23 changes: 13 additions & 10 deletions torchhd/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"multiset",
"multibind",
"cross_product",
"sequence",
"distinct_sequence",
"bundle_sequence",
"bind_sequence",
"ngrams",
"hash_table",
"map_range",
Expand Down Expand Up @@ -621,13 +621,13 @@ def hamming_similarity(input: Tensor, others: Tensor) -> LongTensor:
return torch.sum(input == others, dim=-1, dtype=torch.long)


def multiset(
input: Tensor,
) -> Tensor:
def multiset(input: Tensor) -> Tensor:
r"""Multiset of input hypervectors.

Bundles all the input hypervectors together.

Aliased as ``torchhd.functional.multibundle``.

.. math::

\bigoplus_{i=0}^{n-1} V_i
Expand Down Expand Up @@ -662,6 +662,9 @@ def multiset(
return torch.sum(input, dim=-2, dtype=input.dtype)


multibundle = multiset


def multibind(input: Tensor) -> Tensor:
r"""Binding of multiple hypervectors.

Expand Down Expand Up @@ -747,7 +750,7 @@ def ngrams(input: Tensor, n: int = 3) -> Tensor:
\bigoplus_{i=0}^{m - n} \bigotimes_{j = 0}^{n - 1} \Pi^{n - j - 1}(V_{i + j})

.. note::
For :math:`n=1` use :func:`~torchhd.functional.multiset` instead and for :math:`n=m` use :func:`~torchhd.functional.distinct_sequence` instead.
For :math:`n=1` use :func:`~torchhd.functional.multiset` instead and for :math:`n=m` use :func:`~torchhd.functional.bind_sequence` instead.

Args:
input (Tensor): The value hypervectors.
Expand Down Expand Up @@ -812,7 +815,7 @@ def hash_table(keys: Tensor, values: Tensor) -> Tensor:
return multiset(bind(keys, values))


def sequence(input: Tensor) -> Tensor:
def bundle_sequence(input: Tensor) -> Tensor:
r"""Bundling-based sequence.

The first value is permuted :math:`n-1` times, the last value is not permuted.
Expand All @@ -837,7 +840,7 @@ def sequence(input: Tensor) -> Tensor:
[ 1., 1., 1.],
[-1., -1., -1.],
[ 1., 1., 1.]])
>>> functional.sequence(x)
>>> functional.bundle_sequence(x)
tensor([-1., 3., 1.])

"""
Expand All @@ -851,7 +854,7 @@ def sequence(input: Tensor) -> Tensor:
return multiset(permuted)


def distinct_sequence(input: Tensor) -> Tensor:
def bind_sequence(input: Tensor) -> Tensor:
r"""Binding-based sequence.

The first value is permuted :math:`n-1` times, the last value is not permuted.
Expand All @@ -876,7 +879,7 @@ def distinct_sequence(input: Tensor) -> Tensor:
[ 1., -1., -1.],
[ 1., -1., -1.],
[-1., -1., -1.]])
>>> functional.distinct_sequence(x)
>>> functional.bind_sequence(x)
tensor([-1., 1., 1.])

"""
Expand Down
52 changes: 26 additions & 26 deletions torchhd/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"Memory",
"Multiset",
"HashTable",
"Sequence",
"DistinctSequence",
"BundleSequence",
"BindSequence",
"Graph",
"Tree",
"FiniteStateAutomata",
Expand Down Expand Up @@ -134,7 +134,7 @@ def __delitem__(self, key: Tensor) -> None:


class Multiset:
"""Hypervector-based multiset data structure.
"""Hypervector multiset data structure.

Creates an empty multiset of dim dimensions or from an input tensor.

Expand Down Expand Up @@ -278,7 +278,7 @@ def from_tensor(cls, input: Tensor):


class HashTable:
"""Hypervector-based hash table data structure.
"""Hypervector hash table data structure.

Creates an empty hash table of dim dimensions or a hash table from an input tensor.

Expand Down Expand Up @@ -437,8 +437,8 @@ def from_tensors(cls, keys: Tensor, values: Tensor):
return cls(value, size=keys.size(-2))


class Sequence:
"""Hypervector-based (bundling-based) sequence data structure
class BundleSequence:
"""Hypervector bundling-based sequence data structure

Creates an empty sequence of dim dimensions or from an input tensor.

Expand All @@ -453,11 +453,11 @@ class Sequence:

Examples::

>>> S = structures.Sequence(10000)
>>> S = structures.BundleSequence(10000)

>>> letters = list(string.ascii_lowercase)
>>> letters_hv = functional.random_hv(len(letters), 10000)
>>> S = structures.Sequence(letters_hv[0], size=1)
>>> S = structures.BundleSequence(letters_hv[0], size=1)

"""

Expand Down Expand Up @@ -559,21 +559,21 @@ def replace(self, index: int, old: Tensor, new: Tensor) -> None:
rotated_new = functional.permute(new, shifts=self.size - index - 1)
self.value = functional.bundle(self.value, rotated_new)

def concat(self, seq: "Sequence") -> "Sequence":
def concat(self, seq: "BundleSequence") -> "BundleSequence":
"""Concatenates the current sequence with the given one.

Args:
seq (Sequence): Sequence to be concatenated with the current one.

Examples::

>>> S1 = structures.Sequence(dimensions=10000)
>>> S1 = structures.BundleSequence(dimensions=10000)
>>> S2 = S.concat(S1)

"""
value = functional.permute(self.value, shifts=len(seq))
value = functional.bundle(value, seq.value)
return Sequence(value, size=len(self) + len(seq))
return BundleSequence(value, size=len(self) + len(seq))

def __getitem__(self, index: int) -> Tensor:
"""Gets the approximate value from given index.
Expand Down Expand Up @@ -615,37 +615,37 @@ def clear(self) -> None:
def from_tensor(cls, input: Tensor):
"""Creates a sequence from hypervectors.

See: :func:`~torchhd.functional.sequence`.
See: :func:`~torchhd.functional.bundle_sequence`.

Args:
input (Tensor): Tensor representing a sequence.
input (Tensor): Tensor containing hypervectors that form the sequence.

Examples::
>>> letters_hv = functional.random_hv(len(letters), 10000)
>>> S = structures.Sequence.from_tensor(letters_hv)
>>> S = structures.BundleSequence.from_tensor(letters_hv)

"""
value = functional.sequence(input)
value = functional.bundle_sequence(input)
return cls(value, size=input.size(-2))


class DistinctSequence:
"""Hypervector-based distinct (binding-based) sequence data structure.
class BindSequence:
"""Hypervector binding-based sequence data structure.

Creates an empty sequence of dim dimensions or from an input tensor.

Args:
dimensions (int): number of dimensions of the distinct sequence.
dimensions (int): number of dimensions of the sequence.
dtype (``torch.dtype``, optional): the desired data type of returned tensor. Default: if ``None``, uses a global default (see ``torch.set_default_tensor_type()``).
device (``torch.device``, optional): the desired device of returned tensor. Default: if ``None``, uses the current device for the default tensor type (see torch.set_default_tensor_type()). ``device`` will be the CPU for CPU tensor types and the current CUDA device for CUDA tensor types.

Args:
input (Tensor): tensor representing a distinct sequence.
size (int, optional): the length of the distinct sequence provided as input. Default: ``0``.
input (Tensor): tensor representing a binding-based sequence.
size (int, optional): the length of the sequence provided as input. Default: ``0``.

Examples::

>>> DS = structures.DistinctSequence(10000)
>>> DS = structures.BindSequence(10000)
"""

@overload
Expand Down Expand Up @@ -739,7 +739,7 @@ def replace(self, index: int, old: Tensor, new: Tensor) -> None:

Examples::

>>> DS1 = structures.DistinctSequence(dimensions=10000)
>>> DS1 = structures.BindSequence(dimensions=10000)
>>> DS.concat(DS1)

"""
Expand Down Expand Up @@ -775,17 +775,17 @@ def clear(self) -> None:
def from_tensor(cls, input: Tensor):
"""Creates a sequence from tensor.

See: :func:`~torchhd.functional.distinct_sequence`.
See: :func:`~torchhd.functional.bind_sequence`.

Args:
input (Tensor): Tensor representing a sequence.
input (Tensor): Tensor containing hypervectors that form the sequence.

Examples::
>>> letters_hv = functional.random_hv(len(letters), 10000)
>>> DS = structures.DistinctSequence.from_tensor(letters_hv)
>>> DS = structures.BindSequence.from_tensor(letters_hv)

"""
value = functional.distinct_sequence(input)
value = functional.bind_sequence(input)
return cls(value, size=input.size(-2))


Expand Down
20 changes: 10 additions & 10 deletions torchhd/tests/structures/test_distinct_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
letters = list(string.ascii_lowercase)


class TestDistinctSequence:
class TestBindSequence:
def test_creation_dim(self):
S = structures.DistinctSequence(10000)
S = structures.BindSequence(10000)
assert torch.equal(S.value, torch.ones(10000))

def test_creation_tensor(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)

S = structures.DistinctSequence(hv[0])
S = structures.BindSequence(hv[0])
assert torch.equal(S.value, hv[0])

def test_generator(self):
Expand All @@ -36,23 +36,23 @@ def test_append(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S = structures.BindSequence(10000)
S.append(hv[0])
assert functional.cosine_similarity(S.value, hv)[0] > 0.5

def test_appendleft(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S = structures.BindSequence(10000)
S.appendleft(hv[0])
assert functional.cosine_similarity(S.value, hv)[0] > 0.5

def test_pop(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S = structures.BindSequence(10000)
S.append(hv[0])
S.append(hv[1])
S.pop(hv[1])
Expand All @@ -68,7 +68,7 @@ def test_popleft(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S = structures.BindSequence(10000)
S.appendleft(hv[0])
S.appendleft(hv[1])
S.popleft(hv[1])
Expand All @@ -84,7 +84,7 @@ def test_replace(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S = structures.BindSequence(10000)
S.append(hv[0])
assert functional.cosine_similarity(S.value, hv)[0] > 0.5
S.replace(0, hv[0], hv[1])
Expand All @@ -94,7 +94,7 @@ def test_length(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S = structures.BindSequence(10000)
S.append(hv[0])
S.append(hv[0])
S.append(hv[0])
Expand All @@ -113,7 +113,7 @@ def test_clear(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S = structures.BindSequence(10000)
S.append(hv[0])
S.append(hv[0])
S.append(hv[0])
Expand Down
Loading