18
18
'manhattan' : 1 ,
19
19
'max_dist' : np .inf
20
20
},
21
+ 'scipy-ckdtree' : {
22
+ 'euclidean' : 2 ,
23
+ 'manhattan' : 1 ,
24
+ 'max_dist' : np .inf
25
+ },
21
26
'scipy-pdist' : {
22
27
'euclidean' : 'euclidean' ,
23
28
'manhattan' : 'cityblock' ,
@@ -44,6 +49,13 @@ def _knn_sp_kdtree(X, num_neighbors, dist_type, order=0):
44
49
p = _dist_translation ['scipy-kdtree' ][dist_type ])
45
50
return NN , D
46
51
52
+ def _knn_sp_ckdtree (X , num_neighbors , dist_type , order = 0 ):
53
+ kdt = sps .cKDTree (X )
54
+ D , NN = kdt .query (X , k = (num_neighbors + 1 ),
55
+ p = _dist_translation ['scipy-ckdtree' ][dist_type ])
56
+ return NN , D
57
+
58
+
47
59
def _knn_flann (X , num_neighbors , dist_type , order ):
48
60
# the combination FLANN + max_dist produces incorrect results
49
61
# do not allow it
@@ -66,9 +78,27 @@ def _knn_flann(X, num_neighbors, dist_type, order):
66
78
def _radius_sp_kdtree (X , epsilon , dist_type , order = 0 ):
67
79
kdt = sps .KDTree (X )
68
80
D , NN = kdt .query (X , k = None , distance_upper_bound = epsilon ,
69
- p = _dist_translation ['scipy-kdtree' ][dist_type ])
81
+ p = _dist_translation ['scipy-kdtree' ][dist_type ])
70
82
return NN , D
71
83
84
+ def _radius_sp_ckdtree (X , epsilon , dist_type , order = 0 ):
85
+ N , dim = np .shape (X )
86
+ kdt = sps .cKDTree (X )
87
+ nn = kdt .query_ball_point (X , r = epsilon ,
88
+ p = _dist_translation ['scipy-ckdtree' ][dist_type ])
89
+ D = []
90
+ NN = []
91
+ for k in range (N ):
92
+ x = np .matlib .repmat (X [k , :], len (nn [k ]), 1 )
93
+ d = np .linalg .norm (x - X [nn [k ], :],
94
+ ord = _dist_translation ['scipy-ckdtree' ][dist_type ],
95
+ axis = 1 )
96
+ nidx = d .argsort ()
97
+ NN .append (np .take (nn [k ], nidx ))
98
+ D .append (np .sort (d ))
99
+ return NN , D
100
+
101
+
72
102
def _knn_sp_pdist (X , num_neighbors , dist_type , order ):
73
103
pd = sps .distance .squareform (
74
104
sps .distance .pdist (X ,
@@ -142,7 +172,8 @@ class NNGraph(Graph):
142
172
is 'knn').
143
173
backend : {'scipy-kdtree', 'scipy-pdist', 'flann'}
144
174
Type of the backend for graph construction.
145
- - 'scipy-kdtree'(default) will use scipy.spatial.KDTree
175
+ - 'scipy-kdtree' will use scipy.spatial.KDTree
176
+ - 'scipy-ckdtree'(default) will use scipy.spatial.cKDTree
146
177
- 'scipy-pdist' will use scipy.spatial.distance.pdist (slowest but exact)
147
178
- 'flann' use Fast Library for Approximate Nearest Neighbors (FLANN)
148
179
center : bool, optional
@@ -183,7 +214,7 @@ class NNGraph(Graph):
183
214
184
215
"""
185
216
186
- def __init__ (self , Xin , NNtype = 'knn' , backend = 'scipy-kdtree ' , center = True ,
217
+ def __init__ (self , Xin , NNtype = 'knn' , backend = 'scipy-ckdtree ' , center = True ,
187
218
rescale = True , k = 10 , sigma = 0.1 , epsilon = 0.01 , gtype = None ,
188
219
plotting = {}, symmetrize_type = 'average' , dist_type = 'euclidean' ,
189
220
order = 0 , ** kwargs ):
@@ -197,15 +228,18 @@ def __init__(self, Xin, NNtype='knn', backend='scipy-kdtree', center=True,
197
228
self .sigma = sigma
198
229
self .epsilon = epsilon
199
230
_dist_translation ['scipy-kdtree' ]['minkowski' ] = order
231
+ _dist_translation ['scipy-ckdtree' ]['minkowski' ] = order
200
232
201
233
self ._nn_functions = {
202
234
'knn' : {
203
235
'scipy-kdtree' : _knn_sp_kdtree ,
236
+ 'scipy-ckdtree' : _knn_sp_ckdtree ,
204
237
'scipy-pdist' : _knn_sp_pdist ,
205
238
'flann' : _knn_flann
206
239
},
207
240
'radius' : {
208
241
'scipy-kdtree' : _radius_sp_kdtree ,
242
+ 'scipy-ckdtree' : _radius_sp_ckdtree ,
209
243
'scipy-pdist' : _radius_sp_pdist ,
210
244
'flann' : _radius_flann
211
245
},
0 commit comments