usearch 2.8.7 → 2.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CITATION.cff +1 -1
  2. package/CMakeLists.txt +3 -3
  3. package/CONTRIBUTING.md +3 -3
  4. package/Cargo.toml +1 -1
  5. package/Dockerfile +16 -0
  6. package/README.md +41 -38
  7. package/VERSION +1 -0
  8. package/binding.gyp +57 -8
  9. package/conanfile.py +1 -1
  10. package/include/usearch/index.hpp +1 -1
  11. package/include/usearch/index_plugins.hpp +27 -23
  12. package/package.json +1 -2
  13. package/setup.py +76 -15
  14. package/wasmer.toml +1 -1
  15. package/. npmignore +0 -14
  16. package/.gitignore +0 -95
  17. package/.vscode/launch.json +0 -181
  18. package/.vscode/settings.json +0 -180
  19. package/.vscode/tasks.json +0 -71
  20. package/Package.swift +0 -41
  21. package/csharp/.editorconfig +0 -361
  22. package/csharp/Cloud.Unum.USearch.sln +0 -34
  23. package/csharp/DEV_SETUP.md +0 -51
  24. package/csharp/Directory.Build.props +0 -29
  25. package/csharp/README.md +0 -74
  26. package/csharp/build_and_test.cmd +0 -31
  27. package/csharp/build_and_test.sh +0 -30
  28. package/csharp/nuget/nuget-package.props +0 -33
  29. package/csharp/pack.sh +0 -56
  30. package/csharp/src/Cloud.Unum.USearch.Tests/Cloud.Unum.USearch.Tests.csproj +0 -39
  31. package/csharp/src/Cloud.Unum.USearch.Tests/USearchIndexTests.cs +0 -1013
  32. package/csharp/src/Cloud.Unum.USearch.Tests/Usings.cs +0 -1
  33. package/docs/_static/custom.css +0 -26
  34. package/docs/_static/custom.js +0 -7
  35. package/docs/benchmarks.md +0 -245
  36. package/docs/benchmarks.rst +0 -5
  37. package/docs/c/index.rst +0 -11
  38. package/docs/c/reference.rst +0 -7
  39. package/docs/conf.dox +0 -2668
  40. package/docs/conf.py +0 -53
  41. package/docs/contributing.rst +0 -5
  42. package/docs/cpp/index.rst +0 -11
  43. package/docs/cpp/reference.rst +0 -17
  44. package/docs/csharp/index.rst +0 -6
  45. package/docs/format.md +0 -86
  46. package/docs/format.rst +0 -5
  47. package/docs/golang/index.rst +0 -6
  48. package/docs/index.rst +0 -33
  49. package/docs/java/index.rst +0 -11
  50. package/docs/java/reference.rst +0 -7
  51. package/docs/javascript/index.rst +0 -11
  52. package/docs/javascript/reference.rst +0 -12
  53. package/docs/python/index.rst +0 -11
  54. package/docs/python/reference.rst +0 -42
  55. package/docs/rust/index.rst +0 -6
  56. package/docs/swift/index.rst +0 -6
  57. package/docs/wolfram/index.rst +0 -6
  58. package/golang/README.md +0 -95
  59. package/golang/go.mod +0 -3
  60. package/golang/lib.go +0 -379
  61. package/golang/lib_test.go +0 -108
  62. package/java/README.md +0 -22
  63. package/java/cloud/unum/usearch/Index.java +0 -337
  64. package/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +0 -197
  65. package/java/cloud/unum/usearch/cloud_unum_usearch_Index.h +0 -125
  66. package/java/test/IndexTest.java +0 -30
  67. package/objc/USearchObjective.mm +0 -299
  68. package/objc/include/USearchObjective.h +0 -154
  69. package/python/README.md +0 -292
  70. package/python/lib.cpp +0 -1216
  71. package/python/scripts/bench.ipynb +0 -193
  72. package/python/scripts/bench.py +0 -137
  73. package/python/scripts/bench_exact.py +0 -44
  74. package/python/scripts/cluster.ipynb +0 -160
  75. package/python/scripts/index_faiss.py +0 -100
  76. package/python/scripts/join.py +0 -155
  77. package/python/scripts/test_index.py +0 -247
  78. package/python/scripts/test_jit.py +0 -231
  79. package/python/scripts/test_sparse.py +0 -32
  80. package/python/scripts/test_tooling.py +0 -133
  81. package/python/usearch/__init__.py +0 -0
  82. package/python/usearch/client.py +0 -124
  83. package/python/usearch/eval.py +0 -470
  84. package/python/usearch/index.py +0 -1401
  85. package/python/usearch/io.py +0 -113
  86. package/python/usearch/numba.py +0 -121
  87. package/python/usearch/server.py +0 -137
  88. package/rust/README.md +0 -66
  89. package/rust/lib.cpp +0 -136
  90. package/rust/lib.hpp +0 -69
  91. package/rust/lib.rs +0 -610
  92. package/swift/Index+Sugar.swift +0 -153
  93. package/swift/README.md +0 -48
  94. package/swift/Test.swift +0 -37
  95. package/swift/USearch.swift +0 -8
  96. package/wasm/CMakeLists.txt +0 -7
  97. package/wasm/README.md +0 -13
  98. package/wasm/lib.cpp +0 -5
  99. package/wolfram/CMakeLists.txt +0 -18
  100. package/wolfram/README.md +0 -13
  101. package/wolfram/lib.cpp +0 -160
  102. package/wolfram/test.wls +0 -27
package/golang/lib.go DELETED
@@ -1,379 +0,0 @@
1
- package usearch
2
-
3
- import (
4
- "errors"
5
- "unsafe"
6
- )
7
-
8
- /*
9
- #cgo LDFLAGS: -L. -L/usr/local/lib -lusearch_c
10
- #include "usearch.h"
11
- #include <stdlib.h>
12
- */
13
- import "C"
14
-
15
- type Key = uint64
16
-
17
- type Metric uint8
18
-
19
- const (
20
- InnerProduct Metric = iota
21
- Cosine
22
- L2sq
23
- Haversine
24
- Divergence
25
- Pearson
26
- Hamming
27
- Tanimoto
28
- Sorensen
29
- )
30
-
31
- func (m Metric) String() string {
32
- switch m {
33
- case L2sq:
34
- return "l2sq"
35
- case InnerProduct:
36
- return "ip"
37
- case Cosine:
38
- return "cos"
39
- case Haversine:
40
- return "haversine"
41
- case Divergence:
42
- return "divergence"
43
- case Pearson:
44
- return "pearson"
45
- case Hamming:
46
- return "hamming"
47
- case Tanimoto:
48
- return "tanimoto"
49
- case Sorensen:
50
- return "sorensen"
51
- default:
52
- panic("Unknown metric")
53
- }
54
- }
55
-
56
- type Quantization uint8
57
-
58
- const (
59
- f32 Quantization = iota
60
- f16
61
- f64
62
- i8
63
- b1
64
- )
65
-
66
- func (a Quantization) String() string {
67
- switch a {
68
- case f16:
69
- return "f16"
70
- case f32:
71
- return "f32"
72
- case f64:
73
- return "f64"
74
- case i8:
75
- return "i8"
76
- case b1:
77
- return "b1"
78
- default:
79
- panic("Unknown quantization")
80
- }
81
- }
82
-
83
- type IndexConfig struct {
84
- // The scalar kind used for quantization of vector data during indexing.
85
- Quantization Quantization
86
- // The metric kind used for distance calculation between vectors.
87
- Metric Metric
88
- // The number of dimensions in the vectors to be indexed.
89
- Dimensions uint
90
- // The @b optional connectivity parameter that limits connections-per-node in graph.
91
- Connectivity uint
92
- // The @b optional expansion factor used for index construction when adding vectors.
93
- ExpansionAdd uint
94
- // The @b optional expansion factor used for index construction during search operations.
95
- ExpansionSearch uint
96
- // The @b optional multi flag.
97
- Multi bool
98
- }
99
-
100
- func DefaultConfig(dimensions uint) IndexConfig {
101
- c := IndexConfig{}
102
- c.Dimensions = dimensions
103
- c.Metric = Cosine
104
- // Zeros will be replaced by the underlying C implementation
105
- c.Connectivity = 0
106
- c.ExpansionAdd = 0
107
- c.ExpansionSearch = 0
108
- c.Multi = false
109
- return c
110
- }
111
-
112
- type Index struct {
113
- opaque_handle *C.void
114
- config IndexConfig
115
- }
116
-
117
- // Initializes a new instance of the index.
118
- func NewIndex(conf IndexConfig) (index *Index, err error) {
119
- index = &Index{config: conf}
120
-
121
- conf = index.config
122
- dimensions := C.size_t(conf.Dimensions)
123
- connectivity := C.size_t(conf.Connectivity)
124
- expansion_add := C.size_t(conf.ExpansionAdd)
125
- expansion_search := C.size_t(conf.ExpansionSearch)
126
- multi := C.bool(conf.Multi)
127
-
128
- options := C.struct_usearch_init_options_t{}
129
- options.dimensions = dimensions
130
- options.connectivity = connectivity
131
- options.expansion_add = expansion_add
132
- options.expansion_search = expansion_search
133
- options.multi = multi
134
-
135
- // Map the metric kind to a C enum
136
- switch conf.Metric {
137
- case L2sq:
138
- options.metric_kind = C.usearch_metric_l2sq_k
139
- case InnerProduct:
140
- options.metric_kind = C.usearch_metric_ip_k
141
- case Cosine:
142
- options.metric_kind = C.usearch_metric_cos_k
143
- case Haversine:
144
- options.metric_kind = C.usearch_metric_haversine_k
145
- case Pearson:
146
- options.metric_kind = C.usearch_metric_pearson_k
147
- case Hamming:
148
- options.metric_kind = C.usearch_metric_hamming_k
149
- case Tanimoto:
150
- options.metric_kind = C.usearch_metric_tanimoto_k
151
- case Sorensen:
152
- options.metric_kind = C.usearch_metric_sorensen_k
153
- default:
154
- options.metric_kind = C.usearch_metric_unknown_k
155
- }
156
-
157
- // Map the quantization method
158
- switch conf.Quantization {
159
- case f16:
160
- options.quantization = C.usearch_scalar_f16_k
161
- case f32:
162
- options.quantization = C.usearch_scalar_f32_k
163
- case f64:
164
- options.quantization = C.usearch_scalar_f64_k
165
- case i8:
166
- options.quantization = C.usearch_scalar_i8_k
167
- case b1:
168
- options.quantization = C.usearch_scalar_b1_k
169
- default:
170
- options.quantization = C.usearch_scalar_unknown_k
171
- }
172
-
173
- var errorMessage *C.char
174
- ptr := C.usearch_init(&options, (*C.usearch_error_t)(&errorMessage))
175
- if errorMessage != nil {
176
- return nil, errors.New(C.GoString(errorMessage))
177
- }
178
-
179
- index.opaque_handle = (*C.void)(unsafe.Pointer(ptr))
180
- return index, nil
181
- }
182
-
183
- func (index *Index) Len() (len uint, err error) {
184
- var errorMessage *C.char
185
- len = uint(C.usearch_size((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (*C.usearch_error_t)(&errorMessage)))
186
- if errorMessage != nil {
187
- err = errors.New(C.GoString(errorMessage))
188
- }
189
- return len, err
190
- }
191
-
192
- func (index *Index) Connectivity() (con uint, err error) {
193
- var errorMessage *C.char
194
- con = uint(C.usearch_connectivity((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (*C.usearch_error_t)(&errorMessage)))
195
- if errorMessage != nil {
196
- err = errors.New(C.GoString(errorMessage))
197
- }
198
- return con, err
199
- }
200
-
201
- func (index *Index) Dimensions() (dim uint, err error) {
202
- var errorMessage *C.char
203
- dim = uint(C.usearch_dimensions((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (*C.usearch_error_t)(&errorMessage)))
204
- if errorMessage != nil {
205
- err = errors.New(C.GoString(errorMessage))
206
- }
207
- return dim, err
208
- }
209
-
210
- func (index *Index) Capacity() (cap uint, err error) {
211
- var errorMessage *C.char
212
- cap = uint(C.usearch_capacity((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (*C.usearch_error_t)(&errorMessage)))
213
- if errorMessage != nil {
214
- err = errors.New(C.GoString(errorMessage))
215
- }
216
- return cap, err
217
- }
218
-
219
- // Frees the resources associated with the index.
220
- func (index *Index) Destroy() error {
221
- if index.opaque_handle == nil {
222
- panic("Index is uninitialized")
223
- }
224
-
225
- var errorMessage *C.char
226
- C.usearch_free((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (*C.usearch_error_t)(&errorMessage))
227
- if errorMessage != nil {
228
- return errors.New(C.GoString(errorMessage))
229
- }
230
- index.opaque_handle = nil
231
- index.config = IndexConfig{}
232
- return nil
233
- }
234
-
235
- // Reserves memory for a specified number of incoming vectors.
236
- func (index *Index) Reserve(capacity uint) error {
237
- if index.opaque_handle == nil {
238
- panic("Index is uninitialized")
239
- }
240
-
241
- var errorMessage *C.char
242
- C.usearch_reserve((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (C.size_t)(capacity), (*C.usearch_error_t)(&errorMessage))
243
- if errorMessage != nil {
244
- return errors.New(C.GoString(errorMessage))
245
- }
246
- return nil
247
- }
248
-
249
- // Adds a vector with a key to the index.
250
- func (index *Index) Add(key Key, vec []float32) error {
251
- if index.opaque_handle == nil {
252
- panic("Index is uninitialized")
253
- }
254
-
255
- var errorMessage *C.char
256
- C.usearch_add((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (C.usearch_key_t)(key), unsafe.Pointer(&vec[0]), C.usearch_scalar_f32_k, (*C.usearch_error_t)(&errorMessage))
257
- if errorMessage != nil {
258
- return errors.New(C.GoString(errorMessage))
259
- }
260
- return nil
261
- }
262
-
263
- // Removes the vector associated with the given key from the index.
264
- func (index *Index) Remove(key Key) error {
265
- if index.opaque_handle == nil {
266
- panic("Index is uninitialized")
267
- }
268
-
269
- var errorMessage *C.char
270
- C.usearch_remove((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (C.usearch_key_t)(key), (*C.usearch_error_t)(&errorMessage))
271
- if errorMessage != nil {
272
- return errors.New(C.GoString(errorMessage))
273
- }
274
- return nil
275
- }
276
-
277
- // Checks if the index contains a vector with a specific key.
278
- func (index *Index) Contains(key Key) (found bool, err error) {
279
- if index.opaque_handle == nil {
280
- panic("Index is uninitialized")
281
- }
282
-
283
- var errorMessage *C.char
284
- found = bool(C.usearch_contains((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (C.usearch_key_t)(key), (*C.usearch_error_t)(&errorMessage)))
285
- if errorMessage != nil {
286
- return found, errors.New(C.GoString(errorMessage))
287
- }
288
- return found, nil
289
- }
290
-
291
- func (index *Index) Get(key Key, count uint) (vectors []float32, err error) {
292
- if index.opaque_handle == nil {
293
- panic("Index is uninitialized")
294
- }
295
-
296
- vectors = make([]float32, index.config.Dimensions * count)
297
- var errorMessage *C.char
298
- found := uint(C.usearch_get((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), (C.usearch_key_t)(key), (C.size_t)(count), unsafe.Pointer(&vectors[0]), C.usearch_scalar_f32_k, (*C.usearch_error_t)(&errorMessage)))
299
- if errorMessage != nil {
300
- return nil, errors.New(C.GoString(errorMessage))
301
- }
302
- if found == 0 {
303
- return nil, nil
304
- }
305
- return vectors, nil
306
- }
307
-
308
- // Performs k-Approximate Nearest Neighbors Search for closest vectors to query.
309
- func (index *Index) Search(query []float32, limit uint) (keys []Key, distances []float32, err error) {
310
- if index.opaque_handle == nil {
311
- panic("Index is uninitialized")
312
- }
313
- if len(query) != int(index.config.Dimensions) {
314
- return nil, nil, errors.New("Number of dimensions doesn't match!")
315
- }
316
-
317
- keys = make([]Key, limit)
318
- distances = make([]float32, limit)
319
- var errorMessage *C.char
320
- count := uint(C.usearch_search((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), unsafe.Pointer(&query[0]), C.usearch_scalar_f32_k, (C.size_t)(limit), (*C.usearch_key_t)(&keys[0]), (*C.usearch_distance_t)(&distances[0]), (*C.usearch_error_t)(&errorMessage)))
321
- if errorMessage != nil {
322
- return nil, nil, errors.New(C.GoString(errorMessage))
323
- }
324
-
325
- keys = keys[:count]
326
- distances = distances[:count]
327
- return keys, distances, nil
328
- }
329
-
330
- // Saves the index to a file.
331
- func (index *Index) Save(path string) error {
332
- if index.opaque_handle == nil {
333
- panic("Index is uninitialized")
334
- }
335
-
336
- c_path := C.CString(path)
337
- defer C.free(unsafe.Pointer(c_path))
338
-
339
- var errorMessage *C.char
340
- C.usearch_save((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), c_path, (*C.usearch_error_t)(&errorMessage))
341
- if errorMessage != nil {
342
- return errors.New(C.GoString(errorMessage))
343
- }
344
- return nil
345
- }
346
-
347
- // Loads the index from a file.
348
- func (index *Index) Load(path string) error {
349
- if index.opaque_handle == nil {
350
- panic("Index is uninitialized")
351
- }
352
-
353
- c_path := C.CString(path)
354
- defer C.free(unsafe.Pointer(c_path))
355
-
356
- var errorMessage *C.char
357
- C.usearch_load((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), c_path, (*C.usearch_error_t)(&errorMessage))
358
- if errorMessage != nil {
359
- return errors.New(C.GoString(errorMessage))
360
- }
361
- return nil
362
- }
363
-
364
- // Creates a view of the index from a file without loading it into memory.
365
- func (index *Index) View(path string) error {
366
- if index.opaque_handle == nil {
367
- panic("Index is uninitialized")
368
- }
369
-
370
- c_path := C.CString(path)
371
- defer C.free(unsafe.Pointer(c_path))
372
-
373
- var errorMessage *C.char
374
- C.usearch_view((C.usearch_index_t)(unsafe.Pointer(index.opaque_handle)), c_path, (*C.usearch_error_t)(&errorMessage))
375
- if errorMessage != nil {
376
- return errors.New(C.GoString(errorMessage))
377
- }
378
- return nil
379
- }
@@ -1,108 +0,0 @@
1
- package usearch
2
-
3
- import (
4
- "runtime"
5
- "testing"
6
- "math"
7
- )
8
-
9
- func TestUSearch(t *testing.T) {
10
- runtime.LockOSThread()
11
-
12
- t.Run("Test Index Initialization", func(t *testing.T) {
13
- dim := uint(128)
14
- conf := DefaultConfig(dim)
15
- ind, err := NewIndex(conf)
16
- if err != nil {
17
- t.Fatalf("Failed to construct the index: %s", err)
18
- }
19
- defer ind.Destroy()
20
-
21
- found_dims, err := ind.Dimensions()
22
- if err != nil {
23
- t.Fatalf("Failed to retrieve dimensions: %s", err)
24
- }
25
- if found_dims != dim {
26
- t.Fatalf("Expected %d dimensions, got %d", dim, found_dims)
27
- }
28
-
29
- found_len, err := ind.Len()
30
- if err != nil {
31
- t.Fatalf("Failed to retrieve size: %s", err)
32
- }
33
- if found_len != 0 {
34
- t.Fatalf("Expected size to be 0, got %d", found_len)
35
- }
36
-
37
- err = ind.Reserve(100)
38
- if err != nil {
39
- t.Fatalf("Failed to reserve capacity: %s", err)
40
- }
41
- })
42
-
43
- t.Run("Test Insertion", func(t *testing.T) {
44
- dim := uint(128)
45
- conf := DefaultConfig(dim)
46
- ind, err := NewIndex(conf)
47
- if err != nil {
48
- t.Fatalf("Failed to construct the index: %s", err)
49
- }
50
- defer ind.Destroy()
51
-
52
- err = ind.Reserve(100)
53
- if err != nil {
54
- t.Fatalf("Failed to reserve capacity: %s", err)
55
- }
56
-
57
- vec := make([]float32, dim)
58
- vec[0] = 40.0
59
- vec[1] = 2.0
60
-
61
- err = ind.Add(42, vec)
62
- if err != nil {
63
- t.Fatalf("Failed to insert: %s", err)
64
- }
65
-
66
- found_len, err := ind.Len()
67
- if err != nil {
68
- t.Fatalf("Failed to retrieve size after insertion: %s", err)
69
- }
70
- if found_len != 1 {
71
- t.Fatalf("Expected size to be 1, got %d", found_len)
72
- }
73
- })
74
-
75
- t.Run("Test Search", func(t *testing.T) {
76
- dim := uint(128)
77
- conf := DefaultConfig(dim)
78
- ind, err := NewIndex(conf)
79
- if err != nil {
80
- t.Fatalf("Failed to construct the index: %s", err)
81
- }
82
- defer ind.Destroy()
83
-
84
- err = ind.Reserve(100)
85
- if err != nil {
86
- t.Fatalf("Failed to reserve capacity: %s", err)
87
- }
88
-
89
- vec := make([]float32, dim)
90
- vec[0] = 40.0
91
- vec[1] = 2.0
92
-
93
- err = ind.Add(42, vec)
94
- if err != nil {
95
- t.Fatalf("Failed to insert: %s", err)
96
- }
97
-
98
- keys, distances, err := ind.Search(vec, 10)
99
- if err != nil {
100
- t.Fatalf("Failed to search: %s", err)
101
- }
102
-
103
- const tolerance = 1e-2 // For example, this sets the tolerance to 0.01
104
- if keys[0] != 42 || math.Abs(float64(distances[0])) > tolerance {
105
- t.Fatalf("Expected result 42 with distance 0, got key %d with distance %f", keys[0], distances[0])
106
- }
107
- })
108
- }
package/java/README.md DELETED
@@ -1,22 +0,0 @@
1
- # USearch for Java
2
-
3
- ## Installation
4
-
5
- ```xml
6
- <dependency>
7
- <groupId>cloud.unum</groupId>
8
- <artifactId>usearch</artifactId>
9
- <version>0.2.3</version>
10
- </dependency>
11
- ```
12
-
13
- Add that snippet to your `pom.xml` and hit `mvn install`.
14
-
15
- ## Quickstart
16
-
17
- ```java
18
- Index index = new Index.Config().metric("cos").dimensions(2).build();
19
- float vec[] = {10, 20};
20
- index.add(42, vec);
21
- int[] keys = index.search(vec, 5);
22
- ```