6 """Compute pair-wise squared distance between points in `a` and `b`.
11 An NxM matrix of N samples of dimensionality M.
13 An LxM matrix of L samples of dimensionality M.
18 Returns a matrix of size len(a), len(b) such that eleement (i, j)
19 contains the squared distance between `a[i]` and `b[j]`.
22 a, b = np.asarray(a), np.asarray(b)
23 if len(a) == 0
or len(b) == 0:
24 return np.zeros((len(a), len(b)))
25 a2, b2 = np.square(a).sum(axis=1), np.square(b).sum(axis=1)
26 r2 = -2. * np.dot(a, b.T) + a2[:,
None] + b2[
None, :]
27 r2 = np.clip(r2, 0.,
float(np.inf))
32 """Compute pair-wise cosine distance between points in `a` and `b`.
37 An NxM matrix of N samples of dimensionality M.
39 An LxM matrix of L samples of dimensionality M.
40 data_is_normalized : Optional[bool]
41 If True, assumes rows in a and b are unit length vectors.
42 Otherwise, a and b are explicitly normalized to lenght 1.
47 Returns a matrix of size len(a), len(b) such that eleement (i, j)
48 contains the squared distance between `a[i]` and `b[j]`.
51 if not data_is_normalized:
52 a = np.asarray(a) / np.linalg.norm(a, axis=1, keepdims=
True)
53 b = np.asarray(b) / np.linalg.norm(b, axis=1, keepdims=
True)
54 return 1. - np.dot(a, b.T)
58 """ Helper function for nearest neighbor distance metric (Euclidean).
63 A matrix of N row-vectors (sample points).
65 A matrix of M row-vectors (query points).
70 A vector of length M that contains for each entry in `y` the
71 smallest Euclidean distance to a sample in `x`.
75 return np.maximum(0.0, distances.min(axis=0))
79 """ Helper function for nearest neighbor distance metric (cosine).
84 A matrix of N row-vectors (sample points).
86 A matrix of M row-vectors (query points).
91 A vector of length M that contains for each entry in `y` the
92 smallest cosine distance to a sample in `x`.
96 return distances.min(axis=0)
101 A nearest neighbor distance metric that, for each target, returns
102 the closest distance to any sample that has been observed so far.
107 Either "euclidean" or "cosine".
108 matching_threshold: float
109 The matching threshold. Samples with larger distance are considered an
111 budget : Optional[int]
112 If not None, fix samples per class to at most this number. Removes
113 the oldest samples when the budget is reached.
117 samples : Dict[int -> List[ndarray]]
118 A dictionary that maps from target identities to the list of samples
119 that have been observed so far.
123 def __init__(self, metric, matching_threshold, budget=None):
126 if metric ==
"euclidean":
128 elif metric ==
"cosine":
129 self.
_metric = _nn_cosine_distance
132 "Invalid metric; must be either 'euclidean' or 'cosine'")
138 """Update the distance metric with new data.
143 An NxM matrix of N features of dimensionality M.
145 An integer array of associated target identities.
146 active_targets : List[int]
147 A list of targets that are currently present in the scene.
150 for feature, target
in zip(features, targets):
151 self.
samples.setdefault(target, []).append(feature)
152 if self.
budget is not None:
157 """Compute distance between features and targets.
162 An NxM matrix of N features of dimensionality M.
164 A list of targets to match the given `features` against.
169 Returns a cost matrix of shape len(targets), len(features), where
170 element (i, j) contains the closest squared distance between
171 `targets[i]` and `features[j]`.
174 cost_matrix = np.zeros((len(targets), len(features)))
175 for i, target
in enumerate(targets):