Skip to content

Commit 6262b89

Browse files
committed
Added Manhattan metric
1 parent 33ba8de commit 6262b89

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

src/tdamapper/utils/_metrics.pyx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,22 @@ cpdef inline double chebyshev(double[:] x, double[:] y) nogil:
1111

1212
cpdef inline double euclidean(double[:] x, double[:] y) nogil:
1313
cdef double norm_squared = 0.0
14+
cdef double diff
1415
cdef Py_ssize_t i, n = x.shape[0]
1516
for i in range(n):
16-
norm_squared += pow(fabs(x[i] - y[i]), 2)
17+
diff = x[i] - y[i]
18+
norm_squared += diff * diff
1719
return sqrt(norm_squared)
1820

1921

22+
cpdef inline double manhattan(double[:] x, double[:] y) nogil:
23+
cdef double norm = 0.0
24+
cdef Py_ssize_t i, n = x.shape[0]
25+
for i in range(n):
26+
norm += fabs(x[i] - y[i])
27+
return norm
28+
29+
2030
cpdef inline double minkowski(int p, double[:] x, double[:] y) nogil:
2131
cdef double norm_p = 0.0
2232
cdef Py_ssize_t i, n = x.shape[0]
@@ -33,7 +43,7 @@ cpdef inline double cosine(double[:] x, double[:] y) nogil:
3343
cdef double similarity = 0.0
3444
for i in range(n):
3545
dot_product += x[i] * y[i]
36-
norm_x += pow(x[i], 2)
37-
norm_y += pow(y[i], 2)
46+
norm_x += x[i] * x[i]
47+
norm_y += y[i] * y[i]
3848
similarity = dot_product / sqrt(norm_x * norm_y)
3949
return sqrt(2.0 * (1.0 - similarity))

src/tdamapper/utils/metrics.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121
- Cosine: A distance on unit vectors based on cosine similarity.
2222
"""
2323

24+
import np
2425
import tdamapper.utils._metrics as _metrics
2526

2627

2728
_EUCLIDEAN = 'euclidean'
29+
_MANHATTAN = 'manhattan'
2830
_MINKOWSKI = 'minkowski'
2931
_MINKOWSKI_P = 'p'
3032
_CHEBYSHEV = 'chebyshev'
@@ -40,6 +42,7 @@ def get_supported_metrics():
4042
"""
4143
return [
4244
_EUCLIDEAN,
45+
_MANHATTAN,
4346
_MINKOWSKI,
4447
_CHEBYSHEV,
4548
_COSINE,
@@ -59,6 +62,19 @@ def euclidean():
5962
return _metrics.euclidean
6063

6164

65+
def manhattan():
66+
"""
67+
Return the Manhattan distance function for vectors.
68+
69+
The Manhattan distance is defined as the sum of the absolute differences
70+
between the components of the vectors.
71+
72+
:return: The Manhattan distance function.
73+
:rtype: callable
74+
"""
75+
return _metrics.manhattan
76+
77+
6278
def chebyshev():
6379
"""
6480
Return the Chebyshev distance function for vectors.
@@ -76,16 +92,23 @@ def minkowski(p):
7692
"""
7793
Return the Minkowski distance function for order p on vectors.
7894
79-
The Minkowski distance is a generalization of the Euclidean and
80-
Chebyshev distances. When p = 1, it is equivalent to the Manhattan
81-
distance, and when p = 2, it is equivalent to the Euclidean distance.
95+
The Minkowski distance is a generalization of the Euclidean and Chebyshev
96+
distances. When p = 1, it is equivalent to the Manhattan distance, and
97+
when p = 2, it is equivalent to the Euclidean distance. When p is infinite,
98+
it is equivalent to the Chebyshev distance.
8299
83100
:param p: The order of the Minkowski distance.
84101
:type p: int
85102
86103
:return: The Minkowski distance function.
87104
:rtype: callable
88105
"""
106+
if p == 1:
107+
return manhattan()
108+
elif p == 2:
109+
return euclidean()
110+
elif np.isinf(p):
111+
return chebyshev()
89112
return lambda x, y: _metrics.minkowski(p, x, y)
90113

91114

@@ -131,6 +154,8 @@ def get_metric(metric, **kwargs):
131154
return metric
132155
elif metric == _EUCLIDEAN:
133156
return euclidean()
157+
elif metric == _MANHATTAN:
158+
return manhattan()
134159
elif metric == _MINKOWSKI:
135160
p = kwargs.get(_MINKOWSKI_P, 2)
136161
return minkowski(p)

0 commit comments

Comments
 (0)