add metric option precomputed
@@ -642,17 +642,26 @@ def fuzzy_simplicial_set(X, n_neighbors, random_state,
cols = np.zeros((X.shape[0] * n_neighbors), dtype=np.int64)
vals = np.zeros((X.shape[0] * n_neighbors), dtype=np.float64)
+ if metric == 'precomputed':
+ # Compute indices of n neares neighbors
+ knn_indices = np.argsort(X)[:,:n_neighbors]
+ # Compute the neares neighbor distances
+ # (equivalent to np.sort(X)[:,:n_neighbors])
+ knn_dists = X[np.arange(X.shape[0])[:,None], knn_indices].copy()
+ else:
if callable(metric):
distance_func = metric
elif metric in dist.named_distances:
distance_func = dist.named_distances[metric]
else:
- raise ValueError('Metric is neither callable, nor a recognised string')
+ raise ValueError('Metric is neither callable, ' +
+ 'nor a recognised string')
if metric in ('cosine', 'correlation', 'dice', 'jaccard'):
angular = True
- rng_state = random_state.randint(INT32_MIN, INT32_MAX, 3).astype(np.int64)
+ rng_state = random_state.randint(INT32_MIN, INT32_MAX, 3) \
+ .astype(np.int64)
if scipy.sparse.isspmatrix_csr(X):
if metric in sparse.sparse_named_distances:
@@ -660,10 +669,10 @@ def fuzzy_simplicial_set(X, n_neighbors, random_state,
if metric in sparse.sparse_need_n_features:
metric_kwds['n_features'] = X.shape[1]
else:
- raise ValueError('Metric {} not supported for sparse '
+ raise ValueError('Metric {} not supported for sparse ' +
'data'.format(metric))
- metric_nn_descent = sparse.make_sparse_nn_descent(distance_func,
- tuple(metric_kwds.values()))
+ metric_nn_descent = sparse.make_sparse_nn_descent(
+ distance_func, tuple(metric_kwds.values()))
leaf_array = rptree_leaf_array(X, n_neighbors,
rng_state, n_trees=10,
angular=angular)
