1#!python 2#cython: boundscheck=False 3#cython: wraparound=False 4#cython: cdivision=True 5 6import cython 7cimport cython 8 9import numpy as np 10cimport numpy as np 11 12from libc.math cimport fabs, sqrt, exp, cos, pow 13 14ctypedef np.double_t DTYPE_t 15ctypedef np.intp_t ITYPE_t 16 17cdef enum: 18 DTYPECODE = np.NPY_FLOAT64 19 ITYPECODE = np.NPY_INTP 20 21# Fused type for certain operations 22ctypedef fused DITYPE_t: 23 ITYPE_t 24 DTYPE_t 25 26ITYPE = np.intp 27 28DTYPE = np.double 29 30###################################################################### 31# Inline distance functions 32# 33# We use these for the default (euclidean) case so that they can be 34# inlined. This leads to faster computation for the most common case 35cdef inline DTYPE_t euclidean_dist(DTYPE_t* x1, DTYPE_t* x2, 36 ITYPE_t size) nogil except -1: 37 cdef DTYPE_t tmp, d=0 38 cdef np.intp_t j 39 for j in range(size): 40 tmp = x1[j] - x2[j] 41 d += tmp * tmp 42 return sqrt(d) 43 44 45cdef inline DTYPE_t euclidean_rdist(DTYPE_t* x1, DTYPE_t* x2, 46 ITYPE_t size) nogil except -1: 47 cdef DTYPE_t tmp, d=0 48 cdef np.intp_t j 49 for j in range(size): 50 tmp = x1[j] - x2[j] 51 d += tmp * tmp 52 return d 53 54 55cdef inline DTYPE_t euclidean_dist_to_rdist(DTYPE_t dist) nogil except -1: 56 return dist * dist 57 58 59cdef inline DTYPE_t euclidean_rdist_to_dist(DTYPE_t dist) except -1: 60 return sqrt(dist) 61 62 63###################################################################### 64# DistanceMetric base class 65cdef class DistanceMetric: 66 # The following attributes are required for a few of the subclasses. 67 # we must define them here so that cython's limited polymorphism will work. 68 # Because we don't expect to instantiate a lot of these objects, the 69 # extra memory overhead of this setup should not be an issue. 70 cdef DTYPE_t p 71 #cdef DTYPE_t[::1] vec 72 #cdef DTYPE_t[:, ::1] mat 73 cdef np.ndarray vec 74 cdef np.ndarray mat 75 cdef DTYPE_t* vec_ptr 76 cdef DTYPE_t* mat_ptr 77 cdef ITYPE_t size 78 cdef object func 79 cdef object kwargs 80 81 cdef DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, 82 ITYPE_t size) nogil except -1 83 84 cdef DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2, 85 ITYPE_t size) nogil except -1 86 87 cdef int pdist(self, DTYPE_t[:, ::1] X, DTYPE_t[:, ::1] D) except -1 88 89 cdef int cdist(self, DTYPE_t[:, ::1] X, DTYPE_t[:, ::1] Y, 90 DTYPE_t[:, ::1] D) except -1 91 92 cdef DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) except -1 93 94 cdef DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1 95