usearch 2.8.14 → 2.8.16
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.
- package/.github/workflows/prerelease.yml +4 -4
- package/.github/workflows/release.yml +5 -2
- package/CITATION.cff +1 -1
- package/Cargo.toml +1 -1
- package/README.md +2 -2
- package/VERSION +1 -1
- package/conanfile.py +1 -1
- package/include/usearch/index.hpp +1 -1
- package/include/usearch/index_plugins.hpp +2 -1
- package/package.json +1 -1
- package/simsimd/README.md +55 -25
- package/simsimd/bench.js +51 -0
- package/simsimd/binding.gyp +18 -0
- package/simsimd/include/simsimd/probability.h +5 -5
- package/simsimd/include/simsimd/simsimd.h +6 -2
- package/simsimd/include/simsimd/spatial.h +19 -20
- package/simsimd/javascript/bench.js +20 -10
- package/simsimd/javascript/dist-package-cjs.json +3 -0
- package/simsimd/javascript/dist-package-esm.json +3 -0
- package/simsimd/javascript/fallback.ts +193 -0
- package/simsimd/javascript/node-gyp-build.d.ts +1 -0
- package/simsimd/javascript/simsimd.ts +124 -0
- package/simsimd/javascript/test.mjs +153 -0
- package/simsimd/javascript/tsconfig-base.json +25 -0
- package/simsimd/javascript/tsconfig-cjs.json +8 -0
- package/simsimd/javascript/tsconfig-esm.json +8 -0
- package/simsimd/package-lock.json +1688 -0
- package/simsimd/package.json +26 -11
- package/wasmer.toml +1 -1
- package/simsimd/javascript/simsimd.js +0 -45
- package/simsimd/javascript/test/simsimd.test.js +0 -47
|
@@ -0,0 +1,193 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module "node-gyp-build";
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import build from "node-gyp-build";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { getFileName, getRoot } from "bindings";
|
|
5
|
+
import * as fallback from "./fallback.js";
|
|
6
|
+
|
|
7
|
+
let compiled: any;
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
let builddir = getBuildDir(getDirName());
|
|
11
|
+
compiled = build(builddir);
|
|
12
|
+
} catch (e) {
|
|
13
|
+
compiled = fallback;
|
|
14
|
+
console.warn(
|
|
15
|
+
"It seems like your environment does't support the native simsimd module, so we are providing a JS fallback."
|
|
16
|
+
);
|
|
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 const sqeuclidean = (
|
|
26
|
+
a: Float32Array | Int8Array,
|
|
27
|
+
b: Float32Array | Int8Array
|
|
28
|
+
): number => {
|
|
29
|
+
return compiled.sqeuclidean(a, b);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @brief Computes the cosine distance between two vectors.
|
|
34
|
+
* @param {Float32Array|Int8Array} a - The first vector.
|
|
35
|
+
* @param {Float32Array|Int8Array} b - The second vector.
|
|
36
|
+
* @returns {number} The cosine distance between vectors a and b.
|
|
37
|
+
*/
|
|
38
|
+
export const cosine = (
|
|
39
|
+
a: Float32Array | Int8Array,
|
|
40
|
+
b: Float32Array | Int8Array
|
|
41
|
+
): number => {
|
|
42
|
+
return compiled.cosine(a, b);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @brief Computes the inner distance of two vectors.
|
|
47
|
+
* @param {Float32Array} a - The first vector.
|
|
48
|
+
* @param {Float32Array} b - The second vector.
|
|
49
|
+
* @returns {number} The inner distance of vectors a and b.
|
|
50
|
+
*/
|
|
51
|
+
export const inner = (a: Float32Array, b: Float32Array): number => {
|
|
52
|
+
return compiled.inner(a, b);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @brief Computes the bitwise Hamming distance between two vectors.
|
|
57
|
+
* @param {Uint8Array} a - The first vector.
|
|
58
|
+
* @param {Uint8Array} b - The second vector.
|
|
59
|
+
* @returns {number} The Hamming distance between vectors a and b.
|
|
60
|
+
*/
|
|
61
|
+
export const hamming = (a: Uint8Array, b: Uint8Array): number => {
|
|
62
|
+
return compiled.hamming(a, b);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @brief Computes the bitwise Jaccard similarity coefficient between two vectors.
|
|
67
|
+
* @param {Uint8Array} a - The first vector.
|
|
68
|
+
* @param {Uint8Array} b - The second vector.
|
|
69
|
+
* @returns {number} The Jaccard similarity coefficient between vectors a and b.
|
|
70
|
+
*/
|
|
71
|
+
export const jaccard = (a: Uint8Array, b: Uint8Array): number => {
|
|
72
|
+
return compiled.jaccard(a, b);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @brief Computes the kullbackleibler similarity coefficient between two vectors.
|
|
77
|
+
* @param {Float32Array} a - The first vector.
|
|
78
|
+
* @param {Float32Array} b - The second vector.
|
|
79
|
+
* @returns {number} The Jaccard similarity coefficient between vectors a and b.
|
|
80
|
+
*/
|
|
81
|
+
export const kullbackleibler = (a: Float32Array, b: Float32Array): number => {
|
|
82
|
+
return compiled.kullbackleibler(a, b);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @brief Computes the jensenshannon similarity coefficient between two vectors.
|
|
87
|
+
* @param {Float32Array} a - The first vector.
|
|
88
|
+
* @param {Float32Array} b - The second vector.
|
|
89
|
+
* @returns {number} The Jaccard similarity coefficient between vectors a and b.
|
|
90
|
+
*/
|
|
91
|
+
export const jensenshannon = (a: Float32Array, b: Float32Array): number => {
|
|
92
|
+
return compiled.jensenshannon(a, b);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export default {
|
|
96
|
+
sqeuclidean,
|
|
97
|
+
cosine,
|
|
98
|
+
inner,
|
|
99
|
+
hamming,
|
|
100
|
+
jaccard,
|
|
101
|
+
kullbackleibler,
|
|
102
|
+
jensenshannon,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// utility functions to help find native builds
|
|
106
|
+
|
|
107
|
+
function getBuildDir(dir: string) {
|
|
108
|
+
if (existsSync(path.join(dir, "build"))) return dir;
|
|
109
|
+
if (existsSync(path.join(dir, "prebuilds"))) return dir;
|
|
110
|
+
if (path.basename(dir) === ".next") {
|
|
111
|
+
// special case for next.js on custom node (not vercel)
|
|
112
|
+
const sideways = path.join(dir, "..", "node_modules", "simsimd");
|
|
113
|
+
if (existsSync(sideways)) return getBuildDir(sideways);
|
|
114
|
+
}
|
|
115
|
+
if (dir === "/") throw new Error("Could not find native build for simsimd");
|
|
116
|
+
return getBuildDir(path.join(dir, ".."));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getDirName() {
|
|
120
|
+
try {
|
|
121
|
+
if (__dirname) return __dirname;
|
|
122
|
+
} catch (e) {}
|
|
123
|
+
return getRoot(getFileName());
|
|
124
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert";
|
|
3
|
+
|
|
4
|
+
import * as simsimd from "./dist/esm/simsimd.js";
|
|
5
|
+
|
|
6
|
+
import * as fallback from "./dist/esm/fallback.js";
|
|
7
|
+
|
|
8
|
+
function assertAlmostEqual(actual, expected, tolerance = 1e-6) {
|
|
9
|
+
const lowerBound = expected - tolerance;
|
|
10
|
+
const upperBound = expected + tolerance;
|
|
11
|
+
assert(
|
|
12
|
+
actual >= lowerBound && actual <= upperBound,
|
|
13
|
+
`Expected ${actual} to be almost equal to ${expected}`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
test("Distance from itself", () => {
|
|
18
|
+
const f32s = new Float32Array([1.0, 2.0, 3.0]);
|
|
19
|
+
assertAlmostEqual(simsimd.sqeuclidean(f32s, f32s), 0.0, 0.01);
|
|
20
|
+
assertAlmostEqual(simsimd.cosine(f32s, f32s), 0.0, 0.01);
|
|
21
|
+
|
|
22
|
+
const f32sNormalized = new Float32Array([
|
|
23
|
+
1.0 / Math.sqrt(14),
|
|
24
|
+
2.0 / Math.sqrt(14),
|
|
25
|
+
3.0 / Math.sqrt(14),
|
|
26
|
+
]);
|
|
27
|
+
assertAlmostEqual(simsimd.inner(f32sNormalized, f32sNormalized), 0.0, 0.01);
|
|
28
|
+
|
|
29
|
+
const f32sDistribution = new Float32Array([1.0 / 6, 2.0 / 6, 3.0 / 6]);
|
|
30
|
+
assertAlmostEqual(
|
|
31
|
+
simsimd.kullbackleibler(f32sDistribution, f32sDistribution),
|
|
32
|
+
0.0,
|
|
33
|
+
0.01
|
|
34
|
+
);
|
|
35
|
+
assertAlmostEqual(
|
|
36
|
+
simsimd.jensenshannon(f32sDistribution, f32sDistribution),
|
|
37
|
+
0.0,
|
|
38
|
+
0.01
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const u8s = new Uint8Array([1, 2, 3]);
|
|
42
|
+
assertAlmostEqual(simsimd.hamming(u8s, u8s), 0.0, 0.01);
|
|
43
|
+
assertAlmostEqual(simsimd.jaccard(u8s, u8s), 0.0, 0.01);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("Distance from itself JS fallback", () => {
|
|
47
|
+
const f32s = new Float32Array([1.0, 2.0, 3.0]);
|
|
48
|
+
|
|
49
|
+
assertAlmostEqual(fallback.sqeuclidean(f32s, f32s), 0.0, 0.01);
|
|
50
|
+
assertAlmostEqual(fallback.cosine(f32s, f32s), 0.0, 0.01);
|
|
51
|
+
|
|
52
|
+
const arrNormalized = new Float32Array([
|
|
53
|
+
1.0 / Math.sqrt(14),
|
|
54
|
+
2.0 / Math.sqrt(14),
|
|
55
|
+
3.0 / Math.sqrt(14),
|
|
56
|
+
]);
|
|
57
|
+
assertAlmostEqual(fallback.inner(arrNormalized, arrNormalized), 0.0, 0.01);
|
|
58
|
+
|
|
59
|
+
const f32sDistribution = new Float32Array([1.0 / 6, 2.0 / 6, 3.0 / 6]);
|
|
60
|
+
assertAlmostEqual(
|
|
61
|
+
fallback.kullbackleibler(f32sDistribution, f32sDistribution),
|
|
62
|
+
0.0,
|
|
63
|
+
0.01
|
|
64
|
+
);
|
|
65
|
+
assertAlmostEqual(
|
|
66
|
+
fallback.jensenshannon(f32sDistribution, f32sDistribution),
|
|
67
|
+
0.0,
|
|
68
|
+
0.01
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const u8s = new Uint8Array([1, 2, 3]);
|
|
72
|
+
assertAlmostEqual(fallback.hamming(u8s, u8s), 0.0, 0.01);
|
|
73
|
+
assertAlmostEqual(fallback.jaccard(u8s, u8s), 0.0, 0.01);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const f32Array1 = new Float32Array([1.0, 2.0, 3.0]);
|
|
77
|
+
const f32Array2 = new Float32Array([4.0, 5.0, 6.0]);
|
|
78
|
+
|
|
79
|
+
test("Squared Euclidean Distance", () => {
|
|
80
|
+
const result = simsimd.sqeuclidean(f32Array1, f32Array2);
|
|
81
|
+
assertAlmostEqual(result, 27.0, 0.01);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("Inner Distance", () => {
|
|
85
|
+
const result = simsimd.inner(f32Array1, f32Array2);
|
|
86
|
+
assertAlmostEqual(result, -31.0, 0.01);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("Cosine Similarity", () => {
|
|
90
|
+
const result = simsimd.cosine(f32Array1, f32Array2);
|
|
91
|
+
assertAlmostEqual(result, 0.029, 0.01);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("Squared Euclidean Distance JS", () => {
|
|
95
|
+
const result = fallback.sqeuclidean(f32Array1, f32Array2);
|
|
96
|
+
assertAlmostEqual(result, 27.0, 0.01);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("Inner Distance JS", () => {
|
|
100
|
+
const result = fallback.inner(f32Array1, f32Array2);
|
|
101
|
+
assertAlmostEqual(result, -31.0, 0.01);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("Cosine Similarity JS", () => {
|
|
105
|
+
const result = fallback.cosine(f32Array1, f32Array2);
|
|
106
|
+
assertAlmostEqual(result, 0.029, 0.01);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("Squared Euclidean Distance C vs JS", () => {
|
|
110
|
+
const result = simsimd.sqeuclidean(f32Array1, f32Array2);
|
|
111
|
+
const resultjs = fallback.sqeuclidean(f32Array1, f32Array2);
|
|
112
|
+
assertAlmostEqual(resultjs, result, 0.01);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("Inner Distance C vs JS", () => {
|
|
116
|
+
const result = simsimd.inner(f32Array1, f32Array2);
|
|
117
|
+
const resultjs = fallback.inner(f32Array1, f32Array2);
|
|
118
|
+
assertAlmostEqual(resultjs, result, 0.01);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("Cosine Similarity C vs JS", () => {
|
|
122
|
+
const result = simsimd.cosine(f32Array1, f32Array2);
|
|
123
|
+
const resultjs = fallback.cosine(f32Array1, f32Array2);
|
|
124
|
+
assertAlmostEqual(resultjs, result, 0.01);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("Hamming C vs JS", () => {
|
|
128
|
+
const u8s = new Uint8Array([1, 2, 3]);
|
|
129
|
+
const result = simsimd.hamming(u8s, u8s);
|
|
130
|
+
const resultjs = fallback.cosine(u8s, u8s);
|
|
131
|
+
assertAlmostEqual(resultjs, result, 0.01);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("Jaccard C vs JS", () => {
|
|
135
|
+
const u8s = new Uint8Array([1, 2, 3]);
|
|
136
|
+
const result = simsimd.jaccard(u8s, u8s);
|
|
137
|
+
const resultjs = fallback.jaccard(u8s, u8s);
|
|
138
|
+
assertAlmostEqual(resultjs, result, 0.01);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("Kullback-Leibler C vs JS", () => {
|
|
142
|
+
const f32sDistribution = new Float32Array([1.0 / 6, 2.0 / 6, 3.0 / 6]);
|
|
143
|
+
const result = simsimd.kullbackleibler(f32sDistribution, f32sDistribution);
|
|
144
|
+
const resultjs = fallback.kullbackleibler(f32sDistribution, f32sDistribution);
|
|
145
|
+
assertAlmostEqual(resultjs, result, 0.01);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("Jensen-Shannon C vs JS", () => {
|
|
149
|
+
const f32sDistribution = new Float32Array([1.0 / 6, 2.0 / 6, 3.0 / 6]);
|
|
150
|
+
const result = simsimd.jensenshannon(f32sDistribution, f32sDistribution);
|
|
151
|
+
const resultjs = fallback.jensenshannon(f32sDistribution, f32sDistribution);
|
|
152
|
+
assertAlmostEqual(resultjs, result, 0.01);
|
|
153
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compileOnSave": false,
|
|
3
|
+
"exclude": ["node_modules", "dist"],
|
|
4
|
+
"include": ["node-gyp-build.d.ts", "simsimd.ts", "fallback.ts"],
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"allowSyntheticDefaultImports": true,
|
|
8
|
+
"baseUrl": ".",
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"inlineSourceMap": false,
|
|
12
|
+
"lib": ["esnext"],
|
|
13
|
+
"listEmittedFiles": false,
|
|
14
|
+
"listFiles": false,
|
|
15
|
+
"moduleResolution": "node",
|
|
16
|
+
"noFallthroughCasesInSwitch": true,
|
|
17
|
+
"pretty": true,
|
|
18
|
+
"resolveJsonModule": true,
|
|
19
|
+
"rootDir": ".",
|
|
20
|
+
"skipLibCheck": true,
|
|
21
|
+
"strict": true,
|
|
22
|
+
"traceResolution": false,
|
|
23
|
+
"types": ["node","./node-gyp-build.d.ts"]
|
|
24
|
+
}
|
|
25
|
+
}
|