Skip to content
This repository was archived by the owner on Sep 9, 2026. It is now read-only.

Commit e410061

Browse files
author
anna-charlotte
committed
fix: euclidean dist
Signed-off-by: anna-charlotte <[email protected]>
1 parent 82dad92 commit e410061

2 files changed

Lines changed: 74 additions & 8 deletions

File tree

docarray/computation/tensorflow_backend.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,10 @@ def cosine_sim(
205205

206206
@staticmethod
207207
def euclidean_dist(
208-
x_mat: 'tf.Tensor',
209-
y_mat: 'tf.Tensor',
208+
x_mat: 'TensorFlowTensor',
209+
y_mat: 'TensorFlowTensor',
210210
device: Optional[str] = None,
211-
) -> 'tf.Tensor':
211+
) -> 'TensorFlowTensor':
212212
"""Pairwise Euclidian distances between all vectors in x_mat and y_mat.
213213
214214
:param x_mat: tensor of shape (n_vectors, n_dim), where n_vectors is the
@@ -222,14 +222,25 @@ def euclidean_dist(
222222
The index [i_x, i_y] contains the euclidian distance between
223223
x_mat[i_x] and y_mat[i_y].
224224
"""
225-
...
225+
x_mat: tf.Tensor = TensorFlowCompBackend._norm_right(x_mat)
226+
y_mat: tf.Tensor = TensorFlowCompBackend._norm_right(y_mat)
227+
228+
with tf.device(device):
229+
x_mat, y_mat = _unsqueeze_if_single_axis(x_mat, y_mat)
230+
231+
dists = tf.squeeze(
232+
tf.norm(tf.subtract(x_mat, y_mat), axis=-1, ord='euclidean')
233+
)
234+
dists = _unsqueeze_if_scalar(dists)
235+
236+
return TensorFlowCompBackend._norm_left(dists)
226237

227238
@staticmethod
228239
def sqeuclidean_dist(
229-
x_mat: 'tf.Tensor',
230-
y_mat: 'tf.Tensor',
240+
x_mat: 'TensorFlowTensor',
241+
y_mat: 'TensorFlowTensor',
231242
device: Optional[str] = None,
232-
) -> 'tf.Tensor':
243+
) -> 'TensorFlowTensor':
233244
"""Pairwise Squared Euclidian distances between all vectors
234245
in x_mat and y_mat.
235246
@@ -246,4 +257,9 @@ def sqeuclidean_dist(
246257
The index [i_x, i_y] contains the euclidian distance between
247258
x_mat[i_x] and y_mat[i_y].
248259
"""
249-
...
260+
dists = TensorFlowCompBackend.Metrics.euclidean_dist(x_mat, y_mat)
261+
squared: tf.Tensor = tf.math.square(
262+
TensorFlowCompBackend._norm_right(dists)
263+
)
264+
265+
return TensorFlowCompBackend._norm_left(squared)

tests/units/computation_backends/tensorflow_backend/test_metrics.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,53 @@ def test_cosine_sim_tf():
1919
assert metrics.cosine_sim(b, a).tensor.shape == (5, 10)
2020
diag_dists = tf.linalg.diag(metrics.cosine_sim(b, b).tensor) # self-comparisons
2121
tf.experimental.numpy.allclose(diag_dists, tf.ones(5))
22+
23+
24+
def test_euclidean_dist_tf():
25+
a = TensorFlowTensor(tf.random.normal((128,)))
26+
b = TensorFlowTensor(tf.random.normal((128,)))
27+
assert metrics.euclidean_dist(a, b).tensor.shape == (1,)
28+
assert metrics.euclidean_dist(a, b).tensor == metrics.euclidean_dist(b, a).tensor
29+
tf.experimental.numpy.allclose(metrics.euclidean_dist(a, a).tensor, tf.zeros(1))
30+
31+
a = TensorFlowTensor(tf.zeros((1, 1)))
32+
b = TensorFlowTensor(tf.ones((4, 1)))
33+
assert metrics.euclidean_dist(a, b).tensor.shape == (4,)
34+
tf.experimental.numpy.allclose(
35+
metrics.euclidean_dist(a, b).tensor, metrics.euclidean_dist(b, a).tensor
36+
)
37+
tf.experimental.numpy.allclose(metrics.euclidean_dist(a, a).tensor, tf.zeros(1))
38+
39+
a = TensorFlowTensor(tf.constant([0.0, 2.0, 0.0]))
40+
b = TensorFlowTensor(tf.constant([0.0, 0.0, 2.0]))
41+
desired_output_singleton: tf.Tensor = tf.math.sqrt(
42+
tf.constant([2.0**2.0 + 2.0**2.0])
43+
)
44+
tf.experimental.numpy.allclose(
45+
metrics.euclidean_dist(a, b).tensor, desired_output_singleton
46+
)
47+
48+
a = TensorFlowTensor(tf.constant([[0.0, 2.0, 0.0], [0.0, 0.0, 2.0]]))
49+
b = TensorFlowTensor(tf.constant([[0.0, 0.0, 2.0], [0.0, 2.0, 0.0]]))
50+
desired_output_singleton = tf.constant([[2.828427, 0.0], [0.0, 2.828427]])
51+
tf.experimental.numpy.allclose(
52+
metrics.euclidean_dist(a, b).tensor, desired_output_singleton
53+
)
54+
55+
56+
def test_sqeuclidean_dist_torch():
57+
a = TensorFlowTensor(tf.random.normal((128,)))
58+
b = TensorFlowTensor(tf.random.normal((128,)))
59+
assert metrics.sqeuclidean_dist(a, b).tensor.shape == (1,)
60+
tf.experimental.numpy.allclose(
61+
metrics.sqeuclidean_dist(a, b).tensor,
62+
metrics.euclidean_dist(a, b).tensor ** 2,
63+
)
64+
65+
a = TensorFlowTensor(tf.random.normal((1, 1)))
66+
b = TensorFlowTensor(tf.random.normal((4, 1)))
67+
assert metrics.sqeuclidean_dist(b, a).tensor.shape == (4,)
68+
tf.experimental.numpy.allclose(
69+
metrics.sqeuclidean_dist(a, b).tensor,
70+
metrics.euclidean_dist(a, b).tensor ** 2,
71+
)

0 commit comments

Comments
 (0)