Skip to content

Commit

Permalink
MNT Remove fixtures for Numpy 1.3 and 1.4 compatibility (#20323)
Browse files Browse the repository at this point in the history
Co-authored-by: Thomas J. Fan <thomasjpfan@gmail.com>
  • Loading branch information
jjerphan and thomasjpfan committed Jul 22, 2021
1 parent 460c961 commit 03aa496
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 32 deletions.
8 changes: 2 additions & 6 deletions sklearn/neighbors/_dist_metrics.pxd
Expand Up @@ -51,12 +51,8 @@ cdef class DistanceMetric:
# 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 DTYPE_t p
#cdef DTYPE_t[::1] vec
#cdef DTYPE_t[:, ::1] mat
cdef np.ndarray vec
cdef np.ndarray mat
cdef DTYPE_t* vec_ptr
cdef DTYPE_t* mat_ptr
cdef DTYPE_t[::1] vec
cdef DTYPE_t[:, ::1] mat
cdef ITYPE_t size
cdef object func
cdef object kwargs
Expand Down
34 changes: 8 additions & 26 deletions sklearn/neighbors/_dist_metrics.pyx
@@ -1,6 +1,7 @@
#!python
#cython: boundscheck=False
#cython: wraparound=False
#cython: initializedcheck=False
#cython: cdivision=True

# By Jake Vanderplas (2013) <jakevdp@cs.washington.edu>
Expand All @@ -12,17 +13,6 @@ cimport numpy as np
np.import_array() # required in order to use C-API


######################################################################
# Numpy 1.3-1.4 compatibility utilities
cdef DTYPE_t* get_vec_ptr(np.ndarray[DTYPE_t, ndim=1, mode='c'] vec):
return &vec[0]


cdef DTYPE_t* get_mat_ptr(np.ndarray[DTYPE_t, ndim=2, mode='c'] mat):
return &mat[0, 0]
######################################################################


# First, define a function to get an ndarray from a memory bufffer
cdef extern from "arrayobject.h":
object PyArray_SimpleNewFromData(int nd, np.npy_intp* dims,
Expand Down Expand Up @@ -209,8 +199,6 @@ cdef class DistanceMetric:
self.p = 2
self.vec = np.zeros(1, dtype=DTYPE, order='c')
self.mat = np.zeros((1, 1), dtype=DTYPE, order='c')
self.vec_ptr = get_vec_ptr(self.vec)
self.mat_ptr = get_mat_ptr(self.mat)
self.size = 1

def __reduce__(self):
Expand All @@ -224,8 +212,8 @@ cdef class DistanceMetric:
get state for pickling
"""
if self.__class__.__name__ == "PyFuncDistance":
return (float(self.p), self.vec, self.mat, self.func, self.kwargs)
return (float(self.p), self.vec, self.mat)
return (float(self.p), np.asarray(self.vec), np.asarray(self.mat), self.func, self.kwargs)
return (float(self.p), np.asarray(self.vec), np.asarray(self.mat))

def __setstate__(self, state):
"""
Expand All @@ -237,8 +225,6 @@ cdef class DistanceMetric:
if self.__class__.__name__ == "PyFuncDistance":
self.func = state[3]
self.kwargs = state[4]
self.vec_ptr = get_vec_ptr(self.vec)
self.mat_ptr = get_mat_ptr(self.mat)
self.size = self.vec.shape[0]

@classmethod
Expand Down Expand Up @@ -468,7 +454,6 @@ cdef class SEuclideanDistance(DistanceMetric):
"""
def __init__(self, V):
self.vec = np.asarray(V, dtype=DTYPE)
self.vec_ptr = get_vec_ptr(self.vec)
self.size = self.vec.shape[0]
self.p = 2

Expand All @@ -482,7 +467,7 @@ cdef class SEuclideanDistance(DistanceMetric):
cdef np.intp_t j
for j in range(size):
tmp = x1[j] - x2[j]
d += tmp * tmp / self.vec_ptr[j]
d += tmp * tmp / self.vec[j]
return d

cdef inline DTYPE_t dist(self, const DTYPE_t* x1, const DTYPE_t* x2,
Expand Down Expand Up @@ -630,7 +615,6 @@ cdef class WMinkowskiDistance(DistanceMetric):
"For p=inf, use ChebyshevDistance.")
self.p = p
self.vec = np.asarray(w, dtype=DTYPE)
self.vec_ptr = get_vec_ptr(self.vec)
self.size = self.vec.shape[0]

def _validate_data(self, X):
Expand All @@ -643,7 +627,7 @@ cdef class WMinkowskiDistance(DistanceMetric):
cdef DTYPE_t d=0
cdef np.intp_t j
for j in range(size):
d += pow(self.vec_ptr[j] * fabs(x1[j] - x2[j]), self.p)
d += pow(self.vec[j] * fabs(x1[j] - x2[j]), self.p)
return d

cdef inline DTYPE_t dist(self, const DTYPE_t* x1, const DTYPE_t* x2,
Expand Down Expand Up @@ -691,13 +675,11 @@ cdef class MahalanobisDistance(DistanceMetric):
raise ValueError("V/VI must be square")

self.mat = np.asarray(VI, dtype=float, order='C')
self.mat_ptr = get_mat_ptr(self.mat)

self.size = self.mat.shape[0]

# we need vec as a work buffer
self.vec = np.zeros(self.size, dtype=DTYPE)
self.vec_ptr = get_vec_ptr(self.vec)

def _validate_data(self, X):
if X.shape[1] != self.size:
Expand All @@ -710,13 +692,13 @@ cdef class MahalanobisDistance(DistanceMetric):

# compute (x1 - x2).T * VI * (x1 - x2)
for i in range(size):
self.vec_ptr[i] = x1[i] - x2[i]
self.vec[i] = x1[i] - x2[i]

for i in range(size):
tmp = 0
for j in range(size):
tmp += self.mat_ptr[i * size + j] * self.vec_ptr[j]
d += tmp * self.vec_ptr[i]
tmp += self.mat[i, j] * self.vec[j]
d += tmp * self.vec[i]
return d

cdef inline DTYPE_t dist(self, const DTYPE_t* x1, const DTYPE_t* x2,
Expand Down

0 comments on commit 03aa496

Please sign in to comment.