from libc.math cimport sqrt, exp from ..utils._typedefs cimport float64_t, float32_t, int32_t, intp_t cdef class DistanceMetric: pass ###################################################################### # Inline distance functions # # We use these for the default (euclidean) case so that they can be # inlined. This leads to faster computation for the most common case cdef inline float64_t euclidean_dist64( const float64_t* x1, const float64_t* x2, intp_t size, ) except -1 nogil: cdef float64_t tmp, d=0 cdef intp_t j for j in range(size): tmp = (x1[j] - x2[j]) d += tmp * tmp return sqrt(d) cdef inline float64_t euclidean_rdist64( const float64_t* x1, const float64_t* x2, intp_t size, ) except -1 nogil: cdef float64_t tmp, d=0 cdef intp_t j for j in range(size): tmp = (x1[j] - x2[j]) d += tmp * tmp return d cdef inline float64_t euclidean_dist_to_rdist64(const float64_t dist) except -1 nogil: return dist * dist cdef inline float64_t euclidean_rdist_to_dist64(const float64_t dist) except -1 nogil: return sqrt(dist) ###################################################################### # DistanceMetric64 base class cdef class DistanceMetric64(DistanceMetric): # The following attributes are required for a few of the subclasses. # we must define them here so that cython's limited polymorphism will work. # Because we don't expect to instantiate a lot of these objects, the # extra memory overhead of this setup should not be an issue. cdef float64_t p cdef const float64_t[::1] vec cdef const float64_t[:, ::1] mat cdef intp_t size cdef object func cdef object kwargs cdef float64_t dist( self, const float64_t* x1, const float64_t* x2, intp_t size, ) except -1 nogil cdef float64_t rdist( self, const float64_t* x1, const float64_t* x2, intp_t size, ) except -1 nogil cdef float64_t dist_csr( self, const float64_t* x1_data, const int32_t* x1_indices, const float64_t* x2_data, const int32_t* x2_indices, const int32_t x1_start, const int32_t x1_end, const int32_t x2_start, const int32_t x2_end, const intp_t size, ) except -1 nogil cdef float64_t rdist_csr( self, const float64_t* x1_data, const int32_t* x1_indices, const float64_t* x2_data, const int32_t* x2_indices, const int32_t x1_start, const int32_t x1_end, const int32_t x2_start, const int32_t x2_end, const intp_t size, ) except -1 nogil cdef int pdist( self, const float64_t[:, ::1] X, float64_t[:, ::1] D, ) except -1 cdef int cdist( self, const float64_t[:, ::1] X, const float64_t[:, ::1] Y, float64_t[:, ::1] D, ) except -1 cdef int pdist_csr( self, const float64_t* x1_data, const int32_t[::1] x1_indices, const int32_t[::1] x1_indptr, const intp_t size, float64_t[:, ::1] D, ) except -1 nogil cdef int cdist_csr( self, const float64_t* x1_data, const int32_t[::1] x1_indices, const int32_t[::1] x1_indptr, const float64_t* x2_data, const int32_t[::1] x2_indices, const int32_t[::1] x2_indptr, const intp_t size, float64_t[:, ::1] D, ) except -1 nogil cdef float64_t _rdist_to_dist(self, float64_t rdist) except -1 nogil cdef float64_t _dist_to_rdist(self, float64_t dist) except -1 nogil ###################################################################### # Inline distance functions # # We use these for the default (euclidean) case so that they can be # inlined. This leads to faster computation for the most common case cdef inline float64_t euclidean_dist32( const float32_t* x1, const float32_t* x2, intp_t size, ) except -1 nogil: cdef float64_t tmp, d=0 cdef intp_t j for j in range(size): tmp = (x1[j] - x2[j]) d += tmp * tmp return sqrt(d) cdef inline float64_t euclidean_rdist32( const float32_t* x1, const float32_t* x2, intp_t size, ) except -1 nogil: cdef float64_t tmp, d=0 cdef intp_t j for j in range(size): tmp = (x1[j] - x2[j]) d += tmp * tmp return d cdef inline float64_t euclidean_dist_to_rdist32(const float32_t dist) except -1 nogil: return dist * dist cdef inline float64_t euclidean_rdist_to_dist32(const float32_t dist) except -1 nogil: return sqrt(dist) ###################################################################### # DistanceMetric32 base class cdef class DistanceMetric32(DistanceMetric): # The following attributes are required for a few of the subclasses. # we must define them here so that cython's limited polymorphism will work. # Because we don't expect to instantiate a lot of these objects, the # extra memory overhead of this setup should not be an issue. cdef float64_t p cdef const float64_t[::1] vec cdef const float64_t[:, ::1] mat cdef intp_t size cdef object func cdef object kwargs cdef float32_t dist( self, const float32_t* x1, const float32_t* x2, intp_t size, ) except -1 nogil cdef float32_t rdist( self, const float32_t* x1, const float32_t* x2, intp_t size, ) except -1 nogil cdef float32_t dist_csr( self, const float32_t* x1_data, const int32_t* x1_indices, const float32_t* x2_data, const int32_t* x2_indices, const int32_t x1_start, const int32_t x1_end, const int32_t x2_start, const int32_t x2_end, const intp_t size, ) except -1 nogil cdef float32_t rdist_csr( self, const float32_t* x1_data, const int32_t* x1_indices, const float32_t* x2_data, const int32_t* x2_indices, const int32_t x1_start, const int32_t x1_end, const int32_t x2_start, const int32_t x2_end, const intp_t size, ) except -1 nogil cdef int pdist( self, const float32_t[:, ::1] X, float32_t[:, ::1] D, ) except -1 cdef int cdist( self, const float32_t[:, ::1] X, const float32_t[:, ::1] Y, float32_t[:, ::1] D, ) except -1 cdef int pdist_csr( self, const float32_t* x1_data, const int32_t[::1] x1_indices, const int32_t[::1] x1_indptr, const intp_t size, float32_t[:, ::1] D, ) except -1 nogil cdef int cdist_csr( self, const float32_t* x1_data, const int32_t[::1] x1_indices, const int32_t[::1] x1_indptr, const float32_t* x2_data, const int32_t[::1] x2_indices, const int32_t[::1] x2_indptr, const intp_t size, float32_t[:, ::1] D, ) except -1 nogil cdef float32_t _rdist_to_dist(self, float32_t rdist) except -1 nogil cdef float32_t _dist_to_rdist(self, float32_t dist) except -1 nogil