usearch 2.8.7 → 2.8.9

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 (113) hide show
  1. package/CITATION.cff +1 -1
  2. package/CMakeLists.txt +3 -3
  3. package/CONTRIBUTING.md +26 -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 +28 -24
  12. package/javascript/README.md +64 -12
  13. package/javascript/lib.cpp +11 -3
  14. package/javascript/usearch.js +4 -2
  15. package/javascript/usearch.test.js +15 -0
  16. package/package.json +1 -2
  17. package/setup.py +76 -15
  18. package/simsimd/README.md +14 -13
  19. package/simsimd/include/simsimd/probability.h +2 -2
  20. package/simsimd/package.json +1 -1
  21. package/wasmer.toml +1 -1
  22. package/. npmignore +0 -14
  23. package/.gitignore +0 -95
  24. package/.vscode/launch.json +0 -181
  25. package/.vscode/settings.json +0 -180
  26. package/.vscode/tasks.json +0 -71
  27. package/Package.swift +0 -41
  28. package/csharp/.editorconfig +0 -361
  29. package/csharp/Cloud.Unum.USearch.sln +0 -34
  30. package/csharp/DEV_SETUP.md +0 -51
  31. package/csharp/Directory.Build.props +0 -29
  32. package/csharp/README.md +0 -74
  33. package/csharp/build_and_test.cmd +0 -31
  34. package/csharp/build_and_test.sh +0 -30
  35. package/csharp/nuget/nuget-package.props +0 -33
  36. package/csharp/pack.sh +0 -56
  37. package/csharp/src/Cloud.Unum.USearch.Tests/Cloud.Unum.USearch.Tests.csproj +0 -39
  38. package/csharp/src/Cloud.Unum.USearch.Tests/USearchIndexTests.cs +0 -1013
  39. package/csharp/src/Cloud.Unum.USearch.Tests/Usings.cs +0 -1
  40. package/docs/_static/custom.css +0 -26
  41. package/docs/_static/custom.js +0 -7
  42. package/docs/benchmarks.md +0 -245
  43. package/docs/benchmarks.rst +0 -5
  44. package/docs/c/index.rst +0 -11
  45. package/docs/c/reference.rst +0 -7
  46. package/docs/conf.dox +0 -2668
  47. package/docs/conf.py +0 -53
  48. package/docs/contributing.rst +0 -5
  49. package/docs/cpp/index.rst +0 -11
  50. package/docs/cpp/reference.rst +0 -17
  51. package/docs/csharp/index.rst +0 -6
  52. package/docs/format.md +0 -86
  53. package/docs/format.rst +0 -5
  54. package/docs/golang/index.rst +0 -6
  55. package/docs/index.rst +0 -33
  56. package/docs/java/index.rst +0 -11
  57. package/docs/java/reference.rst +0 -7
  58. package/docs/javascript/index.rst +0 -11
  59. package/docs/javascript/reference.rst +0 -12
  60. package/docs/python/index.rst +0 -11
  61. package/docs/python/reference.rst +0 -42
  62. package/docs/rust/index.rst +0 -6
  63. package/docs/swift/index.rst +0 -6
  64. package/docs/wolfram/index.rst +0 -6
  65. package/golang/README.md +0 -95
  66. package/golang/go.mod +0 -3
  67. package/golang/lib.go +0 -379
  68. package/golang/lib_test.go +0 -108
  69. package/java/README.md +0 -22
  70. package/java/cloud/unum/usearch/Index.java +0 -337
  71. package/java/cloud/unum/usearch/cloud_unum_usearch_Index.cpp +0 -197
  72. package/java/cloud/unum/usearch/cloud_unum_usearch_Index.h +0 -125
  73. package/java/test/IndexTest.java +0 -30
  74. package/objc/USearchObjective.mm +0 -299
  75. package/objc/include/USearchObjective.h +0 -154
  76. package/python/README.md +0 -292
  77. package/python/lib.cpp +0 -1216
  78. package/python/scripts/bench.ipynb +0 -193
  79. package/python/scripts/bench.py +0 -137
  80. package/python/scripts/bench_exact.py +0 -44
  81. package/python/scripts/cluster.ipynb +0 -160
  82. package/python/scripts/index_faiss.py +0 -100
  83. package/python/scripts/join.py +0 -155
  84. package/python/scripts/test_index.py +0 -247
  85. package/python/scripts/test_jit.py +0 -231
  86. package/python/scripts/test_sparse.py +0 -32
  87. package/python/scripts/test_tooling.py +0 -133
  88. package/python/usearch/__init__.py +0 -0
  89. package/python/usearch/client.py +0 -124
  90. package/python/usearch/eval.py +0 -470
  91. package/python/usearch/index.py +0 -1401
  92. package/python/usearch/io.py +0 -113
  93. package/python/usearch/numba.py +0 -121
  94. package/python/usearch/server.py +0 -137
  95. package/rust/README.md +0 -66
  96. package/rust/lib.cpp +0 -136
  97. package/rust/lib.hpp +0 -69
  98. package/rust/lib.rs +0 -610
  99. package/simsimd/CMakeLists.txt +0 -67
  100. package/simsimd/cpp/bench.cxx +0 -206
  101. package/simsimd/package-ci.json +0 -10
  102. package/simsimd/setup.py +0 -86
  103. package/swift/Index+Sugar.swift +0 -153
  104. package/swift/README.md +0 -48
  105. package/swift/Test.swift +0 -37
  106. package/swift/USearch.swift +0 -8
  107. package/wasm/CMakeLists.txt +0 -7
  108. package/wasm/README.md +0 -13
  109. package/wasm/lib.cpp +0 -5
  110. package/wolfram/CMakeLists.txt +0 -18
  111. package/wolfram/README.md +0 -13
  112. package/wolfram/lib.cpp +0 -160
  113. 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
- ```