Note
Go to the end to download the full example code.
Demo: Basic VSA Operations¶
This example demonstrates the core operations of VSA models: - Binding (association) - Unbinding (recovery) - Bundling (superposition) - Permutation (sequence encoding)
12 import sys
13 sys.path.insert(0, '..')
14
15 from holovec import VSA, backend_info
16
17 def main():
18 print("=" * 60)
19 print("HoloVec Demo: Basic VSA Operations")
20 print("=" * 60)
21 print()
22
23 # Show available backends
24 info = backend_info()
25 print(f"Available backends: {info['available_backends']}")
26 print(f"Recommended backend: {info['recommended_backend']}")
27 print()
28
29 # Create a FHRR model (best capacity)
30 print("Creating FHRR model (dim=512)...")
31 model = VSA.create('FHRR', dim=512, seed=42)
32 print(f"Model: {model}")
33 print(f" - Self-inverse: {model.is_self_inverse}")
34 print(f" - Commutative: {model.is_commutative}")
35 print(f" - Exact inverse: {model.is_exact_inverse}")
36 print()
37
38 # Demonstration 1: Binding and Unbinding
39 print("-" * 60)
40 print("Demo 1: Binding and Unbinding (Association)")
41 print("-" * 60)
42
43 # Create role and filler vectors
44 role = model.random(seed=1)
45 filler = model.random(seed=2)
46
47 print("Created vectors:")
48 print(f" role: random vector (seed=1)")
49 print(f" filler: random vector (seed=2)")
50 print()
51
52 # Bind them
53 bound = model.bind(role, filler)
54 print("Binding: bound = role ⊗ filler")
55 print(f" Similarity(bound, role): {model.similarity(bound, role):.4f}")
56 print(f" Similarity(bound, filler): {model.similarity(bound, filler):.4f}")
57 print(" → Bound vector is dissimilar to both inputs ✓")
58 print()
59
60 # Unbind to recover
61 recovered = model.unbind(bound, filler)
62 print("Unbinding: recovered = bound ⊘ filler")
63 print(f" Similarity(recovered, role): {model.similarity(recovered, role):.4f}")
64 print(" → Successfully recovered original vector ✓")
65 print()
66
67 # Demonstration 2: Bundling
68 print("-" * 60)
69 print("Demo 2: Bundling (Superposition)")
70 print("-" * 60)
71
72 # Create multiple vectors
73 vec1 = model.random(seed=10)
74 vec2 = model.random(seed=11)
75 vec3 = model.random(seed=12)
76
77 print("Created 3 random vectors: vec1, vec2, vec3")
78 print()
79
80 # Bundle them
81 bundled = model.bundle([vec1, vec2, vec3])
82 print("Bundling: bundled = vec1 + vec2 + vec3")
83 print(f" Similarity(bundled, vec1): {model.similarity(bundled, vec1):.4f}")
84 print(f" Similarity(bundled, vec2): {model.similarity(bundled, vec2):.4f}")
85 print(f" Similarity(bundled, vec3): {model.similarity(bundled, vec3):.4f}")
86 print(" → Bundled vector is similar to all inputs ✓")
87 print()
88
89 # Demonstration 3: Permutation for Sequences
90 print("-" * 60)
91 print("Demo 3: Permutation (Sequence Encoding)")
92 print("-" * 60)
93
94 # Encode sequence [A, B, C]
95 a = model.random(seed=20)
96 b = model.random(seed=21)
97 c = model.random(seed=22)
98
99 print("Elements: A, B, C")
100 print("Encoding sequence: seq = A + ρ(B) + ρ²(C)")
101 print()
102
103 sequence = model.bundle([
104 a,
105 model.permute(b, k=1),
106 model.permute(c, k=2)
107 ])
108
109 # Query position 0 (should find A)
110 sim_a = model.similarity(sequence, a)
111 print(f"Query position 0 → Similarity(seq, A): {sim_a:.4f}")
112
113 # Query position 1 (should find B)
114 query_pos1 = model.unpermute(sequence, k=1)
115 sim_b = model.similarity(query_pos1, b)
116 print(f"Query position 1 → Similarity(ρ⁻¹(seq), B): {sim_b:.4f}")
117
118 # Query position 2 (should find C)
119 query_pos2 = model.unpermute(sequence, k=2)
120 sim_c = model.similarity(query_pos2, c)
121 print(f"Query position 2 → Similarity(ρ⁻²(seq), C): {sim_c:.4f}")
122 print(" → Successfully encoded and queried sequence ✓")
123 print()
124
125 # Demonstration 4: Structured Representation
126 print("-" * 60)
127 print("Demo 4: Structured Representation")
128 print("-" * 60)
129
130 # Represent: "The ball is red and large"
131 object_role = model.random(seed=30)
132 color_role = model.random(seed=31)
133 size_role = model.random(seed=32)
134
135 ball = model.random(seed=40)
136 red = model.random(seed=41)
137 large = model.random(seed=42)
138
139 print("Creating representation:")
140 print(" 'The ball is red and large'")
141 print()
142 print("Structure:")
143 print(" object=ball ⊗ color=red ⊗ size=large")
144 print()
145
146 representation = model.bundle([
147 model.bind(object_role, ball),
148 model.bind(color_role, red),
149 model.bind(size_role, large)
150 ])
151
152 # Query: What is the color?
153 print("Query: What is the color?")
154 color_query = model.unbind(representation, color_role)
155 sim_red = model.similarity(color_query, red)
156 sim_ball = model.similarity(color_query, ball)
157 sim_large = model.similarity(color_query, large)
158
159 print(f" Similarity(query, red): {sim_red:.4f} ✓")
160 print(f" Similarity(query, ball): {sim_ball:.4f}")
161 print(f" Similarity(query, large): {sim_large:.4f}")
162 print(" → Correctly identified 'red' as the color ✓")
163 print()
164
165 # Demonstration 5: Fractional Power Encoding (FHRR-specific)
166 print("-" * 60)
167 print("Demo 5: Fractional Power Encoding (FHRR)")
168 print("-" * 60)
169
170 # Encode continuous value 2.5
171 base = model.random(seed=50)
172 value = 2.5
173
174 print(f"Encoding value: {value}")
175 print(f" Using base vector and fractional power")
176 print()
177
178 encoded = model.fractional_power(base, value)
179 print(f"Encoded: base^{value}")
180
181 # Decode by dividing
182 decoded = model.fractional_power(encoded, 1.0 / value)
183 sim_base = model.similarity(decoded, base)
184
185 print(f"Decoded: encoded^(1/{value})")
186 print(f" Similarity(decoded, base): {sim_base:.4f}")
187 print(" → Successfully encoded and decoded continuous value ✓")
188 print()
189
190 # Comparison with MAP
191 print("-" * 60)
192 print("Bonus: Comparing FHRR vs MAP")
193 print("-" * 60)
194
195 map_model = VSA.create('MAP', dim=10000, seed=42)
196 print(f"MAP model: {map_model}")
197 print(f" - Self-inverse: {map_model.is_self_inverse}")
198 print(f" - Exact inverse: {map_model.is_exact_inverse}")
199 print()
200
201 # Test unbinding quality
202 a_map = map_model.random(seed=1)
203 b_map = map_model.random(seed=2)
204 c_map = map_model.bind(a_map, b_map)
205 a_recovered_map = map_model.unbind(c_map, b_map)
206
207 sim_map = map_model.similarity(a_map, a_recovered_map)
208 print(f"MAP unbinding quality: {sim_map:.4f}")
209
210 a_fhrr = model.random(seed=1)
211 b_fhrr = model.random(seed=2)
212 c_fhrr = model.bind(a_fhrr, b_fhrr)
213 a_recovered_fhrr = model.unbind(c_fhrr, b_fhrr)
214
215 sim_fhrr = model.similarity(a_fhrr, a_recovered_fhrr)
216 print(f"FHRR unbinding quality: {sim_fhrr:.4f}")
217 print()
218 print(" → FHRR has better unbinding quality (exact inverse) ✓")
219 print()
220
221 print("=" * 60)
222 print("Demo Complete!")
223 print("=" * 60)
224
225
226 if __name__ == '__main__':
227 main()