@@ -77,6 +77,34 @@ def clean_zeros(a, b, M):
7777 return a2 , b2 , M2
7878
7979
80+ def euclidean_distances (X , Y , squared = False ):
81+ """
82+ Considering the rows of X (and Y=X) as vectors, compute the
83+ distance matrix between each pair of vectors.
84+ Parameters
85+ ----------
86+ X : {array-like}, shape (n_samples_1, n_features)
87+ Y : {array-like}, shape (n_samples_2, n_features)
88+ squared : boolean, optional
89+ Return squared Euclidean distances.
90+ Returns
91+ -------
92+ distances : {array}, shape (n_samples_1, n_samples_2)
93+ """
94+ XX = np .einsum ('ij,ij->i' , X , X )[:, np .newaxis ]
95+ YY = np .einsum ('ij,ij->i' , Y , Y )[np .newaxis , :]
96+ distances = np .dot (X , Y .T )
97+ distances *= - 2
98+ distances += XX
99+ distances += YY
100+ np .maximum (distances , 0 , out = distances )
101+ if X is Y :
102+ # Ensure that distances between vectors and themselves are set to 0.0.
103+ # This may not be the case due to floating point rounding errors.
104+ distances .flat [::distances .shape [0 ] + 1 ] = 0.0
105+ return distances if squared else np .sqrt (distances , out = distances )
106+
107+
80108def dist (x1 , x2 = None , metric = 'sqeuclidean' ):
81109 """Compute distance between samples in x1 and x2 using function scipy.spatial.distance.cdist
82110
@@ -104,7 +132,8 @@ def dist(x1, x2=None, metric='sqeuclidean'):
104132 """
105133 if x2 is None :
106134 x2 = x1
107-
135+ if metric == "sqeuclidean" :
136+ return euclidean_distances (x1 , x2 , squared = True )
108137 return cdist (x1 , x2 , metric = metric )
109138
110139
0 commit comments