usearch 2.16.8 → 2.16.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.
- package/README.md +1 -1
- package/include/usearch/index.hpp +1 -1
- package/package.json +1 -1
- package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
- package/prebuilds/linux-arm64/usearch.node +0 -0
- package/prebuilds/linux-x64/usearch.node +0 -0
- package/simsimd/CONTRIBUTING.md +69 -12
- package/simsimd/Cargo.lock +1 -1
- package/simsimd/Cargo.toml +1 -1
- package/simsimd/README.md +253 -40
- package/simsimd/c/lib.c +114 -109
- package/simsimd/include/simsimd/binary.h +33 -17
- package/simsimd/include/simsimd/curved.h +867 -129
- package/simsimd/include/simsimd/dot.h +562 -569
- package/simsimd/include/simsimd/probability.h +14 -9
- package/simsimd/include/simsimd/simsimd.h +102 -46
- package/simsimd/include/simsimd/spatial.h +28 -18
- package/simsimd/include/simsimd/types.h +24 -0
- package/simsimd/javascript/fallback.ts +26 -15
- package/simsimd/javascript/simsimd.ts +1 -1
- package/simsimd/package-lock.json +10 -9
- package/simsimd/package.json +2 -2
- package/simsimd/rust/lib.rs +218 -5
- package/simsimd/scripts/bench.cxx +156 -97
- package/simsimd/scripts/test.c +14 -8
- package/simsimd/scripts/test.mjs +158 -145
- package/simsimd/scripts/test.py +71 -52
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simsimd",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.5",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "simsimd",
|
|
9
|
-
"version": "
|
|
9
|
+
"version": "6.0.5",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "Apache 2.0",
|
|
12
12
|
"dependencies": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@types/bindings": "^1.5.5",
|
|
19
|
-
"@types/node": "^20.17.
|
|
19
|
+
"@types/node": "^20.17.6",
|
|
20
20
|
"node-gyp": "^10.0.1",
|
|
21
21
|
"prebuildify": "^6.0.0",
|
|
22
22
|
"typescript": "^5.3.3"
|
|
@@ -107,9 +107,9 @@
|
|
|
107
107
|
}
|
|
108
108
|
},
|
|
109
109
|
"node_modules/@types/node": {
|
|
110
|
-
"version": "20.17.
|
|
111
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.
|
|
112
|
-
"integrity": "sha512-
|
|
110
|
+
"version": "20.17.6",
|
|
111
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz",
|
|
112
|
+
"integrity": "sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==",
|
|
113
113
|
"devOptional": true,
|
|
114
114
|
"license": "MIT",
|
|
115
115
|
"dependencies": {
|
|
@@ -335,10 +335,11 @@
|
|
|
335
335
|
}
|
|
336
336
|
},
|
|
337
337
|
"node_modules/cross-spawn": {
|
|
338
|
-
"version": "7.0.
|
|
339
|
-
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.
|
|
340
|
-
"integrity": "sha512-
|
|
338
|
+
"version": "7.0.6",
|
|
339
|
+
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
|
340
|
+
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
|
341
341
|
"dev": true,
|
|
342
|
+
"license": "MIT",
|
|
342
343
|
"dependencies": {
|
|
343
344
|
"path-key": "^3.1.0",
|
|
344
345
|
"shebang-command": "^2.0.0",
|
package/simsimd/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simsimd",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.3",
|
|
4
4
|
"description": "Portable mixed-precision BLAS-like vector math library for x86 and ARM",
|
|
5
5
|
"homepage": "https://github.com/ashvardanian/simsimd",
|
|
6
6
|
"author": "Ash Vardanian",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/bindings": "^1.5.5",
|
|
51
|
-
"@types/node": "^20.17.
|
|
51
|
+
"@types/node": "^20.17.6",
|
|
52
52
|
"node-gyp": "^10.0.1",
|
|
53
53
|
"prebuildify": "^6.0.0",
|
|
54
54
|
"typescript": "^5.3.3"
|
package/simsimd/rust/lib.rs
CHANGED
|
@@ -80,6 +80,12 @@ extern "C" {
|
|
|
80
80
|
fn simsimd_l2sq_f32(a: *const f32, b: *const f32, c: usize, d: *mut Distance);
|
|
81
81
|
fn simsimd_l2sq_f64(a: *const f64, b: *const f64, c: usize, d: *mut Distance);
|
|
82
82
|
|
|
83
|
+
fn simsimd_l2_i8(a: *const i8, b: *const i8, c: usize, d: *mut Distance);
|
|
84
|
+
fn simsimd_l2_f16(a: *const u16, b: *const u16, c: usize, d: *mut Distance);
|
|
85
|
+
fn simsimd_l2_bf16(a: *const u16, b: *const u16, c: usize, d: *mut Distance);
|
|
86
|
+
fn simsimd_l2_f32(a: *const f32, b: *const f32, c: usize, d: *mut Distance);
|
|
87
|
+
fn simsimd_l2_f64(a: *const f64, b: *const f64, c: usize, d: *mut Distance);
|
|
88
|
+
|
|
83
89
|
fn simsimd_hamming_b8(a: *const u8, b: *const u8, c: usize, d: *mut Distance);
|
|
84
90
|
fn simsimd_jaccard_b8(a: *const u8, b: *const u8, c: usize, d: *mut Distance);
|
|
85
91
|
|
|
@@ -93,6 +99,9 @@ extern "C" {
|
|
|
93
99
|
fn simsimd_kl_f32(a: *const f32, b: *const f32, c: usize, d: *mut Distance);
|
|
94
100
|
fn simsimd_kl_f64(a: *const f64, b: *const f64, c: usize, d: *mut Distance);
|
|
95
101
|
|
|
102
|
+
fn simsimd_intersect_u16(a: *const u16, b: *const u16, a_length: usize, b_length: usize, d: *mut Distance);
|
|
103
|
+
fn simsimd_intersect_u32(a: *const u32, b: *const u32, a_length: usize, b_length: usize, d: *mut Distance);
|
|
104
|
+
|
|
96
105
|
fn simsimd_uses_neon() -> i32;
|
|
97
106
|
fn simsimd_uses_neon_f16() -> i32;
|
|
98
107
|
fn simsimd_uses_neon_bf16() -> i32;
|
|
@@ -215,6 +224,12 @@ where
|
|
|
215
224
|
/// between corresponding elements of the two slices.
|
|
216
225
|
fn l2sq(a: &[Self], b: &[Self]) -> Option<Distance>;
|
|
217
226
|
|
|
227
|
+
/// Computes the Euclidean distance between two slices.
|
|
228
|
+
/// The Euclidean distance is the square root of
|
|
229
|
+
// sum of the squared differences between corresponding
|
|
230
|
+
/// elements of the two slices.
|
|
231
|
+
fn l2(a: &[Self], b: &[Self]) -> Option<Distance>;
|
|
232
|
+
|
|
218
233
|
/// Computes the squared Euclidean distance between two slices.
|
|
219
234
|
/// The squared Euclidean distance is the sum of the squared differences
|
|
220
235
|
/// between corresponding elements of the two slices.
|
|
@@ -222,6 +237,14 @@ where
|
|
|
222
237
|
SpatialSimilarity::l2sq(a, b)
|
|
223
238
|
}
|
|
224
239
|
|
|
240
|
+
/// Computes the Euclidean distance between two slices.
|
|
241
|
+
/// The Euclidean distance is the square root of the
|
|
242
|
+
/// sum of the squared differences between corresponding
|
|
243
|
+
/// elements of the two slices.
|
|
244
|
+
fn euclidean(a: &[Self], b: &[Self]) -> Option<Distance> {
|
|
245
|
+
SpatialSimilarity::l2(a, b)
|
|
246
|
+
}
|
|
247
|
+
|
|
225
248
|
/// Computes the squared Euclidean distance between two slices.
|
|
226
249
|
/// The squared Euclidean distance is the sum of the squared differences
|
|
227
250
|
/// between corresponding elements of the two slices.
|
|
@@ -295,6 +318,16 @@ where
|
|
|
295
318
|
fn vdot(a: &[Self], b: &[Self]) -> Option<ComplexProduct>;
|
|
296
319
|
}
|
|
297
320
|
|
|
321
|
+
/// `Sparse` provides trait methods for sparse vectors.
|
|
322
|
+
pub trait Sparse
|
|
323
|
+
where
|
|
324
|
+
Self: Sized,
|
|
325
|
+
{
|
|
326
|
+
/// Computes the number of common elements between two sparse vectors.
|
|
327
|
+
/// both vectors must be sorted in ascending order.
|
|
328
|
+
fn intersect(a: &[Self], b: &[Self]) -> Option<Distance>;
|
|
329
|
+
}
|
|
330
|
+
|
|
298
331
|
impl BinarySimilarity for u8 {
|
|
299
332
|
fn hamming(a: &[Self], b: &[Self]) -> Option<Distance> {
|
|
300
333
|
if a.len() != b.len() {
|
|
@@ -347,6 +380,38 @@ impl SpatialSimilarity for i8 {
|
|
|
347
380
|
unsafe { simsimd_l2sq_i8(a.as_ptr(), b.as_ptr(), a.len(), distance_ptr) };
|
|
348
381
|
Some(distance_value)
|
|
349
382
|
}
|
|
383
|
+
|
|
384
|
+
fn l2(a: &[Self], b: &[Self]) -> Option<Distance> {
|
|
385
|
+
if a.len() != b.len() {
|
|
386
|
+
return None;
|
|
387
|
+
}
|
|
388
|
+
let mut distance_value: Distance = 0.0;
|
|
389
|
+
let distance_ptr: *mut Distance = &mut distance_value as *mut Distance;
|
|
390
|
+
unsafe { simsimd_l2_i8(a.as_ptr(), b.as_ptr(), a.len(), distance_ptr) };
|
|
391
|
+
Some(distance_value)
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
impl Sparse for u16 {
|
|
396
|
+
|
|
397
|
+
fn intersect(a: &[Self], b: &[Self]) -> Option<Distance> {
|
|
398
|
+
let mut distance_value: Distance = 0.0;
|
|
399
|
+
let distance_ptr: *mut Distance = &mut distance_value as *mut Distance;
|
|
400
|
+
unsafe { simsimd_intersect_u16(a.as_ptr(), b.as_ptr(), a.len(), b.len(), distance_ptr) };
|
|
401
|
+
Some(distance_value)
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
impl Sparse for u32 {
|
|
407
|
+
|
|
408
|
+
fn intersect(a: &[Self], b: &[Self]) -> Option<Distance> {
|
|
409
|
+
let mut distance_value: Distance = 0.0;
|
|
410
|
+
let distance_ptr: *mut Distance = &mut distance_value as *mut Distance;
|
|
411
|
+
unsafe { simsimd_intersect_u32(a.as_ptr(), b.as_ptr(), a.len(), b.len(), distance_ptr) };
|
|
412
|
+
Some(distance_value)
|
|
413
|
+
}
|
|
414
|
+
|
|
350
415
|
}
|
|
351
416
|
|
|
352
417
|
impl SpatialSimilarity for f16 {
|
|
@@ -391,6 +456,20 @@ impl SpatialSimilarity for f16 {
|
|
|
391
456
|
unsafe { simsimd_l2sq_f16(a_ptr, b_ptr, a.len(), distance_ptr) };
|
|
392
457
|
Some(distance_value)
|
|
393
458
|
}
|
|
459
|
+
|
|
460
|
+
fn l2(a: &[Self], b: &[Self]) -> Option<Distance> {
|
|
461
|
+
|
|
462
|
+
if a.len() != b.len() {
|
|
463
|
+
return None;
|
|
464
|
+
}
|
|
465
|
+
// Explicitly cast `*const f16` to `*const u16`
|
|
466
|
+
let a_ptr = a.as_ptr() as *const u16;
|
|
467
|
+
let b_ptr = b.as_ptr() as *const u16;
|
|
468
|
+
let mut distance_value: Distance = 0.0;
|
|
469
|
+
let distance_ptr: *mut Distance = &mut distance_value as *mut Distance;
|
|
470
|
+
unsafe { simsimd_l2_f16(a_ptr, b_ptr, a.len(), distance_ptr) };
|
|
471
|
+
Some(distance_value)
|
|
472
|
+
}
|
|
394
473
|
}
|
|
395
474
|
|
|
396
475
|
impl SpatialSimilarity for bf16 {
|
|
@@ -435,6 +514,19 @@ impl SpatialSimilarity for bf16 {
|
|
|
435
514
|
unsafe { simsimd_l2sq_bf16(a_ptr, b_ptr, a.len(), distance_ptr) };
|
|
436
515
|
Some(distance_value)
|
|
437
516
|
}
|
|
517
|
+
|
|
518
|
+
fn l2(a: &[Self], b: &[Self]) -> Option<Distance> {
|
|
519
|
+
if a.len() != b.len() {
|
|
520
|
+
return None;
|
|
521
|
+
}
|
|
522
|
+
// Explicitly cast `*const bf16` to `*const u16`
|
|
523
|
+
let a_ptr = a.as_ptr() as *const u16;
|
|
524
|
+
let b_ptr = b.as_ptr() as *const u16;
|
|
525
|
+
let mut distance_value: Distance = 0.0;
|
|
526
|
+
let distance_ptr: *mut Distance = &mut distance_value as *mut Distance;
|
|
527
|
+
unsafe { simsimd_l2sq_bf16(a_ptr, b_ptr, a.len(), distance_ptr) };
|
|
528
|
+
Some(distance_value)
|
|
529
|
+
}
|
|
438
530
|
}
|
|
439
531
|
|
|
440
532
|
impl SpatialSimilarity for f32 {
|
|
@@ -467,6 +559,16 @@ impl SpatialSimilarity for f32 {
|
|
|
467
559
|
unsafe { simsimd_l2sq_f32(a.as_ptr(), b.as_ptr(), a.len(), distance_ptr) };
|
|
468
560
|
Some(distance_value)
|
|
469
561
|
}
|
|
562
|
+
|
|
563
|
+
fn l2(a: &[Self], b: &[Self]) -> Option<Distance> {
|
|
564
|
+
if a.len() != b.len() {
|
|
565
|
+
return None;
|
|
566
|
+
}
|
|
567
|
+
let mut distance_value: Distance = 0.0;
|
|
568
|
+
let distance_ptr: *mut Distance = &mut distance_value as *mut Distance;
|
|
569
|
+
unsafe { simsimd_l2_f32(a.as_ptr(), b.as_ptr(), a.len(), distance_ptr) };
|
|
570
|
+
Some(distance_value)
|
|
571
|
+
}
|
|
470
572
|
}
|
|
471
573
|
|
|
472
574
|
impl SpatialSimilarity for f64 {
|
|
@@ -499,6 +601,16 @@ impl SpatialSimilarity for f64 {
|
|
|
499
601
|
unsafe { simsimd_l2sq_f64(a.as_ptr(), b.as_ptr(), a.len(), distance_ptr) };
|
|
500
602
|
Some(distance_value)
|
|
501
603
|
}
|
|
604
|
+
|
|
605
|
+
fn l2(a: &[Self], b: &[Self]) -> Option<Distance> {
|
|
606
|
+
if a.len() != b.len() {
|
|
607
|
+
return None;
|
|
608
|
+
}
|
|
609
|
+
let mut distance_value: Distance = 0.0;
|
|
610
|
+
let distance_ptr: *mut Distance = &mut distance_value as *mut Distance;
|
|
611
|
+
unsafe { simsimd_l2_f64(a.as_ptr(), b.as_ptr(), a.len(), distance_ptr) };
|
|
612
|
+
Some(distance_value)
|
|
613
|
+
}
|
|
502
614
|
}
|
|
503
615
|
|
|
504
616
|
impl ProbabilitySimilarity for f16 {
|
|
@@ -850,6 +962,60 @@ mod tests {
|
|
|
850
962
|
}
|
|
851
963
|
}
|
|
852
964
|
|
|
965
|
+
#[test]
|
|
966
|
+
fn test_l2_f32() {
|
|
967
|
+
let a: &[f32; 3] = &[1.0, 2.0, 3.0];
|
|
968
|
+
let b: &[f32; 3] = &[4.0, 5.0, 6.0];
|
|
969
|
+
if let Some(result) = SpatialSimilarity::euclidean(a, b) {
|
|
970
|
+
println!("The result of l2_f32 is {:.8}", result);
|
|
971
|
+
assert_almost_equal(5.2, result, 0.01);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
#[test]
|
|
976
|
+
fn test_l2_f64() {
|
|
977
|
+
let a: &[f64; 3] = &[1.0, 2.0, 3.0];
|
|
978
|
+
let b: &[f64; 3] = &[4.0, 5.0, 6.0];
|
|
979
|
+
if let Some(result) = SpatialSimilarity::euclidean(a, b) {
|
|
980
|
+
println!("The result of l2_f64 is {:.8}", result);
|
|
981
|
+
assert_almost_equal(5.2, result, 0.01);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
#[test]
|
|
986
|
+
fn test_l2_f16() {
|
|
987
|
+
let a_half: Vec<HalfF16> = vec![1.0, 2.0, 3.0]
|
|
988
|
+
.iter()
|
|
989
|
+
.map(|&x| HalfF16::from_f32(x))
|
|
990
|
+
.collect();
|
|
991
|
+
let b_half: Vec<HalfF16> = vec![4.0, 5.0, 6.0]
|
|
992
|
+
.iter()
|
|
993
|
+
.map(|&x| HalfF16::from_f32(x))
|
|
994
|
+
.collect();
|
|
995
|
+
|
|
996
|
+
|
|
997
|
+
let a_simsimd: &[f16] =
|
|
998
|
+
unsafe { std::slice::from_raw_parts(a_half.as_ptr() as *const f16, a_half.len()) };
|
|
999
|
+
let b_simsimd: &[f16] =
|
|
1000
|
+
unsafe { std::slice::from_raw_parts(b_half.as_ptr() as *const f16, b_half.len()) };
|
|
1001
|
+
|
|
1002
|
+
if let Some(result) = SpatialSimilarity::euclidean(&a_simsimd, &b_simsimd) {
|
|
1003
|
+
println!("The result of l2_f16 is {:.8}", result);
|
|
1004
|
+
assert_almost_equal(5.2, result, 0.01);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
#[test]
|
|
1010
|
+
fn test_l2_i8() {
|
|
1011
|
+
let a = &[1, 2, 3];
|
|
1012
|
+
let b = &[4, 5, 6];
|
|
1013
|
+
|
|
1014
|
+
if let Some(result) = SpatialSimilarity::euclidean(a, b) {
|
|
1015
|
+
println!("The result of l2_i8 is {:.8}", result);
|
|
1016
|
+
assert_almost_equal(5.2, result, 0.01);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
853
1019
|
// Adding new tests for bit-level distances
|
|
854
1020
|
#[test]
|
|
855
1021
|
fn test_hamming_u8() {
|
|
@@ -877,19 +1043,19 @@ mod tests {
|
|
|
877
1043
|
// Adding new tests for probability similarities
|
|
878
1044
|
#[test]
|
|
879
1045
|
fn test_js_f32() {
|
|
880
|
-
let a = &[0.1, 0.9, 0.0];
|
|
881
|
-
let b = &[0.2, 0.8, 0.0];
|
|
1046
|
+
let a: &[f32; 3] = &[0.1, 0.9, 0.0];
|
|
1047
|
+
let b: &[f32; 3] = &[0.2, 0.8, 0.0];
|
|
882
1048
|
|
|
883
1049
|
if let Some(result) = ProbabilitySimilarity::jensenshannon(a, b) {
|
|
884
1050
|
println!("The result of js_f32 is {:.8}", result);
|
|
885
|
-
assert_almost_equal(0.
|
|
1051
|
+
assert_almost_equal(0.099, result, 0.01); // Example value
|
|
886
1052
|
}
|
|
887
1053
|
}
|
|
888
1054
|
|
|
889
1055
|
#[test]
|
|
890
1056
|
fn test_kl_f32() {
|
|
891
|
-
let a = &[0.1, 0.9, 0.0];
|
|
892
|
-
let b = &[0.2, 0.8, 0.0];
|
|
1057
|
+
let a: &[f32; 3] = &[0.1, 0.9, 0.0];
|
|
1058
|
+
let b: &[f32; 3] = &[0.2, 0.8, 0.0];
|
|
893
1059
|
|
|
894
1060
|
if let Some(result) = ProbabilitySimilarity::kullbackleibler(a, b) {
|
|
895
1061
|
println!("The result of kl_f32 is {:.8}", result);
|
|
@@ -990,4 +1156,51 @@ mod tests {
|
|
|
990
1156
|
assert_almost_equal(0.025, result, 0.01);
|
|
991
1157
|
}
|
|
992
1158
|
}
|
|
1159
|
+
|
|
1160
|
+
#[test]
|
|
1161
|
+
fn test_intersect_u16() {
|
|
1162
|
+
{
|
|
1163
|
+
let a_u16: &[u16] = &[153, 16384, 17408];
|
|
1164
|
+
let b_u16: &[u16] = &[15360, 16384, 7408];
|
|
1165
|
+
|
|
1166
|
+
if let Some(result) = Sparse::intersect(a_u16, b_u16) {
|
|
1167
|
+
println!("The result of intersect_u16 is {:.8}", result);
|
|
1168
|
+
assert_almost_equal(1.0, result, 0.0001);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
{
|
|
1173
|
+
let a_u16: &[u16] = &[153, 11638, 08];
|
|
1174
|
+
let b_u16: &[u16] = &[15360, 16384, 7408];
|
|
1175
|
+
|
|
1176
|
+
if let Some(result) = Sparse::intersect(a_u16, b_u16) {
|
|
1177
|
+
println!("The result of intersect_u16 is {:.8}", result);
|
|
1178
|
+
assert_almost_equal(0.0, result, 0.0001);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
#[test]
|
|
1184
|
+
fn test_intersect_u32() {
|
|
1185
|
+
{
|
|
1186
|
+
let a_u32: &[u32] = &[11, 153];
|
|
1187
|
+
let b_u32: &[u32] = &[11, 153, 7408, 16384];
|
|
1188
|
+
|
|
1189
|
+
if let Some(result) = Sparse::intersect(a_u32, b_u32) {
|
|
1190
|
+
println!("The result of intersect_u32 is {:.8}", result);
|
|
1191
|
+
assert_almost_equal(2.0, result, 0.0001);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
{
|
|
1196
|
+
let a_u32: &[u32] = &[153, 7408, 11638];
|
|
1197
|
+
let b_u32: &[u32] = &[153, 7408, 11638];
|
|
1198
|
+
|
|
1199
|
+
if let Some(result) = Sparse::intersect(a_u32, b_u32) {
|
|
1200
|
+
println!("The result of intersect_u32 is {:.8}", result);
|
|
1201
|
+
assert_almost_equal(3.0, result, 0.0001);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
}
|
|
993
1206
|
}
|