diff --git a/docs/arithmetic.html b/docs/arithmetic.html index 6fe1990..9228450 100644 --- a/docs/arithmetic.html +++ b/docs/arithmetic.html @@ -248,7 +248,7 @@

Examples

diff --git a/docs/graph.html b/docs/graph.html index b17bcb8..ac88dc2 100644 --- a/docs/graph.html +++ b/docs/graph.html @@ -593,7 +593,7 @@

Examples

self._weight_memory(0.0, 1.0, 0.01) graph = None - + for node in self.space.space: # Check whether the current node is not the actual graph memory # Also, check whether the current node is not a weight vector @@ -897,7 +897,7 @@

Graph diff --git a/docs/index.html b/docs/index.html index 7fb6435..0d7ca37 100644 --- a/docs/index.html +++ b/docs/index.html @@ -22,7 +22,7 @@
-

Package hdlib v0.1.17

+

Package hdlib v0.1.18

hdlib is a Python 3 library for building Vector-Symbolic Architectures (VSA, a.k.a. Hyperdimensional Computing).

diff --git a/docs/model.html b/docs/model.html index e0d91d0..77cab67 100644 --- a/docs/model.html +++ b/docs/model.html @@ -184,7 +184,7 @@

Examples

Levels: {} Points: {} Classes: - + {} """.format( self.version, @@ -446,7 +446,7 @@

Examples

distance_method: str="cosine" ) -> Tuple[float, List[Vector], List[str]]: """Compute the error rate. - + Parameters ---------- training_vectors : list @@ -1502,7 +1502,7 @@

MLModel

-

Copyright © 2024 Fabio Cumbo - Distributed under the MIT License - Documentation generated by pdoc 0.11.1.

+

Copyright © 2024 Fabio Cumbo - Distributed under the MIT License - Documentation generated by pdoc 0.11.1.

diff --git a/docs/parser.html b/docs/parser.html index f5815e1..3477ddd 100644 --- a/docs/parser.html +++ b/docs/parser.html @@ -37,7 +37,7 @@

Module hdlib.parser

Functions

-def load_dataset(filepath: , sep: str = '\t') ‑> Tuple[List[str], List[List[float]], List[str]] +def load_dataset(filepath: , sep: str = '\t') ‑> Tuple[List[str], List[List[float]], List[str]]

Load the input numerical dataset.

@@ -126,7 +126,7 @@

Examples

-

Copyright © 2024 Fabio Cumbo - Distributed under the MIT License - Documentation generated by pdoc 0.11.1.

+

Copyright © 2024 Fabio Cumbo - Distributed under the MIT License - Documentation generated by pdoc 0.11.1.

diff --git a/docs/space.html b/docs/space.html index a8b52ff..35441c7 100644 --- a/docs/space.html +++ b/docs/space.html @@ -40,7 +40,7 @@

Classes

class Space -(size: int = 10000, vtype: str = 'bipolar', from_file: Optional[] = None) +(size: int = 10000, vtype: str = 'bipolar', from_file: Optional[] = None)

Vectors space.

@@ -61,6 +61,10 @@

Returns

Raises

+
Exception
+
If the pickle object in from_file is not instance of Space.
+
FileNotFoundError
+
If from_file is not None but the file does not exist.
ValueError
    @@ -68,8 +72,6 @@

    Raises

  • if size is lower than 10,000.
-
FileNotFoundError
-
If from_file is not None but the file does not exist.

Examples

>>> from hdlib.space import Space
@@ -115,11 +117,13 @@ 

Examples

Raises ------ + Exception + If the pickle object in `from_file` is not instance of Space. + FileNotFoundError + If `from_file` is not None but the file does not exist. ValueError - if `vtype` is different than 'binary' or 'bipolar'; - if `size` is lower than 10,000. - FileNotFoundError - If `from_file` is not None but the file does not exist. Examples -------- @@ -144,7 +148,12 @@

Examples

and finally create a new space object `space2` from the pickle file. """ - self.space = dict() + # We may want to iterate over the Space object + # Thus, we need to maintain the order of the vectors into the space dictionary + self.space = OrderedDict() + + # Used to iterate over vectors in the space + self._vector_index = 0 self.version = __version__ @@ -170,18 +179,76 @@

Examples

else: with open(from_file, "rb") as pkl: - self.version, self.size, self.vtype, self.space, self.root = pickle.load(pkl) + from_file_obj = pickle.load(pkl) + + if not isinstance(from_file_obj, type(self)): + raise Exception("Pickle object is not instance of {}".format(type(self))) + + self.__dict__.update(from_file_obj.__dict__) + + if self.version != __version__: + print("Warning: the specified Space has been created with a different version of hdlib") + + def __iter__(self) -> "Space": + """Required to make the Space object iterable.""" + + return self + + def __next__(self) -> str: + """Used to iterate over the vector objects into the Space. + + Returns + ------- + str + The vector name at a specific position. + """ + + if self._vector_index >= len(self.space): + # Set the vector index back to the first position. + # Redy to start iterating again over the vectors in the space + self._vector_index = 0 + + raise StopIteration + + else: + # Retrieve the vector name at a specific position in the space + # Vectors are all ordered in the space since the space is defined as an OrderedDict + vector = self.memory()[self._vector_index] - if self.version != __version__: - print("Warning: the specified Space has been created with a different version of hdlib") + # Increment the vector index for the next iteration + self._vector_index += 1 - for name in self.space: - if self.space[name].tags: - for tag in self.space[name].tags: - if tag not in self.tags: - self.tags[tag] = set() + # This returns the vector name or ID + # It is enough, since the space is a hashmap and we can retrieve the Vector object in O(1) + return vector - self.tags[tag].add(name) + def __contains__(self, vector: str) -> bool: + """Check whether a vector is in the space. + + Parameters + ---------- + vector : str + The vector name or ID. + + Returns + ------- + bool + True if `vector` is in the space, False otherwise. + + Examples + -------- + >>> from hdlib.space import Space, Vector + >>> space = Space() + >>> vector = Vector(name="my_vector") + >>> space.insert(vector) + >>> "my_vector" in space + True + + Create a Space object, add a Vector object into the space, and check whether the + vector is actually in the space by searching for its name. + """ + + return True if vector in self.space else False def __len__(self) -> int: """Get the number of vectors in space. @@ -200,7 +267,7 @@

Examples

>>> len(space) 1 - Create a Space object, add a Vector object to the space, and check the total number + Create a Space object, add a Vector object into the space, and check the total number of Vector objects in the space. """ @@ -247,9 +314,9 @@

Examples

Type: {} Vectors: {} Tags: - + {} - + IDs: {} @@ -306,6 +373,9 @@

Examples

Raises ------ + Exception + - if no `names` or `tags` are provided in input; + - if both `names` and `tags` are provided in input. TypeError If names or tags in the input lists are not instance of primitives. @@ -329,7 +399,10 @@

Examples

""" if not names and not tags: - raise Exception("No names or tags provided!") + raise Exception("No names or tags provided") + + if names and tags: + raise Exception("Cannot search for vectors by their names and tags at the same time") vectors = set() @@ -347,7 +420,7 @@

Examples

elif tags: for tag in tags: if not isinstance(tag, str) and not isinstance(tag, int) and not isinstance(tag, float): - raise TypeError("Tags must be string, integer, or float") + raise TypeError("A tags must be string, integer, or float") if tag in self.tags: for vector_name in self.tags[tag]: @@ -409,7 +482,7 @@

Examples

self, names: List[str], tags: Optional[List[List[Union[str, int, float]]]]=None, - ignore_existing: bool=True + ignore_existing: bool=False ) -> None: """Add vectors to the space in bulk. @@ -419,8 +492,8 @@

Examples

A list with vector names. tags : list, optional An optional list of lists with vector tags. - ignore_existing : bool, default True - Do not raise an exception in case the space contains a vector with the same name specified in `names`. + ignore_existing : bool, default False + If True, do not raise an exception in case the space contains a vector with the same name specified in `names`. Raises ------ @@ -465,15 +538,14 @@

Examples

names = set(names) for pos, name in enumerate(names): - try: - name = str(name) - - except: + if not isinstance(name, (bool, str, int, float, None)): raise TypeError("Entries in input list must be instances of primitives") + name = str(name) + if name in self.space: if not ignore_existing: - raise Exception("Vector \"{}\" already in space".format(name)) + raise Exception("Vector \"{}\" already exists in the space".format(name)) else: continue @@ -738,14 +810,14 @@

Examples

self.root = name - def find(self, vector: Vector, threshold: float=2.0, method: str="cosine") -> Tuple[str, float]: + def find(self, vector: Vector, threshold: float=np.Inf, method: str="cosine") -> Tuple[str, float]: """Search for the closest vector in space. Parameters ---------- vector : Vector Input Vector object. Search for the closest vector to this Vector in the space. - threshold : float, default 2.0 + threshold : float, default numpy.Inf Threshold on distance between vectors. method : {'cosine', 'euclidean', 'hamming'}, default 'cosine' Distance metric. @@ -778,14 +850,14 @@

Examples

return best, distances[best] - def find_all(self, vector: Vector, threshold: float=2.0, method: str="cosine") -> Tuple[dict, str]: + def find_all(self, vector: Vector, threshold: float=np.Inf, method: str="cosine") -> Tuple[dict, str]: """Compute distance of the input vector against all vectors in space. Parameters ---------- vector : Vector Input Vector object. Search for the closest vector to this Vector in the space. - threshold : float, default 2.0 + threshold : float, default numpy.Inf Threshold on distance between vectors. method : {'cosine', 'euclidean', 'hamming'}, default 'cosine' Distance metric. @@ -829,7 +901,7 @@

Examples

distances = dict() - distance = 2.0 + distance = np.Inf best = None @@ -874,13 +946,13 @@

Examples

if not to_file: # Dump the space to a pickle file in the current working directory if not file path is provided - to_file = os.path.join(os.getcwd, "space.pkl") + to_file = os.path.join(os.getcwd(), "space.pkl") if os.path.isfile(to_file): raise Exception("The output file already exists!\n{}".format(to_file)) with open(to_file, "wb") as pkl: - pickle.dump((self.version, self.size, self.vtype, self.space, self.root), pkl)
+ pickle.dump(self, pkl)

Methods

@@ -917,7 +989,7 @@

Examples

for vector with that specific tag within the space. It finally prints the vector names.

-def bulk_insert(self, names: List[str], tags: Optional[List[List[Union[str, int, float]]]] = None, ignore_existing: bool = True) ‑> None +def bulk_insert(self, names: List[str], tags: Optional[List[List[Union[str, int, float]]]] = None, ignore_existing: bool = False) ‑> None

Add vectors to the space in bulk.

@@ -927,8 +999,8 @@

Parameters

A list with vector names.
tags : list, optional
An optional list of lists with vector tags.
-
ignore_existing : bool, default True
-
Do not raise an exception in case the space contains a vector with the same name specified in names.
+
ignore_existing : bool, default False
+
If True, do not raise an exception in case the space contains a vector with the same name specified in names.

Raises

@@ -967,7 +1039,7 @@

Examples

Both 'my_vector_3' and 'my_vector_4' contain 'tag1' in their set of tags.

-def dump(self, to_file: Optional[] = None) ‑> None +def dump(self, to_file: Optional[] = None) ‑> None

Dump the Space object to a pickle file.

@@ -992,7 +1064,7 @@

Examples

Create a Space object and dump it to a pickle file under the home directory.

-def find(self, vector: Vector, threshold: float = 2.0, method: str = 'cosine') ‑> Tuple[str, float] +def find(self, vector: Vector, threshold: float = inf, method: str = 'cosine') ‑> Tuple[str, float]

Search for the closest vector in space.

@@ -1000,7 +1072,7 @@

Parameters

vector : Vector
Input Vector object. Search for the closest vector to this Vector in the space.
-
threshold : float, default 2.0
+
threshold : float, default numpy.Inf
Threshold on distance between vectors.
method : {'cosine', 'euclidean', 'hamming'}, default 'cosine'
Distance metric.
@@ -1026,7 +1098,7 @@

Examples

The result is obviously itself, 'vector1', with a cosine distance of 0.0.

-def find_all(self, vector: Vector, threshold: float = 2.0, method: str = 'cosine') ‑> Tuple[dict, str] +def find_all(self, vector: Vector, threshold: float = inf, method: str = 'cosine') ‑> Tuple[dict, str]

Compute distance of the input vector against all vectors in space.

@@ -1034,7 +1106,7 @@

Parameters

vector : Vector
Input Vector object. Search for the closest vector to this Vector in the space.
-
threshold : float, default 2.0
+
threshold : float, default numpy.Inf
Threshold on distance between vectors.
method : {'cosine', 'euclidean', 'hamming'}, default 'cosine'
Distance metric.
@@ -1087,6 +1159,13 @@

Returns

Raises

+
Exception
+
+
    +
  • if no names or tags are provided in input;
  • +
  • if both names and tags are provided in input.
  • +
+
TypeError
If names or tags in the input lists are not instance of primitives.
@@ -1301,7 +1380,7 @@

Examples

class Vector -(name: Optional[str] = None, size: int = 10000, vector: Optional[numpy.ndarray] = None, vtype: str = 'bipolar', tags: Optional[Set[Union[str, int, float]]] = None, seed: Optional[int] = None, warning: bool = False, from_file: Optional[] = None) +(name: Optional[str] = None, size: int = 10000, vector: Optional[numpy.ndarray] = None, vtype: str = 'bipolar', tags: Optional[Set[Union[str, int, float]]] = None, seed: Optional[int] = None, warning: bool = False, from_file: Optional[] = None)

Vector object.

@@ -1332,6 +1411,10 @@

Returns

Raises

+
Exception
+
If the pickle object in from_file is not instance of Vector.
+
FileNotFoundError
+
If from_file is not None but the file does not exist.
TypeError
-
FileNotFoundError
-
If from_file is not None but the file does not exist.

Examples

>>> from hdlib.space import Vector
@@ -1416,6 +1497,10 @@ 

Examples

Raises ------ + Exception + If the pickle object in `from_file` is not instance of Vector. + FileNotFoundError + If `from_file` is not None but the file does not exist. TypeError - if the vector name is not instance of a primitive; - if `tags` is not an instance of set; @@ -1424,8 +1509,6 @@

Examples

ValueError - if `vtype` is different than 'binary' or 'bipolar'; - if `size` is lower than 10,000. - FileNotFoundError - If `from_file` is not None but the file does not exist. Examples -------- @@ -1519,10 +1602,15 @@

Examples

else: # Load vector from pickle file with open(from_file, "rb") as pkl: - self.version, self.name, self.size, self.vector, self.vtype, self.parents, self.children, self.tags, self.seed = pickle.load(pkl) + from_file_obj = pickle.load(pkl) + + if not isinstance(from_file_obj, type(self)): + raise Exception("Pickle object is not instance of {}".format(type(self))) - if self.version != __version__: - print("Warning: the specified Space has been created with a different version of hdlib") + self.__dict__.update(from_file_obj.__dict__) + + if self.version != __version__: + print("Warning: the specified Space has been created with a different version of hdlib") else: # Conditions on vector size @@ -1622,9 +1710,9 @@

Examples

Size: {} Type: {} Tags: - + {} - + Vector: {} @@ -1867,7 +1955,31 @@

Examples

from hdlib.arithmetic import bundle as bundle_operator self.__override_object(bundle_operator(self, vector)) - + + def subtraction(self, vector: "Vector") -> None: + """Subtract a vector from the current vector object inplace. + + Parameters + ---------- + vector : Vector + The input Vector object. + + Examples + -------- + >>> from hdlib.space import Vector + >>> vector1 = Vector() + >>> vector2 = Vector() + >>> vector1.subtract(vector2) + + It overrides the actual vector content of `vector1` with the result of the subtraction with `vector2`. + Refers to hdlib.arithmetic.subtraction for additional information. + """ + + # Import arithmetic.subtraction here to avoid circular imports + from hdlib.arithmetic import subtraction as subtraction_operator + + self.__override_object(subtraction_operator(self, vector)) + def permute(self, rotate_by: int=1) -> None: """Permute the current vector inplace. @@ -1940,13 +2052,13 @@

Examples

if not to_file: # Dump the vector to a pickle file in the current working directory if not file path is provided - to_file = os.path.join(os.getcwd, "{}.pkl".format(self.name)) + to_file = os.path.join(os.getcwd(), "{}.pkl".format(self.name)) if os.path.isfile(to_file): raise Exception("The output file already exists!\n{}".format(to_file)) with open(to_file, "wb") as pkl: - pickle.dump((self.version, self.name, self.size, self.vector, self.vtype, self.parents, self.children, self.tags, self.seed), pkl)
+ pickle.dump(self, pkl)

Methods

@@ -2020,7 +2132,7 @@

Examples

Generate two random bipolar vectors and compute the distance between them.

-def dump(self, to_file: Optional[] = None) ‑> None +def dump(self, to_file: Optional[] = None) ‑> None

Dump the Vector object to a pickle file.

@@ -2086,6 +2198,25 @@

Examples

It overrides the actual vector content of vector with the result of applying the permute function inplace. Refers to hdlib.arithmetic.permute for additional information.

+
+def subtraction(self, vector: Vector) ‑> None +
+
+

Subtract a vector from the current vector object inplace.

+

Parameters

+
+
vector : Vector
+
The input Vector object.
+
+

Examples

+
>>> from hdlib.space import Vector
+>>> vector1 = Vector()
+>>> vector2 = Vector()
+>>> vector1.subtract(vector2)
+
+

It overrides the actual vector content of vector1 with the result of the subtraction with vector2. +Refers to hdlib.arithmetic.subtraction for additional information.

+
@@ -2129,6 +2260,7 @@

Vectordump
  • normalize
  • permute
  • +
  • subtraction
  • @@ -2137,7 +2269,7 @@

    Vector