2727 "bind_sequence" ,
2828 "ngrams" ,
2929 "hash_table" ,
30+ "graph" ,
3031 "map_range" ,
3132 "value_to_index" ,
3233 "index_to_value" ,
@@ -41,7 +42,7 @@ def identity_hv(
4142 device = None ,
4243 requires_grad = False ,
4344) -> Tensor :
44- """Creates a set of identity hypervector .
45+ """Creates a set of identity hypervectors .
4546
4647 When bound with a random-hypervector :math:`x`, the result is :math:`x`.
4748
@@ -174,24 +175,20 @@ def random_hv(
174175 if dtype == torch .uint8 :
175176 raise ValueError ("Unsigned integer hypervectors are not supported." )
176177
178+ size = (num_embeddings , embedding_dim )
177179 if dtype in {torch .complex64 , torch .complex128 }:
178180 dtype = torch .float if dtype == torch .complex64 else torch .double
179181
180- angle = torch .empty (num_embeddings , embedding_dim , dtype = dtype , device = device )
182+ angle = torch .empty (size , dtype = dtype , device = device )
181183 angle .uniform_ (- math .pi , math .pi )
182- magnitude = torch .ones (
183- num_embeddings , embedding_dim , dtype = dtype , device = device
184- )
184+ magnitude = torch .ones (size , dtype = dtype , device = device )
185185
186186 result = torch .polar (magnitude , angle )
187187 result .requires_grad = requires_grad
188188 return result
189189
190190 select = torch .empty (
191- (
192- num_embeddings ,
193- embedding_dim ,
194- ),
191+ size ,
195192 dtype = torch .bool ,
196193 ).bernoulli_ (1.0 - sparsity , generator = generator )
197194
@@ -1031,7 +1028,7 @@ def hash_table(keys: Tensor, values: Tensor) -> Tensor:
10311028
10321029 .. math::
10331030
1034- \bigoplus_{i = 0}^{m - 1} K_i \otimes V_i
1031+ \bigoplus_{i = 0}^{n - 1} K_i \otimes V_i
10351032
10361033 Args:
10371034 keys (Tensor): The keys hypervectors, must be the same shape as values.
@@ -1066,7 +1063,7 @@ def bundle_sequence(input: Tensor) -> Tensor:
10661063
10671064 .. math::
10681065
1069- \bigoplus_{i=0}^{m -1} \Pi^{m - i - 1}(V_i)
1066+ \bigoplus_{i=0}^{n -1} \Pi^{n - i - 1}(V_i)
10701067
10711068 Args:
10721069 input (Tensor): The hypervector values.
@@ -1105,7 +1102,7 @@ def bind_sequence(input: Tensor) -> Tensor:
11051102
11061103 .. math::
11071104
1108- \bigotimes_{i=0}^{m -1} \Pi^{m - i - 1}(V_i)
1105+ \bigotimes_{i=0}^{n -1} \Pi^{n - i - 1}(V_i)
11091106
11101107 Args:
11111108 input (Tensor): The hypervector values.
@@ -1141,6 +1138,48 @@ def bind_sequence(input: Tensor) -> Tensor:
11411138 return multibind (permuted )
11421139
11431140
1141+ def graph (input : Tensor , * , directed = False ) -> Tensor :
1142+ r"""Graph from node hypervector pairs.
1143+
1144+ If ``directed=False`` this computes:
1145+
1146+ .. math::
1147+
1148+ \bigoplus_{i = 0}^{n - 1} V_{0,i} \otimes V_{1,i}
1149+
1150+ If ``directed=True`` this computes:
1151+
1152+ .. math::
1153+
1154+ \bigoplus_{i = 0}^{n - 1} V_{0,i} \otimes \Pi(V_{1,i})
1155+
1156+ Args:
1157+ input (Tensor): tensor containing pairs of node hypervectors that share an edge.
1158+ directed (bool, optional): specify if the graph is directed or not. Default: ``False``.
1159+
1160+ Shapes:
1161+ - Input: :math:`(*, 2, n, d)`
1162+ - Output: :math:`(*, d)`
1163+
1164+ Examples::
1165+ >>> edges = torch.tensor([[0, 0, 1, 2], [1, 2, 2, 3]])
1166+ >>> node_embedding = embeddings.Random(4, 10000)
1167+ >>> edges_hv = node_embedding(edges)
1168+ >>> graph = functional.graph(edges_hv)
1169+ >>> neighbors = unbind(graph, node_embedding.weight[0])
1170+ >>> cosine_similarity(neighbors, node_embedding.weight)
1171+ tensor([0.0006, 0.5017, 0.4997, 0.0048])
1172+
1173+ """
1174+ to_nodes = input [..., 0 , :, :]
1175+ from_nodes = input [..., 1 , :, :]
1176+
1177+ if directed :
1178+ from_nodes = permute (from_nodes )
1179+
1180+ return multiset (bind (to_nodes , from_nodes ))
1181+
1182+
11441183def map_range (
11451184 input : Tensor ,
11461185 in_min : float ,
0 commit comments