Path: blob/master/python/cython/pairwise1.pyx
2574 views
cimport cython1import numpy as np2from libc.math cimport sqrt34# don't use np.sqrt - the sqrt function from the5# C standard library is much faster67# tricks to improve performance is to turn of some checking that cython does8# wraparound False will not allow for negative slicing9# boundscheck False will not check for IndexError10# http://docs.cython.org/en/latest/src/reference/compilation.html#compiler-directives11@cython.wraparound(False)12@cython.boundscheck(False)13cdef inline double euclidean_distance(double[:] x1, double[:] x2):14cdef int i, N15cdef double tmp, d = 01617# assume x2 has the same shape as x1;18# this could be dangerous!19# and unlike pure numpy, cython's numpy20# does not support broadcasting; thus21# we will have to loop through the vector22# to compute the euclidean distance23N = x1.shape[0]24for i in range(N):25tmp = x1[i] - x2[i]26d += tmp * tmp2728return sqrt(d)293031@cython.wraparound(False)32@cython.boundscheck(False)33def pairwise1(double[:, :] X , metric = 'euclidean'):3435if metric == 'euclidean':36dist_func = euclidean_distance37else:38raise ValueError("unrecognized metric")3940# note that we don't necessarily41# need to assign a value to C variables at declaration time.42cdef double dist43cdef int i, j, n_samples44n_samples = X.shape[0]45cdef double[:, :] D = np.zeros((n_samples, n_samples), dtype = np.float64)4647for i in range(n_samples):48for j in range(i + 1, n_samples):49dist = dist_func(X[i], X[j])50D[i, j] = dist51D[j, i] = dist5253return D54555657