diff --git a/sklearn/metrics/pairwise.py b/sklearn/metrics/pairwise.py index b053a294329b1..8bae420fd92e1 100644 --- a/sklearn/metrics/pairwise.py +++ b/sklearn/metrics/pairwise.py @@ -33,12 +33,13 @@ # Authors: Alexandre Gramfort # Mathieu Blondel # Robert Layton +# David Warde-Farley # License: BSD Style. import numpy as np from scipy.spatial import distance from scipy.sparse import csr_matrix, issparse -from ..utils import safe_asarray, atleast2d_or_csr, deprecated +from ..utils import safe_asarray, atleast2d_or_csr, deprecated, arrayfuncs from ..utils.extmath import safe_sparse_dot @@ -87,8 +88,25 @@ def check_pairwise_arrays(X, Y): return X, Y +def _check_euclidean_dtypes(X, Y, out): + """ + Checks that X and Y have sensible (floating point) dtypes and that + out array (if passed) has the greater precision dtype. + """ + if X.dtype not in (np.float32, np.float64): + raise ValueError('X must have float32 or float64 dtype') + if Y.dtype not in (np.float32, np.float64): + raise ValueError('Y must have float32 or float64 dtype') + if out is not None: + if out.dtype == np.float32: + if X.dtype == np.float64 or Y.dtype == np.float64: + raise ValueError('out argument must have dtype float64 if ' + 'either X or Y are float64') + + # Distances -def euclidean_distances(X, Y=None, Y_norm_squared=None, squared=False): +def euclidean_distances(X, Y=None, Y_norm_squared=None, squared=False, + out=None): """ Considering the rows of X (and Y=X) as vectors, compute the distance matrix between each pair of vectors. @@ -110,11 +128,17 @@ def euclidean_distances(X, Y=None, Y_norm_squared=None, squared=False): Y: {array-like, sparse matrix}, shape = [n_samples_2, n_features] Y_norm_squared: array-like, shape = [n_samples_2], optional - Pre-computed dot-products of vectors in Y (e.g., `(Y**2).sum(axis=1)`) + Pre-computed dot-products of vectors in Y (e.g., `(Y**2).sum(axis=1)`). + Only used if one or more arguments is sparse. squared: boolean, optional Return squared Euclidean distances. + out : ndarray, shape = [n_samples_1, n_samples_2], optional + Optional pre-allocated output array. Only supported when + both X and Y are dense. Should have a float32 dtype if + and only if X and Y are both float32, otherwise float64. + Returns ------- distances: {array, sparse matrix}, shape = [n_samples_1, n_samples_2] @@ -131,18 +155,37 @@ def euclidean_distances(X, Y=None, Y_norm_squared=None, squared=False): >>> euclidean_distances(X, [[0, 0]]) array([[ 1. ], [ 1.41421356]]) + + Notes + ----- + If both arguments are dense arrays, both arrays should be of the + same dtype in order to avoid unnecessary copies (specifically, + if one argument is float32 and the other is float64, the float32 + argument will be upcast to float64, creating a copy that uses + double the memory). """ # should not need X_norm_squared because if you could precompute that as # well as Y, then you should just pre-compute the output and not even # call this function. X, Y = check_pairwise_arrays(X, Y) + _check_euclidean_dtypes(X, Y, out) + if out is not None: + if issparse(X) or issparse(Y): + raise ValueError('out argument not supported for sparse X or Y') + elif not hasattr(out, '__array__'): + raise ValueError('out argument must be an array') + elif out.shape != (X.shape[0], Y.shape[0]): + raise ValueError('shape mismatch for out argument') if issparse(X): XX = X.multiply(X).sum(axis=1) - else: + elif issparse(Y): XX = np.sum(X * X, axis=1)[:, np.newaxis] + else: + # If both arguments are dense, we use the Cython function. + XX = None if X is Y: # shortcut in the common case euclidean_distances(X, X) - YY = XX.T + YY = XX.T if XX is not None else None elif Y_norm_squared is None: if issparse(Y): # scipy.sparse matrices don't have element-wise scalar @@ -150,28 +193,56 @@ def euclidean_distances(X, Y=None, Y_norm_squared=None, squared=False): YY = Y.copy() if isinstance(Y, csr_matrix) else Y.tocsr() YY.data **= 2 YY = np.asarray(YY.sum(axis=1)).T - else: + elif issparse(X): YY = np.sum(Y ** 2, axis=1)[np.newaxis, :] + else: + YY = XX else: YY = atleast2d_or_csr(Y_norm_squared) if YY.shape != (1, Y.shape[0]): raise ValueError( "Incompatible dimensions for Y and Y_norm_squared") - # TODO: a faster Cython implementation would do the clipping of negative - # values in a single pass over the output matrix. - distances = safe_sparse_dot(X, Y.T, dense_output=True) - distances *= -2 - distances += XX - distances += YY - np.maximum(distances, 0, distances) - - if X is Y: - # Ensure that distances between vectors and themselves are set to 0.0. - # This may not be the case due to floating point rounding errors. - distances.flat[::distances.shape[0] + 1] = 0.0 - - return distances if squared else np.sqrt(distances) + # Do specialized faster things for the dense-dense case. + if not issparse(X) and not issparse(Y): + if X.dtype != Y.dtype: + _X = X.astype(np.float64) if X.dtype == np.float32 else X + _Y = Y.astype(np.float64) if Y.dtype == np.float32 else Y + out_dtype = np.float64 + else: + _X = X + _Y = Y + out_dtype = X.dtype + if out is None: + distances = np.empty((X.shape[0], Y.shape[0]), dtype=out_dtype) + else: + distances = out + if X is Y: + if X.dtype == np.float32: + arrayfuncs.fast_pair_sqdist_float32(_X, distances) + else: + arrayfuncs.fast_pair_sqdist_float64(_X, distances) + else: + if X.dtype == np.float32: + arrayfuncs.fast_sqdist_float32(_X, _Y, distances) + else: + arrayfuncs.fast_sqdist_float64(_X, _Y, distances) + else: + distances = safe_sparse_dot(X, Y.T, dense_output=True) + distances *= -2 + distances += XX + distances += YY + np.maximum(distances, 0, distances) + + if X is Y: + # Ensure that distances between vectors and themselves are set to + # 0.0. This may not be the case due to floating point rounding + # errors. + distances.flat[::distances.shape[0] + 1] = 0.0 + + if not squared: + np.sqrt(distances, distances) + return distances @deprecated("use euclidean_distances instead") diff --git a/sklearn/metrics/tests/test_pairwise.py b/sklearn/metrics/tests/test_pairwise.py index afb1375f8999b..de5e89ea2af40 100644 --- a/sklearn/metrics/tests/test_pairwise.py +++ b/sklearn/metrics/tests/test_pairwise.py @@ -118,11 +118,52 @@ def callable_rbf_kernel(x, y, **kwds): def test_euclidean_distances(): """ Check the pairwise Euclidean distances computation""" - X = [[0]] - Y = [[1], [2]] + X = np.array([[0.]]) + Y = np.array([[1.], [2.]]) D = euclidean_distances(X, Y) assert_array_almost_equal(D, [[1., 2.]]) + D = euclidean_distances(X.astype(np.float32), Y.astype(np.float32)) + assert_array_almost_equal(D, [[1., 2.]]) + + D = euclidean_distances(X.astype(np.float64), Y.astype(np.float32)) + assert_array_almost_equal(D, [[1., 2.]]) + + D = euclidean_distances(X, X) + assert_array_almost_equal(D, [[0.]]) + + D = euclidean_distances(Y, Y) + assert_array_almost_equal(D, [[0, 1], [1, 0]]) + + # Tests with output arguments. + out = np.empty((1, 2), dtype=np.float32) + D = euclidean_distances(X.astype(np.float32), Y.astype(np.float32), + out=out) + assert D is out + assert_array_almost_equal(D, [[1., 2.]]) + + out = np.empty((1, 2), dtype=np.float64) + D = euclidean_distances(X.astype(np.float64), Y.astype(np.float32), + out=out) + assert D is out + assert_array_almost_equal(D, [[1., 2.]]) + + out = np.empty((1, 1), dtype=np.float64) + D = euclidean_distances(X, X, out=out) + assert D is out + assert_array_almost_equal(D, [[0.]]) + + out = np.empty((2, 2), dtype=np.float64) + D = euclidean_distances(Y, Y, out=out) + assert D is out + assert_array_almost_equal(D, [[0, 1], [1, 0]]) + + out = np.empty((2, 2), dtype=np.float32) + D = euclidean_distances(Y.astype(np.float32), Y.astype(np.float32), + out=out) + assert D is out + assert_array_almost_equal(D, [[0, 1], [1, 0]]) + X = csr_matrix(X) Y = csr_matrix(Y) D = euclidean_distances(X, Y) diff --git a/sklearn/utils/arrayfuncs.c b/sklearn/utils/arrayfuncs.c index 8c25250823664..d0dc6f06eec5c 100644 --- a/sklearn/utils/arrayfuncs.c +++ b/sklearn/utils/arrayfuncs.c @@ -1,4 +1,4 @@ -/* Generated by Cython 0.15 on Sat Sep 3 13:08:58 2011 */ +/* Generated by Cython 0.15.1 on Mon Dec 19 18:39:43 2011 */ #define PY_SSIZE_T_CLEAN #include "Python.h" @@ -663,6 +663,32 @@ static void __Pyx_RaiseDoubleKeywordsError( static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name); /*proto*/ +/* Run-time type information about structs used with buffers */ +struct __Pyx_StructField_; + +typedef struct { + const char* name; /* for error messages only */ + struct __Pyx_StructField_* fields; + size_t size; /* sizeof(type) */ + char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject */ +} __Pyx_TypeInfo; + +typedef struct __Pyx_StructField_ { + __Pyx_TypeInfo* type; + const char* name; + size_t offset; +} __Pyx_StructField; + +typedef struct { + __Pyx_StructField* field; + size_t parent_offset; +} __Pyx_BufFmt_StackElem; + + +static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); +#define __Pyx_BufPtrStrided2d(type, buf, i0, s0, i1, s1) (type)((char*)buf + i0 * s0 + i1 * s1) + static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); @@ -672,6 +698,16 @@ static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/ +#if PY_MAJOR_VERSION < 3 +static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); +static void __Pyx_ReleaseBuffer(Py_buffer *view); +#else +#define __Pyx_GetBuffer PyObject_GetBuffer +#define __Pyx_ReleaseBuffer PyBuffer_Release +#endif + +Py_ssize_t __Pyx_zeros[] = {0, 0}; +Py_ssize_t __Pyx_minusones[] = {-1, -1}; static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level); /*proto*/ @@ -687,6 +723,10 @@ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int #define __Pyx_PyString_Equals __Pyx_PyBytes_Equals #endif +static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_Py_intptr_t(Py_intptr_t); + +static CYTHON_INLINE Py_intptr_t __Pyx_PyInt_from_py_Py_intptr_t(PyObject *); + #if CYTHON_CCOMPLEX #ifdef __cplusplus #define __Pyx_CREAL(z) ((z).real()) @@ -863,6 +903,12 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *); / /* Module declarations from 'sklearn.utils.arrayfuncs' */ static float __pyx_f_7sklearn_5utils_10arrayfuncs__float_min_pos(float *, Py_ssize_t); /*proto*/ static double __pyx_f_7sklearn_5utils_10arrayfuncs__double_min_pos(double *, Py_ssize_t); /*proto*/ +static PyObject *__pyx_f_7sklearn_5utils_10arrayfuncs_fast_sqdist_float32(PyArrayObject *, PyArrayObject *, PyArrayObject *, int __pyx_skip_dispatch); /*proto*/ +static PyObject *__pyx_f_7sklearn_5utils_10arrayfuncs_fast_sqdist_float64(PyArrayObject *, PyArrayObject *, PyArrayObject *, int __pyx_skip_dispatch); /*proto*/ +static PyObject *__pyx_f_7sklearn_5utils_10arrayfuncs_fast_pair_sqdist_float32(PyArrayObject *, PyArrayObject *, int __pyx_skip_dispatch); /*proto*/ +static PyObject *__pyx_f_7sklearn_5utils_10arrayfuncs_fast_pair_sqdist_float64(PyArrayObject *, PyArrayObject *, int __pyx_skip_dispatch); /*proto*/ +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t = { "float32_t", NULL, sizeof(__pyx_t_5numpy_float32_t), 'R' }; +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t = { "float64_t", NULL, sizeof(__pyx_t_5numpy_float64_t), 'R' }; #define __Pyx_MODULE_NAME "sklearn.utils.arrayfuncs" int __pyx_module_is_main_sklearn__utils__arrayfuncs = 0; @@ -887,6 +933,7 @@ static char __pyx_k__L[] = "L"; static char __pyx_k__O[] = "O"; static char __pyx_k__Q[] = "Q"; static char __pyx_k__X[] = "X"; +static char __pyx_k__Y[] = "Y"; static char __pyx_k__b[] = "b"; static char __pyx_k__d[] = "d"; static char __pyx_k__f[] = "f"; @@ -900,6 +947,7 @@ static char __pyx_k__Zd[] = "Zd"; static char __pyx_k__Zf[] = "Zf"; static char __pyx_k__Zg[] = "Zg"; static char __pyx_k__np[] = "np"; +static char __pyx_k__out[] = "out"; static char __pyx_k__name[] = "name"; static char __pyx_k__size[] = "size"; static char __pyx_k__dtype[] = "dtype"; @@ -928,6 +976,7 @@ static PyObject *__pyx_n_s__L; static PyObject *__pyx_n_s__RuntimeError; static PyObject *__pyx_n_s__ValueError; static PyObject *__pyx_n_s__X; +static PyObject *__pyx_n_s__Y; static PyObject *__pyx_n_s____main__; static PyObject *__pyx_n_s____test__; static PyObject *__pyx_n_s__cholesky_delete; @@ -939,6 +988,7 @@ static PyObject *__pyx_n_s__min_pos; static PyObject *__pyx_n_s__name; static PyObject *__pyx_n_s__np; static PyObject *__pyx_n_s__numpy; +static PyObject *__pyx_n_s__out; static PyObject *__pyx_n_s__range; static PyObject *__pyx_n_s__size; static PyObject *__pyx_n_s__solve_triangular; @@ -1278,37 +1328,40 @@ static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_1solve_triangular(PyObjec static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__X,&__pyx_n_s__y,0}; __Pyx_RefNannySetupContext("solve_triangular"); __pyx_self = __pyx_self; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); + { PyObject* values[2] = {0,0}; - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 0: - values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__X); - if (likely(values[0])) kw_args--; - else goto __pyx_L5_argtuple_error; - case 1: - values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__y); - if (likely(values[1])) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("solve_triangular", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "solve_triangular") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + kw_args = PyDict_Size(__pyx_kwds); + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 0: + values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__X); + if (likely(values[0])) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__y); + if (likely(values[1])) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("solve_triangular", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "solve_triangular") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); } __pyx_v_X = ((PyArrayObject *)values[0]); __pyx_v_y = ((PyArrayObject *)values[1]); - } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { - goto __pyx_L5_argtuple_error; - } else { - __pyx_v_X = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 0)); - __pyx_v_y = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1)); } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; @@ -1483,37 +1536,40 @@ static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_2cholesky_delete(PyObject static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__L,&__pyx_n_s__go_out,0}; __Pyx_RefNannySetupContext("cholesky_delete"); __pyx_self = __pyx_self; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); + { PyObject* values[2] = {0,0}; - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 0: - values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__L); - if (likely(values[0])) kw_args--; - else goto __pyx_L5_argtuple_error; - case 1: - values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__go_out); - if (likely(values[1])) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("cholesky_delete", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "cholesky_delete") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + kw_args = PyDict_Size(__pyx_kwds); + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 0: + values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__L); + if (likely(values[0])) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__go_out); + if (likely(values[1])) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("cholesky_delete", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "cholesky_delete") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); } __pyx_v_L = ((PyArrayObject *)values[0]); __pyx_v_go_out = __Pyx_PyInt_AsInt(values[1]); if (unlikely((__pyx_v_go_out == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { - goto __pyx_L5_argtuple_error; - } else { - __pyx_v_L = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 0)); - __pyx_v_go_out = __Pyx_PyInt_AsInt(PyTuple_GET_ITEM(__pyx_args, 1)); if (unlikely((__pyx_v_go_out == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; @@ -1610,6 +1666,7 @@ static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_2cholesky_delete(PyObject * m = L.strides[0] / sizeof (float) * float_cholesky_delete (m, n, L.data, go_out) # <<<<<<<<<<<<<< * + * # TODO: fast_sqdist_foo and fast_pair_sqdist_foo should be templated */ float_cholesky_delete(__pyx_v_m, __pyx_v_n, ((float *)__pyx_v_L->data), __pyx_v_go_out); goto __pyx_L6; @@ -1629,6 +1686,1173 @@ static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_2cholesky_delete(PyObject return __pyx_r; } +/* "sklearn/utils/arrayfuncs.pyx":121 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * cpdef fast_sqdist_float32(np.ndarray[np.float32_t, ndim=2] X, # <<<<<<<<<<<<<< + * np.ndarray[np.float32_t, ndim=2] Y, + * np.ndarray[np.float32_t, ndim=2] out): + */ + +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_3fast_sqdist_float32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_f_7sklearn_5utils_10arrayfuncs_fast_sqdist_float32(PyArrayObject *__pyx_v_X, PyArrayObject *__pyx_v_Y, PyArrayObject *__pyx_v_out, int __pyx_skip_dispatch) { + npy_intp __pyx_v_i; + npy_intp __pyx_v_j; + npy_intp __pyx_v_k; + Py_buffer __pyx_bstruct_Y; + Py_ssize_t __pyx_bstride_0_Y = 0; + Py_ssize_t __pyx_bstride_1_Y = 0; + Py_ssize_t __pyx_bshape_0_Y = 0; + Py_ssize_t __pyx_bshape_1_Y = 0; + Py_buffer __pyx_bstruct_X; + Py_ssize_t __pyx_bstride_0_X = 0; + Py_ssize_t __pyx_bstride_1_X = 0; + Py_ssize_t __pyx_bshape_0_X = 0; + Py_ssize_t __pyx_bshape_1_X = 0; + Py_buffer __pyx_bstruct_out; + Py_ssize_t __pyx_bstride_0_out = 0; + Py_ssize_t __pyx_bstride_1_out = 0; + Py_ssize_t __pyx_bshape_0_out = 0; + Py_ssize_t __pyx_bshape_1_out = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + npy_intp __pyx_t_1; + npy_intp __pyx_t_2; + npy_intp __pyx_t_3; + npy_intp __pyx_t_4; + npy_intp __pyx_t_5; + npy_intp __pyx_t_6; + npy_intp __pyx_t_7; + npy_intp __pyx_t_8; + npy_intp __pyx_t_9; + npy_intp __pyx_t_10; + npy_intp __pyx_t_11; + npy_intp __pyx_t_12; + npy_intp __pyx_t_13; + npy_intp __pyx_t_14; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("fast_sqdist_float32"); + __pyx_bstruct_X.buf = NULL; + __pyx_bstruct_Y.buf = NULL; + __pyx_bstruct_out.buf = NULL; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_X = __pyx_bstruct_X.strides[0]; __pyx_bstride_1_X = __pyx_bstruct_X.strides[1]; + __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_Y, (PyObject*)__pyx_v_Y, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_Y = __pyx_bstruct_Y.strides[0]; __pyx_bstride_1_Y = __pyx_bstruct_Y.strides[1]; + __pyx_bshape_0_Y = __pyx_bstruct_Y.shape[0]; __pyx_bshape_1_Y = __pyx_bstruct_Y.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_out, (PyObject*)__pyx_v_out, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_out = __pyx_bstruct_out.strides[0]; __pyx_bstride_1_out = __pyx_bstruct_out.strides[1]; + __pyx_bshape_0_out = __pyx_bstruct_out.shape[0]; __pyx_bshape_1_out = __pyx_bstruct_out.shape[1]; + + /* "sklearn/utils/arrayfuncs.pyx":146 + * """ + * cdef np.npy_intp i, j, k + * for i in range(X.shape[0]): # <<<<<<<<<<<<<< + * for j in range(Y.shape[0]): + * out[i, j] = 0 + */ + __pyx_t_1 = (__pyx_v_X->dimensions[0]); + for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { + __pyx_v_i = __pyx_t_2; + + /* "sklearn/utils/arrayfuncs.pyx":147 + * cdef np.npy_intp i, j, k + * for i in range(X.shape[0]): + * for j in range(Y.shape[0]): # <<<<<<<<<<<<<< + * out[i, j] = 0 + * for k in range(X.shape[1]): + */ + __pyx_t_3 = (__pyx_v_Y->dimensions[0]); + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_j = __pyx_t_4; + + /* "sklearn/utils/arrayfuncs.pyx":148 + * for i in range(X.shape[0]): + * for j in range(Y.shape[0]): + * out[i, j] = 0 # <<<<<<<<<<<<<< + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - Y[j, k]) ** 2 + */ + __pyx_t_5 = __pyx_v_i; + __pyx_t_6 = __pyx_v_j; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_out.buf, __pyx_t_5, __pyx_bstride_0_out, __pyx_t_6, __pyx_bstride_1_out) = 0.0; + + /* "sklearn/utils/arrayfuncs.pyx":149 + * for j in range(Y.shape[0]): + * out[i, j] = 0 + * for k in range(X.shape[1]): # <<<<<<<<<<<<<< + * out[i, j] += (X[i, k] - Y[j, k]) ** 2 + * + */ + __pyx_t_7 = (__pyx_v_X->dimensions[1]); + for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) { + __pyx_v_k = __pyx_t_8; + + /* "sklearn/utils/arrayfuncs.pyx":150 + * out[i, j] = 0 + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - Y[j, k]) ** 2 # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_9 = __pyx_v_i; + __pyx_t_10 = __pyx_v_k; + __pyx_t_11 = __pyx_v_j; + __pyx_t_12 = __pyx_v_k; + __pyx_t_13 = __pyx_v_i; + __pyx_t_14 = __pyx_v_j; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_out.buf, __pyx_t_13, __pyx_bstride_0_out, __pyx_t_14, __pyx_bstride_1_out) += powf(((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_X.buf, __pyx_t_9, __pyx_bstride_0_X, __pyx_t_10, __pyx_bstride_1_X)) - (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_Y.buf, __pyx_t_11, __pyx_bstride_0_Y, __pyx_t_12, __pyx_bstride_1_Y))), 2.0); + } + } + } + + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_Y); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_sqdist_float32", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_Y); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "sklearn/utils/arrayfuncs.pyx":121 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * cpdef fast_sqdist_float32(np.ndarray[np.float32_t, ndim=2] X, # <<<<<<<<<<<<<< + * np.ndarray[np.float32_t, ndim=2] Y, + * np.ndarray[np.float32_t, ndim=2] out): + */ + +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_3fast_sqdist_float32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7sklearn_5utils_10arrayfuncs_3fast_sqdist_float32[] = "\n fast_sqdist_float32(X, Y, out)\n\n Low-level function for computing squared Euclidean distances between\n two sets of points.\n\n Parameters\n ----------\n X : ndarray, float32, shape = [n_samples_a, n_features]\n\n Y : ndarray, float32, shape = [n_sample_b, n_features]\n\n out : ndarray, float32, shape = [n_samples_a, n_samples_b]\n\n Notes\n -----\n In order to achieve maximal speed this function performs no checks of\n any array metadata. Use the high-level functions defined in the\n `sklearn.metrics.distance` module unless you really know what you're\n doing.\n "; +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_3fast_sqdist_float32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_X = 0; + PyArrayObject *__pyx_v_Y = 0; + PyArrayObject *__pyx_v_out = 0; + Py_buffer __pyx_bstruct_Y; + Py_ssize_t __pyx_bstride_0_Y = 0; + Py_ssize_t __pyx_bstride_1_Y = 0; + Py_ssize_t __pyx_bshape_0_Y = 0; + Py_ssize_t __pyx_bshape_1_Y = 0; + Py_buffer __pyx_bstruct_X; + Py_ssize_t __pyx_bstride_0_X = 0; + Py_ssize_t __pyx_bstride_1_X = 0; + Py_ssize_t __pyx_bshape_0_X = 0; + Py_ssize_t __pyx_bshape_1_X = 0; + Py_buffer __pyx_bstruct_out; + Py_ssize_t __pyx_bstride_0_out = 0; + Py_ssize_t __pyx_bstride_1_out = 0; + Py_ssize_t __pyx_bshape_0_out = 0; + Py_ssize_t __pyx_bshape_1_out = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__X,&__pyx_n_s__Y,&__pyx_n_s__out,0}; + __Pyx_RefNannySetupContext("fast_sqdist_float32"); + __pyx_self = __pyx_self; + { + PyObject* values[3] = {0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 0: + values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__X); + if (likely(values[0])) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__Y); + if (likely(values[1])) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("fast_sqdist_float32", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 2: + values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__out); + if (likely(values[2])) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("fast_sqdist_float32", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "fast_sqdist_float32") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + } + __pyx_v_X = ((PyArrayObject *)values[0]); + __pyx_v_Y = ((PyArrayObject *)values[1]); + __pyx_v_out = ((PyArrayObject *)values[2]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("fast_sqdist_float32", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_sqdist_float32", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_bstruct_X.buf = NULL; + __pyx_bstruct_Y.buf = NULL; + __pyx_bstruct_out.buf = NULL; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_X), __pyx_ptype_5numpy_ndarray, 1, "X", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_Y), __pyx_ptype_5numpy_ndarray, 1, "Y", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_out), __pyx_ptype_5numpy_ndarray, 1, "out", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_X = __pyx_bstruct_X.strides[0]; __pyx_bstride_1_X = __pyx_bstruct_X.strides[1]; + __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_Y, (PyObject*)__pyx_v_Y, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_Y = __pyx_bstruct_Y.strides[0]; __pyx_bstride_1_Y = __pyx_bstruct_Y.strides[1]; + __pyx_bshape_0_Y = __pyx_bstruct_Y.shape[0]; __pyx_bshape_1_Y = __pyx_bstruct_Y.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_out, (PyObject*)__pyx_v_out, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_out = __pyx_bstruct_out.strides[0]; __pyx_bstride_1_out = __pyx_bstruct_out.strides[1]; + __pyx_bshape_0_out = __pyx_bstruct_out.shape[0]; __pyx_bshape_1_out = __pyx_bstruct_out.shape[1]; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_f_7sklearn_5utils_10arrayfuncs_fast_sqdist_float32(__pyx_v_X, __pyx_v_Y, __pyx_v_out, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_Y); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_sqdist_float32", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_Y); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "sklearn/utils/arrayfuncs.pyx":155 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * cpdef fast_sqdist_float64(np.ndarray[np.float64_t, ndim=2] X, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=2] Y, + * np.ndarray[np.float64_t, ndim=2] out): + */ + +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_4fast_sqdist_float64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_f_7sklearn_5utils_10arrayfuncs_fast_sqdist_float64(PyArrayObject *__pyx_v_X, PyArrayObject *__pyx_v_Y, PyArrayObject *__pyx_v_out, int __pyx_skip_dispatch) { + npy_intp __pyx_v_i; + npy_intp __pyx_v_j; + npy_intp __pyx_v_k; + Py_buffer __pyx_bstruct_Y; + Py_ssize_t __pyx_bstride_0_Y = 0; + Py_ssize_t __pyx_bstride_1_Y = 0; + Py_ssize_t __pyx_bshape_0_Y = 0; + Py_ssize_t __pyx_bshape_1_Y = 0; + Py_buffer __pyx_bstruct_X; + Py_ssize_t __pyx_bstride_0_X = 0; + Py_ssize_t __pyx_bstride_1_X = 0; + Py_ssize_t __pyx_bshape_0_X = 0; + Py_ssize_t __pyx_bshape_1_X = 0; + Py_buffer __pyx_bstruct_out; + Py_ssize_t __pyx_bstride_0_out = 0; + Py_ssize_t __pyx_bstride_1_out = 0; + Py_ssize_t __pyx_bshape_0_out = 0; + Py_ssize_t __pyx_bshape_1_out = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + npy_intp __pyx_t_1; + npy_intp __pyx_t_2; + npy_intp __pyx_t_3; + npy_intp __pyx_t_4; + npy_intp __pyx_t_5; + npy_intp __pyx_t_6; + npy_intp __pyx_t_7; + npy_intp __pyx_t_8; + npy_intp __pyx_t_9; + npy_intp __pyx_t_10; + npy_intp __pyx_t_11; + npy_intp __pyx_t_12; + npy_intp __pyx_t_13; + npy_intp __pyx_t_14; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("fast_sqdist_float64"); + __pyx_bstruct_X.buf = NULL; + __pyx_bstruct_Y.buf = NULL; + __pyx_bstruct_out.buf = NULL; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_X = __pyx_bstruct_X.strides[0]; __pyx_bstride_1_X = __pyx_bstruct_X.strides[1]; + __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_Y, (PyObject*)__pyx_v_Y, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_Y = __pyx_bstruct_Y.strides[0]; __pyx_bstride_1_Y = __pyx_bstruct_Y.strides[1]; + __pyx_bshape_0_Y = __pyx_bstruct_Y.shape[0]; __pyx_bshape_1_Y = __pyx_bstruct_Y.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_out, (PyObject*)__pyx_v_out, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_out = __pyx_bstruct_out.strides[0]; __pyx_bstride_1_out = __pyx_bstruct_out.strides[1]; + __pyx_bshape_0_out = __pyx_bstruct_out.shape[0]; __pyx_bshape_1_out = __pyx_bstruct_out.shape[1]; + + /* "sklearn/utils/arrayfuncs.pyx":180 + * """ + * cdef np.npy_intp i, j, k + * for i in range(X.shape[0]): # <<<<<<<<<<<<<< + * for j in range(Y.shape[0]): + * out[i, j] = 0 + */ + __pyx_t_1 = (__pyx_v_X->dimensions[0]); + for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { + __pyx_v_i = __pyx_t_2; + + /* "sklearn/utils/arrayfuncs.pyx":181 + * cdef np.npy_intp i, j, k + * for i in range(X.shape[0]): + * for j in range(Y.shape[0]): # <<<<<<<<<<<<<< + * out[i, j] = 0 + * for k in range(X.shape[1]): + */ + __pyx_t_3 = (__pyx_v_Y->dimensions[0]); + for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { + __pyx_v_j = __pyx_t_4; + + /* "sklearn/utils/arrayfuncs.pyx":182 + * for i in range(X.shape[0]): + * for j in range(Y.shape[0]): + * out[i, j] = 0 # <<<<<<<<<<<<<< + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - Y[j, k]) ** 2 + */ + __pyx_t_5 = __pyx_v_i; + __pyx_t_6 = __pyx_v_j; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_out.buf, __pyx_t_5, __pyx_bstride_0_out, __pyx_t_6, __pyx_bstride_1_out) = 0.0; + + /* "sklearn/utils/arrayfuncs.pyx":183 + * for j in range(Y.shape[0]): + * out[i, j] = 0 + * for k in range(X.shape[1]): # <<<<<<<<<<<<<< + * out[i, j] += (X[i, k] - Y[j, k]) ** 2 + * + */ + __pyx_t_7 = (__pyx_v_X->dimensions[1]); + for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) { + __pyx_v_k = __pyx_t_8; + + /* "sklearn/utils/arrayfuncs.pyx":184 + * out[i, j] = 0 + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - Y[j, k]) ** 2 # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_9 = __pyx_v_i; + __pyx_t_10 = __pyx_v_k; + __pyx_t_11 = __pyx_v_j; + __pyx_t_12 = __pyx_v_k; + __pyx_t_13 = __pyx_v_i; + __pyx_t_14 = __pyx_v_j; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_out.buf, __pyx_t_13, __pyx_bstride_0_out, __pyx_t_14, __pyx_bstride_1_out) += pow(((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_X.buf, __pyx_t_9, __pyx_bstride_0_X, __pyx_t_10, __pyx_bstride_1_X)) - (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_Y.buf, __pyx_t_11, __pyx_bstride_0_Y, __pyx_t_12, __pyx_bstride_1_Y))), 2.0); + } + } + } + + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_Y); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_sqdist_float64", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_Y); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "sklearn/utils/arrayfuncs.pyx":155 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * cpdef fast_sqdist_float64(np.ndarray[np.float64_t, ndim=2] X, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=2] Y, + * np.ndarray[np.float64_t, ndim=2] out): + */ + +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_4fast_sqdist_float64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7sklearn_5utils_10arrayfuncs_4fast_sqdist_float64[] = "\n fast_sqdist_float64(X, Y, out)\n\n Low-level function for computing squared Euclidean distances between\n two sets of points.\n\n Parameters\n ----------\n X : ndarray, float64, shape = [n_samples_a, n_features]\n\n Y : ndarray, float64, shape = [n_sample_b, n_features]\n\n out : ndarray, float64, shape = [n_samples_a, n_samples_b]\n\n Notes\n -----\n In order to achieve maximal speed this function performs no checks of\n any array metadata. Use the high-level functions defined in the\n `sklearn.metrics.distance` module unless you really know what you're\n doing.\n "; +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_4fast_sqdist_float64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_X = 0; + PyArrayObject *__pyx_v_Y = 0; + PyArrayObject *__pyx_v_out = 0; + Py_buffer __pyx_bstruct_Y; + Py_ssize_t __pyx_bstride_0_Y = 0; + Py_ssize_t __pyx_bstride_1_Y = 0; + Py_ssize_t __pyx_bshape_0_Y = 0; + Py_ssize_t __pyx_bshape_1_Y = 0; + Py_buffer __pyx_bstruct_X; + Py_ssize_t __pyx_bstride_0_X = 0; + Py_ssize_t __pyx_bstride_1_X = 0; + Py_ssize_t __pyx_bshape_0_X = 0; + Py_ssize_t __pyx_bshape_1_X = 0; + Py_buffer __pyx_bstruct_out; + Py_ssize_t __pyx_bstride_0_out = 0; + Py_ssize_t __pyx_bstride_1_out = 0; + Py_ssize_t __pyx_bshape_0_out = 0; + Py_ssize_t __pyx_bshape_1_out = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__X,&__pyx_n_s__Y,&__pyx_n_s__out,0}; + __Pyx_RefNannySetupContext("fast_sqdist_float64"); + __pyx_self = __pyx_self; + { + PyObject* values[3] = {0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 0: + values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__X); + if (likely(values[0])) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__Y); + if (likely(values[1])) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("fast_sqdist_float64", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 2: + values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__out); + if (likely(values[2])) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("fast_sqdist_float64", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "fast_sqdist_float64") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + } + __pyx_v_X = ((PyArrayObject *)values[0]); + __pyx_v_Y = ((PyArrayObject *)values[1]); + __pyx_v_out = ((PyArrayObject *)values[2]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("fast_sqdist_float64", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_sqdist_float64", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_bstruct_X.buf = NULL; + __pyx_bstruct_Y.buf = NULL; + __pyx_bstruct_out.buf = NULL; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_X), __pyx_ptype_5numpy_ndarray, 1, "X", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_Y), __pyx_ptype_5numpy_ndarray, 1, "Y", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_out), __pyx_ptype_5numpy_ndarray, 1, "out", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_X = __pyx_bstruct_X.strides[0]; __pyx_bstride_1_X = __pyx_bstruct_X.strides[1]; + __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_Y, (PyObject*)__pyx_v_Y, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_Y = __pyx_bstruct_Y.strides[0]; __pyx_bstride_1_Y = __pyx_bstruct_Y.strides[1]; + __pyx_bshape_0_Y = __pyx_bstruct_Y.shape[0]; __pyx_bshape_1_Y = __pyx_bstruct_Y.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_out, (PyObject*)__pyx_v_out, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_out = __pyx_bstruct_out.strides[0]; __pyx_bstride_1_out = __pyx_bstruct_out.strides[1]; + __pyx_bshape_0_out = __pyx_bstruct_out.shape[0]; __pyx_bshape_1_out = __pyx_bstruct_out.shape[1]; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_f_7sklearn_5utils_10arrayfuncs_fast_sqdist_float64(__pyx_v_X, __pyx_v_Y, __pyx_v_out, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_Y); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_sqdist_float64", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_Y); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "sklearn/utils/arrayfuncs.pyx":189 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * cpdef fast_pair_sqdist_float32(np.ndarray[np.float32_t, ndim=2] X, # <<<<<<<<<<<<<< + * np.ndarray[np.float32_t, ndim=2] out): + * """ + */ + +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_5fast_pair_sqdist_float32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_f_7sklearn_5utils_10arrayfuncs_fast_pair_sqdist_float32(PyArrayObject *__pyx_v_X, PyArrayObject *__pyx_v_out, int __pyx_skip_dispatch) { + npy_intp __pyx_v_i; + npy_intp __pyx_v_j; + npy_intp __pyx_v_k; + Py_buffer __pyx_bstruct_X; + Py_ssize_t __pyx_bstride_0_X = 0; + Py_ssize_t __pyx_bstride_1_X = 0; + Py_ssize_t __pyx_bshape_0_X = 0; + Py_ssize_t __pyx_bshape_1_X = 0; + Py_buffer __pyx_bstruct_out; + Py_ssize_t __pyx_bstride_0_out = 0; + Py_ssize_t __pyx_bstride_1_out = 0; + Py_ssize_t __pyx_bshape_0_out = 0; + Py_ssize_t __pyx_bshape_1_out = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + npy_intp __pyx_t_1; + npy_intp __pyx_t_2; + npy_intp __pyx_t_3; + npy_intp __pyx_t_4; + npy_intp __pyx_t_5; + npy_intp __pyx_t_6; + npy_intp __pyx_t_7; + npy_intp __pyx_t_8; + npy_intp __pyx_t_9; + npy_intp __pyx_t_10; + npy_intp __pyx_t_11; + npy_intp __pyx_t_12; + npy_intp __pyx_t_13; + npy_intp __pyx_t_14; + npy_intp __pyx_t_15; + npy_intp __pyx_t_16; + npy_intp __pyx_t_17; + npy_intp __pyx_t_18; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("fast_pair_sqdist_float32"); + __pyx_bstruct_X.buf = NULL; + __pyx_bstruct_out.buf = NULL; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_X = __pyx_bstruct_X.strides[0]; __pyx_bstride_1_X = __pyx_bstruct_X.strides[1]; + __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_out, (PyObject*)__pyx_v_out, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_out = __pyx_bstruct_out.strides[0]; __pyx_bstride_1_out = __pyx_bstruct_out.strides[1]; + __pyx_bshape_0_out = __pyx_bstruct_out.shape[0]; __pyx_bshape_1_out = __pyx_bstruct_out.shape[1]; + + /* "sklearn/utils/arrayfuncs.pyx":211 + * """ + * cdef np.npy_intp i, j, k + * for i in range(X.shape[0]): # <<<<<<<<<<<<<< + * out[i, i] = 0 + * for j in range(i + 1, X.shape[0]): + */ + __pyx_t_1 = (__pyx_v_X->dimensions[0]); + for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { + __pyx_v_i = __pyx_t_2; + + /* "sklearn/utils/arrayfuncs.pyx":212 + * cdef np.npy_intp i, j, k + * for i in range(X.shape[0]): + * out[i, i] = 0 # <<<<<<<<<<<<<< + * for j in range(i + 1, X.shape[0]): + * out[i, j] = 0 + */ + __pyx_t_3 = __pyx_v_i; + __pyx_t_4 = __pyx_v_i; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_out.buf, __pyx_t_3, __pyx_bstride_0_out, __pyx_t_4, __pyx_bstride_1_out) = 0.0; + + /* "sklearn/utils/arrayfuncs.pyx":213 + * for i in range(X.shape[0]): + * out[i, i] = 0 + * for j in range(i + 1, X.shape[0]): # <<<<<<<<<<<<<< + * out[i, j] = 0 + * for k in range(X.shape[1]): + */ + __pyx_t_5 = (__pyx_v_X->dimensions[0]); + for (__pyx_t_6 = (__pyx_v_i + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { + __pyx_v_j = __pyx_t_6; + + /* "sklearn/utils/arrayfuncs.pyx":214 + * out[i, i] = 0 + * for j in range(i + 1, X.shape[0]): + * out[i, j] = 0 # <<<<<<<<<<<<<< + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - X[j, k]) ** 2 + */ + __pyx_t_7 = __pyx_v_i; + __pyx_t_8 = __pyx_v_j; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_out.buf, __pyx_t_7, __pyx_bstride_0_out, __pyx_t_8, __pyx_bstride_1_out) = 0.0; + + /* "sklearn/utils/arrayfuncs.pyx":215 + * for j in range(i + 1, X.shape[0]): + * out[i, j] = 0 + * for k in range(X.shape[1]): # <<<<<<<<<<<<<< + * out[i, j] += (X[i, k] - X[j, k]) ** 2 + * out[j, i] = out[i, j] + */ + __pyx_t_9 = (__pyx_v_X->dimensions[1]); + for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { + __pyx_v_k = __pyx_t_10; + + /* "sklearn/utils/arrayfuncs.pyx":216 + * out[i, j] = 0 + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - X[j, k]) ** 2 # <<<<<<<<<<<<<< + * out[j, i] = out[i, j] + * + */ + __pyx_t_11 = __pyx_v_i; + __pyx_t_12 = __pyx_v_k; + __pyx_t_13 = __pyx_v_j; + __pyx_t_14 = __pyx_v_k; + __pyx_t_15 = __pyx_v_i; + __pyx_t_16 = __pyx_v_j; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_out.buf, __pyx_t_15, __pyx_bstride_0_out, __pyx_t_16, __pyx_bstride_1_out) += powf(((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_X.buf, __pyx_t_11, __pyx_bstride_0_X, __pyx_t_12, __pyx_bstride_1_X)) - (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_X.buf, __pyx_t_13, __pyx_bstride_0_X, __pyx_t_14, __pyx_bstride_1_X))), 2.0); + } + + /* "sklearn/utils/arrayfuncs.pyx":217 + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - X[j, k]) ** 2 + * out[j, i] = out[i, j] # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_9 = __pyx_v_i; + __pyx_t_10 = __pyx_v_j; + __pyx_t_17 = __pyx_v_j; + __pyx_t_18 = __pyx_v_i; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_out.buf, __pyx_t_17, __pyx_bstride_0_out, __pyx_t_18, __pyx_bstride_1_out) = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_bstruct_out.buf, __pyx_t_9, __pyx_bstride_0_out, __pyx_t_10, __pyx_bstride_1_out)); + } + } + + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_pair_sqdist_float32", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "sklearn/utils/arrayfuncs.pyx":189 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * cpdef fast_pair_sqdist_float32(np.ndarray[np.float32_t, ndim=2] X, # <<<<<<<<<<<<<< + * np.ndarray[np.float32_t, ndim=2] out): + * """ + */ + +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_5fast_pair_sqdist_float32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7sklearn_5utils_10arrayfuncs_5fast_pair_sqdist_float32[] = "\n fast_pair_sqdist_float32(X, out)\n\n Low-level function for computing squared Euclidean distances between\n every pair of points in a set.\n\n Parameters\n ----------\n X : ndarray, float64, shape = [n_samples, n_features]\n\n out : ndarray, float64, shape = [n_samples, n_samples]\n\n Notes\n -----\n In order to achieve maximal speed this function performs no checks of\n any array metadata. Use the high-level functions defined in the\n `sklearn.metrics.distance` module unless you really know what you're\n doing.\n "; +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_5fast_pair_sqdist_float32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_X = 0; + PyArrayObject *__pyx_v_out = 0; + Py_buffer __pyx_bstruct_X; + Py_ssize_t __pyx_bstride_0_X = 0; + Py_ssize_t __pyx_bstride_1_X = 0; + Py_ssize_t __pyx_bshape_0_X = 0; + Py_ssize_t __pyx_bshape_1_X = 0; + Py_buffer __pyx_bstruct_out; + Py_ssize_t __pyx_bstride_0_out = 0; + Py_ssize_t __pyx_bstride_1_out = 0; + Py_ssize_t __pyx_bshape_0_out = 0; + Py_ssize_t __pyx_bshape_1_out = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__X,&__pyx_n_s__out,0}; + __Pyx_RefNannySetupContext("fast_pair_sqdist_float32"); + __pyx_self = __pyx_self; + { + PyObject* values[2] = {0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 0: + values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__X); + if (likely(values[0])) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__out); + if (likely(values[1])) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("fast_pair_sqdist_float32", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "fast_pair_sqdist_float32") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + } + __pyx_v_X = ((PyArrayObject *)values[0]); + __pyx_v_out = ((PyArrayObject *)values[1]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("fast_pair_sqdist_float32", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_pair_sqdist_float32", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_bstruct_X.buf = NULL; + __pyx_bstruct_out.buf = NULL; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_X), __pyx_ptype_5numpy_ndarray, 1, "X", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_out), __pyx_ptype_5numpy_ndarray, 1, "out", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_X = __pyx_bstruct_X.strides[0]; __pyx_bstride_1_X = __pyx_bstruct_X.strides[1]; + __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_out, (PyObject*)__pyx_v_out, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_out = __pyx_bstruct_out.strides[0]; __pyx_bstride_1_out = __pyx_bstruct_out.strides[1]; + __pyx_bshape_0_out = __pyx_bstruct_out.shape[0]; __pyx_bshape_1_out = __pyx_bstruct_out.shape[1]; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_f_7sklearn_5utils_10arrayfuncs_fast_pair_sqdist_float32(__pyx_v_X, __pyx_v_out, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_pair_sqdist_float32", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "sklearn/utils/arrayfuncs.pyx":222 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * cpdef fast_pair_sqdist_float64(np.ndarray[np.float64_t, ndim=2] X, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=2] out): + * """ + */ + +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_6fast_pair_sqdist_float64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_f_7sklearn_5utils_10arrayfuncs_fast_pair_sqdist_float64(PyArrayObject *__pyx_v_X, PyArrayObject *__pyx_v_out, int __pyx_skip_dispatch) { + npy_intp __pyx_v_i; + npy_intp __pyx_v_j; + npy_intp __pyx_v_k; + Py_buffer __pyx_bstruct_X; + Py_ssize_t __pyx_bstride_0_X = 0; + Py_ssize_t __pyx_bstride_1_X = 0; + Py_ssize_t __pyx_bshape_0_X = 0; + Py_ssize_t __pyx_bshape_1_X = 0; + Py_buffer __pyx_bstruct_out; + Py_ssize_t __pyx_bstride_0_out = 0; + Py_ssize_t __pyx_bstride_1_out = 0; + Py_ssize_t __pyx_bshape_0_out = 0; + Py_ssize_t __pyx_bshape_1_out = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + npy_intp __pyx_t_1; + npy_intp __pyx_t_2; + npy_intp __pyx_t_3; + npy_intp __pyx_t_4; + npy_intp __pyx_t_5; + npy_intp __pyx_t_6; + npy_intp __pyx_t_7; + npy_intp __pyx_t_8; + npy_intp __pyx_t_9; + npy_intp __pyx_t_10; + npy_intp __pyx_t_11; + npy_intp __pyx_t_12; + npy_intp __pyx_t_13; + npy_intp __pyx_t_14; + npy_intp __pyx_t_15; + npy_intp __pyx_t_16; + npy_intp __pyx_t_17; + npy_intp __pyx_t_18; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("fast_pair_sqdist_float64"); + __pyx_bstruct_X.buf = NULL; + __pyx_bstruct_out.buf = NULL; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_X = __pyx_bstruct_X.strides[0]; __pyx_bstride_1_X = __pyx_bstruct_X.strides[1]; + __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_out, (PyObject*)__pyx_v_out, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_out = __pyx_bstruct_out.strides[0]; __pyx_bstride_1_out = __pyx_bstruct_out.strides[1]; + __pyx_bshape_0_out = __pyx_bstruct_out.shape[0]; __pyx_bshape_1_out = __pyx_bstruct_out.shape[1]; + + /* "sklearn/utils/arrayfuncs.pyx":244 + * """ + * cdef np.npy_intp i, j, k + * for i in range(X.shape[0]): # <<<<<<<<<<<<<< + * out[i, i] = 0 + * for j in range(i + 1, X.shape[0]): + */ + __pyx_t_1 = (__pyx_v_X->dimensions[0]); + for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { + __pyx_v_i = __pyx_t_2; + + /* "sklearn/utils/arrayfuncs.pyx":245 + * cdef np.npy_intp i, j, k + * for i in range(X.shape[0]): + * out[i, i] = 0 # <<<<<<<<<<<<<< + * for j in range(i + 1, X.shape[0]): + * out[i, j] = 0 + */ + __pyx_t_3 = __pyx_v_i; + __pyx_t_4 = __pyx_v_i; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_out.buf, __pyx_t_3, __pyx_bstride_0_out, __pyx_t_4, __pyx_bstride_1_out) = 0.0; + + /* "sklearn/utils/arrayfuncs.pyx":246 + * for i in range(X.shape[0]): + * out[i, i] = 0 + * for j in range(i + 1, X.shape[0]): # <<<<<<<<<<<<<< + * out[i, j] = 0 + * for k in range(X.shape[1]): + */ + __pyx_t_5 = (__pyx_v_X->dimensions[0]); + for (__pyx_t_6 = (__pyx_v_i + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { + __pyx_v_j = __pyx_t_6; + + /* "sklearn/utils/arrayfuncs.pyx":247 + * out[i, i] = 0 + * for j in range(i + 1, X.shape[0]): + * out[i, j] = 0 # <<<<<<<<<<<<<< + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - X[j, k]) ** 2 + */ + __pyx_t_7 = __pyx_v_i; + __pyx_t_8 = __pyx_v_j; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_out.buf, __pyx_t_7, __pyx_bstride_0_out, __pyx_t_8, __pyx_bstride_1_out) = 0.0; + + /* "sklearn/utils/arrayfuncs.pyx":248 + * for j in range(i + 1, X.shape[0]): + * out[i, j] = 0 + * for k in range(X.shape[1]): # <<<<<<<<<<<<<< + * out[i, j] += (X[i, k] - X[j, k]) ** 2 + * out[j, i] = out[i, j] + */ + __pyx_t_9 = (__pyx_v_X->dimensions[1]); + for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { + __pyx_v_k = __pyx_t_10; + + /* "sklearn/utils/arrayfuncs.pyx":249 + * out[i, j] = 0 + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - X[j, k]) ** 2 # <<<<<<<<<<<<<< + * out[j, i] = out[i, j] + */ + __pyx_t_11 = __pyx_v_i; + __pyx_t_12 = __pyx_v_k; + __pyx_t_13 = __pyx_v_j; + __pyx_t_14 = __pyx_v_k; + __pyx_t_15 = __pyx_v_i; + __pyx_t_16 = __pyx_v_j; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_out.buf, __pyx_t_15, __pyx_bstride_0_out, __pyx_t_16, __pyx_bstride_1_out) += pow(((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_X.buf, __pyx_t_11, __pyx_bstride_0_X, __pyx_t_12, __pyx_bstride_1_X)) - (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_X.buf, __pyx_t_13, __pyx_bstride_0_X, __pyx_t_14, __pyx_bstride_1_X))), 2.0); + } + + /* "sklearn/utils/arrayfuncs.pyx":250 + * for k in range(X.shape[1]): + * out[i, j] += (X[i, k] - X[j, k]) ** 2 + * out[j, i] = out[i, j] # <<<<<<<<<<<<<< + */ + __pyx_t_9 = __pyx_v_i; + __pyx_t_10 = __pyx_v_j; + __pyx_t_17 = __pyx_v_j; + __pyx_t_18 = __pyx_v_i; + *__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_out.buf, __pyx_t_17, __pyx_bstride_0_out, __pyx_t_18, __pyx_bstride_1_out) = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_out.buf, __pyx_t_9, __pyx_bstride_0_out, __pyx_t_10, __pyx_bstride_1_out)); + } + } + + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_pair_sqdist_float64", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "sklearn/utils/arrayfuncs.pyx":222 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * cpdef fast_pair_sqdist_float64(np.ndarray[np.float64_t, ndim=2] X, # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=2] out): + * """ + */ + +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_6fast_pair_sqdist_float64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7sklearn_5utils_10arrayfuncs_6fast_pair_sqdist_float64[] = "\n fast_pair_sqdist_float64(X, out)\n\n Low-level function for computing squared Euclidean distances between\n every pair of points in a set.\n\n Parameters\n ----------\n X : ndarray, float64, shape = [n_samples, n_features]\n\n out : ndarray, float64, shape = [n_samples, n_samples]\n\n Notes\n -----\n In order to achieve maximal speed this function performs no checks of\n any array metadata. Use the high-level functions defined in the\n `sklearn.metrics.distance` module unless you really know what you're\n doing.\n "; +static PyObject *__pyx_pf_7sklearn_5utils_10arrayfuncs_6fast_pair_sqdist_float64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_X = 0; + PyArrayObject *__pyx_v_out = 0; + Py_buffer __pyx_bstruct_X; + Py_ssize_t __pyx_bstride_0_X = 0; + Py_ssize_t __pyx_bstride_1_X = 0; + Py_ssize_t __pyx_bshape_0_X = 0; + Py_ssize_t __pyx_bshape_1_X = 0; + Py_buffer __pyx_bstruct_out; + Py_ssize_t __pyx_bstride_0_out = 0; + Py_ssize_t __pyx_bstride_1_out = 0; + Py_ssize_t __pyx_bshape_0_out = 0; + Py_ssize_t __pyx_bshape_1_out = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__X,&__pyx_n_s__out,0}; + __Pyx_RefNannySetupContext("fast_pair_sqdist_float64"); + __pyx_self = __pyx_self; + { + PyObject* values[2] = {0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 0: + values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__X); + if (likely(values[0])) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__out); + if (likely(values[1])) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("fast_pair_sqdist_float64", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "fast_pair_sqdist_float64") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + } + __pyx_v_X = ((PyArrayObject *)values[0]); + __pyx_v_out = ((PyArrayObject *)values[1]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("fast_pair_sqdist_float64", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_pair_sqdist_float64", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_bstruct_X.buf = NULL; + __pyx_bstruct_out.buf = NULL; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_X), __pyx_ptype_5numpy_ndarray, 1, "X", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_out), __pyx_ptype_5numpy_ndarray, 1, "out", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_X = __pyx_bstruct_X.strides[0]; __pyx_bstride_1_X = __pyx_bstruct_X.strides[1]; + __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_out, (PyObject*)__pyx_v_out, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + __pyx_bstride_0_out = __pyx_bstruct_out.strides[0]; __pyx_bstride_1_out = __pyx_bstruct_out.strides[1]; + __pyx_bshape_0_out = __pyx_bstruct_out.shape[0]; __pyx_bshape_1_out = __pyx_bstruct_out.shape[1]; + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_f_7sklearn_5utils_10arrayfuncs_fast_pair_sqdist_float64(__pyx_v_X, __pyx_v_out, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("sklearn.utils.arrayfuncs.fast_pair_sqdist_float64", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X); + __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + /* "numpy.pxd":190 * # experimental exception made for __getbuffer__ and __releasebuffer__ * # -- the details of this may change. @@ -3566,6 +4790,10 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py } static PyMethodDef __pyx_methods[] = { + {__Pyx_NAMESTR("fast_sqdist_float32"), (PyCFunction)__pyx_pf_7sklearn_5utils_10arrayfuncs_3fast_sqdist_float32, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7sklearn_5utils_10arrayfuncs_3fast_sqdist_float32)}, + {__Pyx_NAMESTR("fast_sqdist_float64"), (PyCFunction)__pyx_pf_7sklearn_5utils_10arrayfuncs_4fast_sqdist_float64, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7sklearn_5utils_10arrayfuncs_4fast_sqdist_float64)}, + {__Pyx_NAMESTR("fast_pair_sqdist_float32"), (PyCFunction)__pyx_pf_7sklearn_5utils_10arrayfuncs_5fast_pair_sqdist_float32, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7sklearn_5utils_10arrayfuncs_5fast_pair_sqdist_float32)}, + {__Pyx_NAMESTR("fast_pair_sqdist_float64"), (PyCFunction)__pyx_pf_7sklearn_5utils_10arrayfuncs_6fast_pair_sqdist_float64, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7sklearn_5utils_10arrayfuncs_6fast_pair_sqdist_float64)}, {0, 0, 0, 0} }; @@ -3597,6 +4825,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s__RuntimeError, __pyx_k__RuntimeError, sizeof(__pyx_k__RuntimeError), 0, 0, 1, 1}, {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1}, {&__pyx_n_s__X, __pyx_k__X, sizeof(__pyx_k__X), 0, 0, 1, 1}, + {&__pyx_n_s__Y, __pyx_k__Y, sizeof(__pyx_k__Y), 0, 0, 1, 1}, {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1}, {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1}, {&__pyx_n_s__cholesky_delete, __pyx_k__cholesky_delete, sizeof(__pyx_k__cholesky_delete), 0, 0, 1, 1}, @@ -3608,6 +4837,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s__name, __pyx_k__name, sizeof(__pyx_k__name), 0, 0, 1, 1}, {&__pyx_n_s__np, __pyx_k__np, sizeof(__pyx_k__np), 0, 0, 1, 1}, {&__pyx_n_s__numpy, __pyx_k__numpy, sizeof(__pyx_k__numpy), 0, 0, 1, 1}, + {&__pyx_n_s__out, __pyx_k__out, sizeof(__pyx_k__out), 0, 0, 1, 1}, {&__pyx_n_s__range, __pyx_k__range, sizeof(__pyx_k__range), 0, 0, 1, 1}, {&__pyx_n_s__size, __pyx_k__size, sizeof(__pyx_k__size), 0, 0, 1, 1}, {&__pyx_n_s__solve_triangular, __pyx_k__solve_triangular, sizeof(__pyx_k__solve_triangular), 0, 0, 1, 1}, @@ -4237,6 +5467,446 @@ static int __Pyx_ParseOptionalKeywords( return -1; } +static CYTHON_INLINE int __Pyx_IsLittleEndian(void) { + unsigned int n = 1; + return *(unsigned char*)(&n) != 0; +} + +typedef struct { + __Pyx_StructField root; + __Pyx_BufFmt_StackElem* head; + size_t fmt_offset; + size_t new_count, enc_count; + int is_complex; + char enc_type; + char new_packmode; + char enc_packmode; +} __Pyx_BufFmt_Context; + +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type) { + stack[0].field = &ctx->root; + stack[0].parent_offset = 0; + ctx->root.type = type; + ctx->root.name = "buffer dtype"; + ctx->root.offset = 0; + ctx->head = stack; + ctx->head->field = &ctx->root; + ctx->fmt_offset = 0; + ctx->head->parent_offset = 0; + ctx->new_packmode = '@'; + ctx->enc_packmode = '@'; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->is_complex = 0; + while (type->typegroup == 'S') { + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = 0; + type = type->fields->type; + } +} + +static int __Pyx_BufFmt_ParseNumber(const char** ts) { + int count; + const char* t = *ts; + if (*t < '0' || *t > '9') { + return -1; + } else { + count = *t++ - '0'; + while (*t >= '0' && *t < '9') { + count *= 10; + count += *t++ - '0'; + } + } + *ts = t; + return count; +} + +static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { + PyErr_Format(PyExc_ValueError, + "Unexpected format string character: '%c'", ch); +} + +static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { + switch (ch) { + case 'b': return "'char'"; + case 'B': return "'unsigned char'"; + case 'h': return "'short'"; + case 'H': return "'unsigned short'"; + case 'i': return "'int'"; + case 'I': return "'unsigned int'"; + case 'l': return "'long'"; + case 'L': return "'unsigned long'"; + case 'q': return "'long long'"; + case 'Q': return "'unsigned long long'"; + case 'f': return (is_complex ? "'complex float'" : "'float'"); + case 'd': return (is_complex ? "'complex double'" : "'double'"); + case 'g': return (is_complex ? "'complex long double'" : "'long double'"); + case 'T': return "a struct"; + case 'O': return "Python object"; + case 'P': return "a pointer"; + case 0: return "end"; + default: return "unparseable format string"; + } +} + +static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': return 1; + case 'h': case 'H': return 2; + case 'i': case 'I': case 'l': case 'L': return 4; + case 'q': case 'Q': return 8; + case 'f': return (is_complex ? 8 : 4); + case 'd': return (is_complex ? 16 : 8); + case 'g': { + PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); + return 0; + } + case 'O': case 'P': return sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} + +static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { + switch (ch) { + case 'c': case 'b': case 'B': return 1; + case 'h': case 'H': return sizeof(short); + case 'i': case 'I': return sizeof(int); + case 'l': case 'L': return sizeof(long); + #ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(PY_LONG_LONG); + #endif + case 'f': return sizeof(float) * (is_complex ? 2 : 1); + case 'd': return sizeof(double) * (is_complex ? 2 : 1); + case 'g': return sizeof(long double) * (is_complex ? 2 : 1); + case 'O': case 'P': return sizeof(void*); + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} + +typedef struct { char c; short x; } __Pyx_st_short; +typedef struct { char c; int x; } __Pyx_st_int; +typedef struct { char c; long x; } __Pyx_st_long; +typedef struct { char c; float x; } __Pyx_st_float; +typedef struct { char c; double x; } __Pyx_st_double; +typedef struct { char c; long double x; } __Pyx_st_longdouble; +typedef struct { char c; void *x; } __Pyx_st_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; +#endif + +static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': return 1; + case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_st_float) - sizeof(float); + case 'd': return sizeof(__Pyx_st_double) - sizeof(double); + case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} + +static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { + switch (ch) { + case 'c': case 'b': case 'h': case 'i': case 'l': case 'q': return 'I'; + case 'B': case 'H': case 'I': case 'L': case 'Q': return 'U'; + case 'f': case 'd': case 'g': return (is_complex ? 'C' : 'R'); + case 'O': return 'O'; + case 'P': return 'P'; + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} + +static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { + if (ctx->head == NULL || ctx->head->field == &ctx->root) { + const char* expected; + const char* quote; + if (ctx->head == NULL) { + expected = "end"; + quote = ""; + } else { + expected = ctx->head->field->type->name; + quote = "'"; + } + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected %s%s%s but got %s", + quote, expected, quote, + __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); + } else { + __Pyx_StructField* field = ctx->head->field; + __Pyx_StructField* parent = (ctx->head - 1)->field; + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", + field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), + parent->type->name, field->name); + } +} + +static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { + char group; + size_t size, offset; + if (ctx->enc_type == 0) return 0; + group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); + do { + __Pyx_StructField* field = ctx->head->field; + __Pyx_TypeInfo* type = field->type; + + if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { + size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); + } else { + size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); + } + if (ctx->enc_packmode == '@') { + size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); + size_t align_mod_offset; + if (align_at == 0) return -1; + align_mod_offset = ctx->fmt_offset % align_at; + if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; + } + + if (type->size != size || type->typegroup != group) { + if (type->typegroup == 'C' && type->fields != NULL) { + /* special case -- treat as struct rather than complex number */ + size_t parent_offset = ctx->head->parent_offset + field->offset; + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = parent_offset; + continue; + } + + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + + offset = ctx->head->parent_offset + field->offset; + if (ctx->fmt_offset != offset) { + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch; next field is at offset %"PY_FORMAT_SIZE_T"d but %"PY_FORMAT_SIZE_T"d expected", + (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); + return -1; + } + + ctx->fmt_offset += size; + + --ctx->enc_count; /* Consume from buffer string */ + + /* Done checking, move to next field, pushing or popping struct stack if needed */ + while (1) { + if (field == &ctx->root) { + ctx->head = NULL; + if (ctx->enc_count != 0) { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + break; /* breaks both loops as ctx->enc_count == 0 */ + } + ctx->head->field = ++field; + if (field->type == NULL) { + --ctx->head; + field = ctx->head->field; + continue; + } else if (field->type->typegroup == 'S') { + size_t parent_offset = ctx->head->parent_offset + field->offset; + if (field->type->fields->type == NULL) continue; /* empty struct */ + field = field->type->fields; + ++ctx->head; + ctx->head->field = field; + ctx->head->parent_offset = parent_offset; + break; + } else { + break; + } + } + } while (ctx->enc_count); + ctx->enc_type = 0; + ctx->is_complex = 0; + return 0; +} + +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { + int got_Z = 0; + while (1) { + switch(*ts) { + case 0: + if (ctx->enc_type != 0 && ctx->head == NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + if (ctx->head != NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + return ts; + case ' ': + case 10: + case 13: + ++ts; + break; + case '<': + if (!__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '>': + case '!': + if (__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '=': + case '@': + case '^': + ctx->new_packmode = *ts++; + break; + case 'T': /* substruct */ + { + const char* ts_after_sub; + size_t i, struct_count = ctx->new_count; + ctx->new_count = 1; + ++ts; + if (*ts != '{') { + PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); + return NULL; + } + ++ts; + ts_after_sub = ts; + for (i = 0; i != struct_count; ++i) { + ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); + if (!ts_after_sub) return NULL; + } + ts = ts_after_sub; + } + break; + case '}': /* end of substruct; either repeat or move on */ + ++ts; + return ts; + case 'x': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->fmt_offset += ctx->new_count; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->enc_packmode = ctx->new_packmode; + ++ts; + break; + case 'Z': + got_Z = 1; + ++ts; + if (*ts != 'f' && *ts != 'd' && *ts != 'g') { + __Pyx_BufFmt_RaiseUnexpectedChar('Z'); + return NULL; + } /* fall through */ + case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': + case 'l': case 'L': case 'q': case 'Q': + case 'f': case 'd': case 'g': + case 'O': + if (ctx->enc_type == *ts && got_Z == ctx->is_complex && + ctx->enc_packmode == ctx->new_packmode) { + /* Continue pooling same type */ + ctx->enc_count += ctx->new_count; + } else { + /* New type */ + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_count = ctx->new_count; + ctx->enc_packmode = ctx->new_packmode; + ctx->enc_type = *ts; + ctx->is_complex = got_Z; + } + ++ts; + ctx->new_count = 1; + got_Z = 0; + break; + case ':': + ++ts; + while(*ts != ':') ++ts; + ++ts; + break; + default: + { + int number = __Pyx_BufFmt_ParseNumber(&ts); + if (number == -1) { /* First char was not a digit */ + PyErr_Format(PyExc_ValueError, + "Does not understand character buffer dtype format string ('%c')", *ts); + return NULL; + } + ctx->new_count = (size_t)number; + } + } + } +} + +static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { + buf->buf = NULL; + buf->obj = NULL; + buf->strides = __Pyx_zeros; + buf->shape = __Pyx_zeros; + buf->suboffsets = __Pyx_minusones; +} + +static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack) { + if (obj == Py_None || obj == NULL) { + __Pyx_ZeroBuffer(buf); + return 0; + } + buf->buf = NULL; + if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail; + if (buf->ndim != nd) { + PyErr_Format(PyExc_ValueError, + "Buffer has wrong number of dimensions (expected %d, got %d)", + nd, buf->ndim); + goto fail; + } + if (!cast) { + __Pyx_BufFmt_Context ctx; + __Pyx_BufFmt_Init(&ctx, stack, dtype); + if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; + } + if ((unsigned)buf->itemsize != dtype->size) { + PyErr_Format(PyExc_ValueError, + "Item size of buffer (%"PY_FORMAT_SIZE_T"d byte%s) does not match size of '%s' (%"PY_FORMAT_SIZE_T"d byte%s)", + buf->itemsize, (buf->itemsize > 1) ? "s" : "", + dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); + goto fail; + } + if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; + return 0; +fail:; + __Pyx_ZeroBuffer(buf); + return -1; +} + +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { + if (info->buf == NULL) return; + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; + __Pyx_ReleaseBuffer(info); +} + static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { PyErr_Format(PyExc_ValueError, "need more than %"PY_FORMAT_SIZE_T"d value%s to unpack", @@ -4274,6 +5944,32 @@ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { return 0; } +#if PY_MAJOR_VERSION < 3 +static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { + #if PY_VERSION_HEX >= 0x02060000 + if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); + #endif + if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pf_5numpy_7ndarray___getbuffer__(obj, view, flags); + else { + PyErr_Format(PyExc_TypeError, "'%100s' does not have the buffer interface", Py_TYPE(obj)->tp_name); + return -1; + } +} + +static void __Pyx_ReleaseBuffer(Py_buffer *view) { + PyObject* obj = view->obj; + if (obj) { + #if PY_VERSION_HEX >= 0x02060000 + if (PyObject_CheckBuffer(obj)) {PyBuffer_Release(view); return;} + #endif + if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) __pyx_pf_5numpy_7ndarray_1__releasebuffer__(obj, view); + Py_DECREF(obj); + view->obj = NULL; + } +} + +#endif + static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level) { PyObject *py_import = 0; PyObject *empty_list = 0; @@ -4384,6 +6080,83 @@ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int } } +static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_Py_intptr_t(Py_intptr_t val) { + const Py_intptr_t neg_one = (Py_intptr_t)-1, const_zero = (Py_intptr_t)0; + const int is_unsigned = const_zero < neg_one; + if ((sizeof(Py_intptr_t) == sizeof(char)) || + (sizeof(Py_intptr_t) == sizeof(short))) { + return PyInt_FromLong((long)val); + } else if ((sizeof(Py_intptr_t) == sizeof(int)) || + (sizeof(Py_intptr_t) == sizeof(long))) { + if (is_unsigned) + return PyLong_FromUnsignedLong((unsigned long)val); + else + return PyInt_FromLong((long)val); + } else if (sizeof(Py_intptr_t) == sizeof(PY_LONG_LONG)) { + if (is_unsigned) + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)val); + else + return PyLong_FromLongLong((PY_LONG_LONG)val); + } else { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + return _PyLong_FromByteArray(bytes, sizeof(Py_intptr_t), + little, !is_unsigned); + } +} + +static CYTHON_INLINE Py_intptr_t __Pyx_PyInt_from_py_Py_intptr_t(PyObject* x) { + const Py_intptr_t neg_one = (Py_intptr_t)-1, const_zero = (Py_intptr_t)0; + const int is_unsigned = const_zero < neg_one; + if (sizeof(Py_intptr_t) == sizeof(char)) { + if (is_unsigned) + return (Py_intptr_t)__Pyx_PyInt_AsUnsignedChar(x); + else + return (Py_intptr_t)__Pyx_PyInt_AsSignedChar(x); + } else if (sizeof(Py_intptr_t) == sizeof(short)) { + if (is_unsigned) + return (Py_intptr_t)__Pyx_PyInt_AsUnsignedShort(x); + else + return (Py_intptr_t)__Pyx_PyInt_AsSignedShort(x); + } else if (sizeof(Py_intptr_t) == sizeof(int)) { + if (is_unsigned) + return (Py_intptr_t)__Pyx_PyInt_AsUnsignedInt(x); + else + return (Py_intptr_t)__Pyx_PyInt_AsSignedInt(x); + } else if (sizeof(Py_intptr_t) == sizeof(long)) { + if (is_unsigned) + return (Py_intptr_t)__Pyx_PyInt_AsUnsignedLong(x); + else + return (Py_intptr_t)__Pyx_PyInt_AsSignedLong(x); + } else if (sizeof(Py_intptr_t) == sizeof(PY_LONG_LONG)) { + if (is_unsigned) + return (Py_intptr_t)__Pyx_PyInt_AsUnsignedLongLong(x); + else + return (Py_intptr_t)__Pyx_PyInt_AsSignedLongLong(x); + } else { + Py_intptr_t val; + PyObject *v = __Pyx_PyNumber_Int(x); + #if PY_VERSION_HEX < 0x03000000 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } + return (Py_intptr_t)-1; + } +} + #if CYTHON_CCOMPLEX #ifdef __cplusplus static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { diff --git a/sklearn/utils/arrayfuncs.pyx b/sklearn/utils/arrayfuncs.pyx index d75f6cc447d4d..4f4d31482cab4 100644 --- a/sklearn/utils/arrayfuncs.pyx +++ b/sklearn/utils/arrayfuncs.pyx @@ -113,3 +113,138 @@ def cholesky_delete (np.ndarray L, int go_out): m = L.strides[0] / sizeof (float) float_cholesky_delete (m, n, L.data, go_out) +# TODO: fast_sqdist_foo and fast_pair_sqdist_foo should be templated +# for different dtypes, when the templating infrastructure is finally +# set up. +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef fast_sqdist_float32(np.ndarray[np.float32_t, ndim=2] X, + np.ndarray[np.float32_t, ndim=2] Y, + np.ndarray[np.float32_t, ndim=2] out): + """ + fast_sqdist_float32(X, Y, out) + + Low-level function for computing squared Euclidean distances between + two sets of points. + + Parameters + ---------- + X : ndarray, float32, shape = [n_samples_a, n_features] + + Y : ndarray, float32, shape = [n_samples_b, n_features] + + out : ndarray, float32, shape = [n_samples_a, n_samples_b] + + Notes + ----- + In order to achieve maximal speed this function performs no checks of + any array metadata. Use the high-level functions defined in the + `sklearn.metrics.distance` module unless you really know what you're + doing. + """ + cdef np.npy_intp i, j, k + for i in range(X.shape[0]): + for j in range(Y.shape[0]): + out[i, j] = 0 + for k in range(X.shape[1]): + out[i, j] += (X[i, k] - Y[j, k]) ** 2 + + +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef fast_sqdist_float64(np.ndarray[np.float64_t, ndim=2] X, + np.ndarray[np.float64_t, ndim=2] Y, + np.ndarray[np.float64_t, ndim=2] out): + """ + fast_sqdist_float64(X, Y, out) + + Low-level function for computing squared Euclidean distances between + two sets of points. + + Parameters + ---------- + X : ndarray, float64, shape = [n_samples_a, n_features] + + Y : ndarray, float64, shape = [n_samples_b, n_features] + + out : ndarray, float64, shape = [n_samples_a, n_samples_b] + + Notes + ----- + In order to achieve maximal speed this function performs no checks of + any array metadata. Use the high-level functions defined in the + `sklearn.metrics.distance` module unless you really know what you're + doing. + """ + cdef np.npy_intp i, j, k + for i in range(X.shape[0]): + for j in range(Y.shape[0]): + out[i, j] = 0 + for k in range(X.shape[1]): + out[i, j] += (X[i, k] - Y[j, k]) ** 2 + + +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef fast_pair_sqdist_float32(np.ndarray[np.float32_t, ndim=2] X, + np.ndarray[np.float32_t, ndim=2] out): + """ + fast_pair_sqdist_float32(X, out) + + Low-level function for computing squared Euclidean distances between + every pair of points in a set. + + Parameters + ---------- + X : ndarray, float64, shape = [n_samples, n_features] + + out : ndarray, float64, shape = [n_samples, n_samples] + + Notes + ----- + In order to achieve maximal speed this function performs no checks of + any array metadata. Use the high-level functions defined in the + `sklearn.metrics.distance` module unless you really know what you're + doing. + """ + cdef np.npy_intp i, j, k + for i in range(X.shape[0]): + out[i, i] = 0 + for j in range(i + 1, X.shape[0]): + out[i, j] = 0 + for k in range(X.shape[1]): + out[i, j] += (X[i, k] - X[j, k]) ** 2 + out[j, i] = out[i, j] + + +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef fast_pair_sqdist_float64(np.ndarray[np.float64_t, ndim=2] X, + np.ndarray[np.float64_t, ndim=2] out): + """ + fast_pair_sqdist_float64(X, out) + + Low-level function for computing squared Euclidean distances between + every pair of points in a set. + + Parameters + ---------- + X : ndarray, float64, shape = [n_samples, n_features] + + out : ndarray, float64, shape = [n_samples, n_samples] + + Notes + ----- + In order to achieve maximal speed this function performs no checks of + any array metadata. Use the high-level functions defined in the + `sklearn.metrics.distance` module unless you really know what you're + doing. + """ + cdef np.npy_intp i, j, k + for i in range(X.shape[0]): + out[i, i] = 0 + for j in range(i + 1, X.shape[0]): + out[i, j] = 0 + for k in range(X.shape[1]): + out[i, j] += (X[i, k] - X[j, k]) ** 2 + out[j, i] = out[i, j]