1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! Top-level dispatch over [`iqdb_types::DistanceMetric`].
//!
//! These functions are the runtime equivalent of the type-level
//! [`crate::Distance`] trait: the caller chooses the metric at runtime
//! through the enum tag, the dispatcher routes to the matching metric
//! type. They are the entry points used by the engine and query crates,
//! which do not know the metric at compile time.
use ;
use crate::;
/// Compute the distance for `metric` between `a` and `b`.
///
/// Mismatched or empty inputs surface as [`iqdb_types::IqdbError`].
///
/// [`DistanceMetric`] is `#[non_exhaustive]`. A metric this crate does not
/// implement yet surfaces as [`iqdb_types::IqdbError::InvalidMetric`] rather
/// than a panic, so a newer `iqdb-types` that adds a variant never breaks the
/// dispatcher at runtime.
///
/// # Examples
///
/// ```
/// use iqdb_distance::compute;
/// use iqdb_types::DistanceMetric;
///
/// let a = [0.0_f32, 0.0, 0.0];
/// let b = [3.0_f32, 4.0, 0.0];
/// let d = compute(DistanceMetric::Euclidean, &a, &b)
/// .expect("valid pair");
/// assert!((d - 5.0).abs() < 1e-6);
/// ```
/// Compute distances for `metric` between `query` and each entry in
/// `candidates`, writing into `out`.
///
/// `out.len()` MUST equal `candidates.len()`. The function is
/// allocation-free; the caller owns the output buffer.
///
/// As with [`compute`], a metric outside the implemented set surfaces as
/// [`iqdb_types::IqdbError::InvalidMetric`] (`DistanceMetric` is
/// `#[non_exhaustive]`).
///
/// # Examples
///
/// ```
/// use iqdb_distance::compute_batch;
/// use iqdb_types::DistanceMetric;
///
/// let q = [0.0_f32, 0.0];
/// let cs: [&[f32]; 2] = [&[1.0, 0.0], &[0.0, 2.0]];
/// let mut out = [0.0_f32; 2];
///
/// compute_batch(DistanceMetric::Manhattan, &q, &cs, &mut out)
/// .expect("matching lengths");
/// assert!((out[0] - 1.0).abs() < 1e-6);
/// assert!((out[1] - 2.0).abs() < 1e-6);
/// ```