usearch 2.9.2 → 2.10.0

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 (172) hide show
  1. package/README.md +39 -38
  2. package/javascript/{types → dist/cjs}/usearch.d.ts +90 -115
  3. package/javascript/dist/cjs/usearch.js +531 -0
  4. package/javascript/dist/esm/usearch.d.ts +212 -0
  5. package/javascript/{usearch.js → dist/esm/usearch.js} +199 -153
  6. package/package.json +25 -23
  7. package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
  8. package/prebuilds/linux-arm64/usearch.node +0 -0
  9. package/prebuilds/linux-x64/usearch.node +0 -0
  10. package/prebuilds/win32-ia32/usearch.node +0 -0
  11. package/prebuilds/win32-x64/usearch.node +0 -0
  12. package/.clang-format +0 -10
  13. package/.clang-tidy +0 -60
  14. package/.cmake-format.py +0 -19
  15. package/.dockerignore +0 -93
  16. package/.gitattributes +0 -9
  17. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -90
  18. package/.github/ISSUE_TEMPLATE/config.yml +0 -5
  19. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -64
  20. package/.github/workflows/Dockerfile.libs +0 -36
  21. package/.github/workflows/prerelease.yml +0 -331
  22. package/.github/workflows/release.yml +0 -722
  23. package/.github/workflows/update_version.sh +0 -15
  24. package/.gitmodules +0 -9
  25. package/.releaserc +0 -90
  26. package/CITATION.cff +0 -11
  27. package/CMakeLists.txt +0 -324
  28. package/CODE_OF_CONDUCT.md +0 -128
  29. package/CONTRIBUTING.md +0 -361
  30. package/Cargo.toml +0 -19
  31. package/Dockerfile +0 -16
  32. package/VERSION +0 -1
  33. package/assets/unum.png +0 -0
  34. package/assets/usearch-approaches-transparent.png +0 -0
  35. package/assets/usearch-approaches-white.png +0 -0
  36. package/assets/usearch-neighbor-types.png +0 -0
  37. package/binding.gyp +0 -87
  38. package/build.gradle +0 -204
  39. package/build.rs +0 -18
  40. package/c/CMakeLists.txt +0 -25
  41. package/c/README.md +0 -34
  42. package/c/lib.cpp +0 -358
  43. package/c/test.c +0 -382
  44. package/c/usearch.h +0 -311
  45. package/cmake/clipp.cmake +0 -7
  46. package/cmake/config.cmake.in +0 -15
  47. package/cmake/emscripten.cmake +0 -8
  48. package/cmake/jemalloc.cmake +0 -62
  49. package/cmake/pkg-config.pc.in +0 -4
  50. package/cmake/usearchConfigVersion.cmake.in +0 -20
  51. package/conanfile.py +0 -26
  52. package/cpp/CMakeLists.txt +0 -14
  53. package/cpp/README.md +0 -161
  54. package/cpp/bench.cpp +0 -618
  55. package/cpp/test.cpp +0 -323
  56. package/fp16/CMakeLists.txt +0 -176
  57. package/fp16/LICENSE +0 -11
  58. package/fp16/README.md +0 -20
  59. package/fp16/bench/alt-element.cc +0 -89
  60. package/fp16/bench/from-alt-array.cc +0 -175
  61. package/fp16/bench/from-ieee-array.cc +0 -399
  62. package/fp16/bench/ieee-element.cc +0 -272
  63. package/fp16/bench/to-alt-array.cc +0 -91
  64. package/fp16/bench/to-ieee-array.cc +0 -303
  65. package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
  66. package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
  67. package/fp16/cmake/DownloadPSimd.cmake +0 -15
  68. package/fp16/configure.py +0 -65
  69. package/fp16/confu.yaml +0 -8
  70. package/fp16/include/fp16/__init__.py +0 -0
  71. package/fp16/include/fp16/avx.py +0 -50
  72. package/fp16/include/fp16/avx2.py +0 -53
  73. package/fp16/include/fp16/bitcasts.h +0 -92
  74. package/fp16/include/fp16/fp16.h +0 -451
  75. package/fp16/include/fp16/psimd.h +0 -131
  76. package/fp16/include/fp16.h +0 -11
  77. package/fp16/jni/Android.mk +0 -6
  78. package/fp16/jni/Application.mk +0 -4
  79. package/fp16/test/alt-from-fp32-value.cc +0 -498
  80. package/fp16/test/alt-to-fp32-bits.cc +0 -263
  81. package/fp16/test/alt-to-fp32-psimd.cc +0 -145
  82. package/fp16/test/alt-to-fp32-value.cc +0 -348
  83. package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
  84. package/fp16/test/bitcasts.cc +0 -56
  85. package/fp16/test/ieee-from-fp32-value.cc +0 -523
  86. package/fp16/test/ieee-to-fp32-bits.cc +0 -333
  87. package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
  88. package/fp16/test/ieee-to-fp32-value.cc +0 -420
  89. package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
  90. package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
  91. package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
  92. package/fp16/test/peachpy/stubs.py +0 -38
  93. package/fp16/test/tables.cc +0 -530
  94. package/fp16/test/tables.h +0 -13
  95. package/fp16/third-party/THHalf.h +0 -92
  96. package/fp16/third-party/eigen-half.h +0 -170
  97. package/fp16/third-party/float16-compressor.h +0 -80
  98. package/fp16/third-party/half.hpp +0 -2916
  99. package/fp16/third-party/npy-halffloat.h +0 -328
  100. package/include/usearch/index.hpp +0 -3836
  101. package/include/usearch/index_dense.hpp +0 -2004
  102. package/include/usearch/index_plugins.hpp +0 -2213
  103. package/javascript/lib.cpp +0 -341
  104. package/javascript/types/usearch.d.ts.map +0 -1
  105. package/javascript/usearch.test.js +0 -74
  106. package/package-ci.json +0 -10
  107. package/pyproject.toml +0 -51
  108. package/setup.py +0 -201
  109. package/simsimd/.releaserc +0 -86
  110. package/simsimd/CONTRIBUTING.md +0 -88
  111. package/simsimd/Cargo.lock +0 -709
  112. package/simsimd/Cargo.toml +0 -44
  113. package/simsimd/LICENSE +0 -201
  114. package/simsimd/README.md +0 -317
  115. package/simsimd/binding.gyp +0 -36
  116. package/simsimd/build.rs +0 -20
  117. package/simsimd/include/simsimd/binary.h +0 -245
  118. package/simsimd/include/simsimd/complex.h +0 -174
  119. package/simsimd/include/simsimd/probability.h +0 -548
  120. package/simsimd/include/simsimd/simsimd.h +0 -465
  121. package/simsimd/include/simsimd/spatial.h +0 -1267
  122. package/simsimd/include/simsimd/types.h +0 -208
  123. package/simsimd/javascript/bench.js +0 -127
  124. package/simsimd/javascript/fallback.ts +0 -193
  125. package/simsimd/javascript/lib.c +0 -102
  126. package/simsimd/javascript/node-gyp-build.d.ts +0 -1
  127. package/simsimd/javascript/simsimd.ts +0 -124
  128. package/simsimd/javascript/test.mjs +0 -153
  129. package/simsimd/javascript/tsconfig-base.json +0 -25
  130. package/simsimd/javascript/tsconfig-cjs.json +0 -8
  131. package/simsimd/javascript/tsconfig-esm.json +0 -8
  132. package/simsimd/package-lock.json +0 -1688
  133. package/simsimd/package.json +0 -61
  134. package/simsimd/rust/benches/cosine.rs +0 -27
  135. package/simsimd/rust/benches/native.rs +0 -30
  136. package/simsimd/rust/benches/sqeuclidean.rs +0 -27
  137. package/simsimd/rust/lib.c +0 -45
  138. package/simsimd/rust/lib.rs +0 -550
  139. package/sqlite/README.md +0 -178
  140. package/sqlite/lib.cpp +0 -325
  141. package/stringzilla/CONTRIBUTING.md +0 -446
  142. package/stringzilla/Cargo.lock +0 -25
  143. package/stringzilla/Cargo.toml +0 -26
  144. package/stringzilla/LICENSE +0 -201
  145. package/stringzilla/README.md +0 -1422
  146. package/stringzilla/VERSION +0 -1
  147. package/stringzilla/assets/cover-strinzilla.jpeg +0 -0
  148. package/stringzilla/assets/meme-stringzilla-v2.jpeg +0 -0
  149. package/stringzilla/assets/meme-stringzilla-v3.jpeg +0 -0
  150. package/stringzilla/binding.gyp +0 -16
  151. package/stringzilla/build.rs +0 -87
  152. package/stringzilla/c/lib.c +0 -337
  153. package/stringzilla/cli/README.md +0 -65
  154. package/stringzilla/cli/__init__.py +0 -0
  155. package/stringzilla/cli/split.py +0 -105
  156. package/stringzilla/cli/wc.py +0 -117
  157. package/stringzilla/include/stringzilla/experimental.h +0 -845
  158. package/stringzilla/include/stringzilla/module.modulemap +0 -9
  159. package/stringzilla/include/stringzilla/stringzilla.h +0 -5370
  160. package/stringzilla/include/stringzilla/stringzilla.hpp +0 -3838
  161. package/stringzilla/javascript/lib.c +0 -125
  162. package/stringzilla/javascript/stringzilla.js +0 -22
  163. package/stringzilla/package-ci.json +0 -10
  164. package/stringzilla/package.json +0 -32
  165. package/stringzilla/rust/lib.rs +0 -873
  166. package/stringzilla/swift/StringProtocol+StringZilla.swift +0 -280
  167. package/stringzilla/swift/Test.swift +0 -60
  168. package/tsconfig.json +0 -21
  169. package/wasmer.toml +0 -12
  170. package/winlibinstaller.bat +0 -42
  171. /package/{simsimd/javascript/dist-package-cjs.json → javascript/dist/cjs/package.json} +0 -0
  172. /package/{simsimd/javascript/dist-package-esm.json → javascript/dist/esm/package.json} +0 -0
@@ -1,208 +0,0 @@
1
- #ifndef SIMSIMD_TYPES_H
2
- #define SIMSIMD_TYPES_H
3
-
4
- // Compiling for Arm: SIMSIMD_TARGET_ARM
5
- #if !defined(SIMSIMD_TARGET_ARM)
6
- #if defined(__aarch64__) || defined(_M_ARM64)
7
- #define SIMSIMD_TARGET_ARM 1
8
- #else
9
- #define SIMSIMD_TARGET_ARM 0
10
- #endif // defined(__aarch64__) || defined(_M_ARM64)
11
- #endif // !defined(SIMSIMD_TARGET_ARM)
12
-
13
- // Compiling for x86: SIMSIMD_TARGET_X86
14
- #if !defined(SIMSIMD_TARGET_X86)
15
- #if defined(__x86_64__) || defined(_M_X64)
16
- #define SIMSIMD_TARGET_X86 1
17
- #else
18
- #define SIMSIMD_TARGET_X86 0
19
- #endif // defined(__x86_64__) || defined(_M_X64)
20
- #endif // !defined(SIMSIMD_TARGET_X86)
21
-
22
- // Compiling for Arm: SIMSIMD_TARGET_ARM_NEON
23
- #if !defined(SIMSIMD_TARGET_ARM_NEON) || !SIMSIMD_TARGET_ARM
24
- #if defined(__ARM_NEON)
25
- #define SIMSIMD_TARGET_ARM_NEON SIMSIMD_TARGET_ARM
26
- #else
27
- #define SIMSIMD_TARGET_ARM_NEON 0
28
- #endif // defined(__ARM_NEON)
29
- #endif // !defined(SIMSIMD_TARGET_ARM_NEON)
30
-
31
- // Compiling for Arm: SIMSIMD_TARGET_ARM_SVE
32
- #if !defined(SIMSIMD_TARGET_ARM_SVE) || !SIMSIMD_TARGET_ARM
33
- #if defined(__ARM_FEATURE_SVE)
34
- #define SIMSIMD_TARGET_ARM_SVE SIMSIMD_TARGET_ARM
35
- #else
36
- #define SIMSIMD_TARGET_ARM_SVE 0
37
- #endif // defined(__ARM_FEATURE_SVE)
38
- #endif // !defined(SIMSIMD_TARGET_ARM_SVE)
39
-
40
- // Compiling for x86: SIMSIMD_TARGET_X86_AVX2
41
- #if !defined(SIMSIMD_TARGET_X86_AVX2) || !SIMSIMD_TARGET_X86
42
- #if defined(__AVX2__)
43
- #define SIMSIMD_TARGET_X86_AVX2 1
44
- #else
45
- #define SIMSIMD_TARGET_X86_AVX2 0
46
- #endif // defined(__AVX2__)
47
- #endif // !defined(SIMSIMD_TARGET_X86_AVX2)
48
-
49
- // Compiling for x86: SIMSIMD_TARGET_X86_AVX512
50
- #if !defined(SIMSIMD_TARGET_X86_AVX512) || !SIMSIMD_TARGET_X86
51
- #if defined(__AVX512F__) && defined(__AVX512FP16__) && defined(__AVX512VNNI__) && defined(__AVX512VPOPCNTDQ__)
52
- #define SIMSIMD_TARGET_X86_AVX512 1
53
- #else
54
- #define SIMSIMD_TARGET_X86_AVX512 0
55
- #endif // defined(__AVX512F__) && defined(__AVX512FP16__) && defined(__AVX512VNNI__) && defined(__AVX512VPOPCNTDQ__)
56
- #endif // !defined(SIMSIMD_TARGET_X86_AVX512)
57
-
58
- #ifdef _MSC_VER
59
- #include <intrin.h>
60
- #else
61
-
62
- #if SIMSIMD_TARGET_ARM_NEON
63
- #include <arm_neon.h>
64
- #endif
65
-
66
- #if SIMSIMD_TARGET_ARM_SVE
67
- #include <arm_sve.h>
68
- #endif
69
-
70
- #if SIMSIMD_TARGET_X86_AVX2 || SIMSIMD_TARGET_X86_AVX512
71
- #include <immintrin.h>
72
- #endif
73
-
74
- #endif
75
-
76
- #ifndef SIMSIMD_RSQRT
77
- #include <math.h>
78
- #define SIMSIMD_RSQRT(x) (1 / sqrtf(x))
79
- #endif
80
-
81
- #ifndef SIMSIMD_LOG
82
- #include <math.h>
83
- #define SIMSIMD_LOG(x) (logf(x))
84
- #endif
85
-
86
- #ifndef SIMSIMD_F32_DIVISION_EPSILON
87
- #define SIMSIMD_F32_DIVISION_EPSILON (1e-7)
88
- #endif
89
-
90
- #ifndef SIMSIMD_F16_DIVISION_EPSILON
91
- #define SIMSIMD_F16_DIVISION_EPSILON (1e-3)
92
- #endif
93
-
94
- #ifdef __cplusplus
95
- extern "C" {
96
- #endif
97
-
98
- typedef int simsimd_i32_t;
99
- typedef float simsimd_f32_t;
100
- typedef double simsimd_f64_t;
101
- typedef signed char simsimd_i8_t;
102
- typedef unsigned char simsimd_b8_t;
103
- typedef unsigned long long simsimd_u64_t;
104
- typedef unsigned long long simsimd_size_t;
105
-
106
- #if !defined(SIMSIMD_NATIVE_F16) || SIMSIMD_NATIVE_F16
107
- /**
108
- * @brief Half-precision floating-point type.
109
- *
110
- * - GCC or Clang on 64-bit ARM: `__fp16`, may require `-mfp16-format` option.
111
- * - GCC or Clang on 64-bit x86: `_Float16`.
112
- * - Default: `unsigned short`.
113
- */
114
- #if (defined(__GNUC__) || defined(__clang__)) && (defined(__ARM_ARCH) || defined(__aarch64__)) && \
115
- (defined(__ARM_FP16_FORMAT_IEEE))
116
- #if !defined(SIMSIMD_NATIVE_F16)
117
- #define SIMSIMD_NATIVE_F16 1
118
- #endif
119
- typedef __fp16 simsimd_f16_t;
120
- #elif ((defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__)) && \
121
- (defined(__SSE2__) || defined(__AVX512F__)))
122
- typedef _Float16 simsimd_f16_t;
123
- #if !defined(SIMSIMD_NATIVE_F16)
124
- #define SIMSIMD_NATIVE_F16 1
125
- #endif
126
- #else // Unknown compiler or architecture
127
- #define SIMSIMD_NATIVE_F16 0
128
- #endif // Unknown compiler or architecture
129
- #endif // !SIMSIMD_NATIVE_F16
130
-
131
- #if !SIMSIMD_NATIVE_F16
132
- typedef unsigned short simsimd_f16_t;
133
- #endif
134
-
135
- #define SIMSIMD_IDENTIFY(x) (x)
136
-
137
- /**
138
- * @brief Returns the value of the half-precision floating-point number,
139
- * potentially decompressed into single-precision.
140
- */
141
- #ifndef SIMSIMD_UNCOMPRESS_F16
142
- #if SIMSIMD_NATIVE_F16
143
- #define SIMSIMD_UNCOMPRESS_F16(x) SIMSIMD_IDENTIFY(x)
144
- #else
145
- #define SIMSIMD_UNCOMPRESS_F16(x) simsimd_uncompress_f16(x)
146
- #endif
147
- #endif
148
-
149
- typedef union {
150
- unsigned i;
151
- float f;
152
- } simsimd_f32i32_t;
153
-
154
- /**
155
- * @brief Computes `1/sqrt(x)` using the trick from Quake 3, replacing
156
- * magic numbers with the ones suggested by Jan Kadlec.
157
- */
158
- inline static simsimd_f32_t simsimd_approximate_inverse_square_root(simsimd_f32_t number) {
159
- simsimd_f32i32_t conv;
160
- conv.f = number;
161
- conv.i = 0x5F1FFFF9 - (conv.i >> 1);
162
- conv.f *= 0.703952253f * (2.38924456f - number * conv.f * conv.f);
163
- return conv.f;
164
- }
165
-
166
- /**
167
- * @brief Computes `log(x)` using the Mercator series.
168
- * The series converges to the natural logarithm for args between -1 and 1.
169
- * Published in 1668 in "Logarithmotechnia".
170
- */
171
- inline static simsimd_f32_t simsimd_approximate_log(simsimd_f32_t number) {
172
- simsimd_f32_t x = number - 1;
173
- simsimd_f32_t x2 = x * x;
174
- simsimd_f32_t x3 = x * x * x;
175
- return x - x2 / 2 + x3 / 3;
176
- }
177
-
178
- /**
179
- * @brief For compilers that don't natively support the `_Float16` type,
180
- * upcasts contents into a more conventional `float`.
181
- *
182
- * @warning This function won't handle boundary conditions well.
183
- *
184
- * https://stackoverflow.com/a/60047308
185
- * https://gist.github.com/milhidaka/95863906fe828198f47991c813dbe233
186
- * https://github.com/OpenCyphal/libcanard/blob/636795f4bc395f56af8d2c61d3757b5e762bb9e5/canard.c#L811-L834
187
- */
188
- inline static float simsimd_uncompress_f16(unsigned short x) {
189
- union float_or_unsigned_int_t {
190
- float f;
191
- unsigned int i;
192
- };
193
- unsigned int exponent = (x & 0x7C00) >> 10;
194
- unsigned int mantissa = (x & 0x03FF) << 13;
195
- union float_or_unsigned_int_t mantissa_union;
196
- mantissa_union.f = (float)mantissa;
197
- unsigned int v = (mantissa_union.i) >> 23;
198
- union float_or_unsigned_int_t result_union;
199
- result_union.i = (x & 0x8000) << 16 | (exponent != 0) * ((exponent + 112) << 23 | mantissa) |
200
- ((exponent == 0) & (mantissa != 0)) * ((v - 37) << 23 | ((mantissa << (150 - v)) & 0x007FE000));
201
- return result_union.f;
202
- }
203
-
204
- #ifdef __cplusplus
205
- } // extern "C"
206
- #endif
207
-
208
- #endif
@@ -1,127 +0,0 @@
1
- const benchmark = require('benchmark');
2
- const math = require('mathjs');
3
- const usearch = require('usearch');
4
- const MetricKind = usearch.MetricKind;
5
- const simsimd = require("./dist/cjs/simsimd.js");
6
-
7
- // Assuming the vectors are of the same length
8
- function cosineDistance(a, b) {
9
- let dotProduct = 0;
10
- let magA = 0;
11
- let magB = 0;
12
- for (let i = 0; i < a.length; i++) {
13
- dotProduct += a[i] * b[i];
14
- magA += a[i] * a[i];
15
- magB += b[i] * b[i];
16
- }
17
- return 1 - (dotProduct / (Math.sqrt(magA) * Math.sqrt(magB)));
18
- }
19
-
20
- function cosineDistanceMathJS(a, b) {
21
- let dotProduct = math.dot(a, b);
22
- let magA = math.sqrt(math.dot(a, a));
23
- let magB = math.sqrt(math.dot(b, b));
24
- return 1 - (dotProduct / (magA * magB));
25
- }
26
-
27
- // Generate random data for testing
28
- const dimensions = 1536; // Adjust dimensions as needed
29
- const array1 = Array.from({ length: dimensions }, () => Math.random() * 100);
30
- const array2 = Array.from({ length: dimensions }, () => Math.random() * 100);
31
- const mathm1 = math.matrix(Array.from({ length: dimensions }, () => Math.random() * 100));
32
- const mathm2 = math.matrix(Array.from({ length: dimensions }, () => Math.random() * 100));
33
- const floatArray1 = new Float32Array(array1);
34
- const floatArray2 = new Float32Array(array2);
35
- const intArray1 = new Int8Array(array1);
36
- const intArray2 = new Int8Array(array2);
37
-
38
- // Generate random batch data for testing
39
- const batchSize = 1000;
40
- const matrix1 = Array.from({ length: dimensions * batchSize }, () => Math.random() * 100);
41
- const matrix2 = Array.from({ length: dimensions * batchSize }, () => Math.random() * 100);
42
- const floatMatrix1 = new Float32Array(matrix1);
43
- const floatMatrix2 = new Float32Array(matrix2);
44
- const intMatrix1 = new Int8Array(matrix1);
45
- const intMatrix2 = new Int8Array(matrix2);
46
-
47
- // Create benchmark suite
48
- const singleSuite = new benchmark.Suite('Single Vector Processing');
49
- const batchSuite = new benchmark.Suite('Batch Vector Processing');
50
-
51
- // Single-vector processing benchmarks
52
- singleSuite
53
-
54
- // Pure JavaScript
55
- .add('Array of Numbers', () => {
56
- cosineDistance(array1, array2);
57
- })
58
- .add('TypedArray of Float32', () => {
59
- cosineDistance(floatArray1, floatArray2);
60
- })
61
- .add('TypedArray of Int8', () => {
62
- cosineDistance(intArray1, intArray2);
63
- })
64
-
65
- // Math JS
66
- .add('Array of Numbers with MathJS', () => {
67
- cosineDistanceMathJS(array1, array2);
68
- })
69
- .add('MathMatrix with MathJS', () => {
70
- cosineDistanceMathJS(mathm1, mathm2);
71
- })
72
-
73
- // SimSIMD
74
- .add('TypedArray of Float32 with SimSIMD', () => {
75
- simsimd.cosine(floatArray1, floatArray2);
76
- })
77
- .add('TypedArray of Int8 with SimSIMD', () => {
78
- simsimd.cosine(intArray1, intArray2);
79
- })
80
-
81
- .on('cycle', (event) => {
82
- if (event.target.error) {
83
- console.error(String(event.target.error));
84
- } else {
85
- console.log(String(event.target));
86
- }
87
- })
88
- .on('complete', () => {
89
- console.log('Fastest Single-Vector Processing is ' + singleSuite.filter('fastest').map('name'));
90
- })
91
- .run({
92
- noCache: true,
93
- async: false,
94
- });
95
-
96
- // Batch-vector processing benchmarks
97
- batchSuite
98
- .add('2D Array of Numbers', () => {
99
- for (let i = 0; i < batchSize; i++) {
100
- for (let j = 0; j < batchSize; j++) {
101
- const start = i * dimensions;
102
- const end = start + dimensions;
103
- cosineDistance(matrix1.slice(start, end), matrix2.slice(start, end));
104
- }
105
- }
106
- })
107
- .add('2D TypedArray of Float32 with exact USearch', () => {
108
- usearch.exactSearch(floatMatrix1, floatMatrix2, dimensions, 1, MetricKind.Cos);
109
- })
110
- .add('2D TypedArray of Int8 with exact USearch', () => {
111
- usearch.exactSearch(intMatrix1, intMatrix2, dimensions, 1, MetricKind.Cos);
112
- })
113
- .on('cycle', (event) => {
114
- if (event.target.error) {
115
- console.error(String(event.target.error));
116
- } else {
117
- console.log(String(event.target));
118
- }
119
- })
120
- .on('complete', () => {
121
- console.log('Fastest Batch-Vector Processing is ' + batchSuite.filter('fastest').map('name'));
122
- })
123
- .run({
124
- noCache: true,
125
- async: false,
126
- });
127
-
@@ -1,193 +0,0 @@
1
- /**
2
- * @brief Computes the inner distance of two vectors.
3
- * @param {Float32Array} a - The first vector.
4
- * @param {Float32Array} b - The second vector.
5
- * @returns {number} The inner distance of vectors a and b.
6
- */
7
- export function inner(a: Float32Array, b: Float32Array): number {
8
- if (a.length !== b.length) {
9
- throw new Error("Vectors must have the same length");
10
- }
11
-
12
- let result = 0;
13
- for (let i = 0; i < a.length; i++) {
14
- result += a[i] * b[i];
15
- }
16
- return 1 - result;
17
- }
18
-
19
- /**
20
- * @brief Computes the squared Euclidean distance between two vectors.
21
- * @param {Float32Array|Int8Array} a - The first vector.
22
- * @param {Float32Array|Int8Array} b - The second vector.
23
- * @returns {number} The squared Euclidean distance between vectors a and b.
24
- */
25
- export function sqeuclidean(
26
- a: Float32Array | Int8Array,
27
- b: Float32Array | Int8Array
28
- ): number {
29
- if (a.length !== b.length) {
30
- throw new Error("Vectors must have the same length");
31
- }
32
-
33
- let result = 0;
34
- for (let i = 0; i < a.length; i++) {
35
- result += (a[i] - b[i]) * (a[i] - b[i]);
36
- }
37
- return result;
38
- }
39
-
40
- /**
41
- * @brief Computes the cosine distance between two vectors.
42
- * @param {Float32Array|Int8Array} a - The first vector.
43
- * @param {Float32Array|Int8Array} b - The second vector.
44
- * @returns {number} The cosine distance between vectors a and b.
45
- */
46
- export function cosine(
47
- a: Float32Array | Int8Array,
48
- b: Float32Array | Int8Array
49
- ): number {
50
- if (a.length !== b.length) {
51
- throw new Error("Vectors must have the same length");
52
- }
53
-
54
- let dotProduct = 0;
55
- let magnitudeA = 0;
56
- let magnitudeB = 0;
57
-
58
- for (let i = 0; i < a.length; i++) {
59
- dotProduct += a[i] * b[i];
60
- magnitudeA += a[i] * a[i];
61
- magnitudeB += b[i] * b[i];
62
- }
63
-
64
- magnitudeA = Math.sqrt(magnitudeA);
65
- magnitudeB = Math.sqrt(magnitudeB);
66
-
67
- if (magnitudeA === 0 || magnitudeB === 0) {
68
- console.warn(
69
- "Warning: One of the magnitudes is zero. Cosine similarity is undefined."
70
- );
71
- return 0;
72
- }
73
-
74
- return 1 - dotProduct / (magnitudeA * magnitudeB);
75
- }
76
-
77
- /**
78
- * @brief Computes the bitwise Hamming distance between two vectors.
79
- * @param {Uint8Array} a - The first vector.
80
- * @param {Uint8Array} b - The second vector.
81
- * @returns {number} The Hamming distance between vectors a and b.
82
- */
83
- export const hamming = (a: Uint8Array, b: Uint8Array): number => {
84
- if (a.length !== b.length) {
85
- throw new Error("Arrays must be of the same length");
86
- }
87
-
88
- let distance = 0;
89
-
90
- for (let i = 0; i < a.length; i++) {
91
- let xor = a[i] ^ b[i]; // XOR operation to find differing bits
92
-
93
- // Count the number of set bits (differing bits)
94
- while (xor > 0) {
95
- distance += xor & 1;
96
- xor >>= 1;
97
- }
98
- }
99
-
100
- return distance;
101
- };
102
-
103
- /**
104
- * @brief Computes the bitwise Jaccard similarity coefficient between two vectors.
105
- * @param {Uint8Array} a - The first vector.
106
- * @param {Uint8Array} b - The second vector.
107
- * @returns {number} The Jaccard similarity coefficient between vectors a and b.
108
- */
109
- export const jaccard = (a: Uint8Array, b: Uint8Array): number => {
110
- if (a.length !== b.length) {
111
- throw new Error("Arrays must be of the same length");
112
- }
113
-
114
- let intersection = 0;
115
- let union = 0;
116
-
117
- for (let i = 0; i < a.length; i++) {
118
- let ai = a[i];
119
- let bi = b[i];
120
-
121
- // Count the number of set bits in a AND b for intersection
122
- let and = ai & bi;
123
- while (and > 0) {
124
- intersection += and & 1;
125
- and >>= 1;
126
- }
127
-
128
- // Count the number of set bits in a OR b for union
129
- let or = ai | bi;
130
- while (or > 0) {
131
- union += or & 1;
132
- or >>= 1;
133
- }
134
- }
135
-
136
- if (union === 0) return 0; // Avoid division by zero
137
-
138
- return 1 - intersection / union;
139
- };
140
-
141
- /**
142
- * @brief Computes the kullbackleibler similarity coefficient between two vectors.
143
- * @param {Float32Array} a - The first vector.
144
- * @param {Float32Array} b - The second vector.
145
- * @returns {number} The Jaccard similarity coefficient between vectors a and b.
146
- */
147
- export const kullbackleibler = (a: Float32Array, b: Float32Array): number => {
148
- if (a.length !== b.length) {
149
- throw new Error("Arrays must be of the same length");
150
- }
151
-
152
- let divergence = 0.0;
153
-
154
- for (let i = 0; i < a.length; i++) {
155
- if (a[i] > 0) {
156
- if (b[i] === 0) {
157
- throw new Error(
158
- "Division by zero encountered in KL divergence calculation"
159
- );
160
- }
161
- divergence += a[i] * Math.log(a[i] / b[i]);
162
- }
163
- }
164
-
165
- return divergence;
166
- };
167
-
168
- /**
169
- * @brief Computes the jensenshannon similarity coefficient between two vectors.
170
- * @param {Float32Array} a - The first vector.
171
- * @param {Float32Array} b - The second vector.
172
- * @returns {number} The Jaccard similarity coefficient between vectors a and b.
173
- */
174
- export const jensenshannon = (p: Float32Array, q: Float32Array): number => {
175
- if (p.length !== q.length) {
176
- throw new Error("Arrays must be of the same length");
177
- }
178
-
179
- const m = p.map((value, index) => (value + q[index]) / 2);
180
-
181
- const divergence = 0.5 * kullbackleibler(p, m) + 0.5 * kullbackleibler(q, m);
182
- return Math.sqrt(divergence);
183
- };
184
-
185
- export default {
186
- sqeuclidean,
187
- cosine,
188
- inner,
189
- hamming,
190
- jaccard,
191
- kullbackleibler,
192
- jensenshannon,
193
- };
@@ -1,102 +0,0 @@
1
- /**
2
- * @file lib.c
3
- * @brief JavaScript bindings for SimSIMD.
4
- * @author Ash Vardanian
5
- * @date October 18, 2023
6
- *
7
- * @copyright Copyright (c) 2023
8
- * @see NodeJS docs: https://nodejs.org/api/n-api.html
9
- */
10
-
11
- #include <node_api.h> // `napi_*` functions
12
- #include <simsimd/simsimd.h> // `simsimd_*` functions
13
-
14
- /// @brief Global variable that caches the CPU capabilities, and is computed just onc, when the module is loaded.
15
- simsimd_capability_t static_capabilities = simsimd_cap_serial_k;
16
-
17
- napi_value runAPI(napi_env env, napi_callback_info info, simsimd_metric_kind_t metric_kind) {
18
- size_t argc = 2;
19
- napi_value args[2];
20
- napi_status status;
21
-
22
- // Get callback info and ensure the argument count is correct
23
- status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
24
- if (status != napi_ok || argc != 2) {
25
- napi_throw_error(env, NULL, "Wrong number of arguments");
26
- return NULL;
27
- }
28
-
29
- // Obtain the typed arrays from the arguments
30
- void *data_a, *data_b;
31
- size_t length_a, length_b;
32
- napi_typedarray_type type_a, type_b;
33
- napi_status status_a, status_b;
34
- status_a = napi_get_typedarray_info(env, args[0], &type_a, &length_a, &data_a, NULL, NULL);
35
- status_b = napi_get_typedarray_info(env, args[1], &type_b, &length_b, &data_b, NULL, NULL);
36
- if (status_a != napi_ok || status_b != napi_ok || type_a != type_b || length_a != length_b) {
37
- napi_throw_error(env, NULL, "Both arguments must be typed arrays of matching types and dimensionality");
38
- return NULL;
39
- }
40
- if (type_a != napi_float32_array && type_a != napi_int8_array && type_a != napi_uint8_array) {
41
- napi_throw_error(env, NULL, "Only `float32`, `int8` and `uint8` arrays are supported in JavaScript bindings");
42
- return NULL;
43
- }
44
-
45
- simsimd_datatype_t datatype = simsimd_datatype_unknown_k;
46
- switch (type_a) {
47
- case napi_float32_array: datatype = simsimd_datatype_f32_k; break;
48
- case napi_int8_array: datatype = simsimd_datatype_i8_k; break;
49
- case napi_uint8_array: datatype = simsimd_datatype_b8_k; break;
50
- default: break;
51
- }
52
-
53
- simsimd_metric_punned_t metric = NULL;
54
- simsimd_capability_t capability = simsimd_cap_serial_k;
55
- simsimd_find_metric_punned(metric_kind, datatype, static_capabilities, simsimd_cap_any_k, &metric, &capability);
56
- if (metric == NULL) {
57
- napi_throw_error(env, NULL, "Unsupported datatype");
58
- return NULL;
59
- }
60
-
61
- simsimd_f32_t result = metric(data_a, data_b, length_a, length_b);
62
-
63
- // Convert the result to a JavaScript number
64
- napi_value js_result;
65
- status = napi_create_double(env, result, &js_result);
66
- if (status != napi_ok)
67
- return NULL;
68
-
69
- return js_result;
70
- }
71
-
72
- napi_value l2sqAPI(napi_env env, napi_callback_info info) { return runAPI(env, info, simsimd_metric_sqeuclidean_k); }
73
- napi_value cosAPI(napi_env env, napi_callback_info info) { return runAPI(env, info, simsimd_metric_cosine_k); }
74
- napi_value ipAPI(napi_env env, napi_callback_info info) { return runAPI(env, info, simsimd_metric_ip_k); }
75
- napi_value klAPI(napi_env env, napi_callback_info info) { return runAPI(env, info, simsimd_metric_kl_k); }
76
- napi_value jsAPI(napi_env env, napi_callback_info info) { return runAPI(env, info, simsimd_metric_js_k); }
77
- napi_value hammingAPI(napi_env env, napi_callback_info info) { return runAPI(env, info, simsimd_metric_hamming_k); }
78
- napi_value jaccardAPI(napi_env env, napi_callback_info info) { return runAPI(env, info, simsimd_metric_jaccard_k); }
79
-
80
- napi_value Init(napi_env env, napi_value exports) {
81
-
82
- // Define an array of property descriptors
83
- napi_property_descriptor sqeuclideanDesc = {"sqeuclidean", 0, l2sqAPI, 0, 0, 0, napi_default, 0};
84
- napi_property_descriptor innerDesc = {"inner", 0, ipAPI, 0, 0, 0, napi_default, 0};
85
- napi_property_descriptor cosineDesc = {"cosine", 0, cosAPI, 0, 0, 0, napi_default, 0};
86
- napi_property_descriptor hammingDesc = {"hamming", 0, hammingAPI, 0, 0, 0, napi_default, 0};
87
- napi_property_descriptor jaccardDesc = {"jaccard", 0, jaccardAPI, 0, 0, 0, napi_default, 0};
88
- napi_property_descriptor klDesc = {"kullbackleibler", 0, klAPI, 0, 0, 0, napi_default, 0};
89
- napi_property_descriptor jsDesc = {"jensenshannon", 0, jsAPI, 0, 0, 0, napi_default, 0};
90
- napi_property_descriptor properties[] = {
91
- sqeuclideanDesc, innerDesc, cosineDesc, hammingDesc, jaccardDesc, klDesc, jsDesc,
92
- };
93
-
94
- // Define the properties on the `exports` object
95
- size_t propertyCount = sizeof(properties) / sizeof(properties[0]);
96
- napi_define_properties(env, exports, propertyCount, properties);
97
-
98
- static_capabilities = simsimd_capabilities();
99
- return exports;
100
- }
101
-
102
- NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
@@ -1 +0,0 @@
1
- declare module "node-gyp-build";