From e1c1f7bc69ab2f415684657f84e958f66c764cd5 Mon Sep 17 00:00:00 2001
From: yohila +
" to see the C code that Cython generated for it.
Raw output: _criterion.c
-+001: # cython: cdivision=True
++001: # cython: cdivision=True
__pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; -
002: # cython: boundscheck=False
- 003: # cython: wraparound=False
+002: # cython: boundscheck=False+
003: # cython: wraparound=False
004:
- 005: from libc.stdlib cimport calloc
- 006: from libc.stdlib cimport free
- 007: from libc.string cimport memcpy
- 008: from libc.string cimport memset
- 009: from libc.math cimport fabs
+005: from libc.stdlib cimport calloc+
006: from libc.stdlib cimport free+
007: from libc.string cimport memcpy+
008: from libc.string cimport memset+
009: from libc.math cimport fabs
010:
-+011: import numpy as np
++011: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 11, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(1, 11, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; -
012: cimport numpy as np
-+013: np.import_array()
+012: cimport numpy as np+
+013: np.import_array()
__pyx_t_2 = __pyx_f_5numpy_import_array(); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error)
014:
- 015: from sklearn.tree._utils cimport log
- 016: from sklearn.tree._utils cimport safe_realloc
- 017: from sklearn.tree._utils cimport sizet_ptr_to_ndarray
- 018: from sklearn.tree._utils cimport WeightedMedianCalculator
+015: from sklearn.tree._utils cimport log+
016: from sklearn.tree._utils cimport safe_realloc+
017: from sklearn.tree._utils cimport sizet_ptr_to_ndarray+
018: from sklearn.tree._utils cimport WeightedMedianCalculator
019:
- 020: # from kernel import Kernel
+020: # from kernel import Kernel
021:
-+022: cdef class Criterion:
++022: cdef class Criterion:
struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion { int (*init)(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *, __Pyx_memviewslice, __pyx_t_7sklearn_4tree_5_tree_DOUBLE_t *, double, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *, __pyx_t_7sklearn_4tree_5_tree_SIZE_t, __pyx_t_7sklearn_4tree_5_tree_SIZE_t); int (*reset)(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *); @@ -339,13 +413,13 @@ }; static struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_vtabptr_13stpredictions_6models_3OK3_10_criterion_Criterion; -
023: """Interface for impurity criteria.
+023: """Interface for impurity criteria.
024:
- 025: This object stores methods on how to calculate how good a split is using
- 026: different metrics.
- 027: """
+025: This object stores methods on how to calculate how good a split is using+
026: different metrics.+
027: """
028:
-+029: def __dealloc__(self):
++029: def __dealloc__(self):
/* Python wrapper */
static void __pyx_pw_13stpredictions_6models_3OK3_10_criterion_9Criterion_1__dealloc__(PyObject *__pyx_v_self); /*proto*/
static void __pyx_pw_13stpredictions_6models_3OK3_10_criterion_9Criterion_1__dealloc__(PyObject *__pyx_v_self) {
@@ -364,11 +438,11 @@
/* function exit code */
__Pyx_RefNannyFinishContext();
}
-
030: """Destructor."""
+030: """Destructor."""
031:
- 032: pass
+032: pass
033:
-+034: def __getstate__(self):
++034: def __getstate__(self):
/* Python wrapper */
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_10_criterion_9Criterion_3__getstate__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_10_criterion_9Criterion_3__getstate__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
@@ -397,7 +471,7 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
+035: return {}
++035: return {}
__Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 35, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); @@ -405,7 +479,7 @@ __pyx_t_1 = 0; goto __pyx_L0;
036:
-+037: def __setstate__(self, d):
++037: def __setstate__(self, d):
/* Python wrapper */
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_10_criterion_9Criterion_5__setstate__(PyObject *__pyx_v_self, PyObject *__pyx_v_d); /*proto*/
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_10_criterion_9Criterion_5__setstate__(PyObject *__pyx_v_self, PyObject *__pyx_v_d) {
@@ -430,9 +504,9 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
038: pass
+038: pass
039:
-+040: cdef int init(self, const DOUBLE_t[:, ::1] y, DOUBLE_t* sample_weight,
++040: cdef int init(self, const DOUBLE_t[:, ::1] y, DOUBLE_t* sample_weight,
static int __pyx_f_13stpredictions_6models_3OK3_10_criterion_9Criterion_init(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_v_self, CYTHON_UNUSED __Pyx_memviewslice __pyx_v_y, CYTHON_UNUSED __pyx_t_7sklearn_4tree_5_tree_DOUBLE_t *__pyx_v_sample_weight, CYTHON_UNUSED double __pyx_v_weighted_n_samples, CYTHON_UNUSED __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, CYTHON_UNUSED __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start, CYTHON_UNUSED __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_end) { int __pyx_r; @@ -440,34 +514,34 @@ __pyx_r = 0; return __pyx_r; } -
041: double weighted_n_samples, SIZE_t* samples, SIZE_t start,
- 042: SIZE_t end) nogil except -1:
- 043: """Placeholder for a method which will initialize the criterion.
+041: double weighted_n_samples, SIZE_t* samples, SIZE_t start,+
042: SIZE_t end) nogil except -1:+
043: """Placeholder for a method which will initialize the criterion.
044:
- 045: Returns -1 in case of failure to allocate memory (and raise MemoryError)
- 046: or 0 otherwise.
+045: Returns -1 in case of failure to allocate memory (and raise MemoryError)+
046: or 0 otherwise.
047:
- 048: Parameters
- 049: ----------
- 050: y : array-like, dtype=DOUBLE_t
- 051: y is a buffer that stores values of the output Gramm matrix of the samples
- 052: sample_weight : array-like, dtype=DOUBLE_t
- 053: The weight of each sample
- 054: weighted_n_samples : double
- 055: The total weight of the samples being considered
- 056: samples : array-like, dtype=SIZE_t
- 057: Indices of the samples in X and y, where samples[start:end]
- 058: correspond to the samples in this node
- 059: start : SIZE_t
- 060: The first sample to be used on this node
- 061: end : SIZE_t
- 062: The last sample used on this node
+048: Parameters+
049: ----------+
050: y : array-like, dtype=DOUBLE_t+
051: y is a buffer that stores values of the output Gramm matrix of the samples+
052: sample_weight : array-like, dtype=DOUBLE_t+
053: The weight of each sample+
054: weighted_n_samples : double+
055: The total weight of the samples being considered+
056: samples : array-like, dtype=SIZE_t+
057: Indices of the samples in X and y, where samples[start:end]+
058: correspond to the samples in this node+
059: start : SIZE_t+
060: The first sample to be used on this node+
061: end : SIZE_t+
062: The last sample used on this node
063:
- 064: """
+064: """
065:
- 066: pass
+066: pass
067:
-+068: cdef int reset(self) nogil except -1:
++068: cdef int reset(self) nogil except -1:
static int __pyx_f_13stpredictions_6models_3OK3_10_criterion_9Criterion_reset(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_v_self) { int __pyx_r; @@ -475,14 +549,14 @@ __pyx_r = 0; return __pyx_r; } -
069: """Reset the criterion at pos=start.
+069: """Reset the criterion at pos=start.
070:
- 071: This method must be implemented by the subclass.
- 072: """
+071: This method must be implemented by the subclass.+
072: """
073:
- 074: pass
+074: pass
075:
-+076: cdef int reverse_reset(self) nogil except -1:
++076: cdef int reverse_reset(self) nogil except -1:
static int __pyx_f_13stpredictions_6models_3OK3_10_criterion_9Criterion_reverse_reset(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_v_self) { int __pyx_r; @@ -490,13 +564,13 @@ __pyx_r = 0; return __pyx_r; } -
077: """Reset the criterion at pos=end.
+077: """Reset the criterion at pos=end.
078:
- 079: This method must be implemented by the subclass.
- 080: """
- 081: pass
+079: This method must be implemented by the subclass.+
080: """+
081: pass
082:
-+083: cdef int update(self, SIZE_t new_pos) nogil except -1:
++083: cdef int update(self, SIZE_t new_pos) nogil except -1:
static int __pyx_f_13stpredictions_6models_3OK3_10_criterion_9Criterion_update(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_v_self, CYTHON_UNUSED __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_new_pos) { int __pyx_r; @@ -504,21 +578,21 @@ __pyx_r = 0; return __pyx_r; } -
084: """Updated statistics by moving samples[pos:new_pos] to the left child.
+084: """Updated statistics by moving samples[pos:new_pos] to the left child.
085:
- 086: This updates the collected statistics by moving samples[pos:new_pos]
- 087: from the right child to the left child. It must be implemented by
- 088: the subclass.
+086: This updates the collected statistics by moving samples[pos:new_pos]+
087: from the right child to the left child. It must be implemented by+
088: the subclass.
089:
- 090: Parameters
- 091: ----------
- 092: new_pos : SIZE_t
- 093: New starting index position of the samples in the right child
- 094: """
+090: Parameters+
091: ----------+
092: new_pos : SIZE_t+
093: New starting index position of the samples in the right child+
094: """
095:
- 096: pass
+096: pass
097:
-+098: cdef double node_impurity(self) nogil:
++098: cdef double node_impurity(self) nogil:
static double __pyx_f_13stpredictions_6models_3OK3_10_criterion_9Criterion_node_impurity(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_v_self) { double __pyx_r; @@ -526,58 +600,58 @@ __pyx_r = 0; return __pyx_r; } -
099: """Placeholder for calculating the impurity of the node.
+099: """Placeholder for calculating the impurity of the node.
100:
- 101: Placeholder for a method which will evaluate the impurity of
- 102: the current node, i.e. the impurity of samples[start:end]. This is the
- 103: primary function of the criterion class.
- 104: """
+101: Placeholder for a method which will evaluate the impurity of+
102: the current node, i.e. the impurity of samples[start:end]. This is the+
103: primary function of the criterion class.+
104: """
105:
- 106: pass
+106: pass
107:
-+108: cdef void children_impurity(self, double* impurity_left,
++108: cdef void children_impurity(self, double* impurity_left,
static void __pyx_f_13stpredictions_6models_3OK3_10_criterion_9Criterion_children_impurity(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_v_self, CYTHON_UNUSED double *__pyx_v_impurity_left, CYTHON_UNUSED double *__pyx_v_impurity_right) { /* function exit code */ } -
109: double* impurity_right) nogil:
- 110: """Placeholder for calculating the impurity of children.
+109: double* impurity_right) nogil:+
110: """Placeholder for calculating the impurity of children.
111:
- 112: Placeholder for a method which evaluates the impurity in
- 113: children nodes, i.e. the impurity of samples[start:pos] + the impurity
- 114: of samples[pos:end].
+112: Placeholder for a method which evaluates the impurity in+
113: children nodes, i.e. the impurity of samples[start:pos] + the impurity+
114: of samples[pos:end].
115:
- 116: Parameters
- 117: ----------
- 118: impurity_left : double pointer
- 119: The memory address where the impurity of the left child should be
- 120: stored.
- 121: impurity_right : double pointer
- 122: The memory address where the impurity of the right child should be
- 123: stored
- 124: """
+116: Parameters+
117: ----------+
118: impurity_left : double pointer+
119: The memory address where the impurity of the left child should be+
120: stored.+
121: impurity_right : double pointer+
122: The memory address where the impurity of the right child should be+
123: stored+
124: """
125:
- 126: pass
+126: pass
127:
-+128: cdef void node_value(self, double* dest) nogil:
++128: cdef void node_value(self, double* dest) nogil:
static void __pyx_f_13stpredictions_6models_3OK3_10_criterion_9Criterion_node_value(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_v_self, CYTHON_UNUSED double *__pyx_v_dest) { /* function exit code */ } -
129: """Placeholder for storing the node value.
+129: """Placeholder for storing the node value.
130:
- 131: Placeholder for a method which will save the weighted
- 132: samples[start:end] into dest.
+131: Placeholder for a method which will save the weighted+
132: samples[start:end] into dest.
133:
- 134: Parameters
- 135: ----------
- 136: dest : double pointer
- 137: The memory address where the node value should be stored.
- 138: """
+134: Parameters+
135: ----------+
136: dest : double pointer+
137: The memory address where the node value should be stored.+
138: """
139:
- 140: pass
+140: pass
141:
-+142: cdef double proxy_impurity_improvement(self) nogil:
++142: cdef double proxy_impurity_improvement(self) nogil:
static double __pyx_f_13stpredictions_6models_3OK3_10_criterion_9Criterion_proxy_impurity_improvement(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_v_self) { double __pyx_r; @@ -585,26 +659,26 @@ __pyx_r = 0; return __pyx_r; } -
143: """Compute a proxy of the impurity reduction
+143: """Compute a proxy of the impurity reduction
144:
- 145: This method is used to speed up the search for the best split.
- 146: It is a proxy quantity such that the split that maximizes this value
- 147: also maximizes the impurity improvement. It neglects all constant terms
- 148: of the impurity decrease for a given split.
+145: This method is used to speed up the search for the best split.+
146: It is a proxy quantity such that the split that maximizes this value+
147: also maximizes the impurity improvement. It neglects all constant terms+
148: of the impurity decrease for a given split.
149:
- 150: The absolute impurity improvement is only computed by the
- 151: impurity_improvement method once the best split has been found.
- 152: """
- 153: # cdef double impurity_left
- 154: # cdef double impurity_right
- 155: # self.children_impurity(&impurity_left, &impurity_right)
+150: The absolute impurity improvement is only computed by the+
151: impurity_improvement method once the best split has been found.+
152: """+
153: # cdef double impurity_left+
154: # cdef double impurity_right+
155: # self.children_impurity(&impurity_left, &impurity_right)
156:
- 157: # return (- self.weighted_n_right * impurity_right
- 158: # - self.weighted_n_left * impurity_left)
+157: # return (- self.weighted_n_right * impurity_right+
158: # - self.weighted_n_left * impurity_left)
159:
- 160: pass
+160: pass
161:
-+162: cdef double impurity_improvement(self, double impurity) nogil:
++162: cdef double impurity_improvement(self, double impurity) nogil:
static double __pyx_f_13stpredictions_6models_3OK3_10_criterion_9Criterion_impurity_improvement(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *__pyx_v_self, double __pyx_v_impurity) { double __pyx_v_impurity_left; double __pyx_v_impurity_right; @@ -614,32 +688,32 @@ __pyx_L0:; return __pyx_r; } -
163: """Compute the improvement in impurity
+163: """Compute the improvement in impurity
164:
- 165: This method computes the improvement in impurity when a split occurs.
- 166: The weighted impurity improvement equation is the following:
+165: This method computes the improvement in impurity when a split occurs.+
166: The weighted impurity improvement equation is the following:
167:
- 168: N_t / N * (impurity - N_t_R / N_t * right_impurity
- 169: - N_t_L / N_t * left_impurity)
+168: N_t / N * (impurity - N_t_R / N_t * right_impurity+
169: - N_t_L / N_t * left_impurity)
170:
- 171: where N is the total number of samples, N_t is the number of samples
- 172: at the current node, N_t_L is the number of samples in the left child,
- 173: and N_t_R is the number of samples in the right child,
+171: where N is the total number of samples, N_t is the number of samples+
172: at the current node, N_t_L is the number of samples in the left child,+
173: and N_t_R is the number of samples in the right child,
174:
- 175: Parameters
- 176: ----------
- 177: impurity : double
- 178: The initial impurity of the node before the split
+175: Parameters+
176: ----------+
177: impurity : double+
178: The initial impurity of the node before the split
179:
- 180: Return
- 181: ------
- 182: double : improvement in impurity after the split occurs
- 183: """
+180: Return+
181: ------+
182: double : improvement in impurity after the split occurs+
183: """
184:
- 185: cdef double impurity_left
- 186: cdef double impurity_right
+185: cdef double impurity_left+
186: cdef double impurity_right
187:
-+188: self.children_impurity(&impurity_left, &impurity_right)
++188: self.children_impurity(&impurity_left, &impurity_right)
/* "stpredictions/models/OK3/_criterion.pyx":188 * cdef double impurity_right @@ -650,13 +724,13 @@ */ ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_vtab)->children_impurity(__pyx_v_self, (&__pyx_v_impurity_left), (&__pyx_v_impurity_right));
189:
-+190: return ((self.weighted_n_node_samples / self.weighted_n_samples) *
++190: return ((self.weighted_n_node_samples / self.weighted_n_samples) *
__pyx_r = ((__pyx_v_self->weighted_n_node_samples / __pyx_v_self->weighted_n_samples) * ((__pyx_v_impurity - ((__pyx_v_self->weighted_n_right / __pyx_v_self->weighted_n_node_samples) * __pyx_v_impurity_right)) - ((__pyx_v_self->weighted_n_left / __pyx_v_self->weighted_n_node_samples) * __pyx_v_impurity_left))); goto __pyx_L0; -
191: (impurity - (self.weighted_n_right /
- 192: self.weighted_n_node_samples * impurity_right)
- 193: - (self.weighted_n_left /
- 194: self.weighted_n_node_samples * impurity_left)))
+191: (impurity - (self.weighted_n_right /+
192: self.weighted_n_node_samples * impurity_right)+
193: - (self.weighted_n_left /+
194: self.weighted_n_node_samples * impurity_left)))
195:
196:
197:
@@ -671,21 +745,21 @@
206:
207:
208:
-+209: cdef class KernelizedRegressionCriterion(Criterion):
++209: cdef class KernelizedRegressionCriterion(Criterion):
struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion { struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion __pyx_base; }; static struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion *__pyx_vtabptr_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion; -
210: r"""Abstract kernelized output regression criterion.
+210: r"""Abstract kernelized output regression criterion.
211:
- 212: This handles cases where the target is a structured object and the Gramm
- 213: matrix (the matrix of the kernel evaluated at the output samples) is given
- 214: as y. The impurity is evaluated by computing the variance of the target
- 215: values (embedded in a larger Hilbert space) left and right of the split point.
- 216: """
+212: This handles cases where the target is a structured object and the Gramm+
213: matrix (the matrix of the kernel evaluated at the output samples) is given+
214: as y. The impurity is evaluated by computing the variance of the target+
215: values (embedded in a larger Hilbert space) left and right of the split point.+
216: """
217:
-+218: def __cinit__(self, SIZE_t n_samples):
++218: def __cinit__(self, SIZE_t n_samples):
/* Python wrapper */
static int __pyx_pw_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static int __pyx_pw_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
@@ -749,55 +823,55 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
219: """Initialize parameters for this criterion.
+219: """Initialize parameters for this criterion.
220:
- 221: Parameters
- 222: ----------
- 223: n_samples : SIZE_t
- 224: The total number of samples to fit on
- 225: """
+221: Parameters+
222: ----------+
223: n_samples : SIZE_t+
224: The total number of samples to fit on+
225: """
226:
- 227: # Default values
-+228: self.sample_weight = NULL
+227: # Default values+
+228: self.sample_weight = NULL
__pyx_v_self->__pyx_base.sample_weight = NULL;
229:
-+230: self.samples = NULL
++230: self.samples = NULL
__pyx_v_self->__pyx_base.samples = NULL; -
+231: self.start = 0
++231: self.start = 0
__pyx_v_self->__pyx_base.start = 0; -
+232: self.pos = 0
++232: self.pos = 0
__pyx_v_self->__pyx_base.pos = 0; -
+233: self.end = 0
++233: self.end = 0
__pyx_v_self->__pyx_base.end = 0;
234:
-+235: self.n_samples = n_samples
++235: self.n_samples = n_samples
__pyx_v_self->__pyx_base.n_samples = __pyx_v_n_samples; -
+236: self.n_node_samples = 0
++236: self.n_node_samples = 0
__pyx_v_self->__pyx_base.n_node_samples = 0; -
+237: self.weighted_n_node_samples = 0.0
++237: self.weighted_n_node_samples = 0.0
__pyx_v_self->__pyx_base.weighted_n_node_samples = 0.0; -
+238: self.weighted_n_left = 0.0
++238: self.weighted_n_left = 0.0
__pyx_v_self->__pyx_base.weighted_n_left = 0.0; -
+239: self.weighted_n_right = 0.0
++239: self.weighted_n_right = 0.0
__pyx_v_self->__pyx_base.weighted_n_right = 0.0;
240:
-+241: self.sum_diag_Gramm = 0.0
++241: self.sum_diag_Gramm = 0.0
__pyx_v_self->sum_diag_Gramm = 0.0; -
+242: self.sum_total_Gramm = 0.0
++242: self.sum_total_Gramm = 0.0
__pyx_v_self->sum_total_Gramm = 0.0;
243:
-+244: self.sum_diag_Gramm_left = 0.0
++244: self.sum_diag_Gramm_left = 0.0
__pyx_v_self->sum_diag_Gramm_left = 0.0; -
+245: self.sum_diag_Gramm_right = 0.0
++245: self.sum_diag_Gramm_right = 0.0
__pyx_v_self->sum_diag_Gramm_right = 0.0;
246:
-+247: self.sum_total_Gramm_left = 0.0
++247: self.sum_total_Gramm_left = 0.0
__pyx_v_self->sum_total_Gramm_left = 0.0; -
+248: self.sum_total_Gramm_right = 0.0
++248: self.sum_total_Gramm_right = 0.0
__pyx_v_self->sum_total_Gramm_right = 0.0;
249:
250:
-+251: def __reduce__(self):
++251: def __reduce__(self):
/* Python wrapper */
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_3__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_3__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
@@ -829,7 +903,7 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
+252: return (type(self), (self.n_samples,), self.__getstate__())
++252: return (type(self), (self.n_samples,), self.__getstate__())
__Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyInt_From_Py_intptr_t(__pyx_v_self->__pyx_base.n_samples); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 252, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); @@ -870,7 +944,7 @@ __pyx_t_3 = 0; goto __pyx_L0;
253:
-+254: cdef int init(self, const DOUBLE_t[:, ::1] y, DOUBLE_t* sample_weight,
++254: cdef int init(self, const DOUBLE_t[:, ::1] y, DOUBLE_t* sample_weight,
static int __pyx_f_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_init(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion *__pyx_v_self, __Pyx_memviewslice __pyx_v_y, __pyx_t_7sklearn_4tree_5_tree_DOUBLE_t *__pyx_v_sample_weight, double __pyx_v_weighted_n_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_end) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_i; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_j; @@ -895,98 +969,98 @@ __pyx_L0:; return __pyx_r; } -
255: double weighted_n_samples, SIZE_t* samples, SIZE_t start,
- 256: SIZE_t end) nogil except -1:
- 257: """Initialize the criterion at node samples[start:end] and
- 258: children samples[start:start] and samples[start:end]."""
- 259: # Initialize fields
-+260: self.y = y
+255: double weighted_n_samples, SIZE_t* samples, SIZE_t start,+
256: SIZE_t end) nogil except -1:+
257: """Initialize the criterion at node samples[start:end] and+
258: children samples[start:start] and samples[start:end]."""+
259: # Initialize fields+
+260: self.y = y
__PYX_XDEC_MEMVIEW(&__pyx_v_self->__pyx_base.y, 0); __PYX_INC_MEMVIEW(&__pyx_v_y, 1); __pyx_v_self->__pyx_base.y = __pyx_v_y; -
+261: self.sample_weight = sample_weight
++261: self.sample_weight = sample_weight
__pyx_v_self->__pyx_base.sample_weight = __pyx_v_sample_weight; -
+262: self.samples = samples
++262: self.samples = samples
__pyx_v_self->__pyx_base.samples = __pyx_v_samples; -
+263: self.start = start
++263: self.start = start
__pyx_v_self->__pyx_base.start = __pyx_v_start; -
+264: self.end = end
++264: self.end = end
__pyx_v_self->__pyx_base.end = __pyx_v_end; -
+265: self.n_node_samples = end - start
++265: self.n_node_samples = end - start
__pyx_v_self->__pyx_base.n_node_samples = (__pyx_v_end - __pyx_v_start); -
+266: self.weighted_n_samples = weighted_n_samples
++266: self.weighted_n_samples = weighted_n_samples
__pyx_v_self->__pyx_base.weighted_n_samples = __pyx_v_weighted_n_samples; -
+267: self.weighted_n_node_samples = 0.
++267: self.weighted_n_node_samples = 0.
__pyx_v_self->__pyx_base.weighted_n_node_samples = 0.;
268:
- 269: cdef SIZE_t i
- 270: cdef SIZE_t j
- 271: cdef SIZE_t p
- 272: cdef SIZE_t q
-+273: cdef DOUBLE_t w_i = 1.0
+269: cdef SIZE_t i+
270: cdef SIZE_t j+
271: cdef SIZE_t p+
272: cdef SIZE_t q+
+273: cdef DOUBLE_t w_i = 1.0
__pyx_v_w_i = 1.0; -
+274: cdef DOUBLE_t w_j = 1.0
++274: cdef DOUBLE_t w_j = 1.0
__pyx_v_w_j = 1.0;
275:
-+276: self.sum_diag_Gramm = 0.0
++276: self.sum_diag_Gramm = 0.0
__pyx_v_self->sum_diag_Gramm = 0.0; -
+277: self.sum_total_Gramm = 0.0
++277: self.sum_total_Gramm = 0.0
__pyx_v_self->sum_total_Gramm = 0.0;
278:
-+279: self.sum_diag_Gramm_left = 0.0
++279: self.sum_diag_Gramm_left = 0.0
__pyx_v_self->sum_diag_Gramm_left = 0.0; -
+280: self.sum_diag_Gramm_right = 0.0
++280: self.sum_diag_Gramm_right = 0.0
__pyx_v_self->sum_diag_Gramm_right = 0.0;
281:
-+282: self.sum_total_Gramm_left = 0.0
++282: self.sum_total_Gramm_left = 0.0
__pyx_v_self->sum_total_Gramm_left = 0.0; -
+283: self.sum_total_Gramm_right = 0.0
++283: self.sum_total_Gramm_right = 0.0
__pyx_v_self->sum_total_Gramm_right = 0.0;
284:
-+285: for p in range(start, end):
++285: for p in range(start, end):
__pyx_t_1 = __pyx_v_end; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = __pyx_v_start; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_p = __pyx_t_3; -
+286: i = samples[p]
++286: i = samples[p]
__pyx_v_i = (__pyx_v_samples[__pyx_v_p]); -
287: # with gil:
- 288: # print("print samples :",i)
+287: # with gil:+
288: # print("print samples :",i)
289:
-+290: if sample_weight != NULL:
++290: if sample_weight != NULL:
__pyx_t_4 = ((__pyx_v_sample_weight != NULL) != 0); if (__pyx_t_4) { /* … */ } -
+291: w_i = sample_weight[i]
++291: w_i = sample_weight[i]
__pyx_v_w_i = (__pyx_v_sample_weight[__pyx_v_i]);
292:
-+293: self.weighted_n_node_samples += w_i
++293: self.weighted_n_node_samples += w_i
__pyx_v_self->__pyx_base.weighted_n_node_samples = (__pyx_v_self->__pyx_base.weighted_n_node_samples + __pyx_v_w_i);
294:
-+295: self.sum_diag_Gramm += w_i * self.y[i,i]
++295: self.sum_diag_Gramm += w_i * self.y[i,i]
if (unlikely(!__pyx_v_self->__pyx_base.y.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(1, 295, __pyx_L1_error)} __pyx_t_5 = __pyx_v_i; __pyx_t_6 = __pyx_v_i; __pyx_v_self->sum_diag_Gramm = (__pyx_v_self->sum_diag_Gramm + (__pyx_v_w_i * (*((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=1 */ ((char *) (((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=0 */ (__pyx_v_self->__pyx_base.y.data + __pyx_t_5 * __pyx_v_self->__pyx_base.y.strides[0]) )) + __pyx_t_6)) )))));
296:
-+297: for q in range(start, end):
++297: for q in range(start, end):
__pyx_t_7 = __pyx_v_end; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = __pyx_v_start; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_q = __pyx_t_9; -
+298: j = samples[q]
++298: j = samples[q]
__pyx_v_j = (__pyx_v_samples[__pyx_v_q]);
299:
-+300: if sample_weight != NULL:
++300: if sample_weight != NULL:
__pyx_t_4 = ((__pyx_v_sample_weight != NULL) != 0); if (__pyx_t_4) { /* … */ } -
+301: w_j = sample_weight[j]
++301: w_j = sample_weight[j]
__pyx_v_w_j = (__pyx_v_sample_weight[__pyx_v_j]);
302:
-+303: self.sum_total_Gramm += w_i * w_j * self.y[i,j]
++303: self.sum_total_Gramm += w_i * w_j * self.y[i,j]
if (unlikely(!__pyx_v_self->__pyx_base.y.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(1, 303, __pyx_L1_error)} __pyx_t_6 = __pyx_v_i; __pyx_t_5 = __pyx_v_j; @@ -994,18 +1068,18 @@ } }
304:
- 305: # Reset to pos=start
-+306: self.reset()
+305: # Reset to pos=start+
+306: self.reset()
__pyx_t_10 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base.reset(((struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self)); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(1, 306, __pyx_L1_error)
-
307: # with gil:
- 308: # print("print sum diag :",self.sum_diag_Gramm)
- 309: # print("print sum total :",self.sum_total_Gramm)
- 310: # print("print weighted_n_node_samples :",self.weighted_n_node_samples)
-+311: return 0
+307: # with gil:+
308: # print("print sum diag :",self.sum_diag_Gramm)+
309: # print("print sum total :",self.sum_total_Gramm)+
310: # print("print weighted_n_node_samples :",self.weighted_n_node_samples)+
+311: return 0
__pyx_r = 0; goto __pyx_L0;
312:
-+313: cdef int reset(self) nogil except -1:
++313: cdef int reset(self) nogil except -1:
static int __pyx_f_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_reset(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion *__pyx_v_self) { int __pyx_r; /* … */ @@ -1013,33 +1087,33 @@ __pyx_L0:; return __pyx_r; } -
314: """Reset the criterion at pos=start."""
+314: """Reset the criterion at pos=start."""
315:
-+316: self.sum_diag_Gramm_left = 0.0
++316: self.sum_diag_Gramm_left = 0.0
__pyx_v_self->sum_diag_Gramm_left = 0.0; -
+317: self.sum_diag_Gramm_right = self.sum_diag_Gramm
++317: self.sum_diag_Gramm_right = self.sum_diag_Gramm
__pyx_t_1 = __pyx_v_self->sum_diag_Gramm; __pyx_v_self->sum_diag_Gramm_right = __pyx_t_1;
318:
-+319: self.sum_total_Gramm_left = 0.0
++319: self.sum_total_Gramm_left = 0.0
__pyx_v_self->sum_total_Gramm_left = 0.0; -
+320: self.sum_total_Gramm_right = self.sum_total_Gramm
++320: self.sum_total_Gramm_right = self.sum_total_Gramm
__pyx_t_1 = __pyx_v_self->sum_total_Gramm; __pyx_v_self->sum_total_Gramm_right = __pyx_t_1;
321:
-+322: self.weighted_n_left = 0.0
++322: self.weighted_n_left = 0.0
__pyx_v_self->__pyx_base.weighted_n_left = 0.0; -
+323: self.weighted_n_right = self.weighted_n_node_samples
++323: self.weighted_n_right = self.weighted_n_node_samples
__pyx_t_1 = __pyx_v_self->__pyx_base.weighted_n_node_samples; __pyx_v_self->__pyx_base.weighted_n_right = __pyx_t_1; -
+324: self.pos = self.start
++324: self.pos = self.start
__pyx_t_2 = __pyx_v_self->__pyx_base.start; __pyx_v_self->__pyx_base.pos = __pyx_t_2; -
+325: return 0
++325: return 0
__pyx_r = 0; goto __pyx_L0;
326:
-+327: cdef int reverse_reset(self) nogil except -1:
++327: cdef int reverse_reset(self) nogil except -1:
static int __pyx_f_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_reverse_reset(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion *__pyx_v_self) { int __pyx_r; /* … */ @@ -1047,33 +1121,33 @@ __pyx_L0:; return __pyx_r; } -
328: """Reset the criterion at pos=end."""
+328: """Reset the criterion at pos=end."""
329:
-+330: self.sum_diag_Gramm_right = 0.0
++330: self.sum_diag_Gramm_right = 0.0
__pyx_v_self->sum_diag_Gramm_right = 0.0; -
+331: self.sum_diag_Gramm_left = self.sum_diag_Gramm
++331: self.sum_diag_Gramm_left = self.sum_diag_Gramm
__pyx_t_1 = __pyx_v_self->sum_diag_Gramm; __pyx_v_self->sum_diag_Gramm_left = __pyx_t_1;
332:
-+333: self.sum_total_Gramm_right = 0.0
++333: self.sum_total_Gramm_right = 0.0
__pyx_v_self->sum_total_Gramm_right = 0.0; -
+334: self.sum_total_Gramm_left = self.sum_total_Gramm
++334: self.sum_total_Gramm_left = self.sum_total_Gramm
__pyx_t_1 = __pyx_v_self->sum_total_Gramm; __pyx_v_self->sum_total_Gramm_left = __pyx_t_1;
335:
-+336: self.weighted_n_right = 0.0
++336: self.weighted_n_right = 0.0
__pyx_v_self->__pyx_base.weighted_n_right = 0.0; -
+337: self.weighted_n_left = self.weighted_n_node_samples
++337: self.weighted_n_left = self.weighted_n_node_samples
__pyx_t_1 = __pyx_v_self->__pyx_base.weighted_n_node_samples; __pyx_v_self->__pyx_base.weighted_n_left = __pyx_t_1; -
+338: self.pos = self.end
++338: self.pos = self.end
__pyx_t_2 = __pyx_v_self->__pyx_base.end; __pyx_v_self->__pyx_base.pos = __pyx_t_2; -
+339: return 0
++339: return 0
__pyx_r = 0; goto __pyx_L0;
340:
-+341: cdef int update(self, SIZE_t new_pos) nogil except -1:
++341: cdef int update(self, SIZE_t new_pos) nogil except -1:
static int __pyx_f_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_update(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion *__pyx_v_self, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_new_pos) { double *__pyx_v_sample_weight; __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples; @@ -1103,116 +1177,116 @@ __pyx_L0:; return __pyx_r; } -
342: """Updated statistics by moving samples[pos:new_pos] to the left."""
+342: """Updated statistics by moving samples[pos:new_pos] to the left."""
343:
-+344: cdef double* sample_weight = self.sample_weight
++344: cdef double* sample_weight = self.sample_weight
__pyx_t_1 = __pyx_v_self->__pyx_base.sample_weight; __pyx_v_sample_weight = __pyx_t_1; -
+345: cdef SIZE_t* samples = self.samples
++345: cdef SIZE_t* samples = self.samples
__pyx_t_2 = __pyx_v_self->__pyx_base.samples; __pyx_v_samples = __pyx_t_2;
346:
-+347: cdef SIZE_t start = self.start
++347: cdef SIZE_t start = self.start
__pyx_t_3 = __pyx_v_self->__pyx_base.start; __pyx_v_start = __pyx_t_3; -
+348: cdef SIZE_t pos = self.pos
++348: cdef SIZE_t pos = self.pos
__pyx_t_3 = __pyx_v_self->__pyx_base.pos; __pyx_v_pos = __pyx_t_3; -
+349: cdef SIZE_t end = self.end
++349: cdef SIZE_t end = self.end
__pyx_t_3 = __pyx_v_self->__pyx_base.end; __pyx_v_end = __pyx_t_3;
350:
- 351: cdef SIZE_t i
- 352: cdef SIZE_t j
- 353: cdef SIZE_t p
- 354: cdef SIZE_t q
-+355: cdef DOUBLE_t w_i = 1.0
+351: cdef SIZE_t i+
352: cdef SIZE_t j+
353: cdef SIZE_t p+
354: cdef SIZE_t q+
+355: cdef DOUBLE_t w_i = 1.0
__pyx_v_w_i = 1.0; -
+356: cdef DOUBLE_t w_j = 1.0
++356: cdef DOUBLE_t w_j = 1.0
__pyx_v_w_j = 1.0;
357:
- 358: # Update statistics up to new_pos
+358: # Update statistics up to new_pos
359:
-+360: for p in range(pos, new_pos):
++360: for p in range(pos, new_pos):
__pyx_t_3 = __pyx_v_new_pos; __pyx_t_4 = __pyx_t_3; for (__pyx_t_5 = __pyx_v_pos; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { __pyx_v_p = __pyx_t_5; -
+361: i = samples[p]
++361: i = samples[p]
__pyx_v_i = (__pyx_v_samples[__pyx_v_p]);
362:
-+363: if sample_weight != NULL:
++363: if sample_weight != NULL:
__pyx_t_6 = ((__pyx_v_sample_weight != NULL) != 0); if (__pyx_t_6) { /* … */ } -
+364: w_i = sample_weight[i]
++364: w_i = sample_weight[i]
__pyx_v_w_i = (__pyx_v_sample_weight[__pyx_v_i]);
365:
-+366: self.sum_diag_Gramm_left += w_i * self.y[i,i]
++366: self.sum_diag_Gramm_left += w_i * self.y[i,i]
if (unlikely(!__pyx_v_self->__pyx_base.y.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(1, 366, __pyx_L1_error)} __pyx_t_7 = __pyx_v_i; __pyx_t_8 = __pyx_v_i; __pyx_v_self->sum_diag_Gramm_left = (__pyx_v_self->sum_diag_Gramm_left + (__pyx_v_w_i * (*((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=1 */ ((char *) (((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=0 */ (__pyx_v_self->__pyx_base.y.data + __pyx_t_7 * __pyx_v_self->__pyx_base.y.strides[0]) )) + __pyx_t_8)) )))));
367:
-+368: self.sum_diag_Gramm_right -= w_i * self.y[i,i]
++368: self.sum_diag_Gramm_right -= w_i * self.y[i,i]
if (unlikely(!__pyx_v_self->__pyx_base.y.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(1, 368, __pyx_L1_error)} __pyx_t_8 = __pyx_v_i; __pyx_t_7 = __pyx_v_i; __pyx_v_self->sum_diag_Gramm_right = (__pyx_v_self->sum_diag_Gramm_right - (__pyx_v_w_i * (*((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=1 */ ((char *) (((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=0 */ (__pyx_v_self->__pyx_base.y.data + __pyx_t_8 * __pyx_v_self->__pyx_base.y.strides[0]) )) + __pyx_t_7)) )))));
369:
-+370: self.weighted_n_left += w_i
++370: self.weighted_n_left += w_i
__pyx_v_self->__pyx_base.weighted_n_left = (__pyx_v_self->__pyx_base.weighted_n_left + __pyx_v_w_i);
371:
-+372: self.weighted_n_right -= w_i
++372: self.weighted_n_right -= w_i
__pyx_v_self->__pyx_base.weighted_n_right = (__pyx_v_self->__pyx_base.weighted_n_right - __pyx_v_w_i);
373:
-+374: for q in range(start, pos):
++374: for q in range(start, pos):
__pyx_t_9 = __pyx_v_pos; __pyx_t_10 = __pyx_t_9; for (__pyx_t_11 = __pyx_v_start; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { __pyx_v_q = __pyx_t_11; -
+375: j = samples[q]
++375: j = samples[q]
__pyx_v_j = (__pyx_v_samples[__pyx_v_q]);
376:
-+377: if sample_weight != NULL:
++377: if sample_weight != NULL:
__pyx_t_6 = ((__pyx_v_sample_weight != NULL) != 0); if (__pyx_t_6) { /* … */ } -
+378: w_j = sample_weight[j]
++378: w_j = sample_weight[j]
__pyx_v_w_j = (__pyx_v_sample_weight[__pyx_v_j]);
379:
-+380: self.sum_total_Gramm_left += 2 * w_i * w_j * self.y[i,j]
++380: self.sum_total_Gramm_left += 2 * w_i * w_j * self.y[i,j]
if (unlikely(!__pyx_v_self->__pyx_base.y.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(1, 380, __pyx_L1_error)} __pyx_t_7 = __pyx_v_i; __pyx_t_8 = __pyx_v_j; __pyx_v_self->sum_total_Gramm_left = (__pyx_v_self->sum_total_Gramm_left + (((2.0 * __pyx_v_w_i) * __pyx_v_w_j) * (*((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=1 */ ((char *) (((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=0 */ (__pyx_v_self->__pyx_base.y.data + __pyx_t_7 * __pyx_v_self->__pyx_base.y.strides[0]) )) + __pyx_t_8)) ))))); }
381:
-+382: for q in range(pos, new_pos):
++382: for q in range(pos, new_pos):
__pyx_t_9 = __pyx_v_new_pos; __pyx_t_10 = __pyx_t_9; for (__pyx_t_11 = __pyx_v_pos; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { __pyx_v_q = __pyx_t_11; -
+383: j = samples[q]
++383: j = samples[q]
__pyx_v_j = (__pyx_v_samples[__pyx_v_q]);
384:
-+385: if sample_weight != NULL:
++385: if sample_weight != NULL:
__pyx_t_6 = ((__pyx_v_sample_weight != NULL) != 0); if (__pyx_t_6) { /* … */ } -
+386: w_j = sample_weight[j]
++386: w_j = sample_weight[j]
__pyx_v_w_j = (__pyx_v_sample_weight[__pyx_v_j]);
387:
-+388: self.sum_total_Gramm_left += w_i * w_j * self.y[i,j]
++388: self.sum_total_Gramm_left += w_i * w_j * self.y[i,j]
if (unlikely(!__pyx_v_self->__pyx_base.y.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(1, 388, __pyx_L1_error)} __pyx_t_8 = __pyx_v_i; __pyx_t_7 = __pyx_v_j; __pyx_v_self->sum_total_Gramm_left = (__pyx_v_self->sum_total_Gramm_left + ((__pyx_v_w_i * __pyx_v_w_j) * (*((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=1 */ ((char *) (((__pyx_t_7sklearn_4tree_5_tree_DOUBLE_t const *) ( /* dim=0 */ (__pyx_v_self->__pyx_base.y.data + __pyx_t_8 * __pyx_v_self->__pyx_base.y.strides[0]) )) + __pyx_t_7)) )))));
389:
-+390: self.sum_total_Gramm_right -= w_i * w_j * self.y[i,j]
++390: self.sum_total_Gramm_right -= w_i * w_j * self.y[i,j]
if (unlikely(!__pyx_v_self->__pyx_base.y.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(1, 390, __pyx_L1_error)} __pyx_t_7 = __pyx_v_i; __pyx_t_8 = __pyx_v_j; @@ -1220,39 +1294,39 @@ } }
391:
-+392: for p in range(new_pos, end):
++392: for p in range(new_pos, end):
__pyx_t_3 = __pyx_v_end; __pyx_t_4 = __pyx_t_3; for (__pyx_t_5 = __pyx_v_new_pos; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { __pyx_v_p = __pyx_t_5; -
+393: i = samples[p]
++393: i = samples[p]
__pyx_v_i = (__pyx_v_samples[__pyx_v_p]);
394:
-+395: if sample_weight != NULL:
++395: if sample_weight != NULL:
__pyx_t_6 = ((__pyx_v_sample_weight != NULL) != 0); if (__pyx_t_6) { /* … */ } -
+396: w_i = sample_weight[i]
++396: w_i = sample_weight[i]
__pyx_v_w_i = (__pyx_v_sample_weight[__pyx_v_i]);
397:
-+398: for q in range(pos, new_pos):
++398: for q in range(pos, new_pos):
__pyx_t_9 = __pyx_v_new_pos; __pyx_t_10 = __pyx_t_9; for (__pyx_t_11 = __pyx_v_pos; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { __pyx_v_q = __pyx_t_11; -
+399: j = samples[q]
++399: j = samples[q]
__pyx_v_j = (__pyx_v_samples[__pyx_v_q]);
400:
-+401: if sample_weight != NULL:
++401: if sample_weight != NULL:
__pyx_t_6 = ((__pyx_v_sample_weight != NULL) != 0); if (__pyx_t_6) { /* … */ } -
+402: w_j = sample_weight[j]
++402: w_j = sample_weight[j]
__pyx_v_w_j = (__pyx_v_sample_weight[__pyx_v_j]);
403:
-+404: self.sum_total_Gramm_right -= 2 * w_i * w_j * self.y[i,j]
++404: self.sum_total_Gramm_right -= 2 * w_i * w_j * self.y[i,j]
if (unlikely(!__pyx_v_self->__pyx_base.y.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(1, 404, __pyx_L1_error)} __pyx_t_8 = __pyx_v_i; __pyx_t_7 = __pyx_v_j; @@ -1260,13 +1334,13 @@ } }
405:
-+406: self.pos = new_pos
++406: self.pos = new_pos
__pyx_v_self->__pyx_base.pos = __pyx_v_new_pos; -
+407: return 0
++407: return 0
__pyx_r = 0; goto __pyx_L0;
408:
-+409: cdef double node_impurity(self) nogil:
++409: cdef double node_impurity(self) nogil:
static double __pyx_f_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_node_impurity(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion *__pyx_v_self) { double __pyx_r; @@ -1274,16 +1348,16 @@ __pyx_r = 0; return __pyx_r; } -
410: pass
+410: pass
411:
-+412: cdef void children_impurity(self, double* impurity_left, double* impurity_right) nogil:
++412: cdef void children_impurity(self, double* impurity_left, double* impurity_right) nogil:
static void __pyx_f_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_children_impurity(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion *__pyx_v_self, CYTHON_UNUSED double *__pyx_v_impurity_left, CYTHON_UNUSED double *__pyx_v_impurity_right) { /* function exit code */ } -
413: pass
+413: pass
414:
-+415: cdef void node_value(self, double* dest) nogil:
++415: cdef void node_value(self, double* dest) nogil:
static void __pyx_f_13stpredictions_6models_3OK3_10_criterion_29KernelizedRegressionCriterion_node_value(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion *__pyx_v_self, double *__pyx_v_dest) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_p; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_k; @@ -1291,31 +1365,31 @@ /* … */ /* function exit code */ } -
416: """Compute the node value of samples[start:end] into dest."""
+416: """Compute the node value of samples[start:end] into dest."""
417:
- 418: cdef SIZE_t p
- 419: cdef SIZE_t k
-+420: cdef DOUBLE_t w = 1.0
+418: cdef SIZE_t p+
419: cdef SIZE_t k+
+420: cdef DOUBLE_t w = 1.0
__pyx_v_w = 1.0;
421:
-+422: for p in range(self.start, self.end):
++422: for p in range(self.start, self.end):
__pyx_t_1 = __pyx_v_self->__pyx_base.end; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = __pyx_v_self->__pyx_base.start; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_p = __pyx_t_3;
423:
-+424: k = self.samples[p]
++424: k = self.samples[p]
__pyx_v_k = (__pyx_v_self->__pyx_base.samples[__pyx_v_p]);
425:
-+426: if self.sample_weight != NULL:
++426: if self.sample_weight != NULL:
__pyx_t_4 = ((__pyx_v_self->__pyx_base.sample_weight != NULL) != 0); if (__pyx_t_4) { /* … */ } -
+427: w = self.sample_weight[k]
++427: w = self.sample_weight[k]
__pyx_v_w = (__pyx_v_self->__pyx_base.sample_weight[__pyx_v_k]);
428:
-+429: dest[k] = w / self.weighted_n_node_samples
++429: dest[k] = w / self.weighted_n_node_samples
(__pyx_v_dest[__pyx_v_k]) = (__pyx_v_w / __pyx_v_self->__pyx_base.weighted_n_node_samples); }
430:
@@ -1333,7 +1407,7 @@
442:
443:
444:
-+445: cdef class KernelizedMSE(KernelizedRegressionCriterion):
++445: cdef class KernelizedMSE(KernelizedRegressionCriterion):
struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedMSE { struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedRegressionCriterion __pyx_base; }; @@ -1343,15 +1417,15 @@ }; static struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_KernelizedMSE *__pyx_vtabptr_13stpredictions_6models_3OK3_10_criterion_KernelizedMSE; -
446: """Mean squared error impurity criterion.
- 447:
- 448: var = \sum_i^n (phi(y_i) - phi(y)_bar) ** 2
- 449: = (\sum_i^n phi(y_i) ** 2) - n_samples * phi(y)_bar ** 2
+446: """Mean squared error impurity criterion.+
447:+
448: var = \sum_i^n (phi(y_i) - phi(y)_bar) ** 2+
449: = (\sum_i^n phi(y_i) ** 2) - n_samples * phi(y)_bar ** 2
450:
- 451: MSE = var_left + var_right
- 452: """
+451: MSE = var_left + var_right+
452: """
453:
-+454: cdef double node_impurity(self) nogil:
++454: cdef double node_impurity(self) nogil:
static double __pyx_f_13stpredictions_6models_3OK3_10_criterion_13KernelizedMSE_node_impurity(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedMSE *__pyx_v_self) { double __pyx_v_impurity; double __pyx_r; @@ -1360,19 +1434,19 @@ __pyx_L0:; return __pyx_r; } -
455: """Evaluate the impurity of the current node, i.e. the impurity of
- 456: samples[start:end]."""
+455: """Evaluate the impurity of the current node, i.e. the impurity of+
456: samples[start:end]."""
457:
- 458: cdef double impurity
+458: cdef double impurity
459:
-+460: impurity = self.sum_diag_Gramm / self.weighted_n_node_samples - self.sum_total_Gramm / (self.weighted_n_node_samples)**2
++460: impurity = self.sum_diag_Gramm / self.weighted_n_node_samples - self.sum_total_Gramm / (self.weighted_n_node_samples)**2
__pyx_v_impurity = ((__pyx_v_self->__pyx_base.sum_diag_Gramm / __pyx_v_self->__pyx_base.__pyx_base.weighted_n_node_samples) - (__pyx_v_self->__pyx_base.sum_total_Gramm / pow(__pyx_v_self->__pyx_base.__pyx_base.weighted_n_node_samples, 2.0)));
461:
-+462: return impurity
++462: return impurity
__pyx_r = __pyx_v_impurity; goto __pyx_L0;
463:
-+464: cdef double proxy_impurity_improvement(self) nogil:
++464: cdef double proxy_impurity_improvement(self) nogil:
static double __pyx_f_13stpredictions_6models_3OK3_10_criterion_13KernelizedMSE_proxy_impurity_improvement(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedMSE *__pyx_v_self) { double __pyx_v_proxy_impurity_left; double __pyx_v_proxy_impurity_right; @@ -1382,27 +1456,27 @@ __pyx_L0:; return __pyx_r; } -
465: """Compute a proxy of the impurity reduction
+465: """Compute a proxy of the impurity reduction
466:
- 467: This method is used to speed up the search for the best split.
- 468: It is a proxy quantity such that the split that maximizes this value
- 469: also maximizes the impurity improvement. It neglects all constant terms
- 470: of the impurity decrease for a given split.
+467: This method is used to speed up the search for the best split.+
468: It is a proxy quantity such that the split that maximizes this value+
469: also maximizes the impurity improvement. It neglects all constant terms+
470: of the impurity decrease for a given split.
471:
- 472: The absolute impurity improvement is only computed by the
- 473: impurity_improvement method once the best split has been found.
- 474: """
+472: The absolute impurity improvement is only computed by the+
473: impurity_improvement method once the best split has been found.+
474: """
475:
-+476: cdef double proxy_impurity_left = self.sum_diag_Gramm_left - self.sum_total_Gramm_left / self.weighted_n_left
++476: cdef double proxy_impurity_left = self.sum_diag_Gramm_left - self.sum_total_Gramm_left / self.weighted_n_left
__pyx_v_proxy_impurity_left = (__pyx_v_self->__pyx_base.sum_diag_Gramm_left - (__pyx_v_self->__pyx_base.sum_total_Gramm_left / __pyx_v_self->__pyx_base.__pyx_base.weighted_n_left)); -
+477: cdef double proxy_impurity_right = self.sum_diag_Gramm_right - self.sum_total_Gramm_right / self.weighted_n_right
++477: cdef double proxy_impurity_right = self.sum_diag_Gramm_right - self.sum_total_Gramm_right / self.weighted_n_right
__pyx_v_proxy_impurity_right = (__pyx_v_self->__pyx_base.sum_diag_Gramm_right - (__pyx_v_self->__pyx_base.sum_total_Gramm_right / __pyx_v_self->__pyx_base.__pyx_base.weighted_n_right));
478:
-+479: return (- proxy_impurity_left - proxy_impurity_right)
++479: return (- proxy_impurity_left - proxy_impurity_right)
__pyx_r = ((-__pyx_v_proxy_impurity_left) - __pyx_v_proxy_impurity_right); goto __pyx_L0;
480:
-+481: cdef void children_impurity(self, double* impurity_left, double* impurity_right) nogil:
++481: cdef void children_impurity(self, double* impurity_left, double* impurity_right) nogil:
static void __pyx_f_13stpredictions_6models_3OK3_10_criterion_13KernelizedMSE_children_impurity(struct __pyx_obj_13stpredictions_6models_3OK3_10_criterion_KernelizedMSE *__pyx_v_self, double *__pyx_v_impurity_left, double *__pyx_v_impurity_right) { double __pyx_v_sum_diag_Gramm_left; double __pyx_v_sum_diag_Gramm_right; @@ -1411,27 +1485,27 @@ /* … */ /* function exit code */ } -
482: """Evaluate the impurity in children nodes, i.e. the impurity of the
- 483: left child (samples[start:pos]) and the impurity the right child
- 484: (samples[pos:end])."""
+482: """Evaluate the impurity in children nodes, i.e. the impurity of the+
483: left child (samples[start:pos]) and the impurity the right child+
484: (samples[pos:end])."""
485:
-+486: cdef double sum_diag_Gramm_left = self.sum_diag_Gramm_left
++486: cdef double sum_diag_Gramm_left = self.sum_diag_Gramm_left
__pyx_t_1 = __pyx_v_self->__pyx_base.sum_diag_Gramm_left; __pyx_v_sum_diag_Gramm_left = __pyx_t_1; -
+487: cdef double sum_diag_Gramm_right = self.sum_diag_Gramm_right
++487: cdef double sum_diag_Gramm_right = self.sum_diag_Gramm_right
__pyx_t_1 = __pyx_v_self->__pyx_base.sum_diag_Gramm_right; __pyx_v_sum_diag_Gramm_right = __pyx_t_1;
488:
-+489: cdef double sum_total_Gramm_left = self.sum_total_Gramm_left
++489: cdef double sum_total_Gramm_left = self.sum_total_Gramm_left
__pyx_t_1 = __pyx_v_self->__pyx_base.sum_total_Gramm_left; __pyx_v_sum_total_Gramm_left = __pyx_t_1; -
+490: cdef double sum_total_Gramm_right = self.sum_total_Gramm_right
++490: cdef double sum_total_Gramm_right = self.sum_total_Gramm_right
__pyx_t_1 = __pyx_v_self->__pyx_base.sum_total_Gramm_right; __pyx_v_sum_total_Gramm_right = __pyx_t_1;
491:
-+492: impurity_left[0] = sum_diag_Gramm_left / self.weighted_n_left - sum_total_Gramm_left / (self.weighted_n_left)**2
++492: impurity_left[0] = sum_diag_Gramm_left / self.weighted_n_left - sum_total_Gramm_left / (self.weighted_n_left)**2
(__pyx_v_impurity_left[0]) = ((__pyx_v_sum_diag_Gramm_left / __pyx_v_self->__pyx_base.__pyx_base.weighted_n_left) - (__pyx_v_sum_total_Gramm_left / pow(__pyx_v_self->__pyx_base.__pyx_base.weighted_n_left, 2.0))); -
+493: impurity_right[0] = sum_diag_Gramm_right / self.weighted_n_right - sum_total_Gramm_right / (self.weighted_n_right)**2
++493: impurity_right[0] = sum_diag_Gramm_right / self.weighted_n_right - sum_total_Gramm_right / (self.weighted_n_right)**2
(__pyx_v_impurity_right[0]) = ((__pyx_v_sum_diag_Gramm_right / __pyx_v_self->__pyx_base.__pyx_base.weighted_n_right) - (__pyx_v_sum_total_Gramm_right / pow(__pyx_v_self->__pyx_base.__pyx_base.weighted_n_right, 2.0)));
494:
495:
diff --git a/stpredictions/models/OK3/_splitter.html b/stpredictions/models/OK3/_splitter.html
index 849439216..a6e8fdd15 100644
--- a/stpredictions/models/OK3/_splitter.html
+++ b/stpredictions/models/OK3/_splitter.html
@@ -286,6 +286,80 @@
.cython.score-252 {background-color: #FFFF09;}
.cython.score-253 {background-color: #FFFF09;}
.cython.score-254 {background-color: #FFFF09;}
+pre { line-height: 125%; }
+td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.cython .hll { background-color: #ffffcc }
+.cython { background: #f8f8f8; }
+.cython .c { color: #3D7B7B; font-style: italic } /* Comment */
+.cython .err { border: 1px solid #FF0000 } /* Error */
+.cython .k { color: #008000; font-weight: bold } /* Keyword */
+.cython .o { color: #666666 } /* Operator */
+.cython .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
+.cython .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
+.cython .cp { color: #9C6500 } /* Comment.Preproc */
+.cython .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
+.cython .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
+.cython .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
+.cython .gd { color: #A00000 } /* Generic.Deleted */
+.cython .ge { font-style: italic } /* Generic.Emph */
+.cython .gr { color: #E40000 } /* Generic.Error */
+.cython .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.cython .gi { color: #008400 } /* Generic.Inserted */
+.cython .go { color: #717171 } /* Generic.Output */
+.cython .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.cython .gs { font-weight: bold } /* Generic.Strong */
+.cython .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.cython .gt { color: #0044DD } /* Generic.Traceback */
+.cython .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.cython .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.cython .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.cython .kp { color: #008000 } /* Keyword.Pseudo */
+.cython .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.cython .kt { color: #B00040 } /* Keyword.Type */
+.cython .m { color: #666666 } /* Literal.Number */
+.cython .s { color: #BA2121 } /* Literal.String */
+.cython .na { color: #687822 } /* Name.Attribute */
+.cython .nb { color: #008000 } /* Name.Builtin */
+.cython .nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.cython .no { color: #880000 } /* Name.Constant */
+.cython .nd { color: #AA22FF } /* Name.Decorator */
+.cython .ni { color: #717171; font-weight: bold } /* Name.Entity */
+.cython .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
+.cython .nf { color: #0000FF } /* Name.Function */
+.cython .nl { color: #767600 } /* Name.Label */
+.cython .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.cython .nt { color: #008000; font-weight: bold } /* Name.Tag */
+.cython .nv { color: #19177C } /* Name.Variable */
+.cython .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.cython .w { color: #bbbbbb } /* Text.Whitespace */
+.cython .mb { color: #666666 } /* Literal.Number.Bin */
+.cython .mf { color: #666666 } /* Literal.Number.Float */
+.cython .mh { color: #666666 } /* Literal.Number.Hex */
+.cython .mi { color: #666666 } /* Literal.Number.Integer */
+.cython .mo { color: #666666 } /* Literal.Number.Oct */
+.cython .sa { color: #BA2121 } /* Literal.String.Affix */
+.cython .sb { color: #BA2121 } /* Literal.String.Backtick */
+.cython .sc { color: #BA2121 } /* Literal.String.Char */
+.cython .dl { color: #BA2121 } /* Literal.String.Delimiter */
+.cython .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.cython .s2 { color: #BA2121 } /* Literal.String.Double */
+.cython .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
+.cython .sh { color: #BA2121 } /* Literal.String.Heredoc */
+.cython .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
+.cython .sx { color: #008000 } /* Literal.String.Other */
+.cython .sr { color: #A45A77 } /* Literal.String.Regex */
+.cython .s1 { color: #BA2121 } /* Literal.String.Single */
+.cython .ss { color: #19177C } /* Literal.String.Symbol */
+.cython .bp { color: #008000 } /* Name.Builtin.Pseudo */
+.cython .fm { color: #0000FF } /* Name.Function.Magic */
+.cython .vc { color: #19177C } /* Name.Variable.Class */
+.cython .vg { color: #19177C } /* Name.Variable.Global */
+.cython .vi { color: #19177C } /* Name.Variable.Instance */
+.cython .vm { color: #19177C } /* Name.Variable.Magic */
+.cython .il { color: #666666 } /* Literal.Number.Integer.Long */
@@ -295,31 +369,31 @@
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
Raw output: _splitter.c
-+0001: # cython: cdivision=True
++0001: # cython: cdivision=True
__pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; -
0002: # cython: boundscheck=False
- 0003: # cython: wraparound=False
+0002: # cython: boundscheck=False+
0003: # cython: wraparound=False
0004:
- 0005: from _criterion cimport Criterion
+0005: from _criterion cimport Criterion
0006:
- 0007: from libc.stdlib cimport free
- 0008: from libc.stdlib cimport qsort
- 0009: from libc.string cimport memcpy
- 0010: from libc.string cimport memset
+0007: from libc.stdlib cimport free+
0008: from libc.stdlib cimport qsort+
0009: from libc.string cimport memcpy+
0010: from libc.string cimport memset
0011:
-+0012: import numpy as np
++0012: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 12, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 12, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; -
0013: cimport numpy as np
-+0014: np.import_array()
+0013: cimport numpy as np+
+0014: np.import_array()
__pyx_t_2 = __pyx_f_5numpy_import_array(); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 14, __pyx_L1_error)
0015:
-+0016: from scipy.sparse import csc_matrix
++0016: from scipy.sparse import csc_matrix
__pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_n_s_csc_matrix); @@ -334,13 +408,13 @@ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
0017:
- 0018: from sklearn.tree._utils cimport log
- 0019: from sklearn.tree._utils cimport rand_int
- 0020: from sklearn.tree._utils cimport rand_uniform
- 0021: from sklearn.tree._utils cimport RAND_R_MAX
- 0022: from sklearn.tree._utils cimport safe_realloc
+0018: from sklearn.tree._utils cimport log+
0019: from sklearn.tree._utils cimport rand_int+
0020: from sklearn.tree._utils cimport rand_uniform+
0021: from sklearn.tree._utils cimport RAND_R_MAX+
0022: from sklearn.tree._utils cimport safe_realloc
0023:
-+0024: cdef double INFINITY = np.inf
++0024: cdef double INFINITY = np.inf
__Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 24, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_inf); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error) @@ -350,34 +424,34 @@ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY = __pyx_t_4;
0025:
- 0026: # Mitigate precision differences between 32 bit and 64 bit
-+0027: cdef DTYPE_t FEATURE_THRESHOLD = 1e-7
+0026: # Mitigate precision differences between 32 bit and 64 bit+
+0027: cdef DTYPE_t FEATURE_THRESHOLD = 1e-7
__pyx_v_13stpredictions_6models_3OK3_9_splitter_FEATURE_THRESHOLD = 1e-7;
0028:
- 0029: # Constant to switch between algorithm non zero value extract algorithm
- 0030: # in SparseSplitter
-+0031: cdef DTYPE_t EXTRACT_NNZ_SWITCH = 0.1
+0029: # Constant to switch between algorithm non zero value extract algorithm+
0030: # in SparseSplitter+
+0031: cdef DTYPE_t EXTRACT_NNZ_SWITCH = 0.1
__pyx_v_13stpredictions_6models_3OK3_9_splitter_EXTRACT_NNZ_SWITCH = 0.1;
0032:
-+0033: cdef inline void _init_split(SplitRecord* self, SIZE_t start_pos) nogil:
++0033: cdef inline void _init_split(SplitRecord* self, SIZE_t start_pos) nogil:
static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter__init_split(struct __pyx_t_13stpredictions_6models_3OK3_9_splitter_SplitRecord *__pyx_v_self, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start_pos) { /* … */ /* function exit code */ } -
+0034: self.impurity_left = INFINITY
++0034: self.impurity_left = INFINITY
__pyx_v_self->impurity_left = __pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY; -
+0035: self.impurity_right = INFINITY
++0035: self.impurity_right = INFINITY
__pyx_v_self->impurity_right = __pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY; -
+0036: self.pos = start_pos
++0036: self.pos = start_pos
__pyx_v_self->pos = __pyx_v_start_pos; -
+0037: self.feature = 0
++0037: self.feature = 0
__pyx_v_self->feature = 0; -
+0038: self.threshold = 0.
++0038: self.threshold = 0.
__pyx_v_self->threshold = 0.; -
+0039: self.improvement = -INFINITY
++0039: self.improvement = -INFINITY
__pyx_v_self->improvement = (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY);
0040:
-+0041: cdef class Splitter:
++0041: cdef class Splitter:
struct __pyx_vtabstruct_13stpredictions_6models_3OK3_9_splitter_Splitter { int (*init)(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter *, PyObject *, __Pyx_memviewslice, __pyx_t_7sklearn_4tree_5_tree_DOUBLE_t *); int (*node_reset)(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter *, __pyx_t_7sklearn_4tree_5_tree_SIZE_t, __pyx_t_7sklearn_4tree_5_tree_SIZE_t, double *); @@ -387,13 +461,13 @@ }; static struct __pyx_vtabstruct_13stpredictions_6models_3OK3_9_splitter_Splitter *__pyx_vtabptr_13stpredictions_6models_3OK3_9_splitter_Splitter; -
0042: """Abstract splitter class.
+0042: """Abstract splitter class.
0043:
- 0044: Splitters are called by tree builders to find the best splits on both
- 0045: sparse and dense data, one split at a time.
- 0046: """
+0044: Splitters are called by tree builders to find the best splits on both+
0045: sparse and dense data, one split at a time.+
0046: """
0047:
-+0048: def __cinit__(self, Criterion criterion, SIZE_t max_features,
++0048: def __cinit__(self, Criterion criterion, SIZE_t max_features,
/* Python wrapper */
static int __pyx_pw_13stpredictions_6models_3OK3_9_splitter_8Splitter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static int __pyx_pw_13stpredictions_6models_3OK3_9_splitter_8Splitter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
@@ -506,66 +580,66 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
0049: SIZE_t min_samples_leaf, double min_weight_leaf,
- 0050: object random_state):
- 0051: """
- 0052: Parameters
- 0053: ----------
- 0054: criterion : Criterion
- 0055: The criterion to measure the quality of a split.
+0049: SIZE_t min_samples_leaf, double min_weight_leaf,+
0050: object random_state):+
0051: """+
0052: Parameters+
0053: ----------+
0054: criterion : Criterion+
0055: The criterion to measure the quality of a split.
0056:
- 0057: max_features : SIZE_t
- 0058: The maximal number of randomly selected features which can be
- 0059: considered for a split.
+0057: max_features : SIZE_t+
0058: The maximal number of randomly selected features which can be+
0059: considered for a split.
0060:
- 0061: min_samples_leaf : SIZE_t
- 0062: The minimal number of samples each leaf can have, where splits
- 0063: which would result in having less samples in a leaf are not
- 0064: considered.
+0061: min_samples_leaf : SIZE_t+
0062: The minimal number of samples each leaf can have, where splits+
0063: which would result in having less samples in a leaf are not+
0064: considered.
0065:
- 0066: min_weight_leaf : double
- 0067: The minimal weight each leaf can have, where the weight is the sum
- 0068: of the weights of each sample in it.
+0066: min_weight_leaf : double+
0067: The minimal weight each leaf can have, where the weight is the sum+
0068: of the weights of each sample in it.
0069:
- 0070: random_state : object
- 0071: The user inputted random state to be used for pseudo-randomness
- 0072: """
+0070: random_state : object+
0071: The user inputted random state to be used for pseudo-randomness+
0072: """
0073:
-+0074: self.criterion = criterion
++0074: self.criterion = criterion
__Pyx_INCREF(((PyObject *)__pyx_v_criterion)); __Pyx_GIVEREF(((PyObject *)__pyx_v_criterion)); __Pyx_GOTREF(__pyx_v_self->criterion); __Pyx_DECREF(((PyObject *)__pyx_v_self->criterion)); __pyx_v_self->criterion = __pyx_v_criterion;
0075:
-+0076: self.samples = NULL
++0076: self.samples = NULL
__pyx_v_self->samples = NULL; -
+0077: self.n_samples = 0
++0077: self.n_samples = 0
__pyx_v_self->n_samples = 0; -
+0078: self.features = NULL
++0078: self.features = NULL
__pyx_v_self->features = NULL; -
+0079: self.n_features = 0
++0079: self.n_features = 0
__pyx_v_self->n_features = 0; -
+0080: self.feature_values = NULL
++0080: self.feature_values = NULL
__pyx_v_self->feature_values = NULL;
0081:
-+0082: self.sample_weight = NULL
++0082: self.sample_weight = NULL
__pyx_v_self->sample_weight = NULL;
0083:
-+0084: self.max_features = max_features
++0084: self.max_features = max_features
__pyx_v_self->max_features = __pyx_v_max_features; -
+0085: self.min_samples_leaf = min_samples_leaf
++0085: self.min_samples_leaf = min_samples_leaf
__pyx_v_self->min_samples_leaf = __pyx_v_min_samples_leaf; -
+0086: self.min_weight_leaf = min_weight_leaf
++0086: self.min_weight_leaf = min_weight_leaf
__pyx_v_self->min_weight_leaf = __pyx_v_min_weight_leaf; -
+0087: self.random_state = random_state
++0087: self.random_state = random_state
__Pyx_INCREF(__pyx_v_random_state); __Pyx_GIVEREF(__pyx_v_random_state); __Pyx_GOTREF(__pyx_v_self->random_state); __Pyx_DECREF(__pyx_v_self->random_state); __pyx_v_self->random_state = __pyx_v_random_state;
0088:
-+0089: def __dealloc__(self):
++0089: def __dealloc__(self):
/* Python wrapper */
static void __pyx_pw_13stpredictions_6models_3OK3_9_splitter_8Splitter_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
static void __pyx_pw_13stpredictions_6models_3OK3_9_splitter_8Splitter_3__dealloc__(PyObject *__pyx_v_self) {
@@ -584,18 +658,18 @@
/* function exit code */
__Pyx_RefNannyFinishContext();
}
-
0090: """Destructor."""
+0090: """Destructor."""
0091:
-+0092: free(self.samples)
++0092: free(self.samples)
free(__pyx_v_self->samples); -
+0093: free(self.features)
++0093: free(self.features)
free(__pyx_v_self->features); -
+0094: free(self.constant_features)
++0094: free(self.constant_features)
free(__pyx_v_self->constant_features); -
+0095: free(self.feature_values)
++0095: free(self.feature_values)
free(__pyx_v_self->feature_values);
0096:
-+0097: def __getstate__(self):
++0097: def __getstate__(self):
/* Python wrapper */
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_8Splitter_5__getstate__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_8Splitter_5__getstate__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
@@ -624,7 +698,7 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
+0098: return {}
++0098: return {}
__Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 98, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); @@ -632,7 +706,7 @@ __pyx_t_1 = 0; goto __pyx_L0;
0099:
-+0100: def __setstate__(self, d):
++0100: def __setstate__(self, d):
/* Python wrapper */
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_8Splitter_7__setstate__(PyObject *__pyx_v_self, PyObject *__pyx_v_d); /*proto*/
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_8Splitter_7__setstate__(PyObject *__pyx_v_self, PyObject *__pyx_v_d) {
@@ -657,9 +731,9 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
0101: pass
+0101: pass
0102:
-+0103: cdef int init(self,
++0103: cdef int init(self,
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_8Splitter_init(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter *__pyx_v_self, PyObject *__pyx_v_X, __Pyx_memviewslice __pyx_v_y, __pyx_t_7sklearn_4tree_5_tree_DOUBLE_t *__pyx_v_sample_weight) {
__pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_n_samples;
__pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples;
@@ -685,31 +759,31 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
0104: object X,
- 0105: const DOUBLE_t[:, ::1] y,
- 0106: DOUBLE_t* sample_weight) except -1:
- 0107: """Initialize the splitter.
+0104: object X,+
0105: const DOUBLE_t[:, ::1] y,+
0106: DOUBLE_t* sample_weight) except -1:+
0107: """Initialize the splitter.
0108:
- 0109: Take in the input data X, the target Y, and optional sample weights.
+0109: Take in the input data X, the target Y, and optional sample weights.
0110:
- 0111: Returns -1 in case of failure to allocate memory (and raise MemoryError)
- 0112: or 0 otherwise.
+0111: Returns -1 in case of failure to allocate memory (and raise MemoryError)+
0112: or 0 otherwise.
0113:
- 0114: Parameters
- 0115: ----------
- 0116: X : object
- 0117: This contains the inputs. Usually it is a 2d numpy array.
+0114: Parameters+
0115: ----------+
0116: X : object+
0117: This contains the inputs. Usually it is a 2d numpy array.
0118:
- 0119: y : ndarray, dtype=DOUBLE_t
- 0120: This is the vector of targets, or true labels, for the samples
+0119: y : ndarray, dtype=DOUBLE_t+
0120: This is the vector of targets, or true labels, for the samples
0121:
- 0122: sample_weight : DOUBLE_t*
- 0123: The weights of the samples, where higher weighted samples are fit
- 0124: closer than lower weight samples. If not provided, all samples
- 0125: are assumed to have uniform weight.
- 0126: """
+0122: sample_weight : DOUBLE_t*+
0123: The weights of the samples, where higher weighted samples are fit+
0124: closer than lower weight samples. If not provided, all samples+
0125: are assumed to have uniform weight.+
0126: """
0127:
-+0128: self.rand_r_state = self.random_state.randint(0, RAND_R_MAX)
++0128: self.rand_r_state = self.random_state.randint(0, RAND_R_MAX)
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->random_state, __pyx_n_s_randint); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 128, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_e_7sklearn_4tree_6_utils_RAND_R_MAX); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 128, __pyx_L1_error) @@ -764,7 +838,7 @@ __pyx_t_7 = __Pyx_PyInt_As_npy_uint32(__pyx_t_1); if (unlikely((__pyx_t_7 == ((npy_uint32)-1)) && PyErr_Occurred())) __PYX_ERR(0, 128, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_self->rand_r_state = __pyx_t_7; -
+0129: cdef SIZE_t n_samples = X.shape[0]
++0129: cdef SIZE_t n_samples = X.shape[0]
__pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_X, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 129, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 129, __pyx_L1_error) @@ -774,25 +848,25 @@ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_v_n_samples = __pyx_t_8;
0130:
- 0131: # Create a new array which will be used to store nonzero
- 0132: # samples from the feature of interest
-+0133: cdef SIZE_t* samples = safe_realloc(&self.samples, n_samples)
+0131: # Create a new array which will be used to store nonzero+
0132: # samples from the feature of interest+
+0133: cdef SIZE_t* samples = safe_realloc(&self.samples, n_samples)
__pyx_t_9 = __pyx_fuse_1__pyx_f_7sklearn_4tree_6_utils_safe_realloc((&__pyx_v_self->samples), __pyx_v_n_samples); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 133, __pyx_L1_error)
__pyx_v_samples = __pyx_t_9;
0134:
- 0135: cdef SIZE_t i, j
-+0136: cdef double weighted_n_samples = 0.0
+0135: cdef SIZE_t i, j+
+0136: cdef double weighted_n_samples = 0.0
__pyx_v_weighted_n_samples = 0.0; -
+0137: j = 0
++0137: j = 0
__pyx_v_j = 0;
0138:
-+0139: for i in range(n_samples):
++0139: for i in range(n_samples):
__pyx_t_8 = __pyx_v_n_samples; __pyx_t_10 = __pyx_t_8; for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { __pyx_v_i = __pyx_t_11; -
0140: # Only work with positively weighted samples
-+0141: if sample_weight == NULL or sample_weight[i] != 0.0:
+0140: # Only work with positively weighted samples+
+0141: if sample_weight == NULL or sample_weight[i] != 0.0:
__pyx_t_13 = ((__pyx_v_sample_weight == NULL) != 0); if (!__pyx_t_13) { } else { @@ -805,34 +879,34 @@ if (__pyx_t_12) { /* … */ } -
+0142: samples[j] = i
++0142: samples[j] = i
(__pyx_v_samples[__pyx_v_j]) = __pyx_v_i; -
+0143: j += 1
++0143: j += 1
__pyx_v_j = (__pyx_v_j + 1);
0144:
-+0145: if sample_weight != NULL:
++0145: if sample_weight != NULL:
__pyx_t_12 = ((__pyx_v_sample_weight != NULL) != 0); if (__pyx_t_12) { /* … */ goto __pyx_L8; } -
+0146: weighted_n_samples += sample_weight[i]
++0146: weighted_n_samples += sample_weight[i]
__pyx_v_weighted_n_samples = (__pyx_v_weighted_n_samples + (__pyx_v_sample_weight[__pyx_v_i])); -
0147: else:
-+0148: weighted_n_samples += 1.0
+0147: else:+
+0148: weighted_n_samples += 1.0
/*else*/ { __pyx_v_weighted_n_samples = (__pyx_v_weighted_n_samples + 1.0); } __pyx_L8:; }
0149:
- 0150: # Number of samples is number of positively weighted samples
-+0151: self.n_samples = j
+0150: # Number of samples is number of positively weighted samples+
+0151: self.n_samples = j
__pyx_v_self->n_samples = __pyx_v_j; -
+0152: self.weighted_n_samples = weighted_n_samples
++0152: self.weighted_n_samples = weighted_n_samples
__pyx_v_self->weighted_n_samples = __pyx_v_weighted_n_samples;
0153:
-+0154: cdef SIZE_t n_features = X.shape[1]
++0154: cdef SIZE_t n_features = X.shape[1]
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_X, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 154, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 154, __pyx_L1_error) @@ -841,39 +915,39 @@ __pyx_t_8 = __Pyx_PyInt_As_Py_intptr_t(__pyx_t_1); if (unlikely((__pyx_t_8 == ((npy_intp)-1)) && PyErr_Occurred())) __PYX_ERR(0, 154, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_v_n_features = __pyx_t_8; -
+0155: cdef SIZE_t* features = safe_realloc(&self.features, n_features)
++0155: cdef SIZE_t* features = safe_realloc(&self.features, n_features)
__pyx_t_9 = __pyx_fuse_1__pyx_f_7sklearn_4tree_6_utils_safe_realloc((&__pyx_v_self->features), __pyx_v_n_features); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 155, __pyx_L1_error)
__pyx_v_features = __pyx_t_9;
0156:
-+0157: for i in range(n_features):
++0157: for i in range(n_features):
__pyx_t_8 = __pyx_v_n_features; __pyx_t_10 = __pyx_t_8; for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { __pyx_v_i = __pyx_t_11; -
+0158: features[i] = i
++0158: features[i] = i
(__pyx_v_features[__pyx_v_i]) = __pyx_v_i; }
0159:
-+0160: self.n_features = n_features
++0160: self.n_features = n_features
__pyx_v_self->n_features = __pyx_v_n_features;
0161:
-+0162: safe_realloc(&self.feature_values, n_samples)
++0162: safe_realloc(&self.feature_values, n_samples)
__pyx_fuse_0__pyx_f_7sklearn_4tree_6_utils_safe_realloc((&__pyx_v_self->feature_values), __pyx_v_n_samples); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 162, __pyx_L1_error)
-
+0163: safe_realloc(&self.constant_features, n_features)
++0163: safe_realloc(&self.constant_features, n_features)
__pyx_fuse_1__pyx_f_7sklearn_4tree_6_utils_safe_realloc((&__pyx_v_self->constant_features), __pyx_v_n_features); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 163, __pyx_L1_error)
0164:
-+0165: self.y = y
++0165: self.y = y
__PYX_XDEC_MEMVIEW(&__pyx_v_self->y, 0); __PYX_INC_MEMVIEW(&__pyx_v_y, 0); __pyx_v_self->y = __pyx_v_y;
0166:
-+0167: self.sample_weight = sample_weight
++0167: self.sample_weight = sample_weight
__pyx_v_self->sample_weight = __pyx_v_sample_weight; -
+0168: return 0
++0168: return 0
__pyx_r = 0; goto __pyx_L0;
0169:
-+0170: cdef int node_reset(self, SIZE_t start, SIZE_t end,
++0170: cdef int node_reset(self, SIZE_t start, SIZE_t end,
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_8Splitter_node_reset(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter *__pyx_v_self, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_end, double *__pyx_v_weighted_n_node_samples) { int __pyx_r; /* … */ @@ -892,45 +966,45 @@ __pyx_L0:; return __pyx_r; } -
0171: double* weighted_n_node_samples) nogil except -1:
- 0172: """Reset splitter on node samples[start:end].
+0171: double* weighted_n_node_samples) nogil except -1:+
0172: """Reset splitter on node samples[start:end].
0173:
- 0174: Returns -1 in case of failure to allocate memory (and raise MemoryError)
- 0175: or 0 otherwise.
+0174: Returns -1 in case of failure to allocate memory (and raise MemoryError)+
0175: or 0 otherwise.
0176:
- 0177: Parameters
- 0178: ----------
- 0179: start : SIZE_t
- 0180: The index of the first sample to consider
- 0181: end : SIZE_t
- 0182: The index of the last sample to consider
- 0183: weighted_n_node_samples : ndarray, dtype=double pointer
- 0184: The total weight of those samples
- 0185: """
+0177: Parameters+
0178: ----------+
0179: start : SIZE_t+
0180: The index of the first sample to consider+
0181: end : SIZE_t+
0182: The index of the last sample to consider+
0183: weighted_n_node_samples : ndarray, dtype=double pointer+
0184: The total weight of those samples+
0185: """
0186:
-+0187: self.start = start
++0187: self.start = start
__pyx_v_self->start = __pyx_v_start; -
+0188: self.end = end
++0188: self.end = end
__pyx_v_self->end = __pyx_v_end;
0189:
-+0190: self.criterion.init(self.y,
++0190: self.criterion.init(self.y,
if (unlikely(!__pyx_v_self->y.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 190, __pyx_L1_error)} /* … */ __pyx_t_1 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->criterion->__pyx_vtab)->init(__pyx_v_self->criterion, __pyx_v_self->y, __pyx_v_self->sample_weight, __pyx_v_self->weighted_n_samples, __pyx_v_self->samples, __pyx_v_start, __pyx_v_end); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 190, __pyx_L1_error) -
0191: self.sample_weight,
- 0192: self.weighted_n_samples,
- 0193: self.samples,
- 0194: start,
- 0195: end)
+0191: self.sample_weight,+
0192: self.weighted_n_samples,+
0193: self.samples,+
0194: start,+
0195: end)
0196:
-+0197: weighted_n_node_samples[0] = self.criterion.weighted_n_node_samples
++0197: weighted_n_node_samples[0] = self.criterion.weighted_n_node_samples
__pyx_t_2 = __pyx_v_self->criterion->weighted_n_node_samples; (__pyx_v_weighted_n_node_samples[0]) = __pyx_t_2; -
+0198: return 0
++0198: return 0
__pyx_r = 0; goto __pyx_L0;
0199:
-+0200: cdef int node_split(self, double impurity, SplitRecord* split,
++0200: cdef int node_split(self, double impurity, SplitRecord* split,
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_8Splitter_node_split(CYTHON_UNUSED struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter *__pyx_v_self, CYTHON_UNUSED double __pyx_v_impurity, CYTHON_UNUSED struct __pyx_t_13stpredictions_6models_3OK3_9_splitter_SplitRecord *__pyx_v_split, CYTHON_UNUSED __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_n_constant_features) { int __pyx_r; @@ -938,28 +1012,28 @@ __pyx_r = 0; return __pyx_r; } -
0201: SIZE_t* n_constant_features) nogil except -1:
- 0202: """Find the best split on node samples[start:end].
+0201: SIZE_t* n_constant_features) nogil except -1:+
0202: """Find the best split on node samples[start:end].
0203:
- 0204: This is a placeholder method. The majority of computation will be done
- 0205: here.
+0204: This is a placeholder method. The majority of computation will be done+
0205: here.
0206:
- 0207: It should return -1 upon errors.
- 0208: """
+0207: It should return -1 upon errors.+
0208: """
0209:
- 0210: pass
+0210: pass
0211:
-+0212: cdef void node_value(self, double* dest) nogil:
++0212: cdef void node_value(self, double* dest) nogil:
static void __pyx_f_13stpredictions_6models_3OK3_9_splitter_8Splitter_node_value(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter *__pyx_v_self, double *__pyx_v_dest) { /* … */ /* function exit code */ } -
0213: """Copy the value of node samples[start:end] into dest."""
+0213: """Copy the value of node samples[start:end] into dest."""
0214:
-+0215: self.criterion.node_value(dest)
++0215: self.criterion.node_value(dest)
((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->criterion->__pyx_vtab)->node_value(__pyx_v_self->criterion, __pyx_v_dest);
0216:
-+0217: cdef double node_impurity(self) nogil:
++0217: cdef double node_impurity(self) nogil:
static double __pyx_f_13stpredictions_6models_3OK3_9_splitter_8Splitter_node_impurity(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter *__pyx_v_self) { double __pyx_r; /* … */ @@ -967,14 +1041,14 @@ __pyx_L0:; return __pyx_r; } -
0218: """Return the impurity of the current node."""
+0218: """Return the impurity of the current node."""
0219:
-+0220: return self.criterion.node_impurity()
++0220: return self.criterion.node_impurity()
__pyx_r = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->criterion->__pyx_vtab)->node_impurity(__pyx_v_self->criterion); goto __pyx_L0;
0221:
0222:
-+0223: cdef class BaseDenseSplitter(Splitter):
++0223: cdef class BaseDenseSplitter(Splitter):
struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseDenseSplitter { struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter __pyx_base; __Pyx_memviewslice X; @@ -986,11 +1060,11 @@ }; static struct __pyx_vtabstruct_13stpredictions_6models_3OK3_9_splitter_BaseDenseSplitter *__pyx_vtabptr_13stpredictions_6models_3OK3_9_splitter_BaseDenseSplitter; -
0224: cdef const DTYPE_t[:, :] X
+0224: cdef const DTYPE_t[:, :] X
0225:
- 0226: cdef SIZE_t n_total_samples
+0226: cdef SIZE_t n_total_samples
0227:
-+0228: cdef int init(self,
++0228: cdef int init(self,
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_17BaseDenseSplitter_init(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseDenseSplitter *__pyx_v_self, PyObject *__pyx_v_X, __Pyx_memviewslice __pyx_v_y, __pyx_t_7sklearn_4tree_5_tree_DOUBLE_t *__pyx_v_sample_weight) { int __pyx_r; __Pyx_RefNannyDeclarations @@ -1005,31 +1079,31 @@ __Pyx_RefNannyFinishContext(); return __pyx_r; } -
0229: object X,
- 0230: const DOUBLE_t[:, ::1] y,
- 0231: DOUBLE_t* sample_weight) except -1:
- 0232: """Initialize the splitter
+0229: object X,+
0230: const DOUBLE_t[:, ::1] y,+
0231: DOUBLE_t* sample_weight) except -1:+
0232: """Initialize the splitter
0233:
- 0234: Returns -1 in case of failure to allocate memory (and raise MemoryError)
- 0235: or 0 otherwise.
- 0236: """
+0234: Returns -1 in case of failure to allocate memory (and raise MemoryError)+
0235: or 0 otherwise.+
0236: """
0237:
- 0238: # Call parent init
-+0239: Splitter.init(self, X, y, sample_weight)
+0238: # Call parent init+
+0239: Splitter.init(self, X, y, sample_weight)
__pyx_t_1 = __pyx_f_13stpredictions_6models_3OK3_9_splitter_8Splitter_init(((struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter *)__pyx_v_self), __pyx_v_X, __pyx_v_y, __pyx_v_sample_weight); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 239, __pyx_L1_error)
0240:
-+0241: self.X = X
++0241: self.X = X
__pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_dsds_nn___pyx_t_7sklearn_4tree_5_tree_DTYPE_t__const__(__pyx_v_X, 0); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 241, __pyx_L1_error)
__PYX_XDEC_MEMVIEW(&__pyx_v_self->X, 0);
__pyx_v_self->X = __pyx_t_2;
__pyx_t_2.memview = NULL;
__pyx_t_2.data = NULL;
-
+0242: return 0
++0242: return 0
__pyx_r = 0; goto __pyx_L0;
0243:
0244:
-+0245: cdef class BestSplitter(BaseDenseSplitter):
++0245: cdef class BestSplitter(BaseDenseSplitter):
struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BestSplitter { struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseDenseSplitter __pyx_base; }; @@ -1039,8 +1113,8 @@ }; static struct __pyx_vtabstruct_13stpredictions_6models_3OK3_9_splitter_BestSplitter *__pyx_vtabptr_13stpredictions_6models_3OK3_9_splitter_BestSplitter; -
0246: """Splitter for finding the best split."""
-+0247: def __reduce__(self):
+0246: """Splitter for finding the best split."""+
+0247: def __reduce__(self):
/* Python wrapper */
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_12BestSplitter_1__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_12BestSplitter_1__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
@@ -1072,7 +1146,7 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
+0248: return (BestSplitter, (self.criterion,
++0248: return (BestSplitter, (self.criterion,
__Pyx_XDECREF(__pyx_r); /* … */ __pyx_t_4 = PyTuple_New(5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 248, __pyx_L1_error) @@ -1107,16 +1181,16 @@ __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; -
+0249: self.max_features,
++0249: self.max_features,
__pyx_t_1 = __Pyx_PyInt_From_Py_intptr_t(__pyx_v_self->__pyx_base.__pyx_base.max_features); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 249, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); -
+0250: self.min_samples_leaf,
++0250: self.min_samples_leaf,
__pyx_t_2 = __Pyx_PyInt_From_Py_intptr_t(__pyx_v_self->__pyx_base.__pyx_base.min_samples_leaf); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 250, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); -
+0251: self.min_weight_leaf,
++0251: self.min_weight_leaf,
__pyx_t_3 = PyFloat_FromDouble(__pyx_v_self->__pyx_base.__pyx_base.min_weight_leaf); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 251, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); -
+0252: self.random_state), self.__getstate__())
++0252: self.random_state), self.__getstate__())
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_getstate); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 252, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_1 = NULL; @@ -1135,7 +1209,7 @@ __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
0253:
-+0254: cdef int node_split(self, double impurity, SplitRecord* split,
++0254: cdef int node_split(self, double impurity, SplitRecord* split,
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_12BestSplitter_node_split(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BestSplitter *__pyx_v_self, double __pyx_v_impurity, struct __pyx_t_13stpredictions_6models_3OK3_9_splitter_SplitRecord *__pyx_v_split, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_n_constant_features) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start; @@ -1179,92 +1253,92 @@ __pyx_L0:; return __pyx_r; } -
0255: SIZE_t* n_constant_features) nogil except -1:
- 0256: """Find the best split on node samples[start:end]
+0255: SIZE_t* n_constant_features) nogil except -1:+
0256: """Find the best split on node samples[start:end]
0257:
- 0258: Returns -1 in case of failure to allocate memory (and raise MemoryError)
- 0259: or 0 otherwise.
- 0260: """
- 0261: # Find the best split
-+0262: cdef SIZE_t* samples = self.samples
+0258: Returns -1 in case of failure to allocate memory (and raise MemoryError)+
0259: or 0 otherwise.+
0260: """+
0261: # Find the best split+
+0262: cdef SIZE_t* samples = self.samples
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.samples; __pyx_v_samples = __pyx_t_1; -
+0263: cdef SIZE_t start = self.start
++0263: cdef SIZE_t start = self.start
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.start; __pyx_v_start = __pyx_t_2; -
+0264: cdef SIZE_t end = self.end
++0264: cdef SIZE_t end = self.end
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.end; __pyx_v_end = __pyx_t_2;
0265:
-+0266: cdef SIZE_t* features = self.features
++0266: cdef SIZE_t* features = self.features
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.features; __pyx_v_features = __pyx_t_1; -
+0267: cdef SIZE_t* constant_features = self.constant_features
++0267: cdef SIZE_t* constant_features = self.constant_features
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.constant_features; __pyx_v_constant_features = __pyx_t_1; -
+0268: cdef SIZE_t n_features = self.n_features
++0268: cdef SIZE_t n_features = self.n_features
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.n_features; __pyx_v_n_features = __pyx_t_2;
0269:
-+0270: cdef DTYPE_t* Xf = self.feature_values
++0270: cdef DTYPE_t* Xf = self.feature_values
__pyx_t_3 = __pyx_v_self->__pyx_base.__pyx_base.feature_values; __pyx_v_Xf = __pyx_t_3; -
+0271: cdef SIZE_t max_features = self.max_features
++0271: cdef SIZE_t max_features = self.max_features
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.max_features; __pyx_v_max_features = __pyx_t_2; -
+0272: cdef SIZE_t min_samples_leaf = self.min_samples_leaf
++0272: cdef SIZE_t min_samples_leaf = self.min_samples_leaf
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.min_samples_leaf; __pyx_v_min_samples_leaf = __pyx_t_2; -
+0273: cdef double min_weight_leaf = self.min_weight_leaf
++0273: cdef double min_weight_leaf = self.min_weight_leaf
__pyx_t_4 = __pyx_v_self->__pyx_base.__pyx_base.min_weight_leaf; __pyx_v_min_weight_leaf = __pyx_t_4; -
+0274: cdef UINT32_t* random_state = &self.rand_r_state
++0274: cdef UINT32_t* random_state = &self.rand_r_state
__pyx_v_random_state = (&__pyx_v_self->__pyx_base.__pyx_base.rand_r_state);
0275:
- 0276: cdef SplitRecord best, current
-+0277: cdef double current_proxy_improvement = -INFINITY
+0276: cdef SplitRecord best, current+
+0277: cdef double current_proxy_improvement = -INFINITY
__pyx_v_current_proxy_improvement = (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY); -
+0278: cdef double best_proxy_improvement = -INFINITY
++0278: cdef double best_proxy_improvement = -INFINITY
__pyx_v_best_proxy_improvement = (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY);
0279:
-+0280: cdef SIZE_t f_i = n_features
++0280: cdef SIZE_t f_i = n_features
__pyx_v_f_i = __pyx_v_n_features; -
0281: cdef SIZE_t f_j
- 0282: cdef SIZE_t p
- 0283: cdef SIZE_t feature_idx_offset
- 0284: cdef SIZE_t feature_offset
- 0285: cdef SIZE_t i
- 0286: cdef SIZE_t j
+0281: cdef SIZE_t f_j+
0282: cdef SIZE_t p+
0283: cdef SIZE_t feature_idx_offset+
0284: cdef SIZE_t feature_offset+
0285: cdef SIZE_t i+
0286: cdef SIZE_t j
0287:
-+0288: cdef SIZE_t n_visited_features = 0
++0288: cdef SIZE_t n_visited_features = 0
__pyx_v_n_visited_features = 0; -
0289: # Number of features discovered to be constant during the split search
-+0290: cdef SIZE_t n_found_constants = 0
+0289: # Number of features discovered to be constant during the split search+
+0290: cdef SIZE_t n_found_constants = 0
__pyx_v_n_found_constants = 0; -
0291: # Number of features known to be constant and drawn without replacement
-+0292: cdef SIZE_t n_drawn_constants = 0
+0291: # Number of features known to be constant and drawn without replacement+
+0292: cdef SIZE_t n_drawn_constants = 0
__pyx_v_n_drawn_constants = 0; -
+0293: cdef SIZE_t n_known_constants = n_constant_features[0]
++0293: cdef SIZE_t n_known_constants = n_constant_features[0]
__pyx_v_n_known_constants = (__pyx_v_n_constant_features[0]); -
0294: # n_total_constants = n_known_constants + n_found_constants
-+0295: cdef SIZE_t n_total_constants = n_known_constants
+0294: # n_total_constants = n_known_constants + n_found_constants+
+0295: cdef SIZE_t n_total_constants = n_known_constants
__pyx_v_n_total_constants = __pyx_v_n_known_constants; -
0296: cdef DTYPE_t current_feature_value
- 0297: cdef SIZE_t partition_end
+0296: cdef DTYPE_t current_feature_value+
0297: cdef SIZE_t partition_end
0298:
-+0299: _init_split(&best, end)
++0299: _init_split(&best, end)
__pyx_f_13stpredictions_6models_3OK3_9_splitter__init_split((&__pyx_v_best), __pyx_v_end);
0300:
- 0301: # Sample up to max_features without replacement using a
- 0302: # Fisher-Yates-based algorithm (using the local variables `f_i` and
- 0303: # `f_j` to compute a permutation of the `features` array).
- 0304: #
- 0305: # Skip the CPU intensive evaluation of the impurity criterion for
- 0306: # features that were already detected as constant (hence not suitable
- 0307: # for good splitting) by ancestor nodes and save the information on
- 0308: # newly discovered constant features to spare computation on descendant
- 0309: # nodes.
-+0310: while (f_i > n_total_constants and # Stop early if remaining features
+0301: # Sample up to max_features without replacement using a+
0302: # Fisher-Yates-based algorithm (using the local variables `f_i` and+
0303: # `f_j` to compute a permutation of the `features` array).+
0304: #+
0305: # Skip the CPU intensive evaluation of the impurity criterion for+
0306: # features that were already detected as constant (hence not suitable+
0307: # for good splitting) by ancestor nodes and save the information on+
0308: # newly discovered constant features to spare computation on descendant+
0309: # nodes.+
+0310: while (f_i > n_total_constants and # Stop early if remaining features
while (1) { __pyx_t_6 = ((__pyx_v_f_i > __pyx_v_n_total_constants) != 0); if (__pyx_t_6) { @@ -1272,122 +1346,122 @@ __pyx_t_5 = __pyx_t_6; goto __pyx_L5_bool_binop_done; } -
0311: # are constant
-+0312: (n_visited_features < max_features or
+0311: # are constant+
+0312: (n_visited_features < max_features or
__pyx_t_6 = ((__pyx_v_n_visited_features < __pyx_v_max_features) != 0); if (!__pyx_t_6) { } else { __pyx_t_5 = __pyx_t_6; goto __pyx_L5_bool_binop_done; } -
0313: # At least one drawn features must be non constant
-+0314: n_visited_features <= n_found_constants + n_drawn_constants)):
+0313: # At least one drawn features must be non constant+
+0314: n_visited_features <= n_found_constants + n_drawn_constants)):
__pyx_t_6 = ((__pyx_v_n_visited_features <= (__pyx_v_n_found_constants + __pyx_v_n_drawn_constants)) != 0); __pyx_t_5 = __pyx_t_6; __pyx_L5_bool_binop_done:; if (!__pyx_t_5) break;
0315:
-+0316: n_visited_features += 1
++0316: n_visited_features += 1
__pyx_v_n_visited_features = (__pyx_v_n_visited_features + 1);
0317:
- 0318: # Loop invariant: elements of features in
- 0319: # - [:n_drawn_constant[ holds drawn and known constant features;
- 0320: # - [n_drawn_constant:n_known_constant[ holds known constant
- 0321: # features that haven't been drawn yet;
- 0322: # - [n_known_constant:n_total_constant[ holds newly found constant
- 0323: # features;
- 0324: # - [n_total_constant:f_i[ holds features that haven't been drawn
- 0325: # yet and aren't constant apriori.
- 0326: # - [f_i:n_features[ holds features that have been drawn
- 0327: # and aren't constant.
+0318: # Loop invariant: elements of features in+
0319: # - [:n_drawn_constant[ holds drawn and known constant features;+
0320: # - [n_drawn_constant:n_known_constant[ holds known constant+
0321: # features that haven't been drawn yet;+
0322: # - [n_known_constant:n_total_constant[ holds newly found constant+
0323: # features;+
0324: # - [n_total_constant:f_i[ holds features that haven't been drawn+
0325: # yet and aren't constant apriori.+
0326: # - [f_i:n_features[ holds features that have been drawn+
0327: # and aren't constant.
0328:
- 0329: # Draw a feature at random
-+0330: f_j = rand_int(n_drawn_constants, f_i - n_found_constants,
+0329: # Draw a feature at random+
+0330: f_j = rand_int(n_drawn_constants, f_i - n_found_constants,
__pyx_v_f_j = __pyx_f_7sklearn_4tree_6_utils_rand_int(__pyx_v_n_drawn_constants, (__pyx_v_f_i - __pyx_v_n_found_constants), __pyx_v_random_state); -
0331: random_state)
+0331: random_state)
0332:
-+0333: if f_j < n_known_constants:
++0333: if f_j < n_known_constants:
__pyx_t_5 = ((__pyx_v_f_j < __pyx_v_n_known_constants) != 0); if (__pyx_t_5) { /* … */ goto __pyx_L8; } -
0334: # f_j in the interval [n_drawn_constants, n_known_constants[
-+0335: features[n_drawn_constants], features[f_j] = features[f_j], features[n_drawn_constants]
+0334: # f_j in the interval [n_drawn_constants, n_known_constants[+
+0335: features[n_drawn_constants], features[f_j] = features[f_j], features[n_drawn_constants]
__pyx_t_2 = (__pyx_v_features[__pyx_v_f_j]); __pyx_t_7 = (__pyx_v_features[__pyx_v_n_drawn_constants]); (__pyx_v_features[__pyx_v_n_drawn_constants]) = __pyx_t_2; (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_7;
0336:
-+0337: n_drawn_constants += 1
++0337: n_drawn_constants += 1
__pyx_v_n_drawn_constants = (__pyx_v_n_drawn_constants + 1);
0338:
- 0339: else:
- 0340: # f_j in the interval [n_known_constants, f_i - n_found_constants[
-+0341: f_j += n_found_constants
+0339: else:+
0340: # f_j in the interval [n_known_constants, f_i - n_found_constants[+
+0341: f_j += n_found_constants
/*else*/ { __pyx_v_f_j = (__pyx_v_f_j + __pyx_v_n_found_constants); -
0342: # f_j in the interval [n_total_constants, f_i[
-+0343: current.feature = features[f_j]
+0342: # f_j in the interval [n_total_constants, f_i[+
+0343: current.feature = features[f_j]
__pyx_v_current.feature = (__pyx_v_features[__pyx_v_f_j]);
0344:
- 0345: # Sort samples along that feature; by
- 0346: # copying the values into an array and
- 0347: # sorting the array in a manner which utilizes the cache more
- 0348: # effectively.
-+0349: for i in range(start, end):
+0345: # Sort samples along that feature; by+
0346: # copying the values into an array and+
0347: # sorting the array in a manner which utilizes the cache more+
0348: # effectively.+
+0349: for i in range(start, end):
__pyx_t_7 = __pyx_v_end; __pyx_t_2 = __pyx_t_7; for (__pyx_t_8 = __pyx_v_start; __pyx_t_8 < __pyx_t_2; __pyx_t_8+=1) { __pyx_v_i = __pyx_t_8; -
+0350: Xf[i] = self.X[samples[i], current.feature]
++0350: Xf[i] = self.X[samples[i], current.feature]
if (unlikely(!__pyx_v_self->__pyx_base.X.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 350, __pyx_L1_error)} __pyx_t_9 = (__pyx_v_samples[__pyx_v_i]); __pyx_t_10 = __pyx_v_current.feature; (__pyx_v_Xf[__pyx_v_i]) = (*((__pyx_t_7sklearn_4tree_5_tree_DTYPE_t const *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->__pyx_base.X.data + __pyx_t_9 * __pyx_v_self->__pyx_base.X.strides[0]) ) + __pyx_t_10 * __pyx_v_self->__pyx_base.X.strides[1]) ))); }
0351:
-+0352: sort(Xf + start, samples + start, end - start)
++0352: sort(Xf + start, samples + start, end - start)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sort((__pyx_v_Xf + __pyx_v_start), (__pyx_v_samples + __pyx_v_start), (__pyx_v_end - __pyx_v_start));
0353:
-+0354: if Xf[end - 1] <= Xf[start] + FEATURE_THRESHOLD:
++0354: if Xf[end - 1] <= Xf[start] + FEATURE_THRESHOLD:
__pyx_t_5 = (((__pyx_v_Xf[(__pyx_v_end - 1)]) <= ((__pyx_v_Xf[__pyx_v_start]) + __pyx_v_13stpredictions_6models_3OK3_9_splitter_FEATURE_THRESHOLD)) != 0); if (__pyx_t_5) { /* … */ goto __pyx_L11; } -
+0355: features[f_j], features[n_total_constants] = features[n_total_constants], features[f_j]
++0355: features[f_j], features[n_total_constants] = features[n_total_constants], features[f_j]
__pyx_t_7 = (__pyx_v_features[__pyx_v_n_total_constants]); __pyx_t_2 = (__pyx_v_features[__pyx_v_f_j]); (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_7; (__pyx_v_features[__pyx_v_n_total_constants]) = __pyx_t_2;
0356:
-+0357: n_found_constants += 1
++0357: n_found_constants += 1
__pyx_v_n_found_constants = (__pyx_v_n_found_constants + 1); -
+0358: n_total_constants += 1
++0358: n_total_constants += 1
__pyx_v_n_total_constants = (__pyx_v_n_total_constants + 1);
0359:
- 0360: else:
-+0361: f_i -= 1
+0360: else:+
+0361: f_i -= 1
/*else*/ { __pyx_v_f_i = (__pyx_v_f_i - 1); -
+0362: features[f_i], features[f_j] = features[f_j], features[f_i]
++0362: features[f_i], features[f_j] = features[f_j], features[f_i]
__pyx_t_2 = (__pyx_v_features[__pyx_v_f_j]); __pyx_t_7 = (__pyx_v_features[__pyx_v_f_i]); (__pyx_v_features[__pyx_v_f_i]) = __pyx_t_2; (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_7;
0363:
- 0364: # Evaluate all splits
-+0365: self.criterion.reset()
+0364: # Evaluate all splits+
+0365: self.criterion.reset()
__pyx_t_11 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->reset(__pyx_v_self->__pyx_base.__pyx_base.criterion); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 365, __pyx_L1_error)
-
+0366: p = start
++0366: p = start
__pyx_v_p = __pyx_v_start;
0367:
-+0368: while p < end:
++0368: while p < end:
while (1) { __pyx_t_5 = ((__pyx_v_p < __pyx_v_end) != 0); if (!__pyx_t_5) break; -
+0369: while (p + 1 < end and
++0369: while (p + 1 < end and
while (1) { __pyx_t_6 = (((__pyx_v_p + 1) < __pyx_v_end) != 0); if (__pyx_t_6) { @@ -1395,23 +1469,23 @@ __pyx_t_5 = __pyx_t_6; goto __pyx_L16_bool_binop_done; } -
+0370: Xf[p + 1] <= Xf[p] + FEATURE_THRESHOLD):
++0370: Xf[p + 1] <= Xf[p] + FEATURE_THRESHOLD):
__pyx_t_6 = (((__pyx_v_Xf[(__pyx_v_p + 1)]) <= ((__pyx_v_Xf[__pyx_v_p]) + __pyx_v_13stpredictions_6models_3OK3_9_splitter_FEATURE_THRESHOLD)) != 0); __pyx_t_5 = __pyx_t_6; __pyx_L16_bool_binop_done:; if (!__pyx_t_5) break; -
+0371: p += 1
++0371: p += 1
__pyx_v_p = (__pyx_v_p + 1); }
0372:
- 0373: # (p + 1 >= end) or (X[samples[p + 1], current.feature] >
- 0374: # X[samples[p], current.feature])
-+0375: p += 1
+0373: # (p + 1 >= end) or (X[samples[p + 1], current.feature] >+
0374: # X[samples[p], current.feature])+
+0375: p += 1
__pyx_v_p = (__pyx_v_p + 1); -
0376: # (p >= end) or (X[samples[p], current.feature] >
- 0377: # X[samples[p - 1], current.feature])
+0376: # (p >= end) or (X[samples[p], current.feature] >+
0377: # X[samples[p - 1], current.feature])
0378:
-+0379: if p < end:
++0379: if p < end:
__pyx_t_5 = ((__pyx_v_p < __pyx_v_end) != 0); if (__pyx_t_5) { /* … */ @@ -1423,11 +1497,11 @@ } __pyx_L8:; } -
+0380: current.pos = p
++0380: current.pos = p
__pyx_v_current.pos = __pyx_v_p;
0381:
- 0382: # Reject if min_samples_leaf is not guaranteed
-+0383: if (((current.pos - start) < min_samples_leaf) or
+0382: # Reject if min_samples_leaf is not guaranteed+
+0383: if (((current.pos - start) < min_samples_leaf) or
__pyx_t_6 = (((__pyx_v_current.pos - __pyx_v_start) < __pyx_v_min_samples_leaf) != 0); if (!__pyx_t_6) { } else { @@ -1438,18 +1512,18 @@ if (__pyx_t_5) { /* … */ } -
+0384: ((end - current.pos) < min_samples_leaf)):
++0384: ((end - current.pos) < min_samples_leaf)):
__pyx_t_6 = (((__pyx_v_end - __pyx_v_current.pos) < __pyx_v_min_samples_leaf) != 0); __pyx_t_5 = __pyx_t_6; __pyx_L20_bool_binop_done:; -
+0385: continue
++0385: continue
goto __pyx_L12_continue;
0386:
-+0387: self.criterion.update(current.pos)
++0387: self.criterion.update(current.pos)
__pyx_t_11 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->update(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_current.pos); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 387, __pyx_L1_error)
0388:
- 0389: # Reject if min_weight_leaf is not satisfied
-+0390: if ((self.criterion.weighted_n_left < min_weight_leaf) or
+0389: # Reject if min_weight_leaf is not satisfied+
+0390: if ((self.criterion.weighted_n_left < min_weight_leaf) or
__pyx_t_6 = ((__pyx_v_self->__pyx_base.__pyx_base.criterion->weighted_n_left < __pyx_v_min_weight_leaf) != 0); if (!__pyx_t_6) { } else { @@ -1460,34 +1534,34 @@ if (__pyx_t_5) { /* … */ } -
+0391: (self.criterion.weighted_n_right < min_weight_leaf)):
++0391: (self.criterion.weighted_n_right < min_weight_leaf)):
__pyx_t_6 = ((__pyx_v_self->__pyx_base.__pyx_base.criterion->weighted_n_right < __pyx_v_min_weight_leaf) != 0); __pyx_t_5 = __pyx_t_6; __pyx_L23_bool_binop_done:; -
+0392: continue
++0392: continue
goto __pyx_L12_continue;
0393:
-+0394: current_proxy_improvement = self.criterion.proxy_impurity_improvement()
++0394: current_proxy_improvement = self.criterion.proxy_impurity_improvement()
__pyx_v_current_proxy_improvement = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->proxy_impurity_improvement(__pyx_v_self->__pyx_base.__pyx_base.criterion);
0395:
- 0396: # with gil:
- 0397: # print("feature ", current.feature)
- 0398: # print("threshold ", current.threshold)
- 0399: # print("proxy ", current_proxy_improvement)
- 0400: # print()
+0396: # with gil:+
0397: # print("feature ", current.feature)+
0398: # print("threshold ", current.threshold)+
0399: # print("proxy ", current_proxy_improvement)+
0400: # print()
0401:
-+0402: if current_proxy_improvement > best_proxy_improvement:
++0402: if current_proxy_improvement > best_proxy_improvement:
__pyx_t_5 = ((__pyx_v_current_proxy_improvement > __pyx_v_best_proxy_improvement) != 0); if (__pyx_t_5) { /* … */ } -
+0403: best_proxy_improvement = current_proxy_improvement
++0403: best_proxy_improvement = current_proxy_improvement
__pyx_v_best_proxy_improvement = __pyx_v_current_proxy_improvement; -
0404: # sum of halves is used to avoid infinite value
-+0405: current.threshold = Xf[p - 1] / 2.0 + Xf[p] / 2.0
+0404: # sum of halves is used to avoid infinite value+
+0405: current.threshold = Xf[p - 1] / 2.0 + Xf[p] / 2.0
__pyx_v_current.threshold = (((__pyx_v_Xf[(__pyx_v_p - 1)]) / 2.0) + ((__pyx_v_Xf[__pyx_v_p]) / 2.0));
0406:
-+0407: if ((current.threshold == Xf[p]) or
++0407: if ((current.threshold == Xf[p]) or
__pyx_t_6 = ((__pyx_v_current.threshold == (__pyx_v_Xf[__pyx_v_p])) != 0); if (!__pyx_t_6) { } else { @@ -1498,39 +1572,39 @@ if (__pyx_t_5) { /* … */ } -
+0408: (current.threshold == INFINITY) or
++0408: (current.threshold == INFINITY) or
__pyx_t_6 = ((__pyx_v_current.threshold == __pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY) != 0); if (!__pyx_t_6) { } else { __pyx_t_5 = __pyx_t_6; goto __pyx_L27_bool_binop_done; } -
+0409: (current.threshold == -INFINITY)):
++0409: (current.threshold == -INFINITY)):
__pyx_t_6 = ((__pyx_v_current.threshold == (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY)) != 0); __pyx_t_5 = __pyx_t_6; __pyx_L27_bool_binop_done:; -
+0410: current.threshold = Xf[p - 1]
++0410: current.threshold = Xf[p - 1]
__pyx_v_current.threshold = (__pyx_v_Xf[(__pyx_v_p - 1)]);
0411:
-+0412: best = current # copy
++0412: best = current # copy
__pyx_v_best = __pyx_v_current;
0413:
- 0414: # Reorganize into samples[start:best.pos] + samples[best.pos:end]
-+0415: if best.pos < end:
+0414: # Reorganize into samples[start:best.pos] + samples[best.pos:end]+
+0415: if best.pos < end:
__pyx_t_5 = ((__pyx_v_best.pos < __pyx_v_end) != 0); if (__pyx_t_5) { /* … */ } -
+0416: partition_end = end
++0416: partition_end = end
__pyx_v_partition_end = __pyx_v_end; -
+0417: p = start
++0417: p = start
__pyx_v_p = __pyx_v_start;
0418:
-+0419: while p < partition_end:
++0419: while p < partition_end:
while (1) { __pyx_t_5 = ((__pyx_v_p < __pyx_v_partition_end) != 0); if (!__pyx_t_5) break; -
+0420: if self.X[samples[p], best.feature] <= best.threshold:
++0420: if self.X[samples[p], best.feature] <= best.threshold:
if (unlikely(!__pyx_v_self->__pyx_base.X.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 420, __pyx_L1_error)} __pyx_t_10 = (__pyx_v_samples[__pyx_v_p]); __pyx_t_9 = __pyx_v_best.feature; @@ -1539,15 +1613,15 @@ /* … */ goto __pyx_L33; } -
+0421: p += 1
++0421: p += 1
__pyx_v_p = (__pyx_v_p + 1);
0422:
- 0423: else:
-+0424: partition_end -= 1
+0423: else:+
+0424: partition_end -= 1
/*else*/ { __pyx_v_partition_end = (__pyx_v_partition_end - 1);
0425:
-+0426: samples[p], samples[partition_end] = samples[partition_end], samples[p]
++0426: samples[p], samples[partition_end] = samples[partition_end], samples[p]
__pyx_t_7 = (__pyx_v_samples[__pyx_v_partition_end]); __pyx_t_2 = (__pyx_v_samples[__pyx_v_p]); (__pyx_v_samples[__pyx_v_p]) = __pyx_t_7; @@ -1556,80 +1630,80 @@ __pyx_L33:; }
0427:
-+0428: self.criterion.reset()
++0428: self.criterion.reset()
__pyx_t_11 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->reset(__pyx_v_self->__pyx_base.__pyx_base.criterion); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 428, __pyx_L1_error)
-
+0429: self.criterion.update(best.pos)
++0429: self.criterion.update(best.pos)
__pyx_t_11 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->update(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_best.pos); if (unlikely(__pyx_t_11 == ((int)-1))) __PYX_ERR(0, 429, __pyx_L1_error)
-
+0430: best.improvement = self.criterion.impurity_improvement(impurity)
++0430: best.improvement = self.criterion.impurity_improvement(impurity)
__pyx_v_best.improvement = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->impurity_improvement(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_impurity); -
+0431: self.criterion.children_impurity(&best.impurity_left,
++0431: self.criterion.children_impurity(&best.impurity_left,
((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->children_impurity(__pyx_v_self->__pyx_base.__pyx_base.criterion, (&__pyx_v_best.impurity_left), (&__pyx_v_best.impurity_right)); -
0432: &best.impurity_right)
+0432: &best.impurity_right)
0433:
- 0434: # Respect invariant for constant features: the original order of
- 0435: # element in features[:n_known_constants] must be preserved for sibling
- 0436: # and child nodes
-+0437: memcpy(features, constant_features, sizeof(SIZE_t) * n_known_constants)
+0434: # Respect invariant for constant features: the original order of+
0435: # element in features[:n_known_constants] must be preserved for sibling+
0436: # and child nodes+
+0437: memcpy(features, constant_features, sizeof(SIZE_t) * n_known_constants)
(void)(memcpy(__pyx_v_features, __pyx_v_constant_features, ((sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t)) * __pyx_v_n_known_constants)));
0438:
- 0439: # Copy newly found constant features
-+0440: memcpy(constant_features + n_known_constants,
+0439: # Copy newly found constant features+
+0440: memcpy(constant_features + n_known_constants,
(void)(memcpy((__pyx_v_constant_features + __pyx_v_n_known_constants), (__pyx_v_features + __pyx_v_n_known_constants), ((sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t)) * __pyx_v_n_found_constants))); -
0441: features + n_known_constants,
- 0442: sizeof(SIZE_t) * n_found_constants)
+0441: features + n_known_constants,+
0442: sizeof(SIZE_t) * n_found_constants)
0443:
- 0444: # Return values
-+0445: split[0] = best
+0444: # Return values+
+0445: split[0] = best
(__pyx_v_split[0]) = __pyx_v_best; -
+0446: n_constant_features[0] = n_total_constants
++0446: n_constant_features[0] = n_total_constants
(__pyx_v_n_constant_features[0]) = __pyx_v_n_total_constants; -
+0447: return 0
++0447: return 0
__pyx_r = 0; goto __pyx_L0;
0448:
0449:
- 0450: # Sort n-element arrays pointed to by Xf and samples, simultaneously,
- 0451: # by the values in Xf. Algorithm: Introsort (Musser, SP&E, 1997).
-+0452: cdef inline void sort(DTYPE_t* Xf, SIZE_t* samples, SIZE_t n) nogil:
+0450: # Sort n-element arrays pointed to by Xf and samples, simultaneously,+
0451: # by the values in Xf. Algorithm: Introsort (Musser, SP&E, 1997).+
+0452: cdef inline void sort(DTYPE_t* Xf, SIZE_t* samples, SIZE_t n) nogil:
static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter_sort(__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_Xf, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_n) { int __pyx_v_maxd; /* … */ /* function exit code */ __pyx_L0:; } -
+0453: if n == 0:
++0453: if n == 0:
__pyx_t_1 = ((__pyx_v_n == 0) != 0); if (__pyx_t_1) { /* … */ } -
+0454: return
++0454: return
goto __pyx_L0; -
+0455: cdef int maxd = 2 * <int>log(n)
++0455: cdef int maxd = 2 * <int>log(n)
__pyx_v_maxd = (2 * ((int)__pyx_f_7sklearn_4tree_6_utils_log(__pyx_v_n))); -
+0456: introsort(Xf, samples, n, maxd)
++0456: introsort(Xf, samples, n, maxd)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_introsort(__pyx_v_Xf, __pyx_v_samples, __pyx_v_n, __pyx_v_maxd);
0457:
0458:
-+0459: cdef inline void swap(DTYPE_t* Xf, SIZE_t* samples,
++0459: cdef inline void swap(DTYPE_t* Xf, SIZE_t* samples,
static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter_swap(__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_Xf, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_i, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_j) { /* … */ /* function exit code */ } -
0460: SIZE_t i, SIZE_t j) nogil:
- 0461: # Helper for sort
-+0462: Xf[i], Xf[j] = Xf[j], Xf[i]
+0460: SIZE_t i, SIZE_t j) nogil:+
0461: # Helper for sort+
+0462: Xf[i], Xf[j] = Xf[j], Xf[i]
__pyx_t_1 = (__pyx_v_Xf[__pyx_v_j]); __pyx_t_2 = (__pyx_v_Xf[__pyx_v_i]); (__pyx_v_Xf[__pyx_v_i]) = __pyx_t_1; (__pyx_v_Xf[__pyx_v_j]) = __pyx_t_2; -
+0463: samples[i], samples[j] = samples[j], samples[i]
++0463: samples[i], samples[j] = samples[j], samples[i]
__pyx_t_3 = (__pyx_v_samples[__pyx_v_j]); __pyx_t_4 = (__pyx_v_samples[__pyx_v_i]); (__pyx_v_samples[__pyx_v_i]) = __pyx_t_3; (__pyx_v_samples[__pyx_v_j]) = __pyx_t_4;
0464:
0465:
-+0466: cdef inline DTYPE_t median3(DTYPE_t* Xf, SIZE_t n) nogil:
++0466: cdef inline DTYPE_t median3(DTYPE_t* Xf, SIZE_t n) nogil:
static CYTHON_INLINE __pyx_t_7sklearn_4tree_5_tree_DTYPE_t __pyx_f_13stpredictions_6models_3OK3_9_splitter_median3(__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_Xf, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_n) { __pyx_t_7sklearn_4tree_5_tree_DTYPE_t __pyx_v_a; __pyx_t_7sklearn_4tree_5_tree_DTYPE_t __pyx_v_b; @@ -1640,69 +1714,69 @@ __pyx_L0:; return __pyx_r; } -
0467: # Median of three pivot selection, after Bentley and McIlroy (1993).
- 0468: # Engineering a sort function. SP&E. Requires 8/3 comparisons on average.
-+0469: cdef DTYPE_t a = Xf[0], b = Xf[n / 2], c = Xf[n - 1]
+0467: # Median of three pivot selection, after Bentley and McIlroy (1993).+
0468: # Engineering a sort function. SP&E. Requires 8/3 comparisons on average.+
+0469: cdef DTYPE_t a = Xf[0], b = Xf[n / 2], c = Xf[n - 1]
__pyx_v_a = (__pyx_v_Xf[0]); __pyx_v_b = (__pyx_v_Xf[(__pyx_v_n / 2)]); __pyx_v_c = (__pyx_v_Xf[(__pyx_v_n - 1)]); -
+0470: if a < b:
++0470: if a < b:
__pyx_t_1 = ((__pyx_v_a < __pyx_v_b) != 0); if (__pyx_t_1) { /* … */ } -
+0471: if b < c:
++0471: if b < c:
__pyx_t_1 = ((__pyx_v_b < __pyx_v_c) != 0); if (__pyx_t_1) { /* … */ } -
+0472: return b
++0472: return b
__pyx_r = __pyx_v_b; goto __pyx_L0; -
+0473: elif a < c:
++0473: elif a < c:
__pyx_t_1 = ((__pyx_v_a < __pyx_v_c) != 0); if (__pyx_t_1) { /* … */ } -
+0474: return c
++0474: return c
__pyx_r = __pyx_v_c; goto __pyx_L0; -
0475: else:
-+0476: return a
+0475: else:+
+0476: return a
/*else*/ { __pyx_r = __pyx_v_a; goto __pyx_L0; } -
+0477: elif b < c:
++0477: elif b < c:
__pyx_t_1 = ((__pyx_v_b < __pyx_v_c) != 0); if (__pyx_t_1) { /* … */ } -
+0478: if a < c:
++0478: if a < c:
__pyx_t_1 = ((__pyx_v_a < __pyx_v_c) != 0); if (__pyx_t_1) { /* … */ } -
+0479: return a
++0479: return a
__pyx_r = __pyx_v_a; goto __pyx_L0; -
0480: else:
-+0481: return c
+0480: else:+
+0481: return c
/*else*/ { __pyx_r = __pyx_v_c; goto __pyx_L0; } -
0482: else:
-+0483: return b
+0482: else:+
+0483: return b
/*else*/ { __pyx_r = __pyx_v_b; goto __pyx_L0; }
0484:
0485:
- 0486: # Introsort with median of 3 pivot selection and 3-way partition function
- 0487: # (robust to repeated elements, e.g. lots of zero features).
-+0488: cdef void introsort(DTYPE_t* Xf, SIZE_t *samples,
+0486: # Introsort with median of 3 pivot selection and 3-way partition function+
0487: # (robust to repeated elements, e.g. lots of zero features).+
+0488: cdef void introsort(DTYPE_t* Xf, SIZE_t *samples,
static void __pyx_f_13stpredictions_6models_3OK3_9_splitter_introsort(__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_Xf, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_n, int __pyx_v_maxd) { __pyx_t_7sklearn_4tree_5_tree_DTYPE_t __pyx_v_pivot; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_i; @@ -1712,81 +1786,81 @@ /* function exit code */ __pyx_L0:; } -
0489: SIZE_t n, int maxd) nogil:
- 0490: cdef DTYPE_t pivot
- 0491: cdef SIZE_t i, l, r
+0489: SIZE_t n, int maxd) nogil:+
0490: cdef DTYPE_t pivot+
0491: cdef SIZE_t i, l, r
0492:
-+0493: while n > 1:
++0493: while n > 1:
while (1) { __pyx_t_1 = ((__pyx_v_n > 1) != 0); if (!__pyx_t_1) break; -
+0494: if maxd <= 0: # max depth limit exceeded ("gone quadratic")
++0494: if maxd <= 0: # max depth limit exceeded ("gone quadratic")
__pyx_t_1 = ((__pyx_v_maxd <= 0) != 0); if (__pyx_t_1) { /* … */ } -
+0495: heapsort(Xf, samples, n)
++0495: heapsort(Xf, samples, n)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_heapsort(__pyx_v_Xf, __pyx_v_samples, __pyx_v_n); -
+0496: return
++0496: return
goto __pyx_L0; -
+0497: maxd -= 1
++0497: maxd -= 1
__pyx_v_maxd = (__pyx_v_maxd - 1);
0498:
-+0499: pivot = median3(Xf, n)
++0499: pivot = median3(Xf, n)
__pyx_v_pivot = __pyx_f_13stpredictions_6models_3OK3_9_splitter_median3(__pyx_v_Xf, __pyx_v_n);
0500:
- 0501: # Three-way partition.
-+0502: i = l = 0
+0501: # Three-way partition.+
+0502: i = l = 0
__pyx_v_i = 0; __pyx_v_l = 0; -
+0503: r = n
++0503: r = n
__pyx_v_r = __pyx_v_n; -
+0504: while i < r:
++0504: while i < r:
while (1) { __pyx_t_1 = ((__pyx_v_i < __pyx_v_r) != 0); if (!__pyx_t_1) break; -
+0505: if Xf[i] < pivot:
++0505: if Xf[i] < pivot:
__pyx_t_1 = (((__pyx_v_Xf[__pyx_v_i]) < __pyx_v_pivot) != 0); if (__pyx_t_1) { /* … */ goto __pyx_L8; } -
+0506: swap(Xf, samples, i, l)
++0506: swap(Xf, samples, i, l)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_swap(__pyx_v_Xf, __pyx_v_samples, __pyx_v_i, __pyx_v_l); -
+0507: i += 1
++0507: i += 1
__pyx_v_i = (__pyx_v_i + 1); -
+0508: l += 1
++0508: l += 1
__pyx_v_l = (__pyx_v_l + 1); -
+0509: elif Xf[i] > pivot:
++0509: elif Xf[i] > pivot:
__pyx_t_1 = (((__pyx_v_Xf[__pyx_v_i]) > __pyx_v_pivot) != 0); if (__pyx_t_1) { /* … */ goto __pyx_L8; } -
+0510: r -= 1
++0510: r -= 1
__pyx_v_r = (__pyx_v_r - 1); -
+0511: swap(Xf, samples, i, r)
++0511: swap(Xf, samples, i, r)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_swap(__pyx_v_Xf, __pyx_v_samples, __pyx_v_i, __pyx_v_r); -
0512: else:
-+0513: i += 1
+0512: else:+
+0513: i += 1
/*else*/ { __pyx_v_i = (__pyx_v_i + 1); } __pyx_L8:; }
0514:
-+0515: introsort(Xf, samples, l, maxd)
++0515: introsort(Xf, samples, l, maxd)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_introsort(__pyx_v_Xf, __pyx_v_samples, __pyx_v_l, __pyx_v_maxd); -
+0516: Xf += r
++0516: Xf += r
__pyx_v_Xf = (__pyx_v_Xf + __pyx_v_r); -
+0517: samples += r
++0517: samples += r
__pyx_v_samples = (__pyx_v_samples + __pyx_v_r); -
+0518: n -= r
++0518: n -= r
__pyx_v_n = (__pyx_v_n - __pyx_v_r); }
0519:
0520:
-+0521: cdef inline void sift_down(DTYPE_t* Xf, SIZE_t* samples,
++0521: cdef inline void sift_down(DTYPE_t* Xf, SIZE_t* samples,
static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter_sift_down(__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_Xf, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_end) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_child; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_maxind; @@ -1794,21 +1868,21 @@ /* … */ /* function exit code */ } -
0522: SIZE_t start, SIZE_t end) nogil:
- 0523: # Restore heap order in Xf[start:end] by moving the max element to start.
- 0524: cdef SIZE_t child, maxind, root
+0522: SIZE_t start, SIZE_t end) nogil:+
0523: # Restore heap order in Xf[start:end] by moving the max element to start.+
0524: cdef SIZE_t child, maxind, root
0525:
-+0526: root = start
++0526: root = start
__pyx_v_root = __pyx_v_start; -
+0527: while True:
++0527: while True:
while (1) { -
+0528: child = root * 2 + 1
++0528: child = root * 2 + 1
__pyx_v_child = ((__pyx_v_root * 2) + 1);
0529:
- 0530: # find max of root, left child, right child
-+0531: maxind = root
+0530: # find max of root, left child, right child+
+0531: maxind = root
__pyx_v_maxind = __pyx_v_root; -
+0532: if child < end and Xf[maxind] < Xf[child]:
++0532: if child < end and Xf[maxind] < Xf[child]:
__pyx_t_2 = ((__pyx_v_child < __pyx_v_end) != 0); if (__pyx_t_2) { } else { @@ -1821,9 +1895,9 @@ if (__pyx_t_1) { /* … */ } -
+0533: maxind = child
++0533: maxind = child
__pyx_v_maxind = __pyx_v_child; -
+0534: if child + 1 < end and Xf[maxind] < Xf[child + 1]:
++0534: if child + 1 < end and Xf[maxind] < Xf[child + 1]:
__pyx_t_2 = (((__pyx_v_child + 1) < __pyx_v_end) != 0); if (__pyx_t_2) { } else { @@ -1836,74 +1910,74 @@ if (__pyx_t_1) { /* … */ } -
+0535: maxind = child + 1
++0535: maxind = child + 1
__pyx_v_maxind = (__pyx_v_child + 1);
0536:
-+0537: if maxind == root:
++0537: if maxind == root:
__pyx_t_1 = ((__pyx_v_maxind == __pyx_v_root) != 0); if (__pyx_t_1) { /* … */ } -
+0538: break
++0538: break
goto __pyx_L4_break; -
0539: else:
-+0540: swap(Xf, samples, root, maxind)
+0539: else:+
+0540: swap(Xf, samples, root, maxind)
/*else*/ { __pyx_f_13stpredictions_6models_3OK3_9_splitter_swap(__pyx_v_Xf, __pyx_v_samples, __pyx_v_root, __pyx_v_maxind); -
+0541: root = maxind
++0541: root = maxind
__pyx_v_root = __pyx_v_maxind; } } __pyx_L4_break:;
0542:
0543:
-+0544: cdef void heapsort(DTYPE_t* Xf, SIZE_t* samples, SIZE_t n) nogil:
++0544: cdef void heapsort(DTYPE_t* Xf, SIZE_t* samples, SIZE_t n) nogil:
static void __pyx_f_13stpredictions_6models_3OK3_9_splitter_heapsort(__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_Xf, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_n) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_end; /* … */ /* function exit code */ } -
0545: cdef SIZE_t start, end
+0545: cdef SIZE_t start, end
0546:
- 0547: # heapify
-+0548: start = (n - 2) / 2
+0547: # heapify+
+0548: start = (n - 2) / 2
__pyx_v_start = ((__pyx_v_n - 2) / 2); -
+0549: end = n
++0549: end = n
__pyx_v_end = __pyx_v_n; -
+0550: while True:
++0550: while True:
while (1) { -
+0551: sift_down(Xf, samples, start, end)
++0551: sift_down(Xf, samples, start, end)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sift_down(__pyx_v_Xf, __pyx_v_samples, __pyx_v_start, __pyx_v_end); -
+0552: if start == 0:
++0552: if start == 0:
__pyx_t_1 = ((__pyx_v_start == 0) != 0); if (__pyx_t_1) { /* … */ } -
+0553: break
++0553: break
goto __pyx_L4_break; -
+0554: start -= 1
++0554: start -= 1
__pyx_v_start = (__pyx_v_start - 1); } __pyx_L4_break:;
0555:
- 0556: # sort by shrinking the heap, putting the max element immediately after it
-+0557: end = n - 1
+0556: # sort by shrinking the heap, putting the max element immediately after it+
+0557: end = n - 1
__pyx_v_end = (__pyx_v_n - 1); -
+0558: while end > 0:
++0558: while end > 0:
while (1) { __pyx_t_1 = ((__pyx_v_end > 0) != 0); if (!__pyx_t_1) break; -
+0559: swap(Xf, samples, 0, end)
++0559: swap(Xf, samples, 0, end)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_swap(__pyx_v_Xf, __pyx_v_samples, 0, __pyx_v_end); -
+0560: sift_down(Xf, samples, 0, end)
++0560: sift_down(Xf, samples, 0, end)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sift_down(__pyx_v_Xf, __pyx_v_samples, 0, __pyx_v_end); -
+0561: end = end - 1
++0561: end = end - 1
__pyx_v_end = (__pyx_v_end - 1); }
0562:
0563:
-+0564: cdef class RandomSplitter(BaseDenseSplitter):
++0564: cdef class RandomSplitter(BaseDenseSplitter):
struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_RandomSplitter { struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseDenseSplitter __pyx_base; }; @@ -1913,8 +1987,8 @@ }; static struct __pyx_vtabstruct_13stpredictions_6models_3OK3_9_splitter_RandomSplitter *__pyx_vtabptr_13stpredictions_6models_3OK3_9_splitter_RandomSplitter; -
0565: """Splitter for finding the best random split."""
-+0566: def __reduce__(self):
+0565: """Splitter for finding the best random split."""+
+0566: def __reduce__(self):
/* Python wrapper */
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_14RandomSplitter_1__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_14RandomSplitter_1__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
@@ -1946,7 +2020,7 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
+0567: return (RandomSplitter, (self.criterion,
++0567: return (RandomSplitter, (self.criterion,
__Pyx_XDECREF(__pyx_r); /* … */ __pyx_t_4 = PyTuple_New(5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 567, __pyx_L1_error) @@ -1981,16 +2055,16 @@ __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; -
+0568: self.max_features,
++0568: self.max_features,
__pyx_t_1 = __Pyx_PyInt_From_Py_intptr_t(__pyx_v_self->__pyx_base.__pyx_base.max_features); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 568, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); -
+0569: self.min_samples_leaf,
++0569: self.min_samples_leaf,
__pyx_t_2 = __Pyx_PyInt_From_Py_intptr_t(__pyx_v_self->__pyx_base.__pyx_base.min_samples_leaf); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 569, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); -
+0570: self.min_weight_leaf,
++0570: self.min_weight_leaf,
__pyx_t_3 = PyFloat_FromDouble(__pyx_v_self->__pyx_base.__pyx_base.min_weight_leaf); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 570, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); -
+0571: self.random_state), self.__getstate__())
++0571: self.random_state), self.__getstate__())
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_getstate); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 571, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_1 = NULL; @@ -2009,7 +2083,7 @@ __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
0572:
-+0573: cdef int node_split(self, double impurity, SplitRecord* split,
++0573: cdef int node_split(self, double impurity, SplitRecord* split,
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_14RandomSplitter_node_split(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_RandomSplitter *__pyx_v_self, double __pyx_v_impurity, struct __pyx_t_13stpredictions_6models_3OK3_9_splitter_SplitRecord *__pyx_v_split, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_n_constant_features) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start; @@ -2055,90 +2129,90 @@ __pyx_L0:; return __pyx_r; } -
0574: SIZE_t* n_constant_features) nogil except -1:
- 0575: """Find the best random split on node samples[start:end]
+0574: SIZE_t* n_constant_features) nogil except -1:+
0575: """Find the best random split on node samples[start:end]
0576:
- 0577: Returns -1 in case of failure to allocate memory (and raise MemoryError)
- 0578: or 0 otherwise.
- 0579: """
- 0580: # Draw random splits and pick the best
-+0581: cdef SIZE_t* samples = self.samples
+0577: Returns -1 in case of failure to allocate memory (and raise MemoryError)+
0578: or 0 otherwise.+
0579: """+
0580: # Draw random splits and pick the best+
+0581: cdef SIZE_t* samples = self.samples
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.samples; __pyx_v_samples = __pyx_t_1; -
+0582: cdef SIZE_t start = self.start
++0582: cdef SIZE_t start = self.start
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.start; __pyx_v_start = __pyx_t_2; -
+0583: cdef SIZE_t end = self.end
++0583: cdef SIZE_t end = self.end
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.end; __pyx_v_end = __pyx_t_2;
0584:
-+0585: cdef SIZE_t* features = self.features
++0585: cdef SIZE_t* features = self.features
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.features; __pyx_v_features = __pyx_t_1; -
+0586: cdef SIZE_t* constant_features = self.constant_features
++0586: cdef SIZE_t* constant_features = self.constant_features
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.constant_features; __pyx_v_constant_features = __pyx_t_1; -
+0587: cdef SIZE_t n_features = self.n_features
++0587: cdef SIZE_t n_features = self.n_features
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.n_features; __pyx_v_n_features = __pyx_t_2;
0588:
-+0589: cdef DTYPE_t* Xf = self.feature_values
++0589: cdef DTYPE_t* Xf = self.feature_values
__pyx_t_3 = __pyx_v_self->__pyx_base.__pyx_base.feature_values; __pyx_v_Xf = __pyx_t_3; -
+0590: cdef SIZE_t max_features = self.max_features
++0590: cdef SIZE_t max_features = self.max_features
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.max_features; __pyx_v_max_features = __pyx_t_2; -
+0591: cdef SIZE_t min_samples_leaf = self.min_samples_leaf
++0591: cdef SIZE_t min_samples_leaf = self.min_samples_leaf
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.min_samples_leaf; __pyx_v_min_samples_leaf = __pyx_t_2; -
+0592: cdef double min_weight_leaf = self.min_weight_leaf
++0592: cdef double min_weight_leaf = self.min_weight_leaf
__pyx_t_4 = __pyx_v_self->__pyx_base.__pyx_base.min_weight_leaf; __pyx_v_min_weight_leaf = __pyx_t_4; -
+0593: cdef UINT32_t* random_state = &self.rand_r_state
++0593: cdef UINT32_t* random_state = &self.rand_r_state
__pyx_v_random_state = (&__pyx_v_self->__pyx_base.__pyx_base.rand_r_state);
0594:
- 0595: cdef SplitRecord best, current
-+0596: cdef double current_proxy_improvement = - INFINITY
+0595: cdef SplitRecord best, current+
+0596: cdef double current_proxy_improvement = - INFINITY
__pyx_v_current_proxy_improvement = (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY); -
+0597: cdef double best_proxy_improvement = - INFINITY
++0597: cdef double best_proxy_improvement = - INFINITY
__pyx_v_best_proxy_improvement = (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY);
0598:
-+0599: cdef SIZE_t f_i = n_features
++0599: cdef SIZE_t f_i = n_features
__pyx_v_f_i = __pyx_v_n_features; -
0600: cdef SIZE_t f_j
- 0601: cdef SIZE_t p
- 0602: cdef SIZE_t partition_end
- 0603: cdef SIZE_t feature_stride
- 0604: # Number of features discovered to be constant during the split search
-+0605: cdef SIZE_t n_found_constants = 0
+0600: cdef SIZE_t f_j+
0601: cdef SIZE_t p+
0602: cdef SIZE_t partition_end+
0603: cdef SIZE_t feature_stride+
0604: # Number of features discovered to be constant during the split search+
+0605: cdef SIZE_t n_found_constants = 0
__pyx_v_n_found_constants = 0; -
0606: # Number of features known to be constant and drawn without replacement
-+0607: cdef SIZE_t n_drawn_constants = 0
+0606: # Number of features known to be constant and drawn without replacement+
+0607: cdef SIZE_t n_drawn_constants = 0
__pyx_v_n_drawn_constants = 0; -
+0608: cdef SIZE_t n_known_constants = n_constant_features[0]
++0608: cdef SIZE_t n_known_constants = n_constant_features[0]
__pyx_v_n_known_constants = (__pyx_v_n_constant_features[0]); -
0609: # n_total_constants = n_known_constants + n_found_constants
-+0610: cdef SIZE_t n_total_constants = n_known_constants
+0609: # n_total_constants = n_known_constants + n_found_constants+
+0610: cdef SIZE_t n_total_constants = n_known_constants
__pyx_v_n_total_constants = __pyx_v_n_known_constants; -
+0611: cdef SIZE_t n_visited_features = 0
++0611: cdef SIZE_t n_visited_features = 0
__pyx_v_n_visited_features = 0; -
0612: cdef DTYPE_t min_feature_value
- 0613: cdef DTYPE_t max_feature_value
- 0614: cdef DTYPE_t current_feature_value
+0612: cdef DTYPE_t min_feature_value+
0613: cdef DTYPE_t max_feature_value+
0614: cdef DTYPE_t current_feature_value
0615:
-+0616: _init_split(&best, end)
++0616: _init_split(&best, end)
__pyx_f_13stpredictions_6models_3OK3_9_splitter__init_split((&__pyx_v_best), __pyx_v_end);
0617:
- 0618: # Sample up to max_features without replacement using a
- 0619: # Fisher-Yates-based algorithm (using the local variables `f_i` and
- 0620: # `f_j` to compute a permutation of the `features` array).
- 0621: #
- 0622: # Skip the CPU intensive evaluation of the impurity criterion for
- 0623: # features that were already detected as constant (hence not suitable
- 0624: # for good splitting) by ancestor nodes and save the information on
- 0625: # newly discovered constant features to spare computation on descendant
- 0626: # nodes.
-+0627: while (f_i > n_total_constants and # Stop early if remaining features
+0618: # Sample up to max_features without replacement using a+
0619: # Fisher-Yates-based algorithm (using the local variables `f_i` and+
0620: # `f_j` to compute a permutation of the `features` array).+
0621: #+
0622: # Skip the CPU intensive evaluation of the impurity criterion for+
0623: # features that were already detected as constant (hence not suitable+
0624: # for good splitting) by ancestor nodes and save the information on+
0625: # newly discovered constant features to spare computation on descendant+
0626: # nodes.+
+0627: while (f_i > n_total_constants and # Stop early if remaining features
while (1) { __pyx_t_6 = ((__pyx_v_f_i > __pyx_v_n_total_constants) != 0); if (__pyx_t_6) { @@ -2146,176 +2220,176 @@ __pyx_t_5 = __pyx_t_6; goto __pyx_L5_bool_binop_done; } -
0628: # are constant
-+0629: (n_visited_features < max_features or
+0628: # are constant+
+0629: (n_visited_features < max_features or
__pyx_t_6 = ((__pyx_v_n_visited_features < __pyx_v_max_features) != 0); if (!__pyx_t_6) { } else { __pyx_t_5 = __pyx_t_6; goto __pyx_L5_bool_binop_done; } -
0630: # At least one drawn features must be non constant
-+0631: n_visited_features <= n_found_constants + n_drawn_constants)):
+0630: # At least one drawn features must be non constant+
+0631: n_visited_features <= n_found_constants + n_drawn_constants)):
__pyx_t_6 = ((__pyx_v_n_visited_features <= (__pyx_v_n_found_constants + __pyx_v_n_drawn_constants)) != 0); __pyx_t_5 = __pyx_t_6; __pyx_L5_bool_binop_done:; if (!__pyx_t_5) break; -
+0632: n_visited_features += 1
++0632: n_visited_features += 1
__pyx_v_n_visited_features = (__pyx_v_n_visited_features + 1);
0633:
- 0634: # Loop invariant: elements of features in
- 0635: # - [:n_drawn_constant[ holds drawn and known constant features;
- 0636: # - [n_drawn_constant:n_known_constant[ holds known constant
- 0637: # features that haven't been drawn yet;
- 0638: # - [n_known_constant:n_total_constant[ holds newly found constant
- 0639: # features;
- 0640: # - [n_total_constant:f_i[ holds features that haven't been drawn
- 0641: # yet and aren't constant apriori.
- 0642: # - [f_i:n_features[ holds features that have been drawn
- 0643: # and aren't constant.
+0634: # Loop invariant: elements of features in+
0635: # - [:n_drawn_constant[ holds drawn and known constant features;+
0636: # - [n_drawn_constant:n_known_constant[ holds known constant+
0637: # features that haven't been drawn yet;+
0638: # - [n_known_constant:n_total_constant[ holds newly found constant+
0639: # features;+
0640: # - [n_total_constant:f_i[ holds features that haven't been drawn+
0641: # yet and aren't constant apriori.+
0642: # - [f_i:n_features[ holds features that have been drawn+
0643: # and aren't constant.
0644:
- 0645: # Draw a feature at random
-+0646: f_j = rand_int(n_drawn_constants, f_i - n_found_constants,
+0645: # Draw a feature at random+
+0646: f_j = rand_int(n_drawn_constants, f_i - n_found_constants,
__pyx_v_f_j = __pyx_f_7sklearn_4tree_6_utils_rand_int(__pyx_v_n_drawn_constants, (__pyx_v_f_i - __pyx_v_n_found_constants), __pyx_v_random_state); -
0647: random_state)
+0647: random_state)
0648:
-+0649: if f_j < n_known_constants:
++0649: if f_j < n_known_constants:
__pyx_t_5 = ((__pyx_v_f_j < __pyx_v_n_known_constants) != 0); if (__pyx_t_5) { /* … */ goto __pyx_L8; } -
0650: # f_j in the interval [n_drawn_constants, n_known_constants[
-+0651: features[n_drawn_constants], features[f_j] = features[f_j], features[n_drawn_constants]
+0650: # f_j in the interval [n_drawn_constants, n_known_constants[+
+0651: features[n_drawn_constants], features[f_j] = features[f_j], features[n_drawn_constants]
__pyx_t_2 = (__pyx_v_features[__pyx_v_f_j]); __pyx_t_7 = (__pyx_v_features[__pyx_v_n_drawn_constants]); (__pyx_v_features[__pyx_v_n_drawn_constants]) = __pyx_t_2; (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_7; -
+0652: n_drawn_constants += 1
++0652: n_drawn_constants += 1
__pyx_v_n_drawn_constants = (__pyx_v_n_drawn_constants + 1);
0653:
- 0654: else:
- 0655: # f_j in the interval [n_known_constants, f_i - n_found_constants[
-+0656: f_j += n_found_constants
+0654: else:+
0655: # f_j in the interval [n_known_constants, f_i - n_found_constants[+
+0656: f_j += n_found_constants
/*else*/ { __pyx_v_f_j = (__pyx_v_f_j + __pyx_v_n_found_constants); -
0657: # f_j in the interval [n_total_constants, f_i[
+0657: # f_j in the interval [n_total_constants, f_i[
0658:
-+0659: current.feature = features[f_j]
++0659: current.feature = features[f_j]
__pyx_v_current.feature = (__pyx_v_features[__pyx_v_f_j]);
0660:
- 0661: # Find min, max
-+0662: min_feature_value = self.X[samples[start], current.feature]
+0661: # Find min, max+
+0662: min_feature_value = self.X[samples[start], current.feature]
if (unlikely(!__pyx_v_self->__pyx_base.X.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 662, __pyx_L1_error)} __pyx_t_8 = (__pyx_v_samples[__pyx_v_start]); __pyx_t_9 = __pyx_v_current.feature; __pyx_v_min_feature_value = (*((__pyx_t_7sklearn_4tree_5_tree_DTYPE_t const *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->__pyx_base.X.data + __pyx_t_8 * __pyx_v_self->__pyx_base.X.strides[0]) ) + __pyx_t_9 * __pyx_v_self->__pyx_base.X.strides[1]) ))); -
+0663: max_feature_value = min_feature_value
++0663: max_feature_value = min_feature_value
__pyx_v_max_feature_value = __pyx_v_min_feature_value; -
+0664: Xf[start] = min_feature_value
++0664: Xf[start] = min_feature_value
(__pyx_v_Xf[__pyx_v_start]) = __pyx_v_min_feature_value;
0665:
-+0666: for p in range(start + 1, end):
++0666: for p in range(start + 1, end):
__pyx_t_7 = __pyx_v_end; __pyx_t_2 = __pyx_t_7; for (__pyx_t_10 = (__pyx_v_start + 1); __pyx_t_10 < __pyx_t_2; __pyx_t_10+=1) { __pyx_v_p = __pyx_t_10; -
+0667: current_feature_value = self.X[samples[p], current.feature]
++0667: current_feature_value = self.X[samples[p], current.feature]
if (unlikely(!__pyx_v_self->__pyx_base.X.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 667, __pyx_L1_error)} __pyx_t_9 = (__pyx_v_samples[__pyx_v_p]); __pyx_t_8 = __pyx_v_current.feature; __pyx_v_current_feature_value = (*((__pyx_t_7sklearn_4tree_5_tree_DTYPE_t const *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->__pyx_base.X.data + __pyx_t_9 * __pyx_v_self->__pyx_base.X.strides[0]) ) + __pyx_t_8 * __pyx_v_self->__pyx_base.X.strides[1]) ))); -
+0668: Xf[p] = current_feature_value
++0668: Xf[p] = current_feature_value
(__pyx_v_Xf[__pyx_v_p]) = __pyx_v_current_feature_value;
0669:
-+0670: if current_feature_value < min_feature_value:
++0670: if current_feature_value < min_feature_value:
__pyx_t_5 = ((__pyx_v_current_feature_value < __pyx_v_min_feature_value) != 0); if (__pyx_t_5) { /* … */ goto __pyx_L11; } -
+0671: min_feature_value = current_feature_value
++0671: min_feature_value = current_feature_value
__pyx_v_min_feature_value = __pyx_v_current_feature_value; -
+0672: elif current_feature_value > max_feature_value:
++0672: elif current_feature_value > max_feature_value:
__pyx_t_5 = ((__pyx_v_current_feature_value > __pyx_v_max_feature_value) != 0); if (__pyx_t_5) { /* … */ } __pyx_L11:; } -
+0673: max_feature_value = current_feature_value
++0673: max_feature_value = current_feature_value
__pyx_v_max_feature_value = __pyx_v_current_feature_value;
0674:
-+0675: if max_feature_value <= min_feature_value + FEATURE_THRESHOLD:
++0675: if max_feature_value <= min_feature_value + FEATURE_THRESHOLD:
__pyx_t_5 = ((__pyx_v_max_feature_value <= (__pyx_v_min_feature_value + __pyx_v_13stpredictions_6models_3OK3_9_splitter_FEATURE_THRESHOLD)) != 0); if (__pyx_t_5) { /* … */ goto __pyx_L12; } -
+0676: features[f_j], features[n_total_constants] = features[n_total_constants], current.feature
++0676: features[f_j], features[n_total_constants] = features[n_total_constants], current.feature
__pyx_t_7 = (__pyx_v_features[__pyx_v_n_total_constants]); __pyx_t_2 = __pyx_v_current.feature; (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_7; (__pyx_v_features[__pyx_v_n_total_constants]) = __pyx_t_2;
0677:
-+0678: n_found_constants += 1
++0678: n_found_constants += 1
__pyx_v_n_found_constants = (__pyx_v_n_found_constants + 1); -
+0679: n_total_constants += 1
++0679: n_total_constants += 1
__pyx_v_n_total_constants = (__pyx_v_n_total_constants + 1);
0680:
- 0681: else:
-+0682: f_i -= 1
+0681: else:+
+0682: f_i -= 1
/*else*/ { __pyx_v_f_i = (__pyx_v_f_i - 1); -
+0683: features[f_i], features[f_j] = features[f_j], features[f_i]
++0683: features[f_i], features[f_j] = features[f_j], features[f_i]
__pyx_t_2 = (__pyx_v_features[__pyx_v_f_j]); __pyx_t_7 = (__pyx_v_features[__pyx_v_f_i]); (__pyx_v_features[__pyx_v_f_i]) = __pyx_t_2; (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_7;
0684:
- 0685: # Draw a random threshold
-+0686: current.threshold = rand_uniform(min_feature_value,
+0685: # Draw a random threshold+
+0686: current.threshold = rand_uniform(min_feature_value,
__pyx_v_current.threshold = __pyx_f_7sklearn_4tree_6_utils_rand_uniform(__pyx_v_min_feature_value, __pyx_v_max_feature_value, __pyx_v_random_state); -
0687: max_feature_value,
- 0688: random_state)
+0687: max_feature_value,+
0688: random_state)
0689:
-+0690: if current.threshold == max_feature_value:
++0690: if current.threshold == max_feature_value:
__pyx_t_5 = ((__pyx_v_current.threshold == __pyx_v_max_feature_value) != 0); if (__pyx_t_5) { /* … */ } -
+0691: current.threshold = min_feature_value
++0691: current.threshold = min_feature_value
__pyx_v_current.threshold = __pyx_v_min_feature_value;
0692:
- 0693: # Partition
-+0694: p, partition_end = start, end
+0693: # Partition+
+0694: p, partition_end = start, end
__pyx_t_7 = __pyx_v_start; __pyx_t_2 = __pyx_v_end; __pyx_v_p = __pyx_t_7; __pyx_v_partition_end = __pyx_t_2; -
+0695: while p < partition_end:
++0695: while p < partition_end:
while (1) { __pyx_t_5 = ((__pyx_v_p < __pyx_v_partition_end) != 0); if (!__pyx_t_5) break; -
+0696: if Xf[p] <= current.threshold:
++0696: if Xf[p] <= current.threshold:
__pyx_t_5 = (((__pyx_v_Xf[__pyx_v_p]) <= __pyx_v_current.threshold) != 0); if (__pyx_t_5) { /* … */ goto __pyx_L16; } -
+0697: p += 1
++0697: p += 1
__pyx_v_p = (__pyx_v_p + 1); -
0698: else:
-+0699: partition_end -= 1
+0698: else:+
+0699: partition_end -= 1
/*else*/ { __pyx_v_partition_end = (__pyx_v_partition_end - 1);
0700:
-+0701: Xf[p], Xf[partition_end] = Xf[partition_end], Xf[p]
++0701: Xf[p], Xf[partition_end] = Xf[partition_end], Xf[p]
__pyx_t_11 = (__pyx_v_Xf[__pyx_v_partition_end]); __pyx_t_12 = (__pyx_v_Xf[__pyx_v_p]); (__pyx_v_Xf[__pyx_v_p]) = __pyx_t_11; (__pyx_v_Xf[__pyx_v_partition_end]) = __pyx_t_12; -
+0702: samples[p], samples[partition_end] = samples[partition_end], samples[p]
++0702: samples[p], samples[partition_end] = samples[partition_end], samples[p]
__pyx_t_2 = (__pyx_v_samples[__pyx_v_partition_end]); __pyx_t_7 = (__pyx_v_samples[__pyx_v_p]); (__pyx_v_samples[__pyx_v_p]) = __pyx_t_2; @@ -2324,11 +2398,11 @@ __pyx_L16:; }
0703:
-+0704: current.pos = partition_end
++0704: current.pos = partition_end
__pyx_v_current.pos = __pyx_v_partition_end;
0705:
- 0706: # Reject if min_samples_leaf is not guaranteed
-+0707: if (((current.pos - start) < min_samples_leaf) or
+0706: # Reject if min_samples_leaf is not guaranteed+
+0707: if (((current.pos - start) < min_samples_leaf) or
__pyx_t_6 = (((__pyx_v_current.pos - __pyx_v_start) < __pyx_v_min_samples_leaf) != 0); if (!__pyx_t_6) { } else { @@ -2339,21 +2413,21 @@ if (__pyx_t_5) { /* … */ } -
+0708: ((end - current.pos) < min_samples_leaf)):
++0708: ((end - current.pos) < min_samples_leaf)):
__pyx_t_6 = (((__pyx_v_end - __pyx_v_current.pos) < __pyx_v_min_samples_leaf) != 0); __pyx_t_5 = __pyx_t_6; __pyx_L18_bool_binop_done:; -
+0709: continue
++0709: continue
goto __pyx_L3_continue;
0710:
- 0711: # Evaluate split
-+0712: self.criterion.reset()
+0711: # Evaluate split+
+0712: self.criterion.reset()
__pyx_t_13 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->reset(__pyx_v_self->__pyx_base.__pyx_base.criterion); if (unlikely(__pyx_t_13 == ((int)-1))) __PYX_ERR(0, 712, __pyx_L1_error)
-
+0713: self.criterion.update(current.pos)
++0713: self.criterion.update(current.pos)
__pyx_t_13 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->update(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_current.pos); if (unlikely(__pyx_t_13 == ((int)-1))) __PYX_ERR(0, 713, __pyx_L1_error)
0714:
- 0715: # Reject if min_weight_leaf is not satisfied
-+0716: if ((self.criterion.weighted_n_left < min_weight_leaf) or
+0715: # Reject if min_weight_leaf is not satisfied+
+0716: if ((self.criterion.weighted_n_left < min_weight_leaf) or
__pyx_t_6 = ((__pyx_v_self->__pyx_base.__pyx_base.criterion->weighted_n_left < __pyx_v_min_weight_leaf) != 0); if (!__pyx_t_6) { } else { @@ -2364,17 +2438,17 @@ if (__pyx_t_5) { /* … */ } -
+0717: (self.criterion.weighted_n_right < min_weight_leaf)):
++0717: (self.criterion.weighted_n_right < min_weight_leaf)):
__pyx_t_6 = ((__pyx_v_self->__pyx_base.__pyx_base.criterion->weighted_n_right < __pyx_v_min_weight_leaf) != 0); __pyx_t_5 = __pyx_t_6; __pyx_L21_bool_binop_done:; -
+0718: continue
++0718: continue
goto __pyx_L3_continue;
0719:
-+0720: current_proxy_improvement = self.criterion.proxy_impurity_improvement()
++0720: current_proxy_improvement = self.criterion.proxy_impurity_improvement()
__pyx_v_current_proxy_improvement = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->proxy_impurity_improvement(__pyx_v_self->__pyx_base.__pyx_base.criterion);
0721:
-+0722: if current_proxy_improvement > best_proxy_improvement:
++0722: if current_proxy_improvement > best_proxy_improvement:
__pyx_t_5 = ((__pyx_v_current_proxy_improvement > __pyx_v_best_proxy_improvement) != 0); if (__pyx_t_5) { /* … */ @@ -2385,33 +2459,33 @@ __pyx_L8:; __pyx_L3_continue:; } -
+0723: best_proxy_improvement = current_proxy_improvement
++0723: best_proxy_improvement = current_proxy_improvement
__pyx_v_best_proxy_improvement = __pyx_v_current_proxy_improvement; -
+0724: best = current # copy
++0724: best = current # copy
__pyx_v_best = __pyx_v_current;
0725:
- 0726: # Reorganize into samples[start:best.pos] + samples[best.pos:end]
-+0727: if best.pos < end:
+0726: # Reorganize into samples[start:best.pos] + samples[best.pos:end]+
+0727: if best.pos < end:
__pyx_t_5 = ((__pyx_v_best.pos < __pyx_v_end) != 0); if (__pyx_t_5) { /* … */ } -
+0728: if current.feature != best.feature:
++0728: if current.feature != best.feature:
__pyx_t_5 = ((__pyx_v_current.feature != __pyx_v_best.feature) != 0); if (__pyx_t_5) { /* … */ } -
+0729: p, partition_end = start, end
++0729: p, partition_end = start, end
__pyx_t_7 = __pyx_v_start; __pyx_t_2 = __pyx_v_end; __pyx_v_p = __pyx_t_7; __pyx_v_partition_end = __pyx_t_2;
0730:
-+0731: while p < partition_end:
++0731: while p < partition_end:
while (1) { __pyx_t_5 = ((__pyx_v_p < __pyx_v_partition_end) != 0); if (!__pyx_t_5) break; -
+0732: if self.X[samples[p], best.feature] <= best.threshold:
++0732: if self.X[samples[p], best.feature] <= best.threshold:
if (unlikely(!__pyx_v_self->__pyx_base.X.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 732, __pyx_L1_error)} __pyx_t_8 = (__pyx_v_samples[__pyx_v_p]); __pyx_t_9 = __pyx_v_best.feature; @@ -2420,14 +2494,14 @@ /* … */ goto __pyx_L28; } -
+0733: p += 1
++0733: p += 1
__pyx_v_p = (__pyx_v_p + 1); -
0734: else:
-+0735: partition_end -= 1
+0734: else:+
+0735: partition_end -= 1
/*else*/ { __pyx_v_partition_end = (__pyx_v_partition_end - 1);
0736:
-+0737: samples[p], samples[partition_end] = samples[partition_end], samples[p]
++0737: samples[p], samples[partition_end] = samples[partition_end], samples[p]
__pyx_t_2 = (__pyx_v_samples[__pyx_v_partition_end]); __pyx_t_7 = (__pyx_v_samples[__pyx_v_p]); (__pyx_v_samples[__pyx_v_p]) = __pyx_t_2; @@ -2436,39 +2510,39 @@ __pyx_L28:; }
0738:
-+0739: self.criterion.reset()
++0739: self.criterion.reset()
__pyx_t_13 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->reset(__pyx_v_self->__pyx_base.__pyx_base.criterion); if (unlikely(__pyx_t_13 == ((int)-1))) __PYX_ERR(0, 739, __pyx_L1_error)
-
+0740: self.criterion.update(best.pos)
++0740: self.criterion.update(best.pos)
__pyx_t_13 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->update(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_best.pos); if (unlikely(__pyx_t_13 == ((int)-1))) __PYX_ERR(0, 740, __pyx_L1_error)
-
+0741: best.improvement = self.criterion.impurity_improvement(impurity)
++0741: best.improvement = self.criterion.impurity_improvement(impurity)
__pyx_v_best.improvement = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->impurity_improvement(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_impurity); -
+0742: self.criterion.children_impurity(&best.impurity_left,
++0742: self.criterion.children_impurity(&best.impurity_left,
((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->children_impurity(__pyx_v_self->__pyx_base.__pyx_base.criterion, (&__pyx_v_best.impurity_left), (&__pyx_v_best.impurity_right)); -
0743: &best.impurity_right)
+0743: &best.impurity_right)
0744:
- 0745: # Respect invariant for constant features: the original order of
- 0746: # element in features[:n_known_constants] must be preserved for sibling
- 0747: # and child nodes
-+0748: memcpy(features, constant_features, sizeof(SIZE_t) * n_known_constants)
+0745: # Respect invariant for constant features: the original order of+
0746: # element in features[:n_known_constants] must be preserved for sibling+
0747: # and child nodes+
+0748: memcpy(features, constant_features, sizeof(SIZE_t) * n_known_constants)
(void)(memcpy(__pyx_v_features, __pyx_v_constant_features, ((sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t)) * __pyx_v_n_known_constants)));
0749:
- 0750: # Copy newly found constant features
-+0751: memcpy(constant_features + n_known_constants,
+0750: # Copy newly found constant features+
+0751: memcpy(constant_features + n_known_constants,
(void)(memcpy((__pyx_v_constant_features + __pyx_v_n_known_constants), (__pyx_v_features + __pyx_v_n_known_constants), ((sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t)) * __pyx_v_n_found_constants))); -
0752: features + n_known_constants,
- 0753: sizeof(SIZE_t) * n_found_constants)
+0752: features + n_known_constants,+
0753: sizeof(SIZE_t) * n_found_constants)
0754:
- 0755: # Return values
-+0756: split[0] = best
+0755: # Return values+
+0756: split[0] = best
(__pyx_v_split[0]) = __pyx_v_best; -
+0757: n_constant_features[0] = n_total_constants
++0757: n_constant_features[0] = n_total_constants
(__pyx_v_n_constant_features[0]) = __pyx_v_n_total_constants; -
+0758: return 0
++0758: return 0
__pyx_r = 0; goto __pyx_L0;
0759:
0760:
-+0761: cdef class BaseSparseSplitter(Splitter):
++0761: cdef class BaseSparseSplitter(Splitter):
struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter { struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter __pyx_base; __pyx_t_7sklearn_4tree_5_tree_DTYPE_t *X_data; @@ -2488,17 +2562,17 @@ static CYTHON_INLINE __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter__partition(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *, double, __pyx_t_7sklearn_4tree_5_tree_SIZE_t, __pyx_t_7sklearn_4tree_5_tree_SIZE_t, __pyx_t_7sklearn_4tree_5_tree_SIZE_t); static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_extract_nnz(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *, __pyx_t_7sklearn_4tree_5_tree_SIZE_t, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *, int *); -
0762: # The sparse splitter works only with csc sparse matrix format
- 0763: cdef DTYPE_t* X_data
- 0764: cdef INT32_t* X_indices
- 0765: cdef INT32_t* X_indptr
+0762: # The sparse splitter works only with csc sparse matrix format+
0763: cdef DTYPE_t* X_data+
0764: cdef INT32_t* X_indices+
0765: cdef INT32_t* X_indptr
0766:
- 0767: cdef SIZE_t n_total_samples
+0767: cdef SIZE_t n_total_samples
0768:
- 0769: cdef SIZE_t* index_to_samples
- 0770: cdef SIZE_t* sorted_samples
+0769: cdef SIZE_t* index_to_samples+
0770: cdef SIZE_t* sorted_samples
0771:
-+0772: def __cinit__(self, Criterion criterion, SIZE_t max_features,
++0772: def __cinit__(self, Criterion criterion, SIZE_t max_features,
/* Python wrapper */
static int __pyx_pw_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static int __pyx_pw_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
@@ -2611,26 +2685,26 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
0773: SIZE_t min_samples_leaf, double min_weight_leaf,
- 0774: object random_state):
- 0775: # Parent __cinit__ is automatically called
+0773: SIZE_t min_samples_leaf, double min_weight_leaf,+
0774: object random_state):+
0775: # Parent __cinit__ is automatically called
0776:
-+0777: self.X_data = NULL
++0777: self.X_data = NULL
__pyx_v_self->X_data = NULL; -
+0778: self.X_indices = NULL
++0778: self.X_indices = NULL
__pyx_v_self->X_indices = NULL; -
+0779: self.X_indptr = NULL
++0779: self.X_indptr = NULL
__pyx_v_self->X_indptr = NULL;
0780:
-+0781: self.n_total_samples = 0
++0781: self.n_total_samples = 0
__pyx_v_self->n_total_samples = 0;
0782:
-+0783: self.index_to_samples = NULL
++0783: self.index_to_samples = NULL
__pyx_v_self->index_to_samples = NULL; -
+0784: self.sorted_samples = NULL
++0784: self.sorted_samples = NULL
__pyx_v_self->sorted_samples = NULL;
0785:
-+0786: def __dealloc__(self):
++0786: def __dealloc__(self):
/* Python wrapper */
static void __pyx_pw_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
static void __pyx_pw_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_3__dealloc__(PyObject *__pyx_v_self) {
@@ -2649,13 +2723,13 @@
/* function exit code */
__Pyx_RefNannyFinishContext();
}
-
0787: """Deallocate memory."""
-+0788: free(self.index_to_samples)
+0787: """Deallocate memory."""+
+0788: free(self.index_to_samples)
free(__pyx_v_self->index_to_samples); -
+0789: free(self.sorted_samples)
++0789: free(self.sorted_samples)
free(__pyx_v_self->sorted_samples);
0790:
-+0791: cdef int init(self,
++0791: cdef int init(self,
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_init(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *__pyx_v_self, PyObject *__pyx_v_X, __Pyx_memviewslice __pyx_v_y, __pyx_t_7sklearn_4tree_5_tree_DOUBLE_t *__pyx_v_sample_weight) {
__pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples;
__pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_n_samples;
@@ -2713,19 +2787,19 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
0792: object X,
- 0793: const DOUBLE_t[:, ::1] y,
- 0794: DOUBLE_t* sample_weight) except -1:
- 0795: """Initialize the splitter
+0792: object X,+
0793: const DOUBLE_t[:, ::1] y,+
0794: DOUBLE_t* sample_weight) except -1:+
0795: """Initialize the splitter
0796:
- 0797: Returns -1 in case of failure to allocate memory (and raise MemoryError)
- 0798: or 0 otherwise.
- 0799: """
- 0800: # Call parent init
-+0801: Splitter.init(self, X, y, sample_weight)
+0797: Returns -1 in case of failure to allocate memory (and raise MemoryError)+
0798: or 0 otherwise.+
0799: """+
0800: # Call parent init+
+0801: Splitter.init(self, X, y, sample_weight)
__pyx_t_1 = __pyx_f_13stpredictions_6models_3OK3_9_splitter_8Splitter_init(((struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_Splitter *)__pyx_v_self), __pyx_v_X, __pyx_v_y, __pyx_v_sample_weight); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 801, __pyx_L1_error)
0802:
-+0803: if not isinstance(X, csc_matrix):
++0803: if not isinstance(X, csc_matrix):
__Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_csc_matrix); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 803, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyObject_IsInstance(__pyx_v_X, __pyx_t_2); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 803, __pyx_L1_error) @@ -2734,7 +2808,7 @@ if (unlikely(__pyx_t_4)) { /* … */ } -
+0804: raise ValueError("X should be in csc format")
++0804: raise ValueError("X should be in csc format")
__pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 804, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_Raise(__pyx_t_2, 0, 0, 0); @@ -2745,15 +2819,15 @@ __Pyx_GOTREF(__pyx_tuple__5); __Pyx_GIVEREF(__pyx_tuple__5);
0805:
-+0806: cdef SIZE_t* samples = self.samples
++0806: cdef SIZE_t* samples = self.samples
__pyx_t_5 = __pyx_v_self->__pyx_base.samples; __pyx_v_samples = __pyx_t_5; -
+0807: cdef SIZE_t n_samples = self.n_samples
++0807: cdef SIZE_t n_samples = self.n_samples
__pyx_t_6 = __pyx_v_self->__pyx_base.n_samples; __pyx_v_n_samples = __pyx_t_6;
0808:
- 0809: # Initialize X
-+0810: cdef np.ndarray[dtype=DTYPE_t, ndim=1] data = X.data
+0809: # Initialize X+
+0810: cdef np.ndarray[dtype=DTYPE_t, ndim=1] data = X.data
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_X, __pyx_n_s_data); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 810, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 810, __pyx_L1_error) @@ -2769,7 +2843,7 @@ __pyx_t_7 = 0; __pyx_v_data = ((PyArrayObject *)__pyx_t_2); __pyx_t_2 = 0; -
+0811: cdef np.ndarray[dtype=INT32_t, ndim=1] indices = X.indices
++0811: cdef np.ndarray[dtype=INT32_t, ndim=1] indices = X.indices
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_X, __pyx_n_s_indices); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 811, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 811, __pyx_L1_error) @@ -2785,7 +2859,7 @@ __pyx_t_8 = 0; __pyx_v_indices = ((PyArrayObject *)__pyx_t_2); __pyx_t_2 = 0; -
+0812: cdef np.ndarray[dtype=INT32_t, ndim=1] indptr = X.indptr
++0812: cdef np.ndarray[dtype=INT32_t, ndim=1] indptr = X.indptr
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_X, __pyx_n_s_indptr); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 812, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 812, __pyx_L1_error) @@ -2801,7 +2875,7 @@ __pyx_t_9 = 0; __pyx_v_indptr = ((PyArrayObject *)__pyx_t_2); __pyx_t_2 = 0; -
+0813: cdef SIZE_t n_total_samples = X.shape[0]
++0813: cdef SIZE_t n_total_samples = X.shape[0]
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_X, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 813, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_10 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 813, __pyx_L1_error) @@ -2811,47 +2885,47 @@ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __pyx_v_n_total_samples = __pyx_t_6;
0814:
-+0815: self.X_data = <DTYPE_t*> data.data
++0815: self.X_data = <DTYPE_t*> data.data
__pyx_v_self->X_data = ((__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *)__pyx_v_data->data); -
+0816: self.X_indices = <INT32_t*> indices.data
++0816: self.X_indices = <INT32_t*> indices.data
__pyx_v_self->X_indices = ((__pyx_t_7sklearn_4tree_5_tree_INT32_t *)__pyx_v_indices->data); -
+0817: self.X_indptr = <INT32_t*> indptr.data
++0817: self.X_indptr = <INT32_t*> indptr.data
__pyx_v_self->X_indptr = ((__pyx_t_7sklearn_4tree_5_tree_INT32_t *)__pyx_v_indptr->data); -
+0818: self.n_total_samples = n_total_samples
++0818: self.n_total_samples = n_total_samples
__pyx_v_self->n_total_samples = __pyx_v_n_total_samples;
0819:
- 0820: # Initialize auxiliary array used to perform split
-+0821: safe_realloc(&self.index_to_samples, n_total_samples)
+0820: # Initialize auxiliary array used to perform split+
+0821: safe_realloc(&self.index_to_samples, n_total_samples)
__pyx_fuse_1__pyx_f_7sklearn_4tree_6_utils_safe_realloc((&__pyx_v_self->index_to_samples), __pyx_v_n_total_samples); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 821, __pyx_L1_error)
-
+0822: safe_realloc(&self.sorted_samples, n_samples)
++0822: safe_realloc(&self.sorted_samples, n_samples)
__pyx_fuse_1__pyx_f_7sklearn_4tree_6_utils_safe_realloc((&__pyx_v_self->sorted_samples), __pyx_v_n_samples); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 822, __pyx_L1_error)
0823:
-+0824: cdef SIZE_t* index_to_samples = self.index_to_samples
++0824: cdef SIZE_t* index_to_samples = self.index_to_samples
__pyx_t_5 = __pyx_v_self->index_to_samples; __pyx_v_index_to_samples = __pyx_t_5; -
0825: cdef SIZE_t p
-+0826: for p in range(n_total_samples):
+0825: cdef SIZE_t p+
+0826: for p in range(n_total_samples):
__pyx_t_6 = __pyx_v_n_total_samples; __pyx_t_11 = __pyx_t_6; for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) { __pyx_v_p = __pyx_t_12; -
+0827: index_to_samples[p] = -1
++0827: index_to_samples[p] = -1
(__pyx_v_index_to_samples[__pyx_v_p]) = -1; }
0828:
-+0829: for p in range(n_samples):
++0829: for p in range(n_samples):
__pyx_t_6 = __pyx_v_n_samples; __pyx_t_11 = __pyx_t_6; for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) { __pyx_v_p = __pyx_t_12; -
+0830: index_to_samples[samples[p]] = p
++0830: index_to_samples[samples[p]] = p
(__pyx_v_index_to_samples[(__pyx_v_samples[__pyx_v_p])]) = __pyx_v_p; } -
+0831: return 0
++0831: return 0
__pyx_r = 0; goto __pyx_L0;
0832:
-+0833: cdef inline SIZE_t _partition(self, double threshold,
++0833: cdef inline SIZE_t _partition(self, double threshold,
static CYTHON_INLINE __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter__partition(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *__pyx_v_self, double __pyx_v_threshold, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_end_negative, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start_positive, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_zero_pos) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_p; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_partition_end; @@ -2864,88 +2938,88 @@ __pyx_L0:; return __pyx_r; } -
0834: SIZE_t end_negative, SIZE_t start_positive,
- 0835: SIZE_t zero_pos) nogil:
- 0836: """Partition samples[start:end] based on threshold."""
+0834: SIZE_t end_negative, SIZE_t start_positive,+
0835: SIZE_t zero_pos) nogil:+
0836: """Partition samples[start:end] based on threshold."""
0837:
- 0838: cdef SIZE_t p
- 0839: cdef SIZE_t partition_end
+0838: cdef SIZE_t p+
0839: cdef SIZE_t partition_end
0840:
-+0841: cdef DTYPE_t* Xf = self.feature_values
++0841: cdef DTYPE_t* Xf = self.feature_values
__pyx_t_1 = __pyx_v_self->__pyx_base.feature_values; __pyx_v_Xf = __pyx_t_1; -
+0842: cdef SIZE_t* samples = self.samples
++0842: cdef SIZE_t* samples = self.samples
__pyx_t_2 = __pyx_v_self->__pyx_base.samples; __pyx_v_samples = __pyx_t_2; -
+0843: cdef SIZE_t* index_to_samples = self.index_to_samples
++0843: cdef SIZE_t* index_to_samples = self.index_to_samples
__pyx_t_2 = __pyx_v_self->index_to_samples; __pyx_v_index_to_samples = __pyx_t_2;
0844:
-+0845: if threshold < 0.:
++0845: if threshold < 0.:
__pyx_t_3 = ((__pyx_v_threshold < 0.) != 0); if (__pyx_t_3) { /* … */ goto __pyx_L3; } -
+0846: p = self.start
++0846: p = self.start
__pyx_t_4 = __pyx_v_self->__pyx_base.start; __pyx_v_p = __pyx_t_4; -
+0847: partition_end = end_negative
++0847: partition_end = end_negative
__pyx_v_partition_end = __pyx_v_end_negative; -
+0848: elif threshold > 0.:
++0848: elif threshold > 0.:
__pyx_t_3 = ((__pyx_v_threshold > 0.) != 0); if (__pyx_t_3) { /* … */ goto __pyx_L3; } -
+0849: p = start_positive
++0849: p = start_positive
__pyx_v_p = __pyx_v_start_positive; -
+0850: partition_end = self.end
++0850: partition_end = self.end
__pyx_t_4 = __pyx_v_self->__pyx_base.end; __pyx_v_partition_end = __pyx_t_4; -
0851: else:
- 0852: # Data are already split
-+0853: return zero_pos
+0851: else:+
0852: # Data are already split+
+0853: return zero_pos
/*else*/ { __pyx_r = __pyx_v_zero_pos; goto __pyx_L0; } __pyx_L3:;
0854:
-+0855: while p < partition_end:
++0855: while p < partition_end:
while (1) { __pyx_t_3 = ((__pyx_v_p < __pyx_v_partition_end) != 0); if (!__pyx_t_3) break; -
+0856: if Xf[p] <= threshold:
++0856: if Xf[p] <= threshold:
__pyx_t_3 = (((__pyx_v_Xf[__pyx_v_p]) <= __pyx_v_threshold) != 0); if (__pyx_t_3) { /* … */ goto __pyx_L6; } -
+0857: p += 1
++0857: p += 1
__pyx_v_p = (__pyx_v_p + 1);
0858:
- 0859: else:
-+0860: partition_end -= 1
+0859: else:+
+0860: partition_end -= 1
/*else*/ { __pyx_v_partition_end = (__pyx_v_partition_end - 1);
0861:
-+0862: Xf[p], Xf[partition_end] = Xf[partition_end], Xf[p]
++0862: Xf[p], Xf[partition_end] = Xf[partition_end], Xf[p]
__pyx_t_5 = (__pyx_v_Xf[__pyx_v_partition_end]); __pyx_t_6 = (__pyx_v_Xf[__pyx_v_p]); (__pyx_v_Xf[__pyx_v_p]) = __pyx_t_5; (__pyx_v_Xf[__pyx_v_partition_end]) = __pyx_t_6; -
+0863: sparse_swap(index_to_samples, samples, p, partition_end)
++0863: sparse_swap(index_to_samples, samples, p, partition_end)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sparse_swap(__pyx_v_index_to_samples, __pyx_v_samples, __pyx_v_p, __pyx_v_partition_end); } __pyx_L6:; }
0864:
-+0865: return partition_end
++0865: return partition_end
__pyx_r = __pyx_v_partition_end; goto __pyx_L0;
0866:
-+0867: cdef inline void extract_nnz(self, SIZE_t feature,
++0867: cdef inline void extract_nnz(self, SIZE_t feature,
static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_extract_nnz(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *__pyx_v_self, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_feature, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_end_negative, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_start_positive, int *__pyx_v_is_samples_sorted) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_indptr_start; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_indptr_end; @@ -2954,84 +3028,84 @@ /* … */ /* function exit code */ } -
0868: SIZE_t* end_negative, SIZE_t* start_positive,
- 0869: bint* is_samples_sorted) nogil:
- 0870: """Extract and partition values for a given feature.
+0868: SIZE_t* end_negative, SIZE_t* start_positive,+
0869: bint* is_samples_sorted) nogil:+
0870: """Extract and partition values for a given feature.
0871:
- 0872: The extracted values are partitioned between negative values
- 0873: Xf[start:end_negative[0]] and positive values Xf[start_positive[0]:end].
- 0874: The samples and index_to_samples are modified according to this
- 0875: partition.
+0872: The extracted values are partitioned between negative values+
0873: Xf[start:end_negative[0]] and positive values Xf[start_positive[0]:end].+
0874: The samples and index_to_samples are modified according to this+
0875: partition.
0876:
- 0877: The extraction corresponds to the intersection between the arrays
- 0878: X_indices[indptr_start:indptr_end] and samples[start:end].
- 0879: This is done efficiently using either an index_to_samples based approach
- 0880: or binary search based approach.
+0877: The extraction corresponds to the intersection between the arrays+
0878: X_indices[indptr_start:indptr_end] and samples[start:end].+
0879: This is done efficiently using either an index_to_samples based approach+
0880: or binary search based approach.
0881:
- 0882: Parameters
- 0883: ----------
- 0884: feature : SIZE_t,
- 0885: Index of the feature we want to extract non zero value.
+0882: Parameters+
0883: ----------+
0884: feature : SIZE_t,+
0885: Index of the feature we want to extract non zero value.
0886:
0887:
- 0888: end_negative, start_positive : SIZE_t*, SIZE_t*,
- 0889: Return extracted non zero values in self.samples[start:end] where
- 0890: negative values are in self.feature_values[start:end_negative[0]]
- 0891: and positive values are in
- 0892: self.feature_values[start_positive[0]:end].
+0888: end_negative, start_positive : SIZE_t*, SIZE_t*,+
0889: Return extracted non zero values in self.samples[start:end] where+
0890: negative values are in self.feature_values[start:end_negative[0]]+
0891: and positive values are in+
0892: self.feature_values[start_positive[0]:end].
0893:
- 0894: is_samples_sorted : bint*,
- 0895: If is_samples_sorted, then self.sorted_samples[start:end] will be
- 0896: the sorted version of self.samples[start:end].
+0894: is_samples_sorted : bint*,+
0895: If is_samples_sorted, then self.sorted_samples[start:end] will be+
0896: the sorted version of self.samples[start:end].
0897:
- 0898: """
-+0899: cdef SIZE_t indptr_start = self.X_indptr[feature],
+0898: """+
+0899: cdef SIZE_t indptr_start = self.X_indptr[feature],
__pyx_v_indptr_start = (__pyx_v_self->X_indptr[__pyx_v_feature]); -
+0900: cdef SIZE_t indptr_end = self.X_indptr[feature + 1]
++0900: cdef SIZE_t indptr_end = self.X_indptr[feature + 1]
__pyx_v_indptr_end = (__pyx_v_self->X_indptr[(__pyx_v_feature + 1)]); -
+0901: cdef SIZE_t n_indices = <SIZE_t>(indptr_end - indptr_start)
++0901: cdef SIZE_t n_indices = <SIZE_t>(indptr_end - indptr_start)
__pyx_v_n_indices = ((__pyx_t_7sklearn_4tree_5_tree_SIZE_t)(__pyx_v_indptr_end - __pyx_v_indptr_start)); -
+0902: cdef SIZE_t n_samples = self.end - self.start
++0902: cdef SIZE_t n_samples = self.end - self.start
__pyx_v_n_samples = (__pyx_v_self->__pyx_base.end - __pyx_v_self->__pyx_base.start);
0903:
- 0904: # Use binary search if n_samples * log(n_indices) <
- 0905: # n_indices and index_to_samples approach otherwise.
- 0906: # O(n_samples * log(n_indices)) is the running time of binary
- 0907: # search and O(n_indices) is the running time of index_to_samples
- 0908: # approach.
-+0909: if ((1 - is_samples_sorted[0]) * n_samples * log(n_samples) +
+0904: # Use binary search if n_samples * log(n_indices) <+
0905: # n_indices and index_to_samples approach otherwise.+
0906: # O(n_samples * log(n_indices)) is the running time of binary+
0907: # search and O(n_indices) is the running time of index_to_samples+
0908: # approach.+
+0909: if ((1 - is_samples_sorted[0]) * n_samples * log(n_samples) +
if (__pyx_t_1) { /* … */ goto __pyx_L3; } -
+0910: n_samples * log(n_indices) < EXTRACT_NNZ_SWITCH * n_indices):
++0910: n_samples * log(n_indices) < EXTRACT_NNZ_SWITCH * n_indices):
__pyx_t_1 = ((((((1 - (__pyx_v_is_samples_sorted[0])) * __pyx_v_n_samples) * __pyx_f_7sklearn_4tree_6_utils_log(__pyx_v_n_samples)) + (__pyx_v_n_samples * __pyx_f_7sklearn_4tree_6_utils_log(__pyx_v_n_indices))) < (__pyx_v_13stpredictions_6models_3OK3_9_splitter_EXTRACT_NNZ_SWITCH * __pyx_v_n_indices)) != 0); -
+0911: extract_nnz_binary_search(self.X_indices, self.X_data,
++0911: extract_nnz_binary_search(self.X_indices, self.X_data,
__pyx_f_13stpredictions_6models_3OK3_9_splitter_extract_nnz_binary_search(__pyx_v_self->X_indices, __pyx_v_self->X_data, __pyx_v_indptr_start, __pyx_v_indptr_end, __pyx_v_self->__pyx_base.samples, __pyx_v_self->__pyx_base.start, __pyx_v_self->__pyx_base.end, __pyx_v_self->index_to_samples, __pyx_v_self->__pyx_base.feature_values, __pyx_v_end_negative, __pyx_v_start_positive, __pyx_v_self->sorted_samples, __pyx_v_is_samples_sorted); -
0912: indptr_start, indptr_end,
- 0913: self.samples, self.start, self.end,
- 0914: self.index_to_samples,
- 0915: self.feature_values,
- 0916: end_negative, start_positive,
- 0917: self.sorted_samples, is_samples_sorted)
+0912: indptr_start, indptr_end,+
0913: self.samples, self.start, self.end,+
0914: self.index_to_samples,+
0915: self.feature_values,+
0916: end_negative, start_positive,+
0917: self.sorted_samples, is_samples_sorted)
0918:
- 0919: # Using an index to samples technique to extract non zero values
- 0920: # index_to_samples is a mapping from X_indices to samples
- 0921: else:
-+0922: extract_nnz_index_to_samples(self.X_indices, self.X_data,
+0919: # Using an index to samples technique to extract non zero values+
0920: # index_to_samples is a mapping from X_indices to samples+
0921: else:+
+0922: extract_nnz_index_to_samples(self.X_indices, self.X_data,
/*else*/ { /* … */ __pyx_f_13stpredictions_6models_3OK3_9_splitter_extract_nnz_index_to_samples(__pyx_v_self->X_indices, __pyx_v_self->X_data, __pyx_v_indptr_start, __pyx_v_indptr_end, __pyx_v_self->__pyx_base.samples, __pyx_v_self->__pyx_base.start, __pyx_v_self->__pyx_base.end, __pyx_v_self->index_to_samples, __pyx_v_self->__pyx_base.feature_values, __pyx_v_end_negative, __pyx_v_start_positive); } __pyx_L3:; -
0923: indptr_start, indptr_end,
- 0924: self.samples, self.start, self.end,
- 0925: self.index_to_samples,
- 0926: self.feature_values,
- 0927: end_negative, start_positive)
+0923: indptr_start, indptr_end,+
0924: self.samples, self.start, self.end,+
0925: self.index_to_samples,+
0926: self.feature_values,+
0927: end_negative, start_positive)
0928:
0929:
-+0930: cdef int compare_SIZE_t(const void* a, const void* b) nogil:
++0930: cdef int compare_SIZE_t(const void* a, const void* b) nogil:
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_compare_SIZE_t(void const *__pyx_v_a, void const *__pyx_v_b) { int __pyx_r; /* … */ @@ -3039,68 +3113,68 @@ __pyx_L0:; return __pyx_r; } -
0931: """Comparison function for sort."""
-+0932: return <int>((<SIZE_t*>a)[0] - (<SIZE_t*>b)[0])
+0931: """Comparison function for sort."""+
+0932: return <int>((<SIZE_t*>a)[0] - (<SIZE_t*>b)[0])
__pyx_r = ((int)((((__pyx_t_7sklearn_4tree_5_tree_SIZE_t *)__pyx_v_a)[0]) - (((__pyx_t_7sklearn_4tree_5_tree_SIZE_t *)__pyx_v_b)[0]))); goto __pyx_L0;
0933:
0934:
-+0935: cdef inline void binary_search(INT32_t* sorted_array,
++0935: cdef inline void binary_search(INT32_t* sorted_array,
static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter_binary_search(__pyx_t_7sklearn_4tree_5_tree_INT32_t *__pyx_v_sorted_array, __pyx_t_7sklearn_4tree_5_tree_INT32_t __pyx_v_start, __pyx_t_7sklearn_4tree_5_tree_INT32_t __pyx_v_end, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_value, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_index, __pyx_t_7sklearn_4tree_5_tree_INT32_t *__pyx_v_new_start) { __pyx_t_7sklearn_4tree_5_tree_INT32_t __pyx_v_pivot; /* … */ /* function exit code */ } -
0936: INT32_t start, INT32_t end,
- 0937: SIZE_t value, SIZE_t* index,
- 0938: INT32_t* new_start) nogil:
- 0939: """Return the index of value in the sorted array.
+0936: INT32_t start, INT32_t end,+
0937: SIZE_t value, SIZE_t* index,+
0938: INT32_t* new_start) nogil:+
0939: """Return the index of value in the sorted array.
0940:
- 0941: If not found, return -1. new_start is the last pivot + 1
- 0942: """
- 0943: cdef INT32_t pivot
-+0944: index[0] = -1
+0941: If not found, return -1. new_start is the last pivot + 1+
0942: """+
0943: cdef INT32_t pivot+
+0944: index[0] = -1
(__pyx_v_index[0]) = -1; -
+0945: while start < end:
++0945: while start < end:
while (1) { __pyx_t_1 = ((__pyx_v_start < __pyx_v_end) != 0); if (!__pyx_t_1) break; -
+0946: pivot = start + (end - start) / 2
++0946: pivot = start + (end - start) / 2
__pyx_v_pivot = (__pyx_v_start + ((__pyx_v_end - __pyx_v_start) / 2));
0947:
-+0948: if sorted_array[pivot] == value:
++0948: if sorted_array[pivot] == value:
__pyx_t_1 = (((__pyx_v_sorted_array[__pyx_v_pivot]) == __pyx_v_value) != 0); if (__pyx_t_1) { /* … */ } -
+0949: index[0] = pivot
++0949: index[0] = pivot
(__pyx_v_index[0]) = __pyx_v_pivot; -
+0950: start = pivot + 1
++0950: start = pivot + 1
__pyx_v_start = (__pyx_v_pivot + 1); -
+0951: break
++0951: break
goto __pyx_L4_break;
0952:
-+0953: if sorted_array[pivot] < value:
++0953: if sorted_array[pivot] < value:
__pyx_t_1 = (((__pyx_v_sorted_array[__pyx_v_pivot]) < __pyx_v_value) != 0); if (__pyx_t_1) { /* … */ goto __pyx_L6; } -
+0954: start = pivot + 1
++0954: start = pivot + 1
__pyx_v_start = (__pyx_v_pivot + 1); -
0955: else:
-+0956: end = pivot
+0955: else:+
+0956: end = pivot
/*else*/ { __pyx_v_end = __pyx_v_pivot; } __pyx_L6:; } __pyx_L4_break:; -
+0957: new_start[0] = start
++0957: new_start[0] = start
(__pyx_v_new_start[0]) = __pyx_v_start;
0958:
0959:
-+0960: cdef inline void extract_nnz_index_to_samples(INT32_t* X_indices,
++0960: cdef inline void extract_nnz_index_to_samples(INT32_t* X_indices,
static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter_extract_nnz_index_to_samples(__pyx_t_7sklearn_4tree_5_tree_INT32_t *__pyx_v_X_indices, __pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_X_data, __pyx_t_7sklearn_4tree_5_tree_INT32_t __pyx_v_indptr_start, __pyx_t_7sklearn_4tree_5_tree_INT32_t __pyx_v_indptr_end, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_end, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_index_to_samples, __pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_Xf, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_end_negative, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_start_positive) { __pyx_t_7sklearn_4tree_5_tree_INT32_t __pyx_v_k; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_index; @@ -3109,33 +3183,33 @@ /* … */ /* function exit code */ } -
0961: DTYPE_t* X_data,
- 0962: INT32_t indptr_start,
- 0963: INT32_t indptr_end,
- 0964: SIZE_t* samples,
- 0965: SIZE_t start,
- 0966: SIZE_t end,
- 0967: SIZE_t* index_to_samples,
- 0968: DTYPE_t* Xf,
- 0969: SIZE_t* end_negative,
- 0970: SIZE_t* start_positive) nogil:
- 0971: """Extract and partition values for a feature using index_to_samples.
+0961: DTYPE_t* X_data,+
0962: INT32_t indptr_start,+
0963: INT32_t indptr_end,+
0964: SIZE_t* samples,+
0965: SIZE_t start,+
0966: SIZE_t end,+
0967: SIZE_t* index_to_samples,+
0968: DTYPE_t* Xf,+
0969: SIZE_t* end_negative,+
0970: SIZE_t* start_positive) nogil:+
0971: """Extract and partition values for a feature using index_to_samples.
0972:
- 0973: Complexity is O(indptr_end - indptr_start).
- 0974: """
- 0975: cdef INT32_t k
- 0976: cdef SIZE_t index
-+0977: cdef SIZE_t end_negative_ = start
+0973: Complexity is O(indptr_end - indptr_start).+
0974: """+
0975: cdef INT32_t k+
0976: cdef SIZE_t index+
+0977: cdef SIZE_t end_negative_ = start
__pyx_v_end_negative_ = __pyx_v_start; -
+0978: cdef SIZE_t start_positive_ = end
++0978: cdef SIZE_t start_positive_ = end
__pyx_v_start_positive_ = __pyx_v_end;
0979:
-+0980: for k in range(indptr_start, indptr_end):
++0980: for k in range(indptr_start, indptr_end):
__pyx_t_1 = __pyx_v_indptr_end; __pyx_t_2 = __pyx_t_1; for (__pyx_t_3 = __pyx_v_indptr_start; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_k = __pyx_t_3; -
+0981: if start <= index_to_samples[X_indices[k]] < end:
++0981: if start <= index_to_samples[X_indices[k]] < end:
__pyx_t_4 = (__pyx_v_start <= (__pyx_v_index_to_samples[(__pyx_v_X_indices[__pyx_v_k])])); if (__pyx_t_4) { __pyx_t_4 = ((__pyx_v_index_to_samples[(__pyx_v_X_indices[__pyx_v_k])]) < __pyx_v_end); @@ -3145,45 +3219,45 @@ /* … */ } } -
+0982: if X_data[k] > 0:
++0982: if X_data[k] > 0:
__pyx_t_5 = (((__pyx_v_X_data[__pyx_v_k]) > 0.0) != 0); if (__pyx_t_5) { /* … */ goto __pyx_L6; } -
+0983: start_positive_ -= 1
++0983: start_positive_ -= 1
__pyx_v_start_positive_ = (__pyx_v_start_positive_ - 1); -
+0984: Xf[start_positive_] = X_data[k]
++0984: Xf[start_positive_] = X_data[k]
(__pyx_v_Xf[__pyx_v_start_positive_]) = (__pyx_v_X_data[__pyx_v_k]); -
+0985: index = index_to_samples[X_indices[k]]
++0985: index = index_to_samples[X_indices[k]]
__pyx_v_index = (__pyx_v_index_to_samples[(__pyx_v_X_indices[__pyx_v_k])]); -
+0986: sparse_swap(index_to_samples, samples, index, start_positive_)
++0986: sparse_swap(index_to_samples, samples, index, start_positive_)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sparse_swap(__pyx_v_index_to_samples, __pyx_v_samples, __pyx_v_index, __pyx_v_start_positive_);
0987:
0988:
-+0989: elif X_data[k] < 0:
++0989: elif X_data[k] < 0:
__pyx_t_5 = (((__pyx_v_X_data[__pyx_v_k]) < 0.0) != 0); if (__pyx_t_5) { /* … */ } __pyx_L6:; -
+0990: Xf[end_negative_] = X_data[k]
++0990: Xf[end_negative_] = X_data[k]
(__pyx_v_Xf[__pyx_v_end_negative_]) = (__pyx_v_X_data[__pyx_v_k]); -
+0991: index = index_to_samples[X_indices[k]]
++0991: index = index_to_samples[X_indices[k]]
__pyx_v_index = (__pyx_v_index_to_samples[(__pyx_v_X_indices[__pyx_v_k])]); -
+0992: sparse_swap(index_to_samples, samples, index, end_negative_)
++0992: sparse_swap(index_to_samples, samples, index, end_negative_)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sparse_swap(__pyx_v_index_to_samples, __pyx_v_samples, __pyx_v_index, __pyx_v_end_negative_); -
+0993: end_negative_ += 1
++0993: end_negative_ += 1
__pyx_v_end_negative_ = (__pyx_v_end_negative_ + 1);
0994:
- 0995: # Returned values
-+0996: end_negative[0] = end_negative_
+0995: # Returned values+
+0996: end_negative[0] = end_negative_
(__pyx_v_end_negative[0]) = __pyx_v_end_negative_; -
+0997: start_positive[0] = start_positive_
++0997: start_positive[0] = start_positive_
(__pyx_v_start_positive[0]) = __pyx_v_start_positive_;
0998:
0999:
-+1000: cdef inline void extract_nnz_binary_search(INT32_t* X_indices,
++1000: cdef inline void extract_nnz_binary_search(INT32_t* X_indices,
static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter_extract_nnz_binary_search(__pyx_t_7sklearn_4tree_5_tree_INT32_t *__pyx_v_X_indices, __pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_X_data, __pyx_t_7sklearn_4tree_5_tree_INT32_t __pyx_v_indptr_start, __pyx_t_7sklearn_4tree_5_tree_INT32_t __pyx_v_indptr_end, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_end, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_index_to_samples, __pyx_t_7sklearn_4tree_5_tree_DTYPE_t *__pyx_v_Xf, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_end_negative, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_start_positive, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_sorted_samples, int *__pyx_v_is_samples_sorted) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_n_samples; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_p; @@ -3194,45 +3268,45 @@ /* … */ /* function exit code */ } -
1001: DTYPE_t* X_data,
- 1002: INT32_t indptr_start,
- 1003: INT32_t indptr_end,
- 1004: SIZE_t* samples,
- 1005: SIZE_t start,
- 1006: SIZE_t end,
- 1007: SIZE_t* index_to_samples,
- 1008: DTYPE_t* Xf,
- 1009: SIZE_t* end_negative,
- 1010: SIZE_t* start_positive,
- 1011: SIZE_t* sorted_samples,
- 1012: bint* is_samples_sorted) nogil:
- 1013: """Extract and partition values for a given feature using binary search.
+1001: DTYPE_t* X_data,+
1002: INT32_t indptr_start,+
1003: INT32_t indptr_end,+
1004: SIZE_t* samples,+
1005: SIZE_t start,+
1006: SIZE_t end,+
1007: SIZE_t* index_to_samples,+
1008: DTYPE_t* Xf,+
1009: SIZE_t* end_negative,+
1010: SIZE_t* start_positive,+
1011: SIZE_t* sorted_samples,+
1012: bint* is_samples_sorted) nogil:+
1013: """Extract and partition values for a given feature using binary search.
1014:
- 1015: If n_samples = end - start and n_indices = indptr_end - indptr_start,
- 1016: the complexity is
+1015: If n_samples = end - start and n_indices = indptr_end - indptr_start,+
1016: the complexity is
1017:
- 1018: O((1 - is_samples_sorted[0]) * n_samples * log(n_samples) +
- 1019: n_samples * log(n_indices)).
- 1020: """
- 1021: cdef SIZE_t n_samples
+1018: O((1 - is_samples_sorted[0]) * n_samples * log(n_samples) ++
1019: n_samples * log(n_indices)).+
1020: """+
1021: cdef SIZE_t n_samples
1022:
-+1023: if not is_samples_sorted[0]:
++1023: if not is_samples_sorted[0]:
__pyx_t_1 = ((!((__pyx_v_is_samples_sorted[0]) != 0)) != 0); if (__pyx_t_1) { /* … */ } -
+1024: n_samples = end - start
++1024: n_samples = end - start
__pyx_v_n_samples = (__pyx_v_end - __pyx_v_start); -
+1025: memcpy(sorted_samples + start, samples + start,
++1025: memcpy(sorted_samples + start, samples + start,
(void)(memcpy((__pyx_v_sorted_samples + __pyx_v_start), (__pyx_v_samples + __pyx_v_start), (__pyx_v_n_samples * (sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t))))); -
1026: n_samples * sizeof(SIZE_t))
-+1027: qsort(sorted_samples + start, n_samples, sizeof(SIZE_t),
+1026: n_samples * sizeof(SIZE_t))+
+1027: qsort(sorted_samples + start, n_samples, sizeof(SIZE_t),
qsort((__pyx_v_sorted_samples + __pyx_v_start), __pyx_v_n_samples, (sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t)), __pyx_f_13stpredictions_6models_3OK3_9_splitter_compare_SIZE_t); -
1028: compare_SIZE_t)
-+1029: is_samples_sorted[0] = 1
+1028: compare_SIZE_t)+
+1029: is_samples_sorted[0] = 1
(__pyx_v_is_samples_sorted[0]) = 1;
1030:
-+1031: while (indptr_start < indptr_end and
++1031: while (indptr_start < indptr_end and
while (1) { __pyx_t_2 = ((__pyx_v_indptr_start < __pyx_v_indptr_end) != 0); if (__pyx_t_2) { @@ -3240,16 +3314,16 @@ __pyx_t_1 = __pyx_t_2; goto __pyx_L6_bool_binop_done; } -
+1032: sorted_samples[start] > X_indices[indptr_start]):
++1032: sorted_samples[start] > X_indices[indptr_start]):
__pyx_t_2 = (((__pyx_v_sorted_samples[__pyx_v_start]) > (__pyx_v_X_indices[__pyx_v_indptr_start])) != 0); __pyx_t_1 = __pyx_t_2; __pyx_L6_bool_binop_done:; if (!__pyx_t_1) break; -
+1033: indptr_start += 1
++1033: indptr_start += 1
__pyx_v_indptr_start = (__pyx_v_indptr_start + 1); }
1034:
-+1035: while (indptr_start < indptr_end and
++1035: while (indptr_start < indptr_end and
while (1) { __pyx_t_2 = ((__pyx_v_indptr_start < __pyx_v_indptr_end) != 0); if (__pyx_t_2) { @@ -3257,25 +3331,25 @@ __pyx_t_1 = __pyx_t_2; goto __pyx_L10_bool_binop_done; } -
+1036: sorted_samples[end - 1] < X_indices[indptr_end - 1]):
++1036: sorted_samples[end - 1] < X_indices[indptr_end - 1]):
__pyx_t_2 = (((__pyx_v_sorted_samples[(__pyx_v_end - 1)]) < (__pyx_v_X_indices[(__pyx_v_indptr_end - 1)])) != 0); __pyx_t_1 = __pyx_t_2; __pyx_L10_bool_binop_done:; if (!__pyx_t_1) break; -
+1037: indptr_end -= 1
++1037: indptr_end -= 1
__pyx_v_indptr_end = (__pyx_v_indptr_end - 1); }
1038:
-+1039: cdef SIZE_t p = start
++1039: cdef SIZE_t p = start
__pyx_v_p = __pyx_v_start; -
1040: cdef SIZE_t index
- 1041: cdef SIZE_t k
-+1042: cdef SIZE_t end_negative_ = start
+1040: cdef SIZE_t index+
1041: cdef SIZE_t k+
+1042: cdef SIZE_t end_negative_ = start
__pyx_v_end_negative_ = __pyx_v_start; -
+1043: cdef SIZE_t start_positive_ = end
++1043: cdef SIZE_t start_positive_ = end
__pyx_v_start_positive_ = __pyx_v_end;
1044:
-+1045: while (p < end and indptr_start < indptr_end):
++1045: while (p < end and indptr_start < indptr_end):
while (1) { __pyx_t_2 = ((__pyx_v_p < __pyx_v_end) != 0); if (__pyx_t_2) { @@ -3287,78 +3361,78 @@ __pyx_t_1 = __pyx_t_2; __pyx_L14_bool_binop_done:; if (!__pyx_t_1) break; -
1046: # Find index of sorted_samples[p] in X_indices
-+1047: binary_search(X_indices, indptr_start, indptr_end,
+1046: # Find index of sorted_samples[p] in X_indices+
+1047: binary_search(X_indices, indptr_start, indptr_end,
__pyx_f_13stpredictions_6models_3OK3_9_splitter_binary_search(__pyx_v_X_indices, __pyx_v_indptr_start, __pyx_v_indptr_end, (__pyx_v_sorted_samples[__pyx_v_p]), (&__pyx_v_k), (&__pyx_v_indptr_start)); -
1048: sorted_samples[p], &k, &indptr_start)
+1048: sorted_samples[p], &k, &indptr_start)
1049:
-+1050: if k != -1:
++1050: if k != -1:
__pyx_t_1 = ((__pyx_v_k != -1L) != 0); if (__pyx_t_1) { /* … */ } -
1051: # If k != -1, we have found a non zero value
+1051: # If k != -1, we have found a non zero value
1052:
-+1053: if X_data[k] > 0:
++1053: if X_data[k] > 0:
__pyx_t_1 = (((__pyx_v_X_data[__pyx_v_k]) > 0.0) != 0); if (__pyx_t_1) { /* … */ goto __pyx_L17; } -
+1054: start_positive_ -= 1
++1054: start_positive_ -= 1
__pyx_v_start_positive_ = (__pyx_v_start_positive_ - 1); -
+1055: Xf[start_positive_] = X_data[k]
++1055: Xf[start_positive_] = X_data[k]
(__pyx_v_Xf[__pyx_v_start_positive_]) = (__pyx_v_X_data[__pyx_v_k]); -
+1056: index = index_to_samples[X_indices[k]]
++1056: index = index_to_samples[X_indices[k]]
__pyx_v_index = (__pyx_v_index_to_samples[(__pyx_v_X_indices[__pyx_v_k])]); -
+1057: sparse_swap(index_to_samples, samples, index, start_positive_)
++1057: sparse_swap(index_to_samples, samples, index, start_positive_)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sparse_swap(__pyx_v_index_to_samples, __pyx_v_samples, __pyx_v_index, __pyx_v_start_positive_);
1058:
1059:
-+1060: elif X_data[k] < 0:
++1060: elif X_data[k] < 0:
__pyx_t_1 = (((__pyx_v_X_data[__pyx_v_k]) < 0.0) != 0); if (__pyx_t_1) { /* … */ } __pyx_L17:; -
+1061: Xf[end_negative_] = X_data[k]
++1061: Xf[end_negative_] = X_data[k]
(__pyx_v_Xf[__pyx_v_end_negative_]) = (__pyx_v_X_data[__pyx_v_k]); -
+1062: index = index_to_samples[X_indices[k]]
++1062: index = index_to_samples[X_indices[k]]
__pyx_v_index = (__pyx_v_index_to_samples[(__pyx_v_X_indices[__pyx_v_k])]); -
+1063: sparse_swap(index_to_samples, samples, index, end_negative_)
++1063: sparse_swap(index_to_samples, samples, index, end_negative_)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sparse_swap(__pyx_v_index_to_samples, __pyx_v_samples, __pyx_v_index, __pyx_v_end_negative_); -
+1064: end_negative_ += 1
++1064: end_negative_ += 1
__pyx_v_end_negative_ = (__pyx_v_end_negative_ + 1); -
+1065: p += 1
++1065: p += 1
__pyx_v_p = (__pyx_v_p + 1); }
1066:
- 1067: # Returned values
-+1068: end_negative[0] = end_negative_
+1067: # Returned values+
+1068: end_negative[0] = end_negative_
(__pyx_v_end_negative[0]) = __pyx_v_end_negative_; -
+1069: start_positive[0] = start_positive_
++1069: start_positive[0] = start_positive_
(__pyx_v_start_positive[0]) = __pyx_v_start_positive_;
1070:
1071:
-+1072: cdef inline void sparse_swap(SIZE_t* index_to_samples, SIZE_t* samples,
++1072: cdef inline void sparse_swap(SIZE_t* index_to_samples, SIZE_t* samples,
static CYTHON_INLINE void __pyx_f_13stpredictions_6models_3OK3_9_splitter_sparse_swap(__pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_index_to_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_pos_1, __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_pos_2) { /* … */ /* function exit code */ } -
1073: SIZE_t pos_1, SIZE_t pos_2) nogil:
- 1074: """Swap sample pos_1 and pos_2 preserving sparse invariant."""
-+1075: samples[pos_1], samples[pos_2] = samples[pos_2], samples[pos_1]
+1073: SIZE_t pos_1, SIZE_t pos_2) nogil:+
1074: """Swap sample pos_1 and pos_2 preserving sparse invariant."""+
+1075: samples[pos_1], samples[pos_2] = samples[pos_2], samples[pos_1]
__pyx_t_1 = (__pyx_v_samples[__pyx_v_pos_2]); __pyx_t_2 = (__pyx_v_samples[__pyx_v_pos_1]); (__pyx_v_samples[__pyx_v_pos_1]) = __pyx_t_1; (__pyx_v_samples[__pyx_v_pos_2]) = __pyx_t_2; -
+1076: index_to_samples[samples[pos_1]] = pos_1
++1076: index_to_samples[samples[pos_1]] = pos_1
(__pyx_v_index_to_samples[(__pyx_v_samples[__pyx_v_pos_1])]) = __pyx_v_pos_1; -
+1077: index_to_samples[samples[pos_2]] = pos_2
++1077: index_to_samples[samples[pos_2]] = pos_2
(__pyx_v_index_to_samples[(__pyx_v_samples[__pyx_v_pos_2])]) = __pyx_v_pos_2;
1078:
1079:
-+1080: cdef class BestSparseSplitter(BaseSparseSplitter):
++1080: cdef class BestSparseSplitter(BaseSparseSplitter):
struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BestSparseSplitter { struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter __pyx_base; }; @@ -3368,9 +3442,9 @@ }; static struct __pyx_vtabstruct_13stpredictions_6models_3OK3_9_splitter_BestSparseSplitter *__pyx_vtabptr_13stpredictions_6models_3OK3_9_splitter_BestSparseSplitter; -
1081: """Splitter for finding the best split, using the sparse data."""
+1081: """Splitter for finding the best split, using the sparse data."""
1082:
-+1083: def __reduce__(self):
++1083: def __reduce__(self):
/* Python wrapper */
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_18BestSparseSplitter_1__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_18BestSparseSplitter_1__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
@@ -3402,7 +3476,7 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
+1084: return (BestSparseSplitter, (self.criterion,
++1084: return (BestSparseSplitter, (self.criterion,
__Pyx_XDECREF(__pyx_r); /* … */ __pyx_t_4 = PyTuple_New(5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1084, __pyx_L1_error) @@ -3437,16 +3511,16 @@ __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; -
+1085: self.max_features,
++1085: self.max_features,
__pyx_t_1 = __Pyx_PyInt_From_Py_intptr_t(__pyx_v_self->__pyx_base.__pyx_base.max_features); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1085, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); -
+1086: self.min_samples_leaf,
++1086: self.min_samples_leaf,
__pyx_t_2 = __Pyx_PyInt_From_Py_intptr_t(__pyx_v_self->__pyx_base.__pyx_base.min_samples_leaf); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1086, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); -
+1087: self.min_weight_leaf,
++1087: self.min_weight_leaf,
__pyx_t_3 = PyFloat_FromDouble(__pyx_v_self->__pyx_base.__pyx_base.min_weight_leaf); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1087, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); -
+1088: self.random_state), self.__getstate__())
++1088: self.random_state), self.__getstate__())
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_getstate); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1088, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_1 = NULL; @@ -3465,7 +3539,7 @@ __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
1089:
-+1090: cdef int node_split(self, double impurity, SplitRecord* split,
++1090: cdef int node_split(self, double impurity, SplitRecord* split,
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_18BestSparseSplitter_node_split(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BestSparseSplitter *__pyx_v_self, double __pyx_v_impurity, struct __pyx_t_13stpredictions_6models_3OK3_9_splitter_SplitRecord *__pyx_v_split, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_n_constant_features) { __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start; @@ -3517,111 +3591,111 @@ __pyx_L0:; return __pyx_r; } -
1091: SIZE_t* n_constant_features) nogil except -1:
- 1092: """Find the best split on node samples[start:end], using sparse features
+1091: SIZE_t* n_constant_features) nogil except -1:+
1092: """Find the best split on node samples[start:end], using sparse features
1093:
- 1094: Returns -1 in case of failure to allocate memory (and raise MemoryError)
- 1095: or 0 otherwise.
- 1096: """
- 1097: # Find the best split
-+1098: cdef SIZE_t* samples = self.samples
+1094: Returns -1 in case of failure to allocate memory (and raise MemoryError)+
1095: or 0 otherwise.+
1096: """+
1097: # Find the best split+
+1098: cdef SIZE_t* samples = self.samples
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.samples; __pyx_v_samples = __pyx_t_1; -
+1099: cdef SIZE_t start = self.start
++1099: cdef SIZE_t start = self.start
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.start; __pyx_v_start = __pyx_t_2; -
+1100: cdef SIZE_t end = self.end
++1100: cdef SIZE_t end = self.end
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.end; __pyx_v_end = __pyx_t_2;
1101:
-+1102: cdef INT32_t* X_indices = self.X_indices
++1102: cdef INT32_t* X_indices = self.X_indices
__pyx_t_3 = __pyx_v_self->__pyx_base.X_indices; __pyx_v_X_indices = __pyx_t_3; -
+1103: cdef INT32_t* X_indptr = self.X_indptr
++1103: cdef INT32_t* X_indptr = self.X_indptr
__pyx_t_3 = __pyx_v_self->__pyx_base.X_indptr; __pyx_v_X_indptr = __pyx_t_3; -
+1104: cdef DTYPE_t* X_data = self.X_data
++1104: cdef DTYPE_t* X_data = self.X_data
__pyx_t_4 = __pyx_v_self->__pyx_base.X_data; __pyx_v_X_data = __pyx_t_4;
1105:
-+1106: cdef SIZE_t* features = self.features
++1106: cdef SIZE_t* features = self.features
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.features; __pyx_v_features = __pyx_t_1; -
+1107: cdef SIZE_t* constant_features = self.constant_features
++1107: cdef SIZE_t* constant_features = self.constant_features
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.constant_features; __pyx_v_constant_features = __pyx_t_1; -
+1108: cdef SIZE_t n_features = self.n_features
++1108: cdef SIZE_t n_features = self.n_features
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.n_features; __pyx_v_n_features = __pyx_t_2;
1109:
-+1110: cdef DTYPE_t* Xf = self.feature_values
++1110: cdef DTYPE_t* Xf = self.feature_values
__pyx_t_4 = __pyx_v_self->__pyx_base.__pyx_base.feature_values; __pyx_v_Xf = __pyx_t_4; -
+1111: cdef SIZE_t* sorted_samples = self.sorted_samples
++1111: cdef SIZE_t* sorted_samples = self.sorted_samples
__pyx_t_1 = __pyx_v_self->__pyx_base.sorted_samples; __pyx_v_sorted_samples = __pyx_t_1; -
+1112: cdef SIZE_t* index_to_samples = self.index_to_samples
++1112: cdef SIZE_t* index_to_samples = self.index_to_samples
__pyx_t_1 = __pyx_v_self->__pyx_base.index_to_samples; __pyx_v_index_to_samples = __pyx_t_1; -
+1113: cdef SIZE_t max_features = self.max_features
++1113: cdef SIZE_t max_features = self.max_features
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.max_features; __pyx_v_max_features = __pyx_t_2; -
+1114: cdef SIZE_t min_samples_leaf = self.min_samples_leaf
++1114: cdef SIZE_t min_samples_leaf = self.min_samples_leaf
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.min_samples_leaf; __pyx_v_min_samples_leaf = __pyx_t_2; -
+1115: cdef double min_weight_leaf = self.min_weight_leaf
++1115: cdef double min_weight_leaf = self.min_weight_leaf
__pyx_t_5 = __pyx_v_self->__pyx_base.__pyx_base.min_weight_leaf; __pyx_v_min_weight_leaf = __pyx_t_5; -
+1116: cdef UINT32_t* random_state = &self.rand_r_state
++1116: cdef UINT32_t* random_state = &self.rand_r_state
__pyx_v_random_state = (&__pyx_v_self->__pyx_base.__pyx_base.rand_r_state);
1117:
- 1118: cdef SplitRecord best, current
-+1119: _init_split(&best, end)
+1118: cdef SplitRecord best, current+
+1119: _init_split(&best, end)
__pyx_f_13stpredictions_6models_3OK3_9_splitter__init_split((&__pyx_v_best), __pyx_v_end); -
+1120: cdef double current_proxy_improvement = - INFINITY
++1120: cdef double current_proxy_improvement = - INFINITY
__pyx_v_current_proxy_improvement = (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY); -
+1121: cdef double best_proxy_improvement = - INFINITY
++1121: cdef double best_proxy_improvement = - INFINITY
__pyx_v_best_proxy_improvement = (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY);
1122:
-+1123: cdef SIZE_t f_i = n_features
++1123: cdef SIZE_t f_i = n_features
__pyx_v_f_i = __pyx_v_n_features; -
1124: cdef SIZE_t f_j, p
-+1125: cdef SIZE_t n_visited_features = 0
+1124: cdef SIZE_t f_j, p+
+1125: cdef SIZE_t n_visited_features = 0
__pyx_v_n_visited_features = 0; -
1126: # Number of features discovered to be constant during the split search
-+1127: cdef SIZE_t n_found_constants = 0
+1126: # Number of features discovered to be constant during the split search+
+1127: cdef SIZE_t n_found_constants = 0
__pyx_v_n_found_constants = 0; -
1128: # Number of features known to be constant and drawn without replacement
-+1129: cdef SIZE_t n_drawn_constants = 0
+1128: # Number of features known to be constant and drawn without replacement+
+1129: cdef SIZE_t n_drawn_constants = 0
__pyx_v_n_drawn_constants = 0; -
+1130: cdef SIZE_t n_known_constants = n_constant_features[0]
++1130: cdef SIZE_t n_known_constants = n_constant_features[0]
__pyx_v_n_known_constants = (__pyx_v_n_constant_features[0]); -
1131: # n_total_constants = n_known_constants + n_found_constants
-+1132: cdef SIZE_t n_total_constants = n_known_constants
+1131: # n_total_constants = n_known_constants + n_found_constants+
+1132: cdef SIZE_t n_total_constants = n_known_constants
__pyx_v_n_total_constants = __pyx_v_n_known_constants; -
1133: cdef DTYPE_t current_feature_value
+1133: cdef DTYPE_t current_feature_value
1134:
- 1135: cdef SIZE_t p_next
- 1136: cdef SIZE_t p_prev
-+1137: cdef bint is_samples_sorted = 0 # indicate is sorted_samples is
+1135: cdef SIZE_t p_next+
1136: cdef SIZE_t p_prev+
+1137: cdef bint is_samples_sorted = 0 # indicate is sorted_samples is
__pyx_v_is_samples_sorted = 0; -
1138: # inititialized
+1138: # inititialized
1139:
- 1140: # We assume implicitly that end_positive = end and
- 1141: # start_negative = start
- 1142: cdef SIZE_t start_positive
- 1143: cdef SIZE_t end_negative
+1140: # We assume implicitly that end_positive = end and+
1141: # start_negative = start+
1142: cdef SIZE_t start_positive+
1143: cdef SIZE_t end_negative
1144:
- 1145: # Sample up to max_features without replacement using a
- 1146: # Fisher-Yates-based algorithm (using the local variables `f_i` and
- 1147: # `f_j` to compute a permutation of the `features` array).
- 1148: #
- 1149: # Skip the CPU intensive evaluation of the impurity criterion for
- 1150: # features that were already detected as constant (hence not suitable
- 1151: # for good splitting) by ancestor nodes and save the information on
- 1152: # newly discovered constant features to spare computation on descendant
- 1153: # nodes.
-+1154: while (f_i > n_total_constants and # Stop early if remaining features
+1145: # Sample up to max_features without replacement using a+
1146: # Fisher-Yates-based algorithm (using the local variables `f_i` and+
1147: # `f_j` to compute a permutation of the `features` array).+
1148: #+
1149: # Skip the CPU intensive evaluation of the impurity criterion for+
1150: # features that were already detected as constant (hence not suitable+
1151: # for good splitting) by ancestor nodes and save the information on+
1152: # newly discovered constant features to spare computation on descendant+
1153: # nodes.+
+1154: while (f_i > n_total_constants and # Stop early if remaining features
while (1) { __pyx_t_7 = ((__pyx_v_f_i > __pyx_v_n_total_constants) != 0); if (__pyx_t_7) { @@ -3629,169 +3703,169 @@ __pyx_t_6 = __pyx_t_7; goto __pyx_L5_bool_binop_done; } -
1155: # are constant
-+1156: (n_visited_features < max_features or
+1155: # are constant+
+1156: (n_visited_features < max_features or
__pyx_t_7 = ((__pyx_v_n_visited_features < __pyx_v_max_features) != 0); if (!__pyx_t_7) { } else { __pyx_t_6 = __pyx_t_7; goto __pyx_L5_bool_binop_done; } -
1157: # At least one drawn features must be non constant
-+1158: n_visited_features <= n_found_constants + n_drawn_constants)):
+1157: # At least one drawn features must be non constant+
+1158: n_visited_features <= n_found_constants + n_drawn_constants)):
__pyx_t_7 = ((__pyx_v_n_visited_features <= (__pyx_v_n_found_constants + __pyx_v_n_drawn_constants)) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L5_bool_binop_done:; if (!__pyx_t_6) break;
1159:
-+1160: n_visited_features += 1
++1160: n_visited_features += 1
__pyx_v_n_visited_features = (__pyx_v_n_visited_features + 1);
1161:
- 1162: # Loop invariant: elements of features in
- 1163: # - [:n_drawn_constant[ holds drawn and known constant features;
- 1164: # - [n_drawn_constant:n_known_constant[ holds known constant
- 1165: # features that haven't been drawn yet;
- 1166: # - [n_known_constant:n_total_constant[ holds newly found constant
- 1167: # features;
- 1168: # - [n_total_constant:f_i[ holds features that haven't been drawn
- 1169: # yet and aren't constant apriori.
- 1170: # - [f_i:n_features[ holds features that have been drawn
- 1171: # and aren't constant.
+1162: # Loop invariant: elements of features in+
1163: # - [:n_drawn_constant[ holds drawn and known constant features;+
1164: # - [n_drawn_constant:n_known_constant[ holds known constant+
1165: # features that haven't been drawn yet;+
1166: # - [n_known_constant:n_total_constant[ holds newly found constant+
1167: # features;+
1168: # - [n_total_constant:f_i[ holds features that haven't been drawn+
1169: # yet and aren't constant apriori.+
1170: # - [f_i:n_features[ holds features that have been drawn+
1171: # and aren't constant.
1172:
- 1173: # Draw a feature at random
-+1174: f_j = rand_int(n_drawn_constants, f_i - n_found_constants,
+1173: # Draw a feature at random+
+1174: f_j = rand_int(n_drawn_constants, f_i - n_found_constants,
__pyx_v_f_j = __pyx_f_7sklearn_4tree_6_utils_rand_int(__pyx_v_n_drawn_constants, (__pyx_v_f_i - __pyx_v_n_found_constants), __pyx_v_random_state); -
1175: random_state)
+1175: random_state)
1176:
-+1177: if f_j < n_known_constants:
++1177: if f_j < n_known_constants:
__pyx_t_6 = ((__pyx_v_f_j < __pyx_v_n_known_constants) != 0); if (__pyx_t_6) { /* … */ goto __pyx_L8; } -
1178: # f_j in the interval [n_drawn_constants, n_known_constants[
-+1179: features[f_j], features[n_drawn_constants] = features[n_drawn_constants], features[f_j]
+1178: # f_j in the interval [n_drawn_constants, n_known_constants[+
+1179: features[f_j], features[n_drawn_constants] = features[n_drawn_constants], features[f_j]
__pyx_t_2 = (__pyx_v_features[__pyx_v_n_drawn_constants]); __pyx_t_8 = (__pyx_v_features[__pyx_v_f_j]); (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_2; (__pyx_v_features[__pyx_v_n_drawn_constants]) = __pyx_t_8;
1180:
-+1181: n_drawn_constants += 1
++1181: n_drawn_constants += 1
__pyx_v_n_drawn_constants = (__pyx_v_n_drawn_constants + 1);
1182:
- 1183: else:
- 1184: # f_j in the interval [n_known_constants, f_i - n_found_constants[
-+1185: f_j += n_found_constants
+1183: else:+
1184: # f_j in the interval [n_known_constants, f_i - n_found_constants[+
+1185: f_j += n_found_constants
/*else*/ { __pyx_v_f_j = (__pyx_v_f_j + __pyx_v_n_found_constants); -
1186: # f_j in the interval [n_total_constants, f_i[
+1186: # f_j in the interval [n_total_constants, f_i[
1187:
-+1188: current.feature = features[f_j]
++1188: current.feature = features[f_j]
__pyx_v_current.feature = (__pyx_v_features[__pyx_v_f_j]); -
+1189: self.extract_nnz(current.feature,
++1189: self.extract_nnz(current.feature,
__pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_extract_nnz(((struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *)__pyx_v_self), __pyx_v_current.feature, (&__pyx_v_end_negative), (&__pyx_v_start_positive), (&__pyx_v_is_samples_sorted)); -
1190: &end_negative, &start_positive,
- 1191: &is_samples_sorted)
+1190: &end_negative, &start_positive,+
1191: &is_samples_sorted)
1192:
- 1193: # Sort the positive and negative parts of `Xf`
-+1194: sort(Xf + start, samples + start, end_negative - start)
+1193: # Sort the positive and negative parts of `Xf`+
+1194: sort(Xf + start, samples + start, end_negative - start)
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sort((__pyx_v_Xf + __pyx_v_start), (__pyx_v_samples + __pyx_v_start), (__pyx_v_end_negative - __pyx_v_start)); -
+1195: sort(Xf + start_positive, samples + start_positive,
++1195: sort(Xf + start_positive, samples + start_positive,
__pyx_f_13stpredictions_6models_3OK3_9_splitter_sort((__pyx_v_Xf + __pyx_v_start_positive), (__pyx_v_samples + __pyx_v_start_positive), (__pyx_v_end - __pyx_v_start_positive)); -
1196: end - start_positive)
+1196: end - start_positive)
1197:
- 1198: # Update index_to_samples to take into account the sort
-+1199: for p in range(start, end_negative):
+1198: # Update index_to_samples to take into account the sort+
+1199: for p in range(start, end_negative):
__pyx_t_8 = __pyx_v_end_negative; __pyx_t_2 = __pyx_t_8; for (__pyx_t_9 = __pyx_v_start; __pyx_t_9 < __pyx_t_2; __pyx_t_9+=1) { __pyx_v_p = __pyx_t_9; -
+1200: index_to_samples[samples[p]] = p
++1200: index_to_samples[samples[p]] = p
(__pyx_v_index_to_samples[(__pyx_v_samples[__pyx_v_p])]) = __pyx_v_p; } -
+1201: for p in range(start_positive, end):
++1201: for p in range(start_positive, end):
__pyx_t_8 = __pyx_v_end; __pyx_t_2 = __pyx_t_8; for (__pyx_t_9 = __pyx_v_start_positive; __pyx_t_9 < __pyx_t_2; __pyx_t_9+=1) { __pyx_v_p = __pyx_t_9; -
+1202: index_to_samples[samples[p]] = p
++1202: index_to_samples[samples[p]] = p
(__pyx_v_index_to_samples[(__pyx_v_samples[__pyx_v_p])]) = __pyx_v_p; }
1203:
- 1204: # Add one or two zeros in Xf, if there is any
-+1205: if end_negative < start_positive:
+1204: # Add one or two zeros in Xf, if there is any+
+1205: if end_negative < start_positive:
__pyx_t_6 = ((__pyx_v_end_negative < __pyx_v_start_positive) != 0); if (__pyx_t_6) { /* … */ } -
+1206: start_positive -= 1
++1206: start_positive -= 1
__pyx_v_start_positive = (__pyx_v_start_positive - 1); -
+1207: Xf[start_positive] = 0.
++1207: Xf[start_positive] = 0.
(__pyx_v_Xf[__pyx_v_start_positive]) = 0.;
1208:
-+1209: if end_negative != start_positive:
++1209: if end_negative != start_positive:
__pyx_t_6 = ((__pyx_v_end_negative != __pyx_v_start_positive) != 0); if (__pyx_t_6) { /* … */ } -
+1210: Xf[end_negative] = 0.
++1210: Xf[end_negative] = 0.
(__pyx_v_Xf[__pyx_v_end_negative]) = 0.; -
+1211: end_negative += 1
++1211: end_negative += 1
__pyx_v_end_negative = (__pyx_v_end_negative + 1);
1212:
-+1213: if Xf[end - 1] <= Xf[start] + FEATURE_THRESHOLD:
++1213: if Xf[end - 1] <= Xf[start] + FEATURE_THRESHOLD:
__pyx_t_6 = (((__pyx_v_Xf[(__pyx_v_end - 1)]) <= ((__pyx_v_Xf[__pyx_v_start]) + __pyx_v_13stpredictions_6models_3OK3_9_splitter_FEATURE_THRESHOLD)) != 0); if (__pyx_t_6) { /* … */ goto __pyx_L15; } -
+1214: features[f_j], features[n_total_constants] = features[n_total_constants], features[f_j]
++1214: features[f_j], features[n_total_constants] = features[n_total_constants], features[f_j]
__pyx_t_8 = (__pyx_v_features[__pyx_v_n_total_constants]); __pyx_t_2 = (__pyx_v_features[__pyx_v_f_j]); (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_8; (__pyx_v_features[__pyx_v_n_total_constants]) = __pyx_t_2;
1215:
-+1216: n_found_constants += 1
++1216: n_found_constants += 1
__pyx_v_n_found_constants = (__pyx_v_n_found_constants + 1); -
+1217: n_total_constants += 1
++1217: n_total_constants += 1
__pyx_v_n_total_constants = (__pyx_v_n_total_constants + 1);
1218:
- 1219: else:
-+1220: f_i -= 1
+1219: else:+
+1220: f_i -= 1
/*else*/ { __pyx_v_f_i = (__pyx_v_f_i - 1); -
+1221: features[f_i], features[f_j] = features[f_j], features[f_i]
++1221: features[f_i], features[f_j] = features[f_j], features[f_i]
__pyx_t_2 = (__pyx_v_features[__pyx_v_f_j]); __pyx_t_8 = (__pyx_v_features[__pyx_v_f_i]); (__pyx_v_features[__pyx_v_f_i]) = __pyx_t_2; (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_8;
1222:
- 1223: # Evaluate all splits
-+1224: self.criterion.reset()
+1223: # Evaluate all splits+
+1224: self.criterion.reset()
__pyx_t_10 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->reset(__pyx_v_self->__pyx_base.__pyx_base.criterion); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1224, __pyx_L1_error)
-
+1225: p = start
++1225: p = start
__pyx_v_p = __pyx_v_start;
1226:
-+1227: while p < end:
++1227: while p < end:
while (1) { __pyx_t_6 = ((__pyx_v_p < __pyx_v_end) != 0); if (!__pyx_t_6) break; -
+1228: if p + 1 != end_negative:
++1228: if p + 1 != end_negative:
__pyx_t_6 = (((__pyx_v_p + 1) != __pyx_v_end_negative) != 0); if (__pyx_t_6) { /* … */ goto __pyx_L18; } -
+1229: p_next = p + 1
++1229: p_next = p + 1
__pyx_v_p_next = (__pyx_v_p + 1); -
1230: else:
-+1231: p_next = start_positive
+1230: else:+
+1231: p_next = start_positive
/*else*/ { __pyx_v_p_next = __pyx_v_start_positive; } __pyx_L18:;
1232:
-+1233: while (p_next < end and
++1233: while (p_next < end and
while (1) { __pyx_t_7 = ((__pyx_v_p_next < __pyx_v_end) != 0); if (__pyx_t_7) { @@ -3799,23 +3873,23 @@ __pyx_t_6 = __pyx_t_7; goto __pyx_L21_bool_binop_done; } -
+1234: Xf[p_next] <= Xf[p] + FEATURE_THRESHOLD):
++1234: Xf[p_next] <= Xf[p] + FEATURE_THRESHOLD):
__pyx_t_7 = (((__pyx_v_Xf[__pyx_v_p_next]) <= ((__pyx_v_Xf[__pyx_v_p]) + __pyx_v_13stpredictions_6models_3OK3_9_splitter_FEATURE_THRESHOLD)) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L21_bool_binop_done:; if (!__pyx_t_6) break; -
+1235: p = p_next
++1235: p = p_next
__pyx_v_p = __pyx_v_p_next; -
+1236: if p + 1 != end_negative:
++1236: if p + 1 != end_negative:
__pyx_t_6 = (((__pyx_v_p + 1) != __pyx_v_end_negative) != 0); if (__pyx_t_6) { /* … */ goto __pyx_L23; } -
+1237: p_next = p + 1
++1237: p_next = p + 1
__pyx_v_p_next = (__pyx_v_p + 1); -
1238: else:
-+1239: p_next = start_positive
+1238: else:+
+1239: p_next = start_positive
/*else*/ { __pyx_v_p_next = __pyx_v_start_positive; } @@ -3823,17 +3897,17 @@ }
1240:
1241:
- 1242: # (p_next >= end) or (X[samples[p_next], current.feature] >
- 1243: # X[samples[p], current.feature])
-+1244: p_prev = p
+1242: # (p_next >= end) or (X[samples[p_next], current.feature] >+
1243: # X[samples[p], current.feature])+
+1244: p_prev = p
__pyx_v_p_prev = __pyx_v_p; -
+1245: p = p_next
++1245: p = p_next
__pyx_v_p = __pyx_v_p_next; -
1246: # (p >= end) or (X[samples[p], current.feature] >
- 1247: # X[samples[p_prev], current.feature])
+1246: # (p >= end) or (X[samples[p], current.feature] >+
1247: # X[samples[p_prev], current.feature])
1248:
1249:
-+1250: if p < end:
++1250: if p < end:
__pyx_t_6 = ((__pyx_v_p < __pyx_v_end) != 0); if (__pyx_t_6) { /* … */ @@ -3845,11 +3919,11 @@ } __pyx_L8:; } -
+1251: current.pos = p
++1251: current.pos = p
__pyx_v_current.pos = __pyx_v_p;
1252:
- 1253: # Reject if min_samples_leaf is not guaranteed
-+1254: if (((current.pos - start) < min_samples_leaf) or
+1253: # Reject if min_samples_leaf is not guaranteed+
+1254: if (((current.pos - start) < min_samples_leaf) or
__pyx_t_7 = (((__pyx_v_current.pos - __pyx_v_start) < __pyx_v_min_samples_leaf) != 0); if (!__pyx_t_7) { } else { @@ -3860,18 +3934,18 @@ if (__pyx_t_6) { /* … */ } -
+1255: ((end - current.pos) < min_samples_leaf)):
++1255: ((end - current.pos) < min_samples_leaf)):
__pyx_t_7 = (((__pyx_v_end - __pyx_v_current.pos) < __pyx_v_min_samples_leaf) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L26_bool_binop_done:; -
+1256: continue
++1256: continue
goto __pyx_L16_continue;
1257:
-+1258: self.criterion.update(current.pos)
++1258: self.criterion.update(current.pos)
__pyx_t_10 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->update(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_current.pos); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1258, __pyx_L1_error)
1259:
- 1260: # Reject if min_weight_leaf is not satisfied
-+1261: if ((self.criterion.weighted_n_left < min_weight_leaf) or
+1260: # Reject if min_weight_leaf is not satisfied+
+1261: if ((self.criterion.weighted_n_left < min_weight_leaf) or
__pyx_t_7 = ((__pyx_v_self->__pyx_base.__pyx_base.criterion->weighted_n_left < __pyx_v_min_weight_leaf) != 0); if (!__pyx_t_7) { } else { @@ -3882,28 +3956,28 @@ if (__pyx_t_6) { /* … */ } -
+1262: (self.criterion.weighted_n_right < min_weight_leaf)):
++1262: (self.criterion.weighted_n_right < min_weight_leaf)):
__pyx_t_7 = ((__pyx_v_self->__pyx_base.__pyx_base.criterion->weighted_n_right < __pyx_v_min_weight_leaf) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L29_bool_binop_done:; -
+1263: continue
++1263: continue
goto __pyx_L16_continue;
1264:
-+1265: current_proxy_improvement = self.criterion.proxy_impurity_improvement()
++1265: current_proxy_improvement = self.criterion.proxy_impurity_improvement()
__pyx_v_current_proxy_improvement = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->proxy_impurity_improvement(__pyx_v_self->__pyx_base.__pyx_base.criterion);
1266:
-+1267: if current_proxy_improvement > best_proxy_improvement:
++1267: if current_proxy_improvement > best_proxy_improvement:
__pyx_t_6 = ((__pyx_v_current_proxy_improvement > __pyx_v_best_proxy_improvement) != 0); if (__pyx_t_6) { /* … */ } -
+1268: best_proxy_improvement = current_proxy_improvement
++1268: best_proxy_improvement = current_proxy_improvement
__pyx_v_best_proxy_improvement = __pyx_v_current_proxy_improvement; -
1269: # sum of halves used to avoid infinite values
-+1270: current.threshold = Xf[p_prev] / 2.0 + Xf[p] / 2.0
+1269: # sum of halves used to avoid infinite values+
+1270: current.threshold = Xf[p_prev] / 2.0 + Xf[p] / 2.0
__pyx_v_current.threshold = (((__pyx_v_Xf[__pyx_v_p_prev]) / 2.0) + ((__pyx_v_Xf[__pyx_v_p]) / 2.0));
1271:
-+1272: if ((current.threshold == Xf[p]) or
++1272: if ((current.threshold == Xf[p]) or
__pyx_t_7 = ((__pyx_v_current.threshold == (__pyx_v_Xf[__pyx_v_p])) != 0); if (!__pyx_t_7) { } else { @@ -3914,70 +3988,70 @@ if (__pyx_t_6) { /* … */ } -
+1273: (current.threshold == INFINITY) or
++1273: (current.threshold == INFINITY) or
__pyx_t_7 = ((__pyx_v_current.threshold == __pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY) != 0); if (!__pyx_t_7) { } else { __pyx_t_6 = __pyx_t_7; goto __pyx_L33_bool_binop_done; } -
+1274: (current.threshold == -INFINITY)):
++1274: (current.threshold == -INFINITY)):
__pyx_t_7 = ((__pyx_v_current.threshold == (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY)) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L33_bool_binop_done:; -
+1275: current.threshold = Xf[p_prev]
++1275: current.threshold = Xf[p_prev]
__pyx_v_current.threshold = (__pyx_v_Xf[__pyx_v_p_prev]);
1276:
-+1277: best = current
++1277: best = current
__pyx_v_best = __pyx_v_current;
1278:
- 1279: # Reorganize into samples[start:best.pos] + samples[best.pos:end]
-+1280: if best.pos < end:
+1279: # Reorganize into samples[start:best.pos] + samples[best.pos:end]+
+1280: if best.pos < end:
__pyx_t_6 = ((__pyx_v_best.pos < __pyx_v_end) != 0); if (__pyx_t_6) { /* … */ } -
+1281: self.extract_nnz(best.feature, &end_negative, &start_positive,
++1281: self.extract_nnz(best.feature, &end_negative, &start_positive,
__pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_extract_nnz(((struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *)__pyx_v_self), __pyx_v_best.feature, (&__pyx_v_end_negative), (&__pyx_v_start_positive), (&__pyx_v_is_samples_sorted)); -
1282: &is_samples_sorted)
+1282: &is_samples_sorted)
1283:
-+1284: self._partition(best.threshold, end_negative, start_positive,
++1284: self._partition(best.threshold, end_negative, start_positive,
(void)(__pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter__partition(((struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *)__pyx_v_self), __pyx_v_best.threshold, __pyx_v_end_negative, __pyx_v_start_positive, __pyx_v_best.pos)); -
1285: best.pos)
+1285: best.pos)
1286:
-+1287: self.criterion.reset()
++1287: self.criterion.reset()
__pyx_t_10 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->reset(__pyx_v_self->__pyx_base.__pyx_base.criterion); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1287, __pyx_L1_error)
-
+1288: self.criterion.update(best.pos)
++1288: self.criterion.update(best.pos)
__pyx_t_10 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->update(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_best.pos); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1288, __pyx_L1_error)
-
+1289: best.improvement = self.criterion.impurity_improvement(impurity)
++1289: best.improvement = self.criterion.impurity_improvement(impurity)
__pyx_v_best.improvement = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->impurity_improvement(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_impurity); -
+1290: self.criterion.children_impurity(&best.impurity_left,
++1290: self.criterion.children_impurity(&best.impurity_left,
((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->children_impurity(__pyx_v_self->__pyx_base.__pyx_base.criterion, (&__pyx_v_best.impurity_left), (&__pyx_v_best.impurity_right)); -
1291: &best.impurity_right)
+1291: &best.impurity_right)
1292:
- 1293: # Respect invariant for constant features: the original order of
- 1294: # element in features[:n_known_constants] must be preserved for sibling
- 1295: # and child nodes
-+1296: memcpy(features, constant_features, sizeof(SIZE_t) * n_known_constants)
+1293: # Respect invariant for constant features: the original order of+
1294: # element in features[:n_known_constants] must be preserved for sibling+
1295: # and child nodes+
+1296: memcpy(features, constant_features, sizeof(SIZE_t) * n_known_constants)
(void)(memcpy(__pyx_v_features, __pyx_v_constant_features, ((sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t)) * __pyx_v_n_known_constants)));
1297:
- 1298: # Copy newly found constant features
-+1299: memcpy(constant_features + n_known_constants,
+1298: # Copy newly found constant features+
+1299: memcpy(constant_features + n_known_constants,
(void)(memcpy((__pyx_v_constant_features + __pyx_v_n_known_constants), (__pyx_v_features + __pyx_v_n_known_constants), ((sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t)) * __pyx_v_n_found_constants))); -
1300: features + n_known_constants,
- 1301: sizeof(SIZE_t) * n_found_constants)
+1300: features + n_known_constants,+
1301: sizeof(SIZE_t) * n_found_constants)
1302:
- 1303: # Return values
-+1304: split[0] = best
+1303: # Return values+
+1304: split[0] = best
(__pyx_v_split[0]) = __pyx_v_best; -
+1305: n_constant_features[0] = n_total_constants
++1305: n_constant_features[0] = n_total_constants
(__pyx_v_n_constant_features[0]) = __pyx_v_n_total_constants; -
+1306: return 0
++1306: return 0
__pyx_r = 0; goto __pyx_L0;
1307:
1308:
-+1309: cdef class RandomSparseSplitter(BaseSparseSplitter):
++1309: cdef class RandomSparseSplitter(BaseSparseSplitter):
struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_RandomSparseSplitter { struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter __pyx_base; }; @@ -3987,9 +4061,9 @@ }; static struct __pyx_vtabstruct_13stpredictions_6models_3OK3_9_splitter_RandomSparseSplitter *__pyx_vtabptr_13stpredictions_6models_3OK3_9_splitter_RandomSparseSplitter; -
1310: """Splitter for finding a random split, using the sparse data."""
+1310: """Splitter for finding a random split, using the sparse data."""
1311:
-+1312: def __reduce__(self):
++1312: def __reduce__(self):
/* Python wrapper */
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_20RandomSparseSplitter_1__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_13stpredictions_6models_3OK3_9_splitter_20RandomSparseSplitter_1__reduce__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
@@ -4021,7 +4095,7 @@
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
-
+1313: return (RandomSparseSplitter, (self.criterion,
++1313: return (RandomSparseSplitter, (self.criterion,
__Pyx_XDECREF(__pyx_r); /* … */ __pyx_t_4 = PyTuple_New(5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1313, __pyx_L1_error) @@ -4056,16 +4130,16 @@ __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; -
+1314: self.max_features,
++1314: self.max_features,
__pyx_t_1 = __Pyx_PyInt_From_Py_intptr_t(__pyx_v_self->__pyx_base.__pyx_base.max_features); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1314, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); -
+1315: self.min_samples_leaf,
++1315: self.min_samples_leaf,
__pyx_t_2 = __Pyx_PyInt_From_Py_intptr_t(__pyx_v_self->__pyx_base.__pyx_base.min_samples_leaf); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1315, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); -
+1316: self.min_weight_leaf,
++1316: self.min_weight_leaf,
__pyx_t_3 = PyFloat_FromDouble(__pyx_v_self->__pyx_base.__pyx_base.min_weight_leaf); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1316, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); -
+1317: self.random_state), self.__getstate__())
++1317: self.random_state), self.__getstate__())
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_getstate); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1317, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_1 = NULL; @@ -4084,7 +4158,7 @@ __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
1318:
-+1319: cdef int node_split(self, double impurity, SplitRecord* split,
++1319: cdef int node_split(self, double impurity, SplitRecord* split,
static int __pyx_f_13stpredictions_6models_3OK3_9_splitter_20RandomSparseSplitter_node_split(struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_RandomSparseSplitter *__pyx_v_self, double __pyx_v_impurity, struct __pyx_t_13stpredictions_6models_3OK3_9_splitter_SplitRecord *__pyx_v_split, __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_n_constant_features) { CYTHON_UNUSED __pyx_t_7sklearn_4tree_5_tree_SIZE_t *__pyx_v_samples; __pyx_t_7sklearn_4tree_5_tree_SIZE_t __pyx_v_start; @@ -4137,114 +4211,114 @@ __pyx_L0:; return __pyx_r; } -
1320: SIZE_t* n_constant_features) nogil except -1:
- 1321: """Find a random split on node samples[start:end], using sparse features
+1320: SIZE_t* n_constant_features) nogil except -1:+
1321: """Find a random split on node samples[start:end], using sparse features
1322:
- 1323: Returns -1 in case of failure to allocate memory (and raise MemoryError)
- 1324: or 0 otherwise.
- 1325: """
- 1326: # Find the best split
-+1327: cdef SIZE_t* samples = self.samples
+1323: Returns -1 in case of failure to allocate memory (and raise MemoryError)+
1324: or 0 otherwise.+
1325: """+
1326: # Find the best split+
+1327: cdef SIZE_t* samples = self.samples
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.samples; __pyx_v_samples = __pyx_t_1; -
+1328: cdef SIZE_t start = self.start
++1328: cdef SIZE_t start = self.start
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.start; __pyx_v_start = __pyx_t_2; -
+1329: cdef SIZE_t end = self.end
++1329: cdef SIZE_t end = self.end
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.end; __pyx_v_end = __pyx_t_2;
1330:
-+1331: cdef INT32_t* X_indices = self.X_indices
++1331: cdef INT32_t* X_indices = self.X_indices
__pyx_t_3 = __pyx_v_self->__pyx_base.X_indices; __pyx_v_X_indices = __pyx_t_3; -
+1332: cdef INT32_t* X_indptr = self.X_indptr
++1332: cdef INT32_t* X_indptr = self.X_indptr
__pyx_t_3 = __pyx_v_self->__pyx_base.X_indptr; __pyx_v_X_indptr = __pyx_t_3; -
+1333: cdef DTYPE_t* X_data = self.X_data
++1333: cdef DTYPE_t* X_data = self.X_data
__pyx_t_4 = __pyx_v_self->__pyx_base.X_data; __pyx_v_X_data = __pyx_t_4;
1334:
-+1335: cdef SIZE_t* features = self.features
++1335: cdef SIZE_t* features = self.features
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.features; __pyx_v_features = __pyx_t_1; -
+1336: cdef SIZE_t* constant_features = self.constant_features
++1336: cdef SIZE_t* constant_features = self.constant_features
__pyx_t_1 = __pyx_v_self->__pyx_base.__pyx_base.constant_features; __pyx_v_constant_features = __pyx_t_1; -
+1337: cdef SIZE_t n_features = self.n_features
++1337: cdef SIZE_t n_features = self.n_features
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.n_features; __pyx_v_n_features = __pyx_t_2;
1338:
-+1339: cdef DTYPE_t* Xf = self.feature_values
++1339: cdef DTYPE_t* Xf = self.feature_values
__pyx_t_4 = __pyx_v_self->__pyx_base.__pyx_base.feature_values; __pyx_v_Xf = __pyx_t_4; -
+1340: cdef SIZE_t* sorted_samples = self.sorted_samples
++1340: cdef SIZE_t* sorted_samples = self.sorted_samples
__pyx_t_1 = __pyx_v_self->__pyx_base.sorted_samples; __pyx_v_sorted_samples = __pyx_t_1; -
+1341: cdef SIZE_t* index_to_samples = self.index_to_samples
++1341: cdef SIZE_t* index_to_samples = self.index_to_samples
__pyx_t_1 = __pyx_v_self->__pyx_base.index_to_samples; __pyx_v_index_to_samples = __pyx_t_1; -
+1342: cdef SIZE_t max_features = self.max_features
++1342: cdef SIZE_t max_features = self.max_features
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.max_features; __pyx_v_max_features = __pyx_t_2; -
+1343: cdef SIZE_t min_samples_leaf = self.min_samples_leaf
++1343: cdef SIZE_t min_samples_leaf = self.min_samples_leaf
__pyx_t_2 = __pyx_v_self->__pyx_base.__pyx_base.min_samples_leaf; __pyx_v_min_samples_leaf = __pyx_t_2; -
+1344: cdef double min_weight_leaf = self.min_weight_leaf
++1344: cdef double min_weight_leaf = self.min_weight_leaf
__pyx_t_5 = __pyx_v_self->__pyx_base.__pyx_base.min_weight_leaf; __pyx_v_min_weight_leaf = __pyx_t_5; -
+1345: cdef UINT32_t* random_state = &self.rand_r_state
++1345: cdef UINT32_t* random_state = &self.rand_r_state
__pyx_v_random_state = (&__pyx_v_self->__pyx_base.__pyx_base.rand_r_state);
1346:
- 1347: cdef SplitRecord best, current
-+1348: _init_split(&best, end)
+1347: cdef SplitRecord best, current+
+1348: _init_split(&best, end)
__pyx_f_13stpredictions_6models_3OK3_9_splitter__init_split((&__pyx_v_best), __pyx_v_end); -
+1349: cdef double current_proxy_improvement = - INFINITY
++1349: cdef double current_proxy_improvement = - INFINITY
__pyx_v_current_proxy_improvement = (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY); -
+1350: cdef double best_proxy_improvement = - INFINITY
++1350: cdef double best_proxy_improvement = - INFINITY
__pyx_v_best_proxy_improvement = (-__pyx_v_13stpredictions_6models_3OK3_9_splitter_INFINITY);
1351:
- 1352: cdef DTYPE_t current_feature_value
+1352: cdef DTYPE_t current_feature_value
1353:
-+1354: cdef SIZE_t f_i = n_features
++1354: cdef SIZE_t f_i = n_features
__pyx_v_f_i = __pyx_v_n_features; -
1355: cdef SIZE_t f_j, p
-+1356: cdef SIZE_t n_visited_features = 0
+1355: cdef SIZE_t f_j, p+
+1356: cdef SIZE_t n_visited_features = 0
__pyx_v_n_visited_features = 0; -
1357: # Number of features discovered to be constant during the split search
-+1358: cdef SIZE_t n_found_constants = 0
+1357: # Number of features discovered to be constant during the split search+
+1358: cdef SIZE_t n_found_constants = 0
__pyx_v_n_found_constants = 0; -
1359: # Number of features known to be constant and drawn without replacement
-+1360: cdef SIZE_t n_drawn_constants = 0
+1359: # Number of features known to be constant and drawn without replacement+
+1360: cdef SIZE_t n_drawn_constants = 0
__pyx_v_n_drawn_constants = 0; -
+1361: cdef SIZE_t n_known_constants = n_constant_features[0]
++1361: cdef SIZE_t n_known_constants = n_constant_features[0]
__pyx_v_n_known_constants = (__pyx_v_n_constant_features[0]); -
1362: # n_total_constants = n_known_constants + n_found_constants
-+1363: cdef SIZE_t n_total_constants = n_known_constants
+1362: # n_total_constants = n_known_constants + n_found_constants+
+1363: cdef SIZE_t n_total_constants = n_known_constants
__pyx_v_n_total_constants = __pyx_v_n_known_constants; -
1364: cdef SIZE_t partition_end
+1364: cdef SIZE_t partition_end
1365:
- 1366: cdef DTYPE_t min_feature_value
- 1367: cdef DTYPE_t max_feature_value
+1366: cdef DTYPE_t min_feature_value+
1367: cdef DTYPE_t max_feature_value
1368:
-+1369: cdef bint is_samples_sorted = 0 # indicate that sorted_samples is
++1369: cdef bint is_samples_sorted = 0 # indicate that sorted_samples is
__pyx_v_is_samples_sorted = 0; -
1370: # inititialized
+1370: # inititialized
1371:
- 1372: # We assume implicitly that end_positive = end and
- 1373: # start_negative = start
- 1374: cdef SIZE_t start_positive
- 1375: cdef SIZE_t end_negative
+1372: # We assume implicitly that end_positive = end and+
1373: # start_negative = start+
1374: cdef SIZE_t start_positive+
1375: cdef SIZE_t end_negative
1376:
- 1377: # Sample up to max_features without replacement using a
- 1378: # Fisher-Yates-based algorithm (using the local variables `f_i` and
- 1379: # `f_j` to compute a permutation of the `features` array).
- 1380: #
- 1381: # Skip the CPU intensive evaluation of the impurity criterion for
- 1382: # features that were already detected as constant (hence not suitable
- 1383: # for good splitting) by ancestor nodes and save the information on
- 1384: # newly discovered constant features to spare computation on descendant
- 1385: # nodes.
-+1386: while (f_i > n_total_constants and # Stop early if remaining features
+1377: # Sample up to max_features without replacement using a+
1378: # Fisher-Yates-based algorithm (using the local variables `f_i` and+
1379: # `f_j` to compute a permutation of the `features` array).+
1380: #+
1381: # Skip the CPU intensive evaluation of the impurity criterion for+
1382: # features that were already detected as constant (hence not suitable+
1383: # for good splitting) by ancestor nodes and save the information on+
1384: # newly discovered constant features to spare computation on descendant+
1385: # nodes.+
+1386: while (f_i > n_total_constants and # Stop early if remaining features
while (1) { __pyx_t_7 = ((__pyx_v_f_i > __pyx_v_n_total_constants) != 0); if (__pyx_t_7) { @@ -4252,202 +4326,202 @@ __pyx_t_6 = __pyx_t_7; goto __pyx_L5_bool_binop_done; } -
1387: # are constant
-+1388: (n_visited_features < max_features or
+1387: # are constant+
+1388: (n_visited_features < max_features or
__pyx_t_7 = ((__pyx_v_n_visited_features < __pyx_v_max_features) != 0); if (!__pyx_t_7) { } else { __pyx_t_6 = __pyx_t_7; goto __pyx_L5_bool_binop_done; } -
1389: # At least one drawn features must be non constant
-+1390: n_visited_features <= n_found_constants + n_drawn_constants)):
+1389: # At least one drawn features must be non constant+
+1390: n_visited_features <= n_found_constants + n_drawn_constants)):
__pyx_t_7 = ((__pyx_v_n_visited_features <= (__pyx_v_n_found_constants + __pyx_v_n_drawn_constants)) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L5_bool_binop_done:; if (!__pyx_t_6) break;
1391:
-+1392: n_visited_features += 1
++1392: n_visited_features += 1
__pyx_v_n_visited_features = (__pyx_v_n_visited_features + 1);
1393:
- 1394: # Loop invariant: elements of features in
- 1395: # - [:n_drawn_constant[ holds drawn and known constant features;
- 1396: # - [n_drawn_constant:n_known_constant[ holds known constant
- 1397: # features that haven't been drawn yet;
- 1398: # - [n_known_constant:n_total_constant[ holds newly found constant
- 1399: # features;
- 1400: # - [n_total_constant:f_i[ holds features that haven't been drawn
- 1401: # yet and aren't constant apriori.
- 1402: # - [f_i:n_features[ holds features that have been drawn
- 1403: # and aren't constant.
+1394: # Loop invariant: elements of features in+
1395: # - [:n_drawn_constant[ holds drawn and known constant features;+
1396: # - [n_drawn_constant:n_known_constant[ holds known constant+
1397: # features that haven't been drawn yet;+
1398: # - [n_known_constant:n_total_constant[ holds newly found constant+
1399: # features;+
1400: # - [n_total_constant:f_i[ holds features that haven't been drawn+
1401: # yet and aren't constant apriori.+
1402: # - [f_i:n_features[ holds features that have been drawn+
1403: # and aren't constant.
1404:
- 1405: # Draw a feature at random
-+1406: f_j = rand_int(n_drawn_constants, f_i - n_found_constants,
+1405: # Draw a feature at random+
+1406: f_j = rand_int(n_drawn_constants, f_i - n_found_constants,
__pyx_v_f_j = __pyx_f_7sklearn_4tree_6_utils_rand_int(__pyx_v_n_drawn_constants, (__pyx_v_f_i - __pyx_v_n_found_constants), __pyx_v_random_state); -
1407: random_state)
+1407: random_state)
1408:
-+1409: if f_j < n_known_constants:
++1409: if f_j < n_known_constants:
__pyx_t_6 = ((__pyx_v_f_j < __pyx_v_n_known_constants) != 0); if (__pyx_t_6) { /* … */ goto __pyx_L8; } -
1410: # f_j in the interval [n_drawn_constants, n_known_constants[
-+1411: features[f_j], features[n_drawn_constants] = features[n_drawn_constants], features[f_j]
+1410: # f_j in the interval [n_drawn_constants, n_known_constants[+
+1411: features[f_j], features[n_drawn_constants] = features[n_drawn_constants], features[f_j]
__pyx_t_2 = (__pyx_v_features[__pyx_v_n_drawn_constants]); __pyx_t_8 = (__pyx_v_features[__pyx_v_f_j]); (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_2; (__pyx_v_features[__pyx_v_n_drawn_constants]) = __pyx_t_8;
1412:
-+1413: n_drawn_constants += 1
++1413: n_drawn_constants += 1
__pyx_v_n_drawn_constants = (__pyx_v_n_drawn_constants + 1);
1414:
- 1415: else:
- 1416: # f_j in the interval [n_known_constants, f_i - n_found_constants[
-+1417: f_j += n_found_constants
+1415: else:+
1416: # f_j in the interval [n_known_constants, f_i - n_found_constants[+
+1417: f_j += n_found_constants
/*else*/ { __pyx_v_f_j = (__pyx_v_f_j + __pyx_v_n_found_constants); -
1418: # f_j in the interval [n_total_constants, f_i[
+1418: # f_j in the interval [n_total_constants, f_i[
1419:
-+1420: current.feature = features[f_j]
++1420: current.feature = features[f_j]
__pyx_v_current.feature = (__pyx_v_features[__pyx_v_f_j]);
1421:
-+1422: self.extract_nnz(current.feature,
++1422: self.extract_nnz(current.feature,
__pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_extract_nnz(((struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *)__pyx_v_self), __pyx_v_current.feature, (&__pyx_v_end_negative), (&__pyx_v_start_positive), (&__pyx_v_is_samples_sorted)); -
1423: &end_negative, &start_positive,
- 1424: &is_samples_sorted)
+1423: &end_negative, &start_positive,+
1424: &is_samples_sorted)
1425:
- 1426: # Add one or two zeros in Xf, if there is any
-+1427: if end_negative < start_positive:
+1426: # Add one or two zeros in Xf, if there is any+
+1427: if end_negative < start_positive:
__pyx_t_6 = ((__pyx_v_end_negative < __pyx_v_start_positive) != 0); if (__pyx_t_6) { /* … */ } -
+1428: start_positive -= 1
++1428: start_positive -= 1
__pyx_v_start_positive = (__pyx_v_start_positive - 1); -
+1429: Xf[start_positive] = 0.
++1429: Xf[start_positive] = 0.
(__pyx_v_Xf[__pyx_v_start_positive]) = 0.;
1430:
-+1431: if end_negative != start_positive:
++1431: if end_negative != start_positive:
__pyx_t_6 = ((__pyx_v_end_negative != __pyx_v_start_positive) != 0); if (__pyx_t_6) { /* … */ } -
+1432: Xf[end_negative] = 0.
++1432: Xf[end_negative] = 0.
(__pyx_v_Xf[__pyx_v_end_negative]) = 0.; -
+1433: end_negative += 1
++1433: end_negative += 1
__pyx_v_end_negative = (__pyx_v_end_negative + 1);
1434:
- 1435: # Find min, max in Xf[start:end_negative]
-+1436: min_feature_value = Xf[start]
+1435: # Find min, max in Xf[start:end_negative]+
+1436: min_feature_value = Xf[start]
__pyx_v_min_feature_value = (__pyx_v_Xf[__pyx_v_start]); -
+1437: max_feature_value = min_feature_value
++1437: max_feature_value = min_feature_value
__pyx_v_max_feature_value = __pyx_v_min_feature_value;
1438:
-+1439: for p in range(start, end_negative):
++1439: for p in range(start, end_negative):
__pyx_t_8 = __pyx_v_end_negative; __pyx_t_2 = __pyx_t_8; for (__pyx_t_9 = __pyx_v_start; __pyx_t_9 < __pyx_t_2; __pyx_t_9+=1) { __pyx_v_p = __pyx_t_9; -
+1440: current_feature_value = Xf[p]
++1440: current_feature_value = Xf[p]
__pyx_v_current_feature_value = (__pyx_v_Xf[__pyx_v_p]);
1441:
-+1442: if current_feature_value < min_feature_value:
++1442: if current_feature_value < min_feature_value:
__pyx_t_6 = ((__pyx_v_current_feature_value < __pyx_v_min_feature_value) != 0); if (__pyx_t_6) { /* … */ goto __pyx_L13; } -
+1443: min_feature_value = current_feature_value
++1443: min_feature_value = current_feature_value
__pyx_v_min_feature_value = __pyx_v_current_feature_value; -
+1444: elif current_feature_value > max_feature_value:
++1444: elif current_feature_value > max_feature_value:
__pyx_t_6 = ((__pyx_v_current_feature_value > __pyx_v_max_feature_value) != 0); if (__pyx_t_6) { /* … */ } __pyx_L13:; } -
+1445: max_feature_value = current_feature_value
++1445: max_feature_value = current_feature_value
__pyx_v_max_feature_value = __pyx_v_current_feature_value;
1446:
- 1447: # Update min, max given Xf[start_positive:end]
-+1448: for p in range(start_positive, end):
+1447: # Update min, max given Xf[start_positive:end]+
+1448: for p in range(start_positive, end):
__pyx_t_8 = __pyx_v_end; __pyx_t_2 = __pyx_t_8; for (__pyx_t_9 = __pyx_v_start_positive; __pyx_t_9 < __pyx_t_2; __pyx_t_9+=1) { __pyx_v_p = __pyx_t_9; -
+1449: current_feature_value = Xf[p]
++1449: current_feature_value = Xf[p]
__pyx_v_current_feature_value = (__pyx_v_Xf[__pyx_v_p]);
1450:
-+1451: if current_feature_value < min_feature_value:
++1451: if current_feature_value < min_feature_value:
__pyx_t_6 = ((__pyx_v_current_feature_value < __pyx_v_min_feature_value) != 0); if (__pyx_t_6) { /* … */ goto __pyx_L16; } -
+1452: min_feature_value = current_feature_value
++1452: min_feature_value = current_feature_value
__pyx_v_min_feature_value = __pyx_v_current_feature_value; -
+1453: elif current_feature_value > max_feature_value:
++1453: elif current_feature_value > max_feature_value:
__pyx_t_6 = ((__pyx_v_current_feature_value > __pyx_v_max_feature_value) != 0); if (__pyx_t_6) { /* … */ } __pyx_L16:; } -
+1454: max_feature_value = current_feature_value
++1454: max_feature_value = current_feature_value
__pyx_v_max_feature_value = __pyx_v_current_feature_value;
1455:
-+1456: if max_feature_value <= min_feature_value + FEATURE_THRESHOLD:
++1456: if max_feature_value <= min_feature_value + FEATURE_THRESHOLD:
__pyx_t_6 = ((__pyx_v_max_feature_value <= (__pyx_v_min_feature_value + __pyx_v_13stpredictions_6models_3OK3_9_splitter_FEATURE_THRESHOLD)) != 0); if (__pyx_t_6) { /* … */ goto __pyx_L17; } -
+1457: features[f_j] = features[n_total_constants]
++1457: features[f_j] = features[n_total_constants]
(__pyx_v_features[__pyx_v_f_j]) = (__pyx_v_features[__pyx_v_n_total_constants]); -
+1458: features[n_total_constants] = current.feature
++1458: features[n_total_constants] = current.feature
__pyx_t_8 = __pyx_v_current.feature; (__pyx_v_features[__pyx_v_n_total_constants]) = __pyx_t_8;
1459:
-+1460: n_found_constants += 1
++1460: n_found_constants += 1
__pyx_v_n_found_constants = (__pyx_v_n_found_constants + 1); -
+1461: n_total_constants += 1
++1461: n_total_constants += 1
__pyx_v_n_total_constants = (__pyx_v_n_total_constants + 1);
1462:
- 1463: else:
-+1464: f_i -= 1
+1463: else:+
+1464: f_i -= 1
/*else*/ { __pyx_v_f_i = (__pyx_v_f_i - 1); -
+1465: features[f_i], features[f_j] = features[f_j], features[f_i]
++1465: features[f_i], features[f_j] = features[f_j], features[f_i]
__pyx_t_8 = (__pyx_v_features[__pyx_v_f_j]); __pyx_t_2 = (__pyx_v_features[__pyx_v_f_i]); (__pyx_v_features[__pyx_v_f_i]) = __pyx_t_8; (__pyx_v_features[__pyx_v_f_j]) = __pyx_t_2;
1466:
- 1467: # Draw a random threshold
-+1468: current.threshold = rand_uniform(min_feature_value,
+1467: # Draw a random threshold+
+1468: current.threshold = rand_uniform(min_feature_value,
__pyx_v_current.threshold = __pyx_f_7sklearn_4tree_6_utils_rand_uniform(__pyx_v_min_feature_value, __pyx_v_max_feature_value, __pyx_v_random_state); -
1469: max_feature_value,
- 1470: random_state)
+1469: max_feature_value,+
1470: random_state)
1471:
-+1472: if current.threshold == max_feature_value:
++1472: if current.threshold == max_feature_value:
__pyx_t_6 = ((__pyx_v_current.threshold == __pyx_v_max_feature_value) != 0); if (__pyx_t_6) { /* … */ } -
+1473: current.threshold = min_feature_value
++1473: current.threshold = min_feature_value
__pyx_v_current.threshold = __pyx_v_min_feature_value;
1474:
- 1475: # Partition
-+1476: current.pos = self._partition(current.threshold,
+1475: # Partition+
+1476: current.pos = self._partition(current.threshold,
__pyx_v_current.pos = __pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter__partition(((struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *)__pyx_v_self), __pyx_v_current.threshold, __pyx_v_end_negative, __pyx_v_start_positive, (__pyx_v_start_positive + ((__pyx_v_Xf[__pyx_v_start_positive]) == 0.))); -
1477: end_negative,
- 1478: start_positive,
- 1479: start_positive +
- 1480: (Xf[start_positive] == 0.))
+1477: end_negative,+
1478: start_positive,+
1479: start_positive ++
1480: (Xf[start_positive] == 0.))
1481:
- 1482: # Reject if min_samples_leaf is not guaranteed
-+1483: if (((current.pos - start) < min_samples_leaf) or
+1482: # Reject if min_samples_leaf is not guaranteed+
+1483: if (((current.pos - start) < min_samples_leaf) or
__pyx_t_7 = (((__pyx_v_current.pos - __pyx_v_start) < __pyx_v_min_samples_leaf) != 0); if (!__pyx_t_7) { } else { @@ -4458,21 +4532,21 @@ if (__pyx_t_6) { /* … */ } -
+1484: ((end - current.pos) < min_samples_leaf)):
++1484: ((end - current.pos) < min_samples_leaf)):
__pyx_t_7 = (((__pyx_v_end - __pyx_v_current.pos) < __pyx_v_min_samples_leaf) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L20_bool_binop_done:; -
+1485: continue
++1485: continue
goto __pyx_L3_continue;
1486:
- 1487: # Evaluate split
-+1488: self.criterion.reset()
+1487: # Evaluate split+
+1488: self.criterion.reset()
__pyx_t_10 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->reset(__pyx_v_self->__pyx_base.__pyx_base.criterion); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1488, __pyx_L1_error)
-
+1489: self.criterion.update(current.pos)
++1489: self.criterion.update(current.pos)
__pyx_t_10 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->update(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_current.pos); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1489, __pyx_L1_error)
1490:
- 1491: # Reject if min_weight_leaf is not satisfied
-+1492: if ((self.criterion.weighted_n_left < min_weight_leaf) or
+1491: # Reject if min_weight_leaf is not satisfied+
+1492: if ((self.criterion.weighted_n_left < min_weight_leaf) or
__pyx_t_7 = ((__pyx_v_self->__pyx_base.__pyx_base.criterion->weighted_n_left < __pyx_v_min_weight_leaf) != 0); if (!__pyx_t_7) { } else { @@ -4483,17 +4557,17 @@ if (__pyx_t_6) { /* … */ } -
+1493: (self.criterion.weighted_n_right < min_weight_leaf)):
++1493: (self.criterion.weighted_n_right < min_weight_leaf)):
__pyx_t_7 = ((__pyx_v_self->__pyx_base.__pyx_base.criterion->weighted_n_right < __pyx_v_min_weight_leaf) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L23_bool_binop_done:; -
+1494: continue
++1494: continue
goto __pyx_L3_continue;
1495:
-+1496: current_proxy_improvement = self.criterion.proxy_impurity_improvement()
++1496: current_proxy_improvement = self.criterion.proxy_impurity_improvement()
__pyx_v_current_proxy_improvement = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->proxy_impurity_improvement(__pyx_v_self->__pyx_base.__pyx_base.criterion);
1497:
-+1498: if current_proxy_improvement > best_proxy_improvement:
++1498: if current_proxy_improvement > best_proxy_improvement:
__pyx_t_6 = ((__pyx_v_current_proxy_improvement > __pyx_v_best_proxy_improvement) != 0); if (__pyx_t_6) { /* … */ @@ -4504,64 +4578,64 @@ __pyx_L8:; __pyx_L3_continue:; } -
+1499: best_proxy_improvement = current_proxy_improvement
++1499: best_proxy_improvement = current_proxy_improvement
__pyx_v_best_proxy_improvement = __pyx_v_current_proxy_improvement; -
+1500: current.improvement = self.criterion.impurity_improvement(impurity)
++1500: current.improvement = self.criterion.impurity_improvement(impurity)
__pyx_v_current.improvement = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->impurity_improvement(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_impurity);
1501:
-+1502: self.criterion.children_impurity(¤t.impurity_left,
++1502: self.criterion.children_impurity(¤t.impurity_left,
((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->children_impurity(__pyx_v_self->__pyx_base.__pyx_base.criterion, (&__pyx_v_current.impurity_left), (&__pyx_v_current.impurity_right)); -
1503: ¤t.impurity_right)
-+1504: best = current
+1503: ¤t.impurity_right)+
+1504: best = current
__pyx_v_best = __pyx_v_current;
1505:
- 1506: # Reorganize into samples[start:best.pos] + samples[best.pos:end]
-+1507: if best.pos < end:
+1506: # Reorganize into samples[start:best.pos] + samples[best.pos:end]+
+1507: if best.pos < end:
__pyx_t_6 = ((__pyx_v_best.pos < __pyx_v_end) != 0); if (__pyx_t_6) { /* … */ } -
+1508: if current.feature != best.feature:
++1508: if current.feature != best.feature:
__pyx_t_6 = ((__pyx_v_current.feature != __pyx_v_best.feature) != 0); if (__pyx_t_6) { /* … */ } -
+1509: self.extract_nnz(best.feature, &end_negative, &start_positive,
++1509: self.extract_nnz(best.feature, &end_negative, &start_positive,
__pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter_extract_nnz(((struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *)__pyx_v_self), __pyx_v_best.feature, (&__pyx_v_end_negative), (&__pyx_v_start_positive), (&__pyx_v_is_samples_sorted)); -
1510: &is_samples_sorted)
+1510: &is_samples_sorted)
1511:
-+1512: self._partition(best.threshold, end_negative, start_positive,
++1512: self._partition(best.threshold, end_negative, start_positive,
(void)(__pyx_f_13stpredictions_6models_3OK3_9_splitter_18BaseSparseSplitter__partition(((struct __pyx_obj_13stpredictions_6models_3OK3_9_splitter_BaseSparseSplitter *)__pyx_v_self), __pyx_v_best.threshold, __pyx_v_end_negative, __pyx_v_start_positive, __pyx_v_best.pos)); -
1513: best.pos)
+1513: best.pos)
1514:
-+1515: self.criterion.reset()
++1515: self.criterion.reset()
__pyx_t_10 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->reset(__pyx_v_self->__pyx_base.__pyx_base.criterion); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1515, __pyx_L1_error)
-
+1516: self.criterion.update(best.pos)
++1516: self.criterion.update(best.pos)
__pyx_t_10 = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->update(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_best.pos); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 1516, __pyx_L1_error)
-
+1517: best.improvement = self.criterion.impurity_improvement(impurity)
++1517: best.improvement = self.criterion.impurity_improvement(impurity)
__pyx_v_best.improvement = ((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->impurity_improvement(__pyx_v_self->__pyx_base.__pyx_base.criterion, __pyx_v_impurity); -
+1518: self.criterion.children_impurity(&best.impurity_left,
++1518: self.criterion.children_impurity(&best.impurity_left,
((struct __pyx_vtabstruct_13stpredictions_6models_3OK3_10_criterion_Criterion *)__pyx_v_self->__pyx_base.__pyx_base.criterion->__pyx_vtab)->children_impurity(__pyx_v_self->__pyx_base.__pyx_base.criterion, (&__pyx_v_best.impurity_left), (&__pyx_v_best.impurity_right)); -
1519: &best.impurity_right)
+1519: &best.impurity_right)
1520:
- 1521: # Respect invariant for constant features: the original order of
- 1522: # element in features[:n_known_constants] must be preserved for sibling
- 1523: # and child nodes
-+1524: memcpy(features, constant_features, sizeof(SIZE_t) * n_known_constants)
+1521: # Respect invariant for constant features: the original order of+
1522: # element in features[:n_known_constants] must be preserved for sibling+
1523: # and child nodes+
+1524: memcpy(features, constant_features, sizeof(SIZE_t) * n_known_constants)
(void)(memcpy(__pyx_v_features, __pyx_v_constant_features, ((sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t)) * __pyx_v_n_known_constants)));
1525:
- 1526: # Copy newly found constant features
-+1527: memcpy(constant_features + n_known_constants,
+1526: # Copy newly found constant features+
+1527: memcpy(constant_features + n_known_constants,
(void)(memcpy((__pyx_v_constant_features + __pyx_v_n_known_constants), (__pyx_v_features + __pyx_v_n_known_constants), ((sizeof(__pyx_t_7sklearn_4tree_5_tree_SIZE_t)) * __pyx_v_n_found_constants))); -
1528: features + n_known_constants,
- 1529: sizeof(SIZE_t) * n_found_constants)
+1528: features + n_known_constants,+
1529: sizeof(SIZE_t) * n_found_constants)
1530:
- 1531: # Return values
-+1532: split[0] = best
+1531: # Return values+
+1532: split[0] = best
(__pyx_v_split[0]) = __pyx_v_best; -
+1533: n_constant_features[0] = n_total_constants
++1533: n_constant_features[0] = n_total_constants
(__pyx_v_n_constant_features[0]) = __pyx_v_n_total_constants; -
+1534: return 0
++1534: return 0
__pyx_r = 0; goto __pyx_L0;