Generated by Cython 3.0.11
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
Raw output: cut_finder.c
+001: # distutils: language = c
__pyx_t_7 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_7) < 0) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
002: # cython: boundscheck = False
003: # cython: wraparound = False
004: # cython: profile = False
005:
+006: import numpy as np
__pyx_t_7 = __Pyx_ImportDottedModule(__pyx_n_s_numpy, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_7) < 0) __PYX_ERR(0, 6, __pyx_L1_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
007: cimport numpy as np
008: cimport cython
009: from cython.parallel import prange
010: from libc.stdlib cimport malloc, free
011:
+012: ctypedef np.int32_t NP_INT_t
typedef __pyx_t_5numpy_int32_t __pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t;
013: ctypedef np.float64_t NP_FLOAT_t
014:
015: cdef extern from "<math.h>" nogil:
016: const float INFINITY
017:
018: cdef extern from "<limits.h>":
019: const int INT_MIN
020: const int INT_MAX
021:
+022: @cython.boundscheck(False)
/* Python wrapper */ static PyObject *__pyx_pw_5d_imm_9splitters_10cut_finder_1get_all_mistakes_histogram(PyObject *__pyx_self, #if CYTHON_METH_FASTCALL PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds #else PyObject *__pyx_args, PyObject *__pyx_kwds #endif ); /*proto*/ PyDoc_STRVAR(__pyx_doc_5d_imm_9splitters_10cut_finder_get_all_mistakes_histogram, "\n Main function to calculate mistakes for all features and thresholds.\n Returns a list of Python dictionaries with 'feature', 'threshold', and 'mistakes'.\n "); static PyMethodDef __pyx_mdef_5d_imm_9splitters_10cut_finder_1get_all_mistakes_histogram = {"get_all_mistakes_histogram", (PyCFunction)(void*)(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_5d_imm_9splitters_10cut_finder_1get_all_mistakes_histogram, __Pyx_METH_FASTCALL|METH_KEYWORDS, __pyx_doc_5d_imm_9splitters_10cut_finder_get_all_mistakes_histogram}; static PyObject *__pyx_pw_5d_imm_9splitters_10cut_finder_1get_all_mistakes_histogram(PyObject *__pyx_self, #if CYTHON_METH_FASTCALL PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds #else PyObject *__pyx_args, PyObject *__pyx_kwds #endif ) { __Pyx_memviewslice __pyx_v_X = { 0, 0, { 0 }, { 0 }, { 0 } }; __Pyx_memviewslice __pyx_v_y = { 0, 0, { 0 }, { 0 }, { 0 } }; __Pyx_memviewslice __pyx_v_centers = { 0, 0, { 0 }, { 0 }, { 0 } }; __Pyx_memviewslice __pyx_v_valid_centers = { 0, 0, { 0 }, { 0 }, { 0 } }; __Pyx_memviewslice __pyx_v_valid_cols = { 0, 0, { 0 }, { 0 }, { 0 } }; PyObject *__pyx_v_histogram = 0; int __pyx_v_njobs; #if !CYTHON_METH_FASTCALL CYTHON_UNUSED Py_ssize_t __pyx_nargs; #endif CYTHON_UNUSED PyObject *const *__pyx_kwvalues; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("get_all_mistakes_histogram (wrapper)", 0); #if !CYTHON_METH_FASTCALL #if CYTHON_ASSUME_SAFE_MACROS __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); #else __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; #endif #endif __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); { PyObject **__pyx_pyargnames[] = {&__pyx_n_s_X,&__pyx_n_s_y,&__pyx_n_s_centers,&__pyx_n_s_valid_centers,&__pyx_n_s_valid_cols,&__pyx_n_s_histogram,&__pyx_n_s_njobs,0}; PyObject* values[7] = {0,0,0,0,0,0,0}; if (__pyx_kwds) { Py_ssize_t kw_args; switch (__pyx_nargs) { case 7: values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); CYTHON_FALLTHROUGH; case 6: values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); CYTHON_FALLTHROUGH; case 5: values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); CYTHON_FALLTHROUGH; case 4: values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); CYTHON_FALLTHROUGH; case 3: values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); CYTHON_FALLTHROUGH; case 2: values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); CYTHON_FALLTHROUGH; case 1: values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = __Pyx_NumKwargs_FASTCALL(__pyx_kwds); switch (__pyx_nargs) { case 0: if (likely((values[0] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_X)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[0]); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 22, __pyx_L3_error) else goto __pyx_L5_argtuple_error; CYTHON_FALLTHROUGH; case 1: if (likely((values[1] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_y)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[1]); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 22, __pyx_L3_error) else { __Pyx_RaiseArgtupleInvalid("get_all_mistakes_histogram", 1, 7, 7, 1); __PYX_ERR(0, 22, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 2: if (likely((values[2] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_centers)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[2]); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 22, __pyx_L3_error) else { __Pyx_RaiseArgtupleInvalid("get_all_mistakes_histogram", 1, 7, 7, 2); __PYX_ERR(0, 22, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 3: if (likely((values[3] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_valid_centers)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[3]); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 22, __pyx_L3_error) else { __Pyx_RaiseArgtupleInvalid("get_all_mistakes_histogram", 1, 7, 7, 3); __PYX_ERR(0, 22, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 4: if (likely((values[4] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_valid_cols)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[4]); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 22, __pyx_L3_error) else { __Pyx_RaiseArgtupleInvalid("get_all_mistakes_histogram", 1, 7, 7, 4); __PYX_ERR(0, 22, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 5: if (likely((values[5] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_histogram)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[5]); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 22, __pyx_L3_error) else { __Pyx_RaiseArgtupleInvalid("get_all_mistakes_histogram", 1, 7, 7, 5); __PYX_ERR(0, 22, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 6: if (likely((values[6] = __Pyx_GetKwValue_FASTCALL(__pyx_kwds, __pyx_kwvalues, __pyx_n_s_njobs)) != 0)) { (void)__Pyx_Arg_NewRef_FASTCALL(values[6]); kw_args--; } else if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 22, __pyx_L3_error) else { __Pyx_RaiseArgtupleInvalid("get_all_mistakes_histogram", 1, 7, 7, 6); __PYX_ERR(0, 22, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { const Py_ssize_t kwd_pos_args = __pyx_nargs; if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values + 0, kwd_pos_args, "get_all_mistakes_histogram") < 0)) __PYX_ERR(0, 22, __pyx_L3_error) } } else if (unlikely(__pyx_nargs != 7)) { goto __pyx_L5_argtuple_error; } else { values[0] = __Pyx_Arg_FASTCALL(__pyx_args, 0); values[1] = __Pyx_Arg_FASTCALL(__pyx_args, 1); values[2] = __Pyx_Arg_FASTCALL(__pyx_args, 2); values[3] = __Pyx_Arg_FASTCALL(__pyx_args, 3); values[4] = __Pyx_Arg_FASTCALL(__pyx_args, 4); values[5] = __Pyx_Arg_FASTCALL(__pyx_args, 5); values[6] = __Pyx_Arg_FASTCALL(__pyx_args, 6); } __pyx_v_X = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t(values[0], PyBUF_WRITABLE); if (unlikely(!__pyx_v_X.memview)) __PYX_ERR(0, 25, __pyx_L3_error) __pyx_v_y = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t(values[1], PyBUF_WRITABLE); if (unlikely(!__pyx_v_y.memview)) __PYX_ERR(0, 25, __pyx_L3_error) __pyx_v_centers = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t(values[2], PyBUF_WRITABLE); if (unlikely(!__pyx_v_centers.memview)) __PYX_ERR(0, 25, __pyx_L3_error) __pyx_v_valid_centers = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t(values[3], PyBUF_WRITABLE); if (unlikely(!__pyx_v_valid_centers.memview)) __PYX_ERR(0, 26, __pyx_L3_error) __pyx_v_valid_cols = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t(values[4], PyBUF_WRITABLE); if (unlikely(!__pyx_v_valid_cols.memview)) __PYX_ERR(0, 26, __pyx_L3_error) __pyx_v_histogram = ((PyObject*)values[5]); __pyx_v_njobs = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_njobs == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 26, __pyx_L3_error) } goto __pyx_L6_skip; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("get_all_mistakes_histogram", 1, 7, 7, __pyx_nargs); __PYX_ERR(0, 22, __pyx_L3_error) __pyx_L6_skip:; goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; { Py_ssize_t __pyx_temp; for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); } } __PYX_XCLEAR_MEMVIEW(&__pyx_v_X, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_v_y, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_v_centers, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_v_valid_centers, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_v_valid_cols, 1); __Pyx_AddTraceback("d_imm.splitters.cut_finder.get_all_mistakes_histogram", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_histogram), (&PyList_Type), 1, "histogram", 1))) __PYX_ERR(0, 26, __pyx_L1_error) __pyx_r = __pyx_pf_5d_imm_9splitters_10cut_finder_get_all_mistakes_histogram(__pyx_self, __pyx_v_X, __pyx_v_y, __pyx_v_centers, __pyx_v_valid_centers, __pyx_v_valid_cols, __pyx_v_histogram, __pyx_v_njobs); int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; /* function exit code */ goto __pyx_L0; __pyx_L1_error:; __pyx_r = NULL; __pyx_L0:; __PYX_XCLEAR_MEMVIEW(&__pyx_v_X, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_v_y, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_v_centers, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_v_valid_centers, 1); __PYX_XCLEAR_MEMVIEW(&__pyx_v_valid_cols, 1); { Py_ssize_t __pyx_temp; for (__pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { __Pyx_Arg_XDECREF_FASTCALL(values[__pyx_temp]); } } __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_5d_imm_9splitters_10cut_finder_get_all_mistakes_histogram(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_X, __Pyx_memviewslice __pyx_v_y, __Pyx_memviewslice __pyx_v_centers, __Pyx_memviewslice __pyx_v_valid_centers, __Pyx_memviewslice __pyx_v_valid_cols, PyObject *__pyx_v_histogram, int __pyx_v_njobs) { int __pyx_v_n; int __pyx_v_k; int __pyx_v_d; PyObject *__pyx_v_feature_results = 0; int __pyx_v_col; PyObject *__pyx_r = NULL; /* … */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("d_imm.splitters.cut_finder.get_all_mistakes_histogram", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_feature_results); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* … */ __pyx_tuple__22 = PyTuple_Pack(12, __pyx_n_s_X, __pyx_n_s_y, __pyx_n_s_centers, __pyx_n_s_valid_centers, __pyx_n_s_valid_cols, __pyx_n_s_histogram, __pyx_n_s_njobs, __pyx_n_s_n, __pyx_n_s_k, __pyx_n_s_d, __pyx_n_s_feature_results, __pyx_n_s_col); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 22, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__22); __Pyx_GIVEREF(__pyx_tuple__22); /* … */ __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_5d_imm_9splitters_10cut_finder_1get_all_mistakes_histogram, 0, __pyx_n_s_get_all_mistakes_histogram, NULL, __pyx_n_s_d_imm_splitters_cut_finder, __pyx_d, ((PyObject *)__pyx_codeobj__23)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 22, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); if (PyDict_SetItem(__pyx_d, __pyx_n_s_get_all_mistakes_histogram, __pyx_t_7) < 0) __PYX_ERR(0, 22, __pyx_L1_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
023: @cython.wraparound(False)
024: def get_all_mistakes_histogram(
025: NP_FLOAT_t[:,:] X, NP_INT_t[:] y, NP_FLOAT_t[:,:] centers,
026: NP_INT_t[:] valid_centers, NP_INT_t[:] valid_cols, list histogram, int njobs
027: ):
028: """
029: Main function to calculate mistakes for all features and thresholds.
030: Returns a list of Python dictionaries with 'feature', 'threshold', and 'mistakes'.
031: """
+032: cdef int n = X.shape[0]
__pyx_v_n = (__pyx_v_X.shape[0]);
+033: cdef int k = centers.shape[0]
__pyx_v_k = (__pyx_v_centers.shape[0]);
+034: cdef int d = valid_cols.shape[0]
__pyx_v_d = (__pyx_v_valid_cols.shape[0]);
+035: cdef list feature_results = []
__pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_feature_results = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0;
036: cdef int col
037:
+038: if njobs is None or njobs <= 1:
__pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_njobs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 38, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = (__pyx_t_1 == Py_None); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (!__pyx_t_3) { } else { __pyx_t_2 = __pyx_t_3; goto __pyx_L4_bool_binop_done; } __pyx_t_3 = (__pyx_v_njobs <= 1); __pyx_t_2 = __pyx_t_3; __pyx_L4_bool_binop_done:; if (__pyx_t_2) { /* … */ goto __pyx_L3; }
039: # Iterate over valid columns
+040: for col in range(d):
__pyx_t_4 = __pyx_v_d; __pyx_t_5 = __pyx_t_4; for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { __pyx_v_col = __pyx_t_6;
+041: if valid_cols[col] == 1:
__pyx_t_7 = __pyx_v_col; __pyx_t_2 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t *) ( /* dim=0 */ (__pyx_v_valid_cols.data + __pyx_t_7 * __pyx_v_valid_cols.strides[0]) ))) == 1); if (__pyx_t_2) { /* … */ } }
+042: update_col_all_mistakes_histogram_unsorted(
__pyx_f_5d_imm_9splitters_10cut_finder_update_col_all_mistakes_histogram_unsorted(__pyx_v_X, __pyx_v_y, __pyx_v_centers, __pyx_v_valid_centers, __pyx_v_col, __pyx_v_n, __pyx_v_k, __pyx_v_feature_results, ((PyObject*)__pyx_t_1)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 42, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
043: X, y, centers, valid_centers,
+044: col, n, k, feature_results, histogram[col]
if (unlikely(__pyx_v_histogram == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); __PYX_ERR(0, 44, __pyx_L1_error) } if (!(likely(PyList_CheckExact(PyList_GET_ITEM(__pyx_v_histogram, __pyx_v_col)))||((PyList_GET_ITEM(__pyx_v_histogram, __pyx_v_col)) == Py_None) || __Pyx_RaiseUnexpectedTypeError("list", PyList_GET_ITEM(__pyx_v_histogram, __pyx_v_col)))) __PYX_ERR(0, 44, __pyx_L1_error) __pyx_t_1 = PyList_GET_ITEM(__pyx_v_histogram, __pyx_v_col); __Pyx_INCREF(__pyx_t_1);
045: )
046: else:
047: # Parallelize the process
+048: for col in prange(d, num_threads=njobs, schedule='dynamic', nogil=True): # Removed nogil=True
/*else*/ { { #ifdef WITH_THREAD PyThreadState *_save; _save = NULL; Py_UNBLOCK_THREADS __Pyx_FastGIL_Remember(); #endif /*try:*/ { __pyx_t_4 = __pyx_v_d; { #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))))) #undef likely #undef unlikely #define likely(x) (x) #define unlikely(x) (x) #endif __pyx_t_6 = (__pyx_t_4 - 0 + 1 - 1/abs(1)) / 1; if (__pyx_t_6 > 0) { #ifdef _OPENMP #pragma omp parallel #endif /* _OPENMP */ { #ifdef _OPENMP #pragma omp for firstprivate(__pyx_v_col) lastprivate(__pyx_v_col) schedule(dynamic) __pyx_t_4 = __pyx_v_d; { #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))))) #undef likely #undef unlikely #define likely(x) (x) #define unlikely(x) (x) #endif __pyx_t_6 = (__pyx_t_4 - 0 + 1 - 1/abs(1)) / 1; if (__pyx_t_6 > 0) { #ifdef _OPENMP #pragma omp parallel #endif /* _OPENMP */ { #ifdef _OPENMP #pragma omp for firstprivate(__pyx_v_col) lastprivate(__pyx_v_col) schedule(dynamic) num_threads(__pyx_v_njobs) #endif /* _OPENMP */ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_6; __pyx_t_5++){ { __pyx_v_col = (int)(0 + 1 * __pyx_t_5); /* … */ /*finally:*/ { /*normal exit:*/{ #ifdef WITH_THREAD __Pyx_FastGIL_Forget(); Py_BLOCK_THREADS #endif goto __pyx_L11; } __pyx_L10_error: { #ifdef WITH_THREAD __Pyx_FastGIL_Forget(); Py_BLOCK_THREADS #endif goto __pyx_L1_error; } __pyx_L11:; } } } __pyx_L3:;
+049: if valid_cols[col] == 1:
__pyx_t_7 = __pyx_v_col; __pyx_t_2 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t *) ( /* dim=0 */ (__pyx_v_valid_cols.data + __pyx_t_7 * __pyx_v_valid_cols.strides[0]) ))) == 1); if (__pyx_t_2) { /* … */ } goto __pyx_L23; __pyx_L14_error:; { #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif #ifdef _OPENMP #pragma omp flush(__pyx_parallel_exc_type) #endif /* _OPENMP */ if (!__pyx_parallel_exc_type) { __Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb); __pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno; __Pyx_GOTREF(__pyx_parallel_exc_type); } #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif } __pyx_parallel_why = 4; goto __pyx_L22; __pyx_L22:; #ifdef _OPENMP #pragma omp critical(__pyx_parallel_lastprivates0) #endif /* _OPENMP */ { __pyx_parallel_temp0 = __pyx_v_col; } __pyx_L23:; #ifdef _OPENMP #pragma omp flush(__pyx_parallel_why) #endif /* _OPENMP */ } } #ifdef _OPENMP Py_END_ALLOW_THREADS #else { #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif #endif /* _OPENMP */ /* Clean up any temporaries */ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif #ifndef _OPENMP } #endif /* _OPENMP */ } } if (__pyx_parallel_exc_type) { /* This may have been overridden by a continue, break or return in another thread. Prefer the error. */ __pyx_parallel_why = 4; } if (__pyx_parallel_why) { __pyx_v_col = __pyx_parallel_temp0; switch (__pyx_parallel_why) { case 4: { #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif __Pyx_GIVEREF(__pyx_parallel_exc_type); __Pyx_ErrRestoreWithState(__pyx_parallel_exc_type, __pyx_parallel_exc_value, __pyx_parallel_exc_tb); __pyx_filename = __pyx_parallel_filename; __pyx_lineno = __pyx_parallel_lineno; __pyx_clineno = __pyx_parallel_clineno; #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif } goto __pyx_L10_error; } } } #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))))) #undef likely #undef unlikely #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #endif }
+050: with gil:
{ #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif /*try:*/ { /* … */ /*finally:*/ { /*normal exit:*/{ #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif goto __pyx_L21; } __pyx_L20_error: { #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif goto __pyx_L14_error; } __pyx_L21:; } }
+051: update_col_all_mistakes_histogram_unsorted(
__pyx_f_5d_imm_9splitters_10cut_finder_update_col_all_mistakes_histogram_unsorted(__pyx_v_X, __pyx_v_y, __pyx_v_centers, __pyx_v_valid_centers, __pyx_v_col, __pyx_v_n, __pyx_v_k, __pyx_v_feature_results, ((PyObject*)__pyx_t_1)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 51, __pyx_L20_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; }
052: X, y, centers, valid_centers,
+053: col, n, k, feature_results, histogram[col]
if (unlikely(__pyx_v_histogram == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); __PYX_ERR(0, 53, __pyx_L20_error) } if (!(likely(PyList_CheckExact(PyList_GET_ITEM(__pyx_v_histogram, __pyx_v_col)))||((PyList_GET_ITEM(__pyx_v_histogram, __pyx_v_col)) == Py_None) || __Pyx_RaiseUnexpectedTypeError("list", PyList_GET_ITEM(__pyx_v_histogram, __pyx_v_col)))) __PYX_ERR(0, 53, __pyx_L20_error) __pyx_t_1 = PyList_GET_ITEM(__pyx_v_histogram, __pyx_v_col); __Pyx_INCREF(__pyx_t_1);
054: )
055:
+056: return feature_results
__Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_feature_results); __pyx_r = __pyx_v_feature_results; goto __pyx_L0;
057:
058:
059: @cython.boundscheck(False)
060: @cython.wraparound(False)
+061: cdef void update_col_all_mistakes_histogram_unsorted(
static void __pyx_f_5d_imm_9splitters_10cut_finder_update_col_all_mistakes_histogram_unsorted(__Pyx_memviewslice __pyx_v_X, __Pyx_memviewslice __pyx_v_y, __Pyx_memviewslice __pyx_v_centers, __Pyx_memviewslice __pyx_v_valid_centers, int __pyx_v_col, int __pyx_v_n, int __pyx_v_k, PyObject *__pyx_v_feature_results, PyObject *__pyx_v_histogram) { int __pyx_v_i; int __pyx_v_ix; CYTHON_UNUSED int __pyx_v_ic; int __pyx_v_mistakes; __pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t __pyx_v_threshold; CYTHON_UNUSED __Pyx_memviewslice __pyx_v_centers_order = { 0, 0, { 0 }, { 0 }, { 0 } }; int __pyx_v_num_thresholds; __pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *__pyx_v_combined_thresholds; __pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t __pyx_v_max_val; __pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t __pyx_v_min_val; PyObject *__pyx_v_unique_thresholds = NULL; PyObject *__pyx_v_split = NULL; PyObject *__pyx_v_sorted_thresholds = NULL; /* … */ /* function exit code */ goto __pyx_L0; __pyx_L1_error:; #ifdef WITH_THREAD __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_8); __Pyx_XDECREF(__pyx_t_9); __Pyx_XDECREF(__pyx_t_10); __PYX_XCLEAR_MEMVIEW(&__pyx_t_11, 1); __Pyx_XDECREF(__pyx_t_12); __PYX_XCLEAR_MEMVIEW(&__pyx_t_14, 1); __Pyx_AddTraceback("d_imm.splitters.cut_finder.update_col_all_mistakes_histogram_unsorted", __pyx_clineno, __pyx_lineno, __pyx_filename); #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif __pyx_L0:; __PYX_XCLEAR_MEMVIEW(&__pyx_v_centers_order, 0); #ifdef WITH_THREAD __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif __Pyx_XDECREF(__pyx_v_unique_thresholds); __Pyx_XDECREF(__pyx_v_split); __Pyx_XDECREF(__pyx_v_sorted_thresholds); __Pyx_RefNannyFinishContext(); #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif }
062: NP_FLOAT_t[:,:] X, NP_INT_t[:] y, NP_FLOAT_t[:,:] centers,
063: NP_INT_t[:] valid_centers,
064: int col, int n, int k,
065: list feature_results, list histogram) nogil: # Marked as noexcept
066: """
067: Helper function to calculate mistakes for a single column using histogram-based and center-based thresholds.
068: Appends the results as Python dictionaries to feature_results.
069: """
070: cdef int i
+071: cdef int ix = 0
__pyx_v_ix = 0;
+072: cdef int ic = 0
__pyx_v_ic = 0;
+073: cdef int mistakes = 0
__pyx_v_mistakes = 0;
074: cdef NP_FLOAT_t threshold
075: cdef np.int64_t[:] centers_order
076: cdef int num_thresholds
077: cdef NP_FLOAT_t *combined_thresholds
078: cdef NP_FLOAT_t max_val
079: cdef NP_FLOAT_t min_val
080:
081: # Find the maximum and minimum valid center values
+082: max_val = -INFINITY
__pyx_v_max_val = (-INFINITY);
+083: min_val = INFINITY
__pyx_v_min_val = INFINITY;
084:
+085: for i in range(k):
__pyx_t_1 = __pyx_v_k; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3;
+086: if valid_centers[i] == 1:
__pyx_t_4 = __pyx_v_i; __pyx_t_5 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t *) ( /* dim=0 */ (__pyx_v_valid_centers.data + __pyx_t_4 * __pyx_v_valid_centers.strides[0]) ))) == 1); if (__pyx_t_5) { /* … */ } }
+087: if centers[i, col] > max_val:
__pyx_t_4 = __pyx_v_i; __pyx_t_6 = __pyx_v_col; __pyx_t_5 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_centers.data + __pyx_t_4 * __pyx_v_centers.strides[0]) ) + __pyx_t_6 * __pyx_v_centers.strides[1]) ))) > __pyx_v_max_val); if (__pyx_t_5) { /* … */ }
+088: max_val = centers[i, col]
__pyx_t_6 = __pyx_v_i; __pyx_t_4 = __pyx_v_col; __pyx_v_max_val = (*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_centers.data + __pyx_t_6 * __pyx_v_centers.strides[0]) ) + __pyx_t_4 * __pyx_v_centers.strides[1]) )));
+089: if centers[i, col] < min_val:
__pyx_t_4 = __pyx_v_i; __pyx_t_6 = __pyx_v_col; __pyx_t_5 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_centers.data + __pyx_t_4 * __pyx_v_centers.strides[0]) ) + __pyx_t_6 * __pyx_v_centers.strides[1]) ))) < __pyx_v_min_val); if (__pyx_t_5) { /* … */ }
+090: min_val = centers[i, col]
__pyx_t_6 = __pyx_v_i; __pyx_t_4 = __pyx_v_col; __pyx_v_min_val = (*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_centers.data + __pyx_t_6 * __pyx_v_centers.strides[0]) ) + __pyx_t_4 * __pyx_v_centers.strides[1]) )));
091:
092: # Sorting and threshold combination
+093: with gil:
{ #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif /*try:*/ { /* … */ /*finally:*/ { /*normal exit:*/{ #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif goto __pyx_L10; } __pyx_L9_error: { #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif goto __pyx_L1_error; } __pyx_L10:; } }
+094: centers_order = np.asarray(centers[:, col]).argsort()
__Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_np); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 94, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_asarray); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 94, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_10); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; __pyx_t_11.data = __pyx_v_centers.data; __pyx_t_11.memview = __pyx_v_centers.memview; __PYX_INC_MEMVIEW(&__pyx_t_11, 1); __pyx_t_11.shape[0] = __pyx_v_centers.shape[0]; __pyx_t_11.strides[0] = __pyx_v_centers.strides[0]; __pyx_t_11.suboffsets[0] = -1; { Py_ssize_t __pyx_tmp_idx = __pyx_v_col; Py_ssize_t __pyx_tmp_stride = __pyx_v_centers.strides[1]; __pyx_t_11.data += __pyx_tmp_idx * __pyx_tmp_stride; } __pyx_t_9 = __pyx_memoryview_fromslice(__pyx_t_11, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t, 0);; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 94, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_9); __PYX_XCLEAR_MEMVIEW(&__pyx_t_11, 1); __pyx_t_11.memview = NULL; __pyx_t_11.data = NULL; __pyx_t_12 = NULL; __pyx_t_13 = 0; #if CYTHON_UNPACK_METHODS if (unlikely(PyMethod_Check(__pyx_t_10))) { __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_10); if (likely(__pyx_t_12)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10); __Pyx_INCREF(__pyx_t_12); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_10, function); __pyx_t_13 = 1; } } #endif { PyObject *__pyx_callargs[2] = {__pyx_t_12, __pyx_t_9}; __pyx_t_8 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_13, 1+__pyx_t_13); __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 94, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_8); __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; } __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_argsort); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 94, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_10); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __pyx_t_8 = NULL; __pyx_t_13 = 0; #if CYTHON_UNPACK_METHODS if (likely(PyMethod_Check(__pyx_t_10))) { __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_10); if (likely(__pyx_t_8)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10); __Pyx_INCREF(__pyx_t_8); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_10, function); __pyx_t_13 = 1; } } #endif { PyObject *__pyx_callargs[2] = {__pyx_t_8, NULL}; __pyx_t_7 = __Pyx_PyObject_FastCall(__pyx_t_10, __pyx_callargs+1-__pyx_t_13, 0+__pyx_t_13); __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 94, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; } __pyx_t_14 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(__pyx_t_7, PyBUF_WRITABLE); if (unlikely(!__pyx_t_14.memview)) __PYX_ERR(0, 94, __pyx_L9_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __pyx_v_centers_order = __pyx_t_14; __pyx_t_14.memview = NULL; __pyx_t_14.data = NULL;
095:
096: # Combine histogram-based and center-based thresholds
+097: unique_thresholds = set()
__pyx_t_7 = PySet_New(0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 97, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_7); __pyx_v_unique_thresholds = ((PyObject*)__pyx_t_7); __pyx_t_7 = 0;
+098: for split in histogram:
if (unlikely(__pyx_v_histogram == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); __PYX_ERR(0, 98, __pyx_L9_error) } __pyx_t_7 = __pyx_v_histogram; __Pyx_INCREF(__pyx_t_7); __pyx_t_15 = 0; for (;;) { { Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_7); #if !CYTHON_ASSUME_SAFE_MACROS if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 98, __pyx_L9_error) #endif if (__pyx_t_15 >= __pyx_temp) break; } #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS __pyx_t_10 = PyList_GET_ITEM(__pyx_t_7, __pyx_t_15); __Pyx_INCREF(__pyx_t_10); __pyx_t_15++; if (unlikely((0 < 0))) __PYX_ERR(0, 98, __pyx_L9_error) #else __pyx_t_10 = __Pyx_PySequence_ITEM(__pyx_t_7, __pyx_t_15); __pyx_t_15++; if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 98, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_10); #endif __Pyx_XDECREF_SET(__pyx_v_split, __pyx_t_10); __pyx_t_10 = 0; /* … */ } __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+099: if min_val <= split.threshold < max_val:
__pyx_t_10 = PyFloat_FromDouble(__pyx_v_min_val); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 99, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_10); __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_split, __pyx_n_s_threshold); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 99, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_8); __pyx_t_9 = PyObject_RichCompare(__pyx_t_10, __pyx_t_8, Py_LE); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 99, __pyx_L9_error) if (__Pyx_PyObject_IsTrue(__pyx_t_9)) { __Pyx_DECREF(__pyx_t_9); __pyx_t_12 = PyFloat_FromDouble(__pyx_v_max_val); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 99, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_12); __pyx_t_9 = PyObject_RichCompare(__pyx_t_8, __pyx_t_12, Py_LT); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 99, __pyx_L9_error) __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; } __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 99, __pyx_L9_error) __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; if (__pyx_t_5) { /* … */ }
+100: unique_thresholds.add(split.threshold)
__pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_split, __pyx_n_s_threshold); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 100, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_16 = PySet_Add(__pyx_v_unique_thresholds, __pyx_t_9); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 100, __pyx_L9_error) __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
101:
+102: for i in range(k):
__pyx_t_1 = __pyx_v_k; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3;
+103: if valid_centers[i] == 1 and centers[i, col]!=max_val:
__pyx_t_4 = __pyx_v_i; __pyx_t_17 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t *) ( /* dim=0 */ (__pyx_v_valid_centers.data + __pyx_t_4 * __pyx_v_valid_centers.strides[0]) ))) == 1); if (__pyx_t_17) { } else { __pyx_t_5 = __pyx_t_17; goto __pyx_L18_bool_binop_done; } __pyx_t_4 = __pyx_v_i; __pyx_t_6 = __pyx_v_col; __pyx_t_17 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_centers.data + __pyx_t_4 * __pyx_v_centers.strides[0]) ) + __pyx_t_6 * __pyx_v_centers.strides[1]) ))) != __pyx_v_max_val); __pyx_t_5 = __pyx_t_17; __pyx_L18_bool_binop_done:; if (__pyx_t_5) { /* … */ } }
+104: unique_thresholds.add(centers[i, col])
__pyx_t_6 = __pyx_v_i; __pyx_t_4 = __pyx_v_col; __pyx_t_7 = PyFloat_FromDouble((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_centers.data + __pyx_t_6 * __pyx_v_centers.strides[0]) ) + __pyx_t_4 * __pyx_v_centers.strides[1]) )))); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 104, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_7); __pyx_t_16 = PySet_Add(__pyx_v_unique_thresholds, __pyx_t_7); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 104, __pyx_L9_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
105:
+106: sorted_thresholds = sorted(unique_thresholds)
__pyx_t_9 = PySequence_List(__pyx_v_unique_thresholds); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 106, __pyx_L9_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_7 = ((PyObject*)__pyx_t_9); __pyx_t_9 = 0; __pyx_t_16 = PyList_Sort(__pyx_t_7); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 106, __pyx_L9_error) __pyx_v_sorted_thresholds = ((PyObject*)__pyx_t_7); __pyx_t_7 = 0;
107:
+108: num_thresholds = len(sorted_thresholds)
__pyx_t_15 = __Pyx_PyList_GET_SIZE(__pyx_v_sorted_thresholds); if (unlikely(__pyx_t_15 == ((Py_ssize_t)-1))) __PYX_ERR(0, 108, __pyx_L9_error) __pyx_v_num_thresholds = __pyx_t_15;
+109: combined_thresholds = <NP_FLOAT_t *> malloc(num_thresholds * sizeof(NP_FLOAT_t))
__pyx_v_combined_thresholds = ((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *)malloc((__pyx_v_num_thresholds * (sizeof(__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t)))));
110:
+111: for i in range(num_thresholds):
__pyx_t_1 = __pyx_v_num_thresholds; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3;
+112: combined_thresholds[i] = sorted_thresholds[i]
__pyx_t_18 = __pyx_PyFloat_AsDouble(PyList_GET_ITEM(__pyx_v_sorted_thresholds, __pyx_v_i)); if (unlikely((__pyx_t_18 == ((npy_float64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 112, __pyx_L9_error) (__pyx_v_combined_thresholds[__pyx_v_i]) = __pyx_t_18; } }
113:
114: # Process each threshold
+115: for i in range(num_thresholds):
__pyx_t_1 = __pyx_v_num_thresholds; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3;
+116: mistakes = 0
__pyx_v_mistakes = 0;
+117: ix = 0
__pyx_v_ix = 0;
+118: threshold = combined_thresholds[i]
__pyx_v_threshold = (__pyx_v_combined_thresholds[__pyx_v_i]);
119:
120: # Count mistakes
+121: while ix < n:
while (1) { __pyx_t_5 = (__pyx_v_ix < __pyx_v_n); if (!__pyx_t_5) break;
+122: if X[ix, col] <= threshold:
__pyx_t_4 = __pyx_v_ix; __pyx_t_6 = __pyx_v_col; __pyx_t_5 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_X.data + __pyx_t_4 * __pyx_v_X.strides[0]) ) + __pyx_t_6 * __pyx_v_X.strides[1]) ))) <= __pyx_v_threshold); if (__pyx_t_5) { /* … */ goto __pyx_L26; }
+123: if centers[y[ix], col] > threshold:
__pyx_t_6 = __pyx_v_ix; __pyx_t_4 = (*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t *) ( /* dim=0 */ (__pyx_v_y.data + __pyx_t_6 * __pyx_v_y.strides[0]) ))); __pyx_t_19 = __pyx_v_col; __pyx_t_5 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_centers.data + __pyx_t_4 * __pyx_v_centers.strides[0]) ) + __pyx_t_19 * __pyx_v_centers.strides[1]) ))) > __pyx_v_threshold); if (__pyx_t_5) { /* … */ }
+124: mistakes += 1
__pyx_v_mistakes = (__pyx_v_mistakes + 1);
125: else:
+126: if centers[y[ix], col] <= threshold:
/*else*/ { __pyx_t_6 = __pyx_v_ix; __pyx_t_19 = (*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_INT_t *) ( /* dim=0 */ (__pyx_v_y.data + __pyx_t_6 * __pyx_v_y.strides[0]) ))); __pyx_t_4 = __pyx_v_col; __pyx_t_5 = ((*((__pyx_t_5d_imm_9splitters_10cut_finder_NP_FLOAT_t *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_centers.data + __pyx_t_19 * __pyx_v_centers.strides[0]) ) + __pyx_t_4 * __pyx_v_centers.strides[1]) ))) <= __pyx_v_threshold); if (__pyx_t_5) { /* … */ } } __pyx_L26:;
+127: mistakes += 1
__pyx_v_mistakes = (__pyx_v_mistakes + 1);
+128: ix += 1
__pyx_v_ix = (__pyx_v_ix + 1); }
129:
130: # Store result
+131: with gil:
{ #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure(); #endif /*try:*/ { /* … */ /*finally:*/ { /*normal exit:*/{ #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif goto __pyx_L33; } __pyx_L32_error: { #ifdef WITH_THREAD __Pyx_PyGILState_Release(__pyx_gilstate_save); #endif goto __pyx_L1_error; } __pyx_L33:; } } }
+132: feature_results.append({
if (unlikely(__pyx_v_feature_results == Py_None)) { PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); __PYX_ERR(0, 132, __pyx_L32_error) } /* … */ __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_feature_results, __pyx_t_7); if (unlikely(__pyx_t_16 == ((int)-1))) __PYX_ERR(0, 132, __pyx_L32_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; }
+133: 'feature': col,
__pyx_t_7 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 133, __pyx_L32_error) __Pyx_GOTREF(__pyx_t_7); __pyx_t_9 = __Pyx_PyInt_From_int(__pyx_v_col); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 133, __pyx_L32_error) __Pyx_GOTREF(__pyx_t_9); if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_feature, __pyx_t_9) < 0) __PYX_ERR(0, 133, __pyx_L32_error) __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+134: 'threshold': threshold,
__pyx_t_9 = PyFloat_FromDouble(__pyx_v_threshold); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 134, __pyx_L32_error) __Pyx_GOTREF(__pyx_t_9); if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_threshold, __pyx_t_9) < 0) __PYX_ERR(0, 133, __pyx_L32_error) __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+135: 'mistakes': mistakes
__pyx_t_9 = __Pyx_PyInt_From_int(__pyx_v_mistakes); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 135, __pyx_L32_error) __Pyx_GOTREF(__pyx_t_9); if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_mistakes, __pyx_t_9) < 0) __PYX_ERR(0, 133, __pyx_L32_error) __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
136: })
137:
+138: free(combined_thresholds)
free(__pyx_v_combined_thresholds);