diff --git a/sklearn/tree/_tree.c b/sklearn/tree/_tree.c
index d3fe7ebec2f77846a97878da7f1120c08553efa5..d75be82230c7f8d09eeab371eee506b99c22fafa 100644
--- a/sklearn/tree/_tree.c
+++ b/sklearn/tree/_tree.c
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.15 on Fri Nov 11 19:32:17 2011 */
+/* Generated by Cython 0.15 on Sat Nov 12 10:51:20 2011 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
@@ -885,8 +885,8 @@ static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
 
 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
     const char *name, int exact); /*proto*/
-#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)
 #define __Pyx_BufPtrStrided2d(type, buf, i0, s0, i1, s1) (type)((char*)buf + i0 * s0 + i1 * s1)
+#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)
 
 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
 
@@ -1137,14 +1137,12 @@ static char __pyx_k__Zg[] = "Zg";
 static char __pyx_k__np[] = "np";
 static char __pyx_k__inf[] = "inf";
 static char __pyx_k__out[] = "out";
-static char __pyx_k__left[] = "left";
 static char __pyx_k__DTYPE[] = "DTYPE";
 static char __pyx_k__dtype[] = "dtype";
 static char __pyx_k__int32[] = "int32";
 static char __pyx_k__numpy[] = "numpy";
 static char __pyx_k__order[] = "order";
 static char __pyx_k__range[] = "range";
-static char __pyx_k__right[] = "right";
 static char __pyx_k__zeros[] = "zeros";
 static char __pyx_k__arange[] = "arange";
 static char __pyx_k__xrange[] = "xrange";
@@ -1152,6 +1150,7 @@ static char __pyx_k__feature[] = "feature";
 static char __pyx_k__float32[] = "float32";
 static char __pyx_k____main__[] = "__main__";
 static char __pyx_k____test__[] = "__test__";
+static char __pyx_k__children[] = "children";
 static char __pyx_k__criterion[] = "criterion";
 static char __pyx_k__n_classes[] = "n_classes";
 static char __pyx_k__n_samples[] = "n_samples";
@@ -1185,13 +1184,13 @@ static PyObject *__pyx_n_s___apply_tree;
 static PyObject *__pyx_n_s___error_at_leaf;
 static PyObject *__pyx_n_s___find_best_split;
 static PyObject *__pyx_n_s__arange;
+static PyObject *__pyx_n_s__children;
 static PyObject *__pyx_n_s__criterion;
 static PyObject *__pyx_n_s__dtype;
 static PyObject *__pyx_n_s__feature;
 static PyObject *__pyx_n_s__float32;
 static PyObject *__pyx_n_s__inf;
 static PyObject *__pyx_n_s__int32;
-static PyObject *__pyx_n_s__left;
 static PyObject *__pyx_n_s__max_features;
 static PyObject *__pyx_n_s__n_classes;
 static PyObject *__pyx_n_s__n_samples;
@@ -1202,7 +1201,6 @@ static PyObject *__pyx_n_s__out;
 static PyObject *__pyx_n_s__permutation;
 static PyObject *__pyx_n_s__random_state;
 static PyObject *__pyx_n_s__range;
-static PyObject *__pyx_n_s__right;
 static PyObject *__pyx_n_s__sample_mask;
 static PyObject *__pyx_n_s__threshold;
 static PyObject *__pyx_n_s__xrange;
@@ -2978,8 +2976,8 @@ static double __pyx_f_7sklearn_4tree_5_tree_3MSE_eval(struct __pyx_obj_7sklearn_
  * 
  * 
  * def _apply_tree(np.ndarray[DTYPE_t, ndim=2] X,             # <<<<<<<<<<<<<<
- *                 np.ndarray[np.int32_t, ndim=1] left,
- *                 np.ndarray[np.int32_t, ndim=1] right,
+ *                 np.ndarray[np.int32_t, ndim=2] children,
+ *                 np.ndarray[np.int32_t, ndim=1] feature,
  */
 
 static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
@@ -2987,17 +2985,13 @@ static char __pyx_doc_7sklearn_4tree_5_tree__apply_tree[] = "Finds the terminal
 static PyMethodDef __pyx_mdef_7sklearn_4tree_5_tree__apply_tree = {__Pyx_NAMESTR("_apply_tree"), (PyCFunction)__pyx_pf_7sklearn_4tree_5_tree__apply_tree, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_7sklearn_4tree_5_tree__apply_tree)};
 static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyArrayObject *__pyx_v_X = 0;
-  PyArrayObject *__pyx_v_left = 0;
-  PyArrayObject *__pyx_v_right = 0;
+  PyArrayObject *__pyx_v_children = 0;
   PyArrayObject *__pyx_v_feature = 0;
   PyArrayObject *__pyx_v_threshold = 0;
   PyArrayObject *__pyx_v_out = 0;
   int __pyx_v_i;
   int __pyx_v_n;
   int __pyx_v_node_id;
-  Py_buffer __pyx_bstruct_right;
-  Py_ssize_t __pyx_bstride_0_right = 0;
-  Py_ssize_t __pyx_bshape_0_right = 0;
   Py_buffer __pyx_bstruct_feature;
   Py_ssize_t __pyx_bstride_0_feature = 0;
   Py_ssize_t __pyx_bshape_0_feature = 0;
@@ -3009,9 +3003,11 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
   Py_ssize_t __pyx_bstride_1_X = 0;
   Py_ssize_t __pyx_bshape_0_X = 0;
   Py_ssize_t __pyx_bshape_1_X = 0;
-  Py_buffer __pyx_bstruct_left;
-  Py_ssize_t __pyx_bstride_0_left = 0;
-  Py_ssize_t __pyx_bshape_0_left = 0;
+  Py_buffer __pyx_bstruct_children;
+  Py_ssize_t __pyx_bstride_0_children = 0;
+  Py_ssize_t __pyx_bstride_1_children = 0;
+  Py_ssize_t __pyx_bshape_0_children = 0;
+  Py_ssize_t __pyx_bshape_1_children = 0;
   Py_buffer __pyx_bstruct_out;
   Py_ssize_t __pyx_bstride_0_out = 0;
   Py_ssize_t __pyx_bshape_0_out = 0;
@@ -3020,28 +3016,31 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
   int __pyx_t_1;
   int __pyx_t_2;
   int __pyx_t_3;
-  int __pyx_t_4;
+  long __pyx_t_4;
   int __pyx_t_5;
   int __pyx_t_6;
-  int __pyx_t_7;
+  long __pyx_t_7;
   int __pyx_t_8;
   int __pyx_t_9;
-  __pyx_t_5numpy_int32_t __pyx_t_10;
+  int __pyx_t_10;
   int __pyx_t_11;
-  int __pyx_t_12;
+  __pyx_t_5numpy_int32_t __pyx_t_12;
   int __pyx_t_13;
   int __pyx_t_14;
+  long __pyx_t_15;
+  int __pyx_t_16;
+  long __pyx_t_17;
+  int __pyx_t_18;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
-  static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__X,&__pyx_n_s__left,&__pyx_n_s__right,&__pyx_n_s__feature,&__pyx_n_s__threshold,&__pyx_n_s__out,0};
+  static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__X,&__pyx_n_s__children,&__pyx_n_s__feature,&__pyx_n_s__threshold,&__pyx_n_s__out,0};
   __Pyx_RefNannySetupContext("_apply_tree");
   __pyx_self = __pyx_self;
   if (unlikely(__pyx_kwds)) {
     Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
-    PyObject* values[6] = {0,0,0,0,0,0};
+    PyObject* values[5] = {0,0,0,0,0};
     switch (PyTuple_GET_SIZE(__pyx_args)) {
-      case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
       case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
       case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
       case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
@@ -3056,75 +3055,65 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
       if (likely(values[0])) kw_args--;
       else goto __pyx_L5_argtuple_error;
       case  1:
-      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__left);
+      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__children);
       if (likely(values[1])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 6, 6, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  2:
-      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__right);
+      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__feature);
       if (likely(values[2])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 6, 6, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  3:
-      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__feature);
+      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__threshold);
       if (likely(values[3])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 6, 6, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  4:
-      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__threshold);
+      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__out);
       if (likely(values[4])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 6, 6, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-      case  5:
-      values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__out);
-      if (likely(values[5])) kw_args--;
-      else {
-        __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 6, 6, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     }
     if (unlikely(kw_args > 0)) {
       if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "_apply_tree") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     }
     __pyx_v_X = ((PyArrayObject *)values[0]);
-    __pyx_v_left = ((PyArrayObject *)values[1]);
-    __pyx_v_right = ((PyArrayObject *)values[2]);
-    __pyx_v_feature = ((PyArrayObject *)values[3]);
-    __pyx_v_threshold = ((PyArrayObject *)values[4]);
-    __pyx_v_out = ((PyArrayObject *)values[5]);
-  } else if (PyTuple_GET_SIZE(__pyx_args) != 6) {
+    __pyx_v_children = ((PyArrayObject *)values[1]);
+    __pyx_v_feature = ((PyArrayObject *)values[2]);
+    __pyx_v_threshold = ((PyArrayObject *)values[3]);
+    __pyx_v_out = ((PyArrayObject *)values[4]);
+  } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
     goto __pyx_L5_argtuple_error;
   } else {
     __pyx_v_X = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 0));
-    __pyx_v_left = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
-    __pyx_v_right = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
-    __pyx_v_feature = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
-    __pyx_v_threshold = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
-    __pyx_v_out = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 5));
+    __pyx_v_children = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
+    __pyx_v_feature = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
+    __pyx_v_threshold = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
+    __pyx_v_out = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("_apply_tree", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("sklearn.tree._tree._apply_tree", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
   __pyx_bstruct_X.buf = NULL;
-  __pyx_bstruct_left.buf = NULL;
-  __pyx_bstruct_right.buf = NULL;
+  __pyx_bstruct_children.buf = NULL;
   __pyx_bstruct_feature.buf = NULL;
   __pyx_bstruct_threshold.buf = NULL;
   __pyx_bstruct_out.buf = NULL;
   if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_X), __pyx_ptype_5numpy_ndarray, 1, "X", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_left), __pyx_ptype_5numpy_ndarray, 1, "left", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_right), __pyx_ptype_5numpy_ndarray, 1, "right", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_feature), __pyx_ptype_5numpy_ndarray, 1, "feature", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_threshold), __pyx_ptype_5numpy_ndarray, 1, "threshold", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_out), __pyx_ptype_5numpy_ndarray, 1, "out", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_children), __pyx_ptype_5numpy_ndarray, 1, "children", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_feature), __pyx_ptype_5numpy_ndarray, 1, "feature", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_threshold), __pyx_ptype_5numpy_ndarray, 1, "threshold", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_out), __pyx_ptype_5numpy_ndarray, 1, "out", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
     if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_4tree_5_tree_DTYPE_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
@@ -3133,16 +3122,10 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
   __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1];
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_left, (PyObject*)__pyx_v_left, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_children, (PyObject*)__pyx_v_children, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
-  __pyx_bstride_0_left = __pyx_bstruct_left.strides[0];
-  __pyx_bshape_0_left = __pyx_bstruct_left.shape[0];
-  {
-    __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_right, (PyObject*)__pyx_v_right, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_bstride_0_right = __pyx_bstruct_right.strides[0];
-  __pyx_bshape_0_right = __pyx_bstruct_right.shape[0];
+  __pyx_bstride_0_children = __pyx_bstruct_children.strides[0]; __pyx_bstride_1_children = __pyx_bstruct_children.strides[1];
+  __pyx_bshape_0_children = __pyx_bstruct_children.shape[0]; __pyx_bshape_1_children = __pyx_bstruct_children.shape[1];
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
     if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_feature, (PyObject*)__pyx_v_feature, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
@@ -3162,7 +3145,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
   __pyx_bstride_0_out = __pyx_bstruct_out.strides[0];
   __pyx_bshape_0_out = __pyx_bstruct_out.shape[0];
 
-  /* "sklearn/tree/_tree.pyx":406
+  /* "sklearn/tree/_tree.pyx":405
  *     """Finds the terminal region (=leaf node) for each sample in
  *     `X` and sets the corresponding element in `out` to its node id."""
  *     cdef int i = 0             # <<<<<<<<<<<<<<
@@ -3171,7 +3154,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
  */
   __pyx_v_i = 0;
 
-  /* "sklearn/tree/_tree.pyx":407
+  /* "sklearn/tree/_tree.pyx":406
  *     `X` and sets the corresponding element in `out` to its node id."""
  *     cdef int i = 0
  *     cdef int n = X.shape[0]             # <<<<<<<<<<<<<<
@@ -3180,7 +3163,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
  */
   __pyx_v_n = (__pyx_v_X->dimensions[0]);
 
-  /* "sklearn/tree/_tree.pyx":408
+  /* "sklearn/tree/_tree.pyx":407
  *     cdef int i = 0
  *     cdef int n = X.shape[0]
  *     cdef int node_id = 0             # <<<<<<<<<<<<<<
@@ -3189,7 +3172,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
  */
   __pyx_v_node_id = 0;
 
-  /* "sklearn/tree/_tree.pyx":409
+  /* "sklearn/tree/_tree.pyx":408
  *     cdef int n = X.shape[0]
  *     cdef int node_id = 0
  *     for i in xrange(n):             # <<<<<<<<<<<<<<
@@ -3200,83 +3183,87 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
   for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
     __pyx_v_i = __pyx_t_2;
 
-    /* "sklearn/tree/_tree.pyx":410
+    /* "sklearn/tree/_tree.pyx":409
  *     cdef int node_id = 0
  *     for i in xrange(n):
  *         node_id = 0             # <<<<<<<<<<<<<<
  *         # While node_id not a leaf
- *         while left[node_id] != -1 and right[node_id] != -1:
+ *         while children[node_id, 0] != -1 and children[node_id, 1] != -1:
  */
     __pyx_v_node_id = 0;
 
-    /* "sklearn/tree/_tree.pyx":412
+    /* "sklearn/tree/_tree.pyx":411
  *         node_id = 0
  *         # While node_id not a leaf
- *         while left[node_id] != -1 and right[node_id] != -1:             # <<<<<<<<<<<<<<
+ *         while children[node_id, 0] != -1 and children[node_id, 1] != -1:             # <<<<<<<<<<<<<<
  *             if X[i, feature[node_id]] <= threshold[node_id]:
- *                 node_id = left[node_id]
+ *                 node_id = children[node_id, 0]
  */
     while (1) {
       __pyx_t_3 = __pyx_v_node_id;
-      __pyx_t_4 = ((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_left.buf, __pyx_t_3, __pyx_bstride_0_left)) != -1);
-      if (__pyx_t_4) {
-        __pyx_t_5 = __pyx_v_node_id;
-        __pyx_t_6 = ((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_right.buf, __pyx_t_5, __pyx_bstride_0_right)) != -1);
-        __pyx_t_7 = __pyx_t_6;
+      __pyx_t_4 = 0;
+      __pyx_t_5 = ((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_children.buf, __pyx_t_3, __pyx_bstride_0_children, __pyx_t_4, __pyx_bstride_1_children)) != -1);
+      if (__pyx_t_5) {
+        __pyx_t_6 = __pyx_v_node_id;
+        __pyx_t_7 = 1;
+        __pyx_t_8 = ((*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_children.buf, __pyx_t_6, __pyx_bstride_0_children, __pyx_t_7, __pyx_bstride_1_children)) != -1);
+        __pyx_t_9 = __pyx_t_8;
       } else {
-        __pyx_t_7 = __pyx_t_4;
+        __pyx_t_9 = __pyx_t_5;
       }
-      if (!__pyx_t_7) break;
+      if (!__pyx_t_9) break;
 
-      /* "sklearn/tree/_tree.pyx":413
+      /* "sklearn/tree/_tree.pyx":412
  *         # While node_id not a leaf
- *         while left[node_id] != -1 and right[node_id] != -1:
+ *         while children[node_id, 0] != -1 and children[node_id, 1] != -1:
  *             if X[i, feature[node_id]] <= threshold[node_id]:             # <<<<<<<<<<<<<<
- *                 node_id = left[node_id]
+ *                 node_id = children[node_id, 0]
  *             else:
  */
-      __pyx_t_8 = __pyx_v_node_id;
-      __pyx_t_9 = __pyx_v_i;
-      __pyx_t_10 = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_feature.buf, __pyx_t_8, __pyx_bstride_0_feature));
-      __pyx_t_11 = __pyx_v_node_id;
-      __pyx_t_7 = ((*__Pyx_BufPtrStrided2d(__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *, __pyx_bstruct_X.buf, __pyx_t_9, __pyx_bstride_0_X, __pyx_t_10, __pyx_bstride_1_X)) <= (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_threshold.buf, __pyx_t_11, __pyx_bstride_0_threshold)));
-      if (__pyx_t_7) {
+      __pyx_t_10 = __pyx_v_node_id;
+      __pyx_t_11 = __pyx_v_i;
+      __pyx_t_12 = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_feature.buf, __pyx_t_10, __pyx_bstride_0_feature));
+      __pyx_t_13 = __pyx_v_node_id;
+      __pyx_t_9 = ((*__Pyx_BufPtrStrided2d(__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *, __pyx_bstruct_X.buf, __pyx_t_11, __pyx_bstride_0_X, __pyx_t_12, __pyx_bstride_1_X)) <= (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_bstruct_threshold.buf, __pyx_t_13, __pyx_bstride_0_threshold)));
+      if (__pyx_t_9) {
 
-        /* "sklearn/tree/_tree.pyx":414
- *         while left[node_id] != -1 and right[node_id] != -1:
+        /* "sklearn/tree/_tree.pyx":413
+ *         while children[node_id, 0] != -1 and children[node_id, 1] != -1:
  *             if X[i, feature[node_id]] <= threshold[node_id]:
- *                 node_id = left[node_id]             # <<<<<<<<<<<<<<
+ *                 node_id = children[node_id, 0]             # <<<<<<<<<<<<<<
  *             else:
- *                 node_id = right[node_id]
+ *                 node_id = children[node_id, 1]
  */
-        __pyx_t_12 = __pyx_v_node_id;
-        __pyx_v_node_id = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_left.buf, __pyx_t_12, __pyx_bstride_0_left));
+        __pyx_t_14 = __pyx_v_node_id;
+        __pyx_t_15 = 0;
+        __pyx_v_node_id = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_children.buf, __pyx_t_14, __pyx_bstride_0_children, __pyx_t_15, __pyx_bstride_1_children));
         goto __pyx_L10;
       }
       /*else*/ {
 
-        /* "sklearn/tree/_tree.pyx":416
- *                 node_id = left[node_id]
+        /* "sklearn/tree/_tree.pyx":415
+ *                 node_id = children[node_id, 0]
  *             else:
- *                 node_id = right[node_id]             # <<<<<<<<<<<<<<
+ *                 node_id = children[node_id, 1]             # <<<<<<<<<<<<<<
  *         out[i] = node_id
  * 
  */
-        __pyx_t_13 = __pyx_v_node_id;
-        __pyx_v_node_id = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_right.buf, __pyx_t_13, __pyx_bstride_0_right));
+        __pyx_t_16 = __pyx_v_node_id;
+        __pyx_t_17 = 1;
+        __pyx_v_node_id = (*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_children.buf, __pyx_t_16, __pyx_bstride_0_children, __pyx_t_17, __pyx_bstride_1_children));
       }
       __pyx_L10:;
     }
 
-    /* "sklearn/tree/_tree.pyx":417
+    /* "sklearn/tree/_tree.pyx":416
  *             else:
- *                 node_id = right[node_id]
+ *                 node_id = children[node_id, 1]
  *         out[i] = node_id             # <<<<<<<<<<<<<<
  * 
  * 
  */
-    __pyx_t_14 = __pyx_v_i;
-    *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_out.buf, __pyx_t_14, __pyx_bstride_0_out) = __pyx_v_node_id;
+    __pyx_t_18 = __pyx_v_i;
+    *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_bstruct_out.buf, __pyx_t_18, __pyx_bstride_0_out) = __pyx_v_node_id;
   }
 
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
@@ -3284,22 +3271,20 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
   __pyx_L1_error:;
   { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
     __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
-    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_right);
     __Pyx_SafeReleaseBuffer(&__pyx_bstruct_feature);
     __Pyx_SafeReleaseBuffer(&__pyx_bstruct_threshold);
     __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X);
-    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_left);
+    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_children);
     __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out);
   __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
   __Pyx_AddTraceback("sklearn.tree._tree._apply_tree", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   goto __pyx_L2;
   __pyx_L0:;
-  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_right);
   __Pyx_SafeReleaseBuffer(&__pyx_bstruct_feature);
   __Pyx_SafeReleaseBuffer(&__pyx_bstruct_threshold);
   __Pyx_SafeReleaseBuffer(&__pyx_bstruct_X);
-  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_left);
+  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_children);
   __Pyx_SafeReleaseBuffer(&__pyx_bstruct_out);
   __pyx_L2:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -3307,7 +3292,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree__apply_tree(PyObject *__pyx_self
   return __pyx_r;
 }
 
-/* "sklearn/tree/_tree.pyx":420
+/* "sklearn/tree/_tree.pyx":419
  * 
  * 
  * def _error_at_leaf(np.ndarray[DTYPE_t, ndim=1, mode="c"] y,             # <<<<<<<<<<<<<<
@@ -3358,56 +3343,56 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_1_error_at_leaf(PyObject *__pyx_
       values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sample_mask);
       if (likely(values[1])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_error_at_leaf", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_error_at_leaf", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  2:
       values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__criterion);
       if (likely(values[2])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_error_at_leaf", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_error_at_leaf", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  3:
       values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__n_samples);
       if (likely(values[3])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_error_at_leaf", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_error_at_leaf", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     }
     if (unlikely(kw_args > 0)) {
-      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "_error_at_leaf") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "_error_at_leaf") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     }
     __pyx_v_y = ((PyArrayObject *)values[0]);
     __pyx_v_sample_mask = ((PyArrayObject *)values[1]);
     __pyx_v_criterion = ((struct __pyx_obj_7sklearn_4tree_5_tree_Criterion *)values[2]);
-    __pyx_v_n_samples = __Pyx_PyInt_AsInt(values[3]); if (unlikely((__pyx_v_n_samples == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_n_samples = __Pyx_PyInt_AsInt(values[3]); if (unlikely((__pyx_v_n_samples == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
     goto __pyx_L5_argtuple_error;
   } else {
     __pyx_v_y = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 0));
     __pyx_v_sample_mask = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
     __pyx_v_criterion = ((struct __pyx_obj_7sklearn_4tree_5_tree_Criterion *)PyTuple_GET_ITEM(__pyx_args, 2));
-    __pyx_v_n_samples = __Pyx_PyInt_AsInt(PyTuple_GET_ITEM(__pyx_args, 3)); if (unlikely((__pyx_v_n_samples == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_n_samples = __Pyx_PyInt_AsInt(PyTuple_GET_ITEM(__pyx_args, 3)); if (unlikely((__pyx_v_n_samples == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("_error_at_leaf", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("_error_at_leaf", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("sklearn.tree._tree._error_at_leaf", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
   __pyx_bstruct_y.buf = NULL;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), __pyx_ptype_5numpy_ndarray, 1, "y", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sample_mask), __pyx_ptype_5numpy_ndarray, 1, "sample_mask", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_criterion), __pyx_ptype_7sklearn_4tree_5_tree_Criterion, 1, "criterion", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), __pyx_ptype_5numpy_ndarray, 1, "y", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sample_mask), __pyx_ptype_5numpy_ndarray, 1, "sample_mask", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_criterion), __pyx_ptype_7sklearn_4tree_5_tree_Criterion, 1, "criterion", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_y, (PyObject*)__pyx_v_y, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_4tree_5_tree_DTYPE_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_y, (PyObject*)__pyx_v_y, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_4tree_5_tree_DTYPE_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_bstride_0_y = __pyx_bstruct_y.strides[0];
   __pyx_bshape_0_y = __pyx_bstruct_y.shape[0];
 
-  /* "sklearn/tree/_tree.pyx":425
+  /* "sklearn/tree/_tree.pyx":424
  *     """Compute criterion error at leaf with terminal region defined
  *     by `sample_mask`. """
  *     cdef int n_total_samples = y.shape[0]             # <<<<<<<<<<<<<<
@@ -3416,7 +3401,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_1_error_at_leaf(PyObject *__pyx_
  */
   __pyx_v_n_total_samples = (__pyx_v_y->dimensions[0]);
 
-  /* "sklearn/tree/_tree.pyx":426
+  /* "sklearn/tree/_tree.pyx":425
  *     by `sample_mask`. """
  *     cdef int n_total_samples = y.shape[0]
  *     cdef DTYPE_t *y_ptr = <DTYPE_t *>y.data             # <<<<<<<<<<<<<<
@@ -3425,7 +3410,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_1_error_at_leaf(PyObject *__pyx_
  */
   __pyx_v_y_ptr = ((__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *)__pyx_v_y->data);
 
-  /* "sklearn/tree/_tree.pyx":427
+  /* "sklearn/tree/_tree.pyx":426
  *     cdef int n_total_samples = y.shape[0]
  *     cdef DTYPE_t *y_ptr = <DTYPE_t *>y.data
  *     cdef BOOL_t *sample_mask_ptr = <BOOL_t *>sample_mask.data             # <<<<<<<<<<<<<<
@@ -3434,7 +3419,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_1_error_at_leaf(PyObject *__pyx_
  */
   __pyx_v_sample_mask_ptr = ((__pyx_t_7sklearn_4tree_5_tree_BOOL_t *)__pyx_v_sample_mask->data);
 
-  /* "sklearn/tree/_tree.pyx":428
+  /* "sklearn/tree/_tree.pyx":427
  *     cdef DTYPE_t *y_ptr = <DTYPE_t *>y.data
  *     cdef BOOL_t *sample_mask_ptr = <BOOL_t *>sample_mask.data
  *     criterion.init(y_ptr, sample_mask_ptr, n_samples, n_total_samples)             # <<<<<<<<<<<<<<
@@ -3443,7 +3428,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_1_error_at_leaf(PyObject *__pyx_
  */
   ((struct __pyx_vtabstruct_7sklearn_4tree_5_tree_Criterion *)__pyx_v_criterion->__pyx_vtab)->init(__pyx_v_criterion, __pyx_v_y_ptr, __pyx_v_sample_mask_ptr, __pyx_v_n_samples, __pyx_v_n_total_samples);
 
-  /* "sklearn/tree/_tree.pyx":429
+  /* "sklearn/tree/_tree.pyx":428
  *     cdef BOOL_t *sample_mask_ptr = <BOOL_t *>sample_mask.data
  *     criterion.init(y_ptr, sample_mask_ptr, n_samples, n_total_samples)
  *     return criterion.eval()             # <<<<<<<<<<<<<<
@@ -3451,7 +3436,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_1_error_at_leaf(PyObject *__pyx_
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyFloat_FromDouble(((struct __pyx_vtabstruct_7sklearn_4tree_5_tree_Criterion *)__pyx_v_criterion->__pyx_vtab)->eval(__pyx_v_criterion)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyFloat_FromDouble(((struct __pyx_vtabstruct_7sklearn_4tree_5_tree_Criterion *)__pyx_v_criterion->__pyx_vtab)->eval(__pyx_v_criterion)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
@@ -3476,7 +3461,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_1_error_at_leaf(PyObject *__pyx_
   return __pyx_r;
 }
 
-/* "sklearn/tree/_tree.pyx":434
+/* "sklearn/tree/_tree.pyx":433
  * 
  * 
  * cdef int smallest_sample_larger_than(int sample_idx, DTYPE_t *X_i,             # <<<<<<<<<<<<<<
@@ -3494,7 +3479,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
   int __pyx_t_2;
   __Pyx_RefNannySetupContext("smallest_sample_larger_than");
 
-  /* "sklearn/tree/_tree.pyx":451
+  /* "sklearn/tree/_tree.pyx":450
  *         -1 if no such element exists.
  *     """
  *     cdef int idx = 0, j             # <<<<<<<<<<<<<<
@@ -3503,7 +3488,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
  */
   __pyx_v_idx = 0;
 
-  /* "sklearn/tree/_tree.pyx":452
+  /* "sklearn/tree/_tree.pyx":451
  *     """
  *     cdef int idx = 0, j
  *     cdef DTYPE_t threshold = -DBL_MAX             # <<<<<<<<<<<<<<
@@ -3512,7 +3497,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
  */
   __pyx_v_threshold = (-DBL_MAX);
 
-  /* "sklearn/tree/_tree.pyx":454
+  /* "sklearn/tree/_tree.pyx":453
  *     cdef DTYPE_t threshold = -DBL_MAX
  * 
  *     if sample_idx > -1:             # <<<<<<<<<<<<<<
@@ -3522,7 +3507,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
   __pyx_t_1 = (__pyx_v_sample_idx > -1);
   if (__pyx_t_1) {
 
-    /* "sklearn/tree/_tree.pyx":455
+    /* "sklearn/tree/_tree.pyx":454
  * 
  *     if sample_idx > -1:
  *         threshold = X_i[X_argsorted_i[sample_idx]]             # <<<<<<<<<<<<<<
@@ -3534,7 +3519,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
   }
   __pyx_L3:;
 
-  /* "sklearn/tree/_tree.pyx":457
+  /* "sklearn/tree/_tree.pyx":456
  *         threshold = X_i[X_argsorted_i[sample_idx]]
  * 
  *     for idx from sample_idx < idx < n_total_samples:             # <<<<<<<<<<<<<<
@@ -3544,7 +3529,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
   __pyx_t_2 = __pyx_v_n_total_samples;
   for (__pyx_v_idx = __pyx_v_sample_idx+1; __pyx_v_idx < __pyx_t_2; __pyx_v_idx++) {
 
-    /* "sklearn/tree/_tree.pyx":458
+    /* "sklearn/tree/_tree.pyx":457
  * 
  *     for idx from sample_idx < idx < n_total_samples:
  *         j = X_argsorted_i[idx]             # <<<<<<<<<<<<<<
@@ -3553,7 +3538,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
  */
     __pyx_v_j = (__pyx_v_X_argsorted_i[__pyx_v_idx]);
 
-    /* "sklearn/tree/_tree.pyx":460
+    /* "sklearn/tree/_tree.pyx":459
  *         j = X_argsorted_i[idx]
  * 
  *         if sample_mask[j] == 0:             # <<<<<<<<<<<<<<
@@ -3563,7 +3548,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
     __pyx_t_1 = ((__pyx_v_sample_mask[__pyx_v_j]) == 0);
     if (__pyx_t_1) {
 
-      /* "sklearn/tree/_tree.pyx":461
+      /* "sklearn/tree/_tree.pyx":460
  * 
  *         if sample_mask[j] == 0:
  *             continue             # <<<<<<<<<<<<<<
@@ -3575,7 +3560,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
     }
     __pyx_L6:;
 
-    /* "sklearn/tree/_tree.pyx":463
+    /* "sklearn/tree/_tree.pyx":462
  *             continue
  * 
  *         if X_i[j] > threshold + 1.e-7:             # <<<<<<<<<<<<<<
@@ -3585,7 +3570,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
     __pyx_t_1 = ((__pyx_v_X_i[__pyx_v_j]) > (__pyx_v_threshold + 1.e-7));
     if (__pyx_t_1) {
 
-      /* "sklearn/tree/_tree.pyx":464
+      /* "sklearn/tree/_tree.pyx":463
  * 
  *         if X_i[j] > threshold + 1.e-7:
  *             return idx             # <<<<<<<<<<<<<<
@@ -3600,7 +3585,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
     __pyx_L4_continue:;
   }
 
-  /* "sklearn/tree/_tree.pyx":466
+  /* "sklearn/tree/_tree.pyx":465
  *             return idx
  * 
  *     return -1             # <<<<<<<<<<<<<<
@@ -3616,7 +3601,7 @@ static int __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(int __pyx_v
   return __pyx_r;
 }
 
-/* "sklearn/tree/_tree.pyx":469
+/* "sklearn/tree/_tree.pyx":468
  * 
  * 
  * def _find_best_split(np.ndarray[DTYPE_t, ndim=2, mode="fortran"] X,             # <<<<<<<<<<<<<<
@@ -3715,54 +3700,54 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
       values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__y);
       if (likely(values[1])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  2:
       values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__X_argsorted);
       if (likely(values[2])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  3:
       values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__sample_mask);
       if (likely(values[3])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  4:
       values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__n_samples);
       if (likely(values[4])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  5:
       values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__max_features);
       if (likely(values[5])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  6:
       values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__criterion);
       if (likely(values[6])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  7:
       values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__random_state);
       if (likely(values[7])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     }
     if (unlikely(kw_args > 0)) {
-      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "_find_best_split") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "_find_best_split") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     }
     __pyx_v_X = ((PyArrayObject *)values[0]);
     __pyx_v_y = ((PyArrayObject *)values[1]);
     __pyx_v_X_argsorted = ((PyArrayObject *)values[2]);
     __pyx_v_sample_mask = ((PyArrayObject *)values[3]);
-    __pyx_v_n_samples = __Pyx_PyInt_AsInt(values[4]); if (unlikely((__pyx_v_n_samples == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    __pyx_v_max_features = __Pyx_PyInt_AsInt(values[5]); if (unlikely((__pyx_v_max_features == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_n_samples = __Pyx_PyInt_AsInt(values[4]); if (unlikely((__pyx_v_n_samples == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_max_features = __Pyx_PyInt_AsInt(values[5]); if (unlikely((__pyx_v_max_features == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     __pyx_v_criterion = ((struct __pyx_obj_7sklearn_4tree_5_tree_Criterion *)values[6]);
     __pyx_v_random_state = values[7];
   } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
@@ -3772,14 +3757,14 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
     __pyx_v_y = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
     __pyx_v_X_argsorted = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
     __pyx_v_sample_mask = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
-    __pyx_v_n_samples = __Pyx_PyInt_AsInt(PyTuple_GET_ITEM(__pyx_args, 4)); if (unlikely((__pyx_v_n_samples == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    __pyx_v_max_features = __Pyx_PyInt_AsInt(PyTuple_GET_ITEM(__pyx_args, 5)); if (unlikely((__pyx_v_max_features == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_n_samples = __Pyx_PyInt_AsInt(PyTuple_GET_ITEM(__pyx_args, 4)); if (unlikely((__pyx_v_n_samples == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_max_features = __Pyx_PyInt_AsInt(PyTuple_GET_ITEM(__pyx_args, 5)); if (unlikely((__pyx_v_max_features == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     __pyx_v_criterion = ((struct __pyx_obj_7sklearn_4tree_5_tree_Criterion *)PyTuple_GET_ITEM(__pyx_args, 6));
     __pyx_v_random_state = PyTuple_GET_ITEM(__pyx_args, 7);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("_find_best_split", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("sklearn.tree._tree._find_best_split", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -3788,31 +3773,31 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
   __pyx_bstruct_X.buf = NULL;
   __pyx_bstruct_y.buf = NULL;
   __pyx_bstruct_X_argsorted.buf = NULL;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_X), __pyx_ptype_5numpy_ndarray, 1, "X", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), __pyx_ptype_5numpy_ndarray, 1, "y", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_X_argsorted), __pyx_ptype_5numpy_ndarray, 1, "X_argsorted", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sample_mask), __pyx_ptype_5numpy_ndarray, 1, "sample_mask", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_criterion), __pyx_ptype_7sklearn_4tree_5_tree_Criterion, 1, "criterion", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_X), __pyx_ptype_5numpy_ndarray, 1, "X", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_y), __pyx_ptype_5numpy_ndarray, 1, "y", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_X_argsorted), __pyx_ptype_5numpy_ndarray, 1, "X_argsorted", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_sample_mask), __pyx_ptype_5numpy_ndarray, 1, "sample_mask", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_criterion), __pyx_ptype_7sklearn_4tree_5_tree_Criterion, 1, "criterion", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_4tree_5_tree_DTYPE_t, PyBUF_FORMAT| PyBUF_F_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X, (PyObject*)__pyx_v_X, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_4tree_5_tree_DTYPE_t, PyBUF_FORMAT| PyBUF_F_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_bstride_0_X = __pyx_bstruct_X.strides[0]; __pyx_bstride_1_X = __pyx_bstruct_X.strides[1];
   __pyx_bshape_0_X = __pyx_bstruct_X.shape[0]; __pyx_bshape_1_X = __pyx_bstruct_X.shape[1];
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_y, (PyObject*)__pyx_v_y, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_4tree_5_tree_DTYPE_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_y, (PyObject*)__pyx_v_y, &__Pyx_TypeInfo_nn___pyx_t_7sklearn_4tree_5_tree_DTYPE_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_bstride_0_y = __pyx_bstruct_y.strides[0];
   __pyx_bshape_0_y = __pyx_bstruct_y.shape[0];
   {
     __Pyx_BufFmt_StackElem __pyx_stack[1];
-    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X_argsorted, (PyObject*)__pyx_v_X_argsorted, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_F_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_bstruct_X_argsorted, (PyObject*)__pyx_v_X_argsorted, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_F_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
   __pyx_bstride_0_X_argsorted = __pyx_bstruct_X_argsorted.strides[0]; __pyx_bstride_1_X_argsorted = __pyx_bstruct_X_argsorted.strides[1];
   __pyx_bshape_0_X_argsorted = __pyx_bstruct_X_argsorted.shape[0]; __pyx_bshape_1_X_argsorted = __pyx_bstruct_X_argsorted.shape[1];
 
-  /* "sklearn/tree/_tree.pyx":523
+  /* "sklearn/tree/_tree.pyx":522
  *     """
  *     # Variables declarations
  *     cdef int n_total_samples = X.shape[0]             # <<<<<<<<<<<<<<
@@ -3821,7 +3806,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_n_total_samples = (__pyx_v_X->dimensions[0]);
 
-  /* "sklearn/tree/_tree.pyx":524
+  /* "sklearn/tree/_tree.pyx":523
  *     # Variables declarations
  *     cdef int n_total_samples = X.shape[0]
  *     cdef int n_features = X.shape[1]             # <<<<<<<<<<<<<<
@@ -3830,7 +3815,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_n_features = (__pyx_v_X->dimensions[1]);
 
-  /* "sklearn/tree/_tree.pyx":525
+  /* "sklearn/tree/_tree.pyx":524
  *     cdef int n_total_samples = X.shape[0]
  *     cdef int n_features = X.shape[1]
  *     cdef int i, a, b, best_i = -1             # <<<<<<<<<<<<<<
@@ -3839,31 +3824,31 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_best_i = -1;
 
-  /* "sklearn/tree/_tree.pyx":527
+  /* "sklearn/tree/_tree.pyx":526
  *     cdef int i, a, b, best_i = -1
  *     cdef DTYPE_t t, initial_error, error
  *     cdef DTYPE_t best_error = np.inf, best_t = np.inf             # <<<<<<<<<<<<<<
  *     cdef DTYPE_t *y_ptr = <DTYPE_t *>y.data
  *     cdef DTYPE_t *X_i = NULL
  */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 527; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__inf); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 527; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__inf); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_3 == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 527; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_3 == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_v_best_error = __pyx_t_3;
-  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 527; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__inf); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 527; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__inf); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_3 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_3 == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 527; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_3 == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 526; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_best_t = __pyx_t_3;
 
-  /* "sklearn/tree/_tree.pyx":528
+  /* "sklearn/tree/_tree.pyx":527
  *     cdef DTYPE_t t, initial_error, error
  *     cdef DTYPE_t best_error = np.inf, best_t = np.inf
  *     cdef DTYPE_t *y_ptr = <DTYPE_t *>y.data             # <<<<<<<<<<<<<<
@@ -3872,7 +3857,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_y_ptr = ((__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *)__pyx_v_y->data);
 
-  /* "sklearn/tree/_tree.pyx":529
+  /* "sklearn/tree/_tree.pyx":528
  *     cdef DTYPE_t best_error = np.inf, best_t = np.inf
  *     cdef DTYPE_t *y_ptr = <DTYPE_t *>y.data
  *     cdef DTYPE_t *X_i = NULL             # <<<<<<<<<<<<<<
@@ -3881,7 +3866,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_X_i = NULL;
 
-  /* "sklearn/tree/_tree.pyx":530
+  /* "sklearn/tree/_tree.pyx":529
  *     cdef DTYPE_t *y_ptr = <DTYPE_t *>y.data
  *     cdef DTYPE_t *X_i = NULL
  *     cdef int *X_argsorted_i = NULL             # <<<<<<<<<<<<<<
@@ -3890,7 +3875,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_X_argsorted_i = NULL;
 
-  /* "sklearn/tree/_tree.pyx":531
+  /* "sklearn/tree/_tree.pyx":530
  *     cdef DTYPE_t *X_i = NULL
  *     cdef int *X_argsorted_i = NULL
  *     cdef BOOL_t *sample_mask_ptr = <BOOL_t *>sample_mask.data             # <<<<<<<<<<<<<<
@@ -3899,7 +3884,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_sample_mask_ptr = ((__pyx_t_7sklearn_4tree_5_tree_BOOL_t *)__pyx_v_sample_mask->data);
 
-  /* "sklearn/tree/_tree.pyx":535
+  /* "sklearn/tree/_tree.pyx":534
  *     # Compute the column strides (increment in pointer elements to get
  *     # from column i to i + 1) for `X` and `X_argsorted`
  *     cdef int X_elem_stride = X.strides[0]             # <<<<<<<<<<<<<<
@@ -3908,7 +3893,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_X_elem_stride = (__pyx_v_X->strides[0]);
 
-  /* "sklearn/tree/_tree.pyx":536
+  /* "sklearn/tree/_tree.pyx":535
  *     # from column i to i + 1) for `X` and `X_argsorted`
  *     cdef int X_elem_stride = X.strides[0]
  *     cdef int X_col_stride = X.strides[1]             # <<<<<<<<<<<<<<
@@ -3917,7 +3902,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_X_col_stride = (__pyx_v_X->strides[1]);
 
-  /* "sklearn/tree/_tree.pyx":537
+  /* "sklearn/tree/_tree.pyx":536
  *     cdef int X_elem_stride = X.strides[0]
  *     cdef int X_col_stride = X.strides[1]
  *     cdef int X_stride = X_col_stride / X_elem_stride             # <<<<<<<<<<<<<<
@@ -3926,7 +3911,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_X_stride = (__pyx_v_X_col_stride / __pyx_v_X_elem_stride);
 
-  /* "sklearn/tree/_tree.pyx":538
+  /* "sklearn/tree/_tree.pyx":537
  *     cdef int X_col_stride = X.strides[1]
  *     cdef int X_stride = X_col_stride / X_elem_stride
  *     cdef int X_argsorted_elem_stride = X_argsorted.strides[0]             # <<<<<<<<<<<<<<
@@ -3935,7 +3920,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_X_argsorted_elem_stride = (__pyx_v_X_argsorted->strides[0]);
 
-  /* "sklearn/tree/_tree.pyx":539
+  /* "sklearn/tree/_tree.pyx":538
  *     cdef int X_stride = X_col_stride / X_elem_stride
  *     cdef int X_argsorted_elem_stride = X_argsorted.strides[0]
  *     cdef int X_argsorted_col_stride = X_argsorted.strides[1]             # <<<<<<<<<<<<<<
@@ -3944,7 +3929,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_X_argsorted_col_stride = (__pyx_v_X_argsorted->strides[1]);
 
-  /* "sklearn/tree/_tree.pyx":540
+  /* "sklearn/tree/_tree.pyx":539
  *     cdef int X_argsorted_elem_stride = X_argsorted.strides[0]
  *     cdef int X_argsorted_col_stride = X_argsorted.strides[1]
  *     cdef int X_argsorted_stride = X_argsorted_col_stride / X_argsorted_elem_stride             # <<<<<<<<<<<<<<
@@ -3953,7 +3938,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_X_argsorted_stride = (__pyx_v_X_argsorted_col_stride / __pyx_v_X_argsorted_elem_stride);
 
-  /* "sklearn/tree/_tree.pyx":543
+  /* "sklearn/tree/_tree.pyx":542
  * 
  *     # Compute the initial criterion value in the node
  *     X_argsorted_i = <int *>X_argsorted.data             # <<<<<<<<<<<<<<
@@ -3962,7 +3947,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_X_argsorted_i = ((int *)__pyx_v_X_argsorted->data);
 
-  /* "sklearn/tree/_tree.pyx":544
+  /* "sklearn/tree/_tree.pyx":543
  *     # Compute the initial criterion value in the node
  *     X_argsorted_i = <int *>X_argsorted.data
  *     criterion.init(y_ptr, sample_mask_ptr, n_samples, n_total_samples)             # <<<<<<<<<<<<<<
@@ -3971,7 +3956,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   ((struct __pyx_vtabstruct_7sklearn_4tree_5_tree_Criterion *)__pyx_v_criterion->__pyx_vtab)->init(__pyx_v_criterion, __pyx_v_y_ptr, __pyx_v_sample_mask_ptr, __pyx_v_n_samples, __pyx_v_n_total_samples);
 
-  /* "sklearn/tree/_tree.pyx":545
+  /* "sklearn/tree/_tree.pyx":544
  *     X_argsorted_i = <int *>X_argsorted.data
  *     criterion.init(y_ptr, sample_mask_ptr, n_samples, n_total_samples)
  *     initial_error = criterion.eval()             # <<<<<<<<<<<<<<
@@ -3980,7 +3965,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_initial_error = ((struct __pyx_vtabstruct_7sklearn_4tree_5_tree_Criterion *)__pyx_v_criterion->__pyx_vtab)->eval(__pyx_v_criterion);
 
-  /* "sklearn/tree/_tree.pyx":547
+  /* "sklearn/tree/_tree.pyx":546
  *     initial_error = criterion.eval()
  * 
  *     if initial_error == 0:  # break early if the node is pure             # <<<<<<<<<<<<<<
@@ -3990,7 +3975,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
   __pyx_t_4 = (__pyx_v_initial_error == 0.0);
   if (__pyx_t_4) {
 
-    /* "sklearn/tree/_tree.pyx":548
+    /* "sklearn/tree/_tree.pyx":547
  * 
  *     if initial_error == 0:  # break early if the node is pure
  *         return best_i, best_t, initial_error, initial_error             # <<<<<<<<<<<<<<
@@ -3998,15 +3983,15 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  *     best_error = initial_error
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_1 = PyInt_FromLong(__pyx_v_best_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = PyInt_FromLong(__pyx_v_best_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyFloat_FromDouble(__pyx_v_best_t); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_2 = PyFloat_FromDouble(__pyx_v_best_t); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_5 = PyFloat_FromDouble(__pyx_v_initial_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyFloat_FromDouble(__pyx_v_initial_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = PyFloat_FromDouble(__pyx_v_initial_error); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyFloat_FromDouble(__pyx_v_initial_error); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_7 = PyTuple_New(4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyTuple_New(4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 547; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_7));
     PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
     __Pyx_GIVEREF(__pyx_t_1);
@@ -4027,7 +4012,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
   }
   __pyx_L6:;
 
-  /* "sklearn/tree/_tree.pyx":550
+  /* "sklearn/tree/_tree.pyx":549
  *         return best_i, best_t, initial_error, initial_error
  * 
  *     best_error = initial_error             # <<<<<<<<<<<<<<
@@ -4036,7 +4021,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
   __pyx_v_best_error = __pyx_v_initial_error;
 
-  /* "sklearn/tree/_tree.pyx":553
+  /* "sklearn/tree/_tree.pyx":552
  * 
  *     # Features to consider
  *     if max_features < 0 or max_features == n_features:             # <<<<<<<<<<<<<<
@@ -4052,26 +4037,26 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
   }
   if (__pyx_t_9) {
 
-    /* "sklearn/tree/_tree.pyx":554
+    /* "sklearn/tree/_tree.pyx":553
  *     # Features to consider
  *     if max_features < 0 or max_features == n_features:
  *         features = np.arange(n_features)             # <<<<<<<<<<<<<<
  *     else:
  *         features = random_state.permutation(n_features)[:max_features]
  */
-    __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_6 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__arange); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__arange); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-    __pyx_t_7 = PyInt_FromLong(__pyx_v_n_features); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyInt_FromLong(__pyx_v_n_features); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_5));
     PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
     __Pyx_GIVEREF(__pyx_t_7);
     __pyx_t_7 = 0;
-    __pyx_t_7 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_5), NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_5)); __pyx_t_5 = 0;
@@ -4081,27 +4066,27 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
   }
   /*else*/ {
 
-    /* "sklearn/tree/_tree.pyx":556
+    /* "sklearn/tree/_tree.pyx":555
  *         features = np.arange(n_features)
  *     else:
  *         features = random_state.permutation(n_features)[:max_features]             # <<<<<<<<<<<<<<
  * 
  *     # Look for the best split
  */
-    __pyx_t_7 = PyObject_GetAttr(__pyx_v_random_state, __pyx_n_s__permutation); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = PyObject_GetAttr(__pyx_v_random_state, __pyx_n_s__permutation); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_7);
-    __pyx_t_5 = PyInt_FromLong(__pyx_v_n_features); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyInt_FromLong(__pyx_v_n_features); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(((PyObject *)__pyx_t_6));
     PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
     __Pyx_GIVEREF(__pyx_t_5);
     __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_5 = PyObject_Call(__pyx_t_7, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-    __pyx_t_6 = __Pyx_PySequence_GetSlice(__pyx_t_5, 0, __pyx_v_max_features); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_6 = __Pyx_PySequence_GetSlice(__pyx_t_5, 0, __pyx_v_max_features); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_v_features = __pyx_t_6;
@@ -4109,7 +4094,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
   }
   __pyx_L7:;
 
-  /* "sklearn/tree/_tree.pyx":559
+  /* "sklearn/tree/_tree.pyx":558
  * 
  *     # Look for the best split
  *     for i in features:             # <<<<<<<<<<<<<<
@@ -4120,7 +4105,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
     __pyx_t_6 = __pyx_v_features; __Pyx_INCREF(__pyx_t_6); __pyx_t_10 = 0;
     __pyx_t_11 = NULL;
   } else {
-    __pyx_t_10 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_v_features); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 559; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_10 = -1; __pyx_t_6 = PyObject_GetIter(__pyx_v_features); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_6);
     __pyx_t_11 = Py_TYPE(__pyx_t_6)->tp_iternext;
   }
@@ -4136,17 +4121,17 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
       if (unlikely(!__pyx_t_5)) {
         if (PyErr_Occurred()) {
           if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 559; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
         }
         break;
       }
       __Pyx_GOTREF(__pyx_t_5);
     }
-    __pyx_t_12 = __Pyx_PyInt_AsInt(__pyx_t_5); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 559; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_12 = __Pyx_PyInt_AsInt(__pyx_t_5); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
     __pyx_v_i = __pyx_t_12;
 
-    /* "sklearn/tree/_tree.pyx":561
+    /* "sklearn/tree/_tree.pyx":560
  *     for i in features:
  *         # Get i-th col of X and X_sorted
  *         X_i = (<DTYPE_t *>X.data) + X_stride * i             # <<<<<<<<<<<<<<
@@ -4155,7 +4140,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
     __pyx_v_X_i = (((__pyx_t_7sklearn_4tree_5_tree_DTYPE_t *)__pyx_v_X->data) + (__pyx_v_X_stride * __pyx_v_i));
 
-    /* "sklearn/tree/_tree.pyx":562
+    /* "sklearn/tree/_tree.pyx":561
  *         # Get i-th col of X and X_sorted
  *         X_i = (<DTYPE_t *>X.data) + X_stride * i
  *         X_argsorted_i = (<int *>X_argsorted.data) + X_argsorted_stride * i             # <<<<<<<<<<<<<<
@@ -4164,7 +4149,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
     __pyx_v_X_argsorted_i = (((int *)__pyx_v_X_argsorted->data) + (__pyx_v_X_argsorted_stride * __pyx_v_i));
 
-    /* "sklearn/tree/_tree.pyx":565
+    /* "sklearn/tree/_tree.pyx":564
  * 
  *         # Reset the criterion for this feature
  *         criterion.reset()             # <<<<<<<<<<<<<<
@@ -4173,7 +4158,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
     ((struct __pyx_vtabstruct_7sklearn_4tree_5_tree_Criterion *)__pyx_v_criterion->__pyx_vtab)->reset(__pyx_v_criterion);
 
-    /* "sklearn/tree/_tree.pyx":568
+    /* "sklearn/tree/_tree.pyx":567
  * 
  *         # Index of smallest sample in X_argsorted_i that is in the sample mask
  *         a = 0             # <<<<<<<<<<<<<<
@@ -4182,7 +4167,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
     __pyx_v_a = 0;
 
-    /* "sklearn/tree/_tree.pyx":569
+    /* "sklearn/tree/_tree.pyx":568
  *         # Index of smallest sample in X_argsorted_i that is in the sample mask
  *         a = 0
  *         while sample_mask_ptr[X_argsorted_i[a]] == 0:             # <<<<<<<<<<<<<<
@@ -4193,7 +4178,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
       __pyx_t_9 = ((__pyx_v_sample_mask_ptr[(__pyx_v_X_argsorted_i[__pyx_v_a])]) == 0);
       if (!__pyx_t_9) break;
 
-      /* "sklearn/tree/_tree.pyx":570
+      /* "sklearn/tree/_tree.pyx":569
  *         a = 0
  *         while sample_mask_ptr[X_argsorted_i[a]] == 0:
  *             a = a + 1             # <<<<<<<<<<<<<<
@@ -4203,7 +4188,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
       __pyx_v_a = (__pyx_v_a + 1);
     }
 
-    /* "sklearn/tree/_tree.pyx":573
+    /* "sklearn/tree/_tree.pyx":572
  * 
  *         # Consider splits between two consecutive samples
  *         while True:             # <<<<<<<<<<<<<<
@@ -4213,7 +4198,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
     while (1) {
       if (!1) break;
 
-      /* "sklearn/tree/_tree.pyx":576
+      /* "sklearn/tree/_tree.pyx":575
  *             # Find the following larger sample
  *             b = smallest_sample_larger_than(a, X_i, X_argsorted_i,
  *                                             sample_mask_ptr, n_total_samples)             # <<<<<<<<<<<<<<
@@ -4222,7 +4207,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
       __pyx_v_b = __pyx_f_7sklearn_4tree_5_tree_smallest_sample_larger_than(__pyx_v_a, __pyx_v_X_i, __pyx_v_X_argsorted_i, __pyx_v_sample_mask_ptr, __pyx_v_n_total_samples);
 
-      /* "sklearn/tree/_tree.pyx":577
+      /* "sklearn/tree/_tree.pyx":576
  *             b = smallest_sample_larger_than(a, X_i, X_argsorted_i,
  *                                             sample_mask_ptr, n_total_samples)
  *             if b == -1:             # <<<<<<<<<<<<<<
@@ -4232,7 +4217,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
       __pyx_t_9 = (__pyx_v_b == -1);
       if (__pyx_t_9) {
 
-        /* "sklearn/tree/_tree.pyx":578
+        /* "sklearn/tree/_tree.pyx":577
  *                                             sample_mask_ptr, n_total_samples)
  *             if b == -1:
  *                 break             # <<<<<<<<<<<<<<
@@ -4244,7 +4229,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
       }
       __pyx_L14:;
 
-      /* "sklearn/tree/_tree.pyx":581
+      /* "sklearn/tree/_tree.pyx":580
  * 
  *             # Better split than the best so far?
  *             criterion.update(a, b, y_ptr, X_argsorted_i, sample_mask_ptr)             # <<<<<<<<<<<<<<
@@ -4253,7 +4238,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
       ((struct __pyx_vtabstruct_7sklearn_4tree_5_tree_Criterion *)__pyx_v_criterion->__pyx_vtab)->update(__pyx_v_criterion, __pyx_v_a, __pyx_v_b, __pyx_v_y_ptr, __pyx_v_X_argsorted_i, __pyx_v_sample_mask_ptr);
 
-      /* "sklearn/tree/_tree.pyx":582
+      /* "sklearn/tree/_tree.pyx":581
  *             # Better split than the best so far?
  *             criterion.update(a, b, y_ptr, X_argsorted_i, sample_mask_ptr)
  *             error = criterion.eval()             # <<<<<<<<<<<<<<
@@ -4262,7 +4247,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
       __pyx_v_error = ((struct __pyx_vtabstruct_7sklearn_4tree_5_tree_Criterion *)__pyx_v_criterion->__pyx_vtab)->eval(__pyx_v_criterion);
 
-      /* "sklearn/tree/_tree.pyx":584
+      /* "sklearn/tree/_tree.pyx":583
  *             error = criterion.eval()
  * 
  *             if error < best_error:             # <<<<<<<<<<<<<<
@@ -4272,7 +4257,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
       __pyx_t_9 = (__pyx_v_error < __pyx_v_best_error);
       if (__pyx_t_9) {
 
-        /* "sklearn/tree/_tree.pyx":586
+        /* "sklearn/tree/_tree.pyx":585
  *             if error < best_error:
  *                 t = X_i[X_argsorted_i[a]] + \
  *                     ((X_i[X_argsorted_i[b]] - X_i[X_argsorted_i[a]]) / 2.0)             # <<<<<<<<<<<<<<
@@ -4281,7 +4266,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
         __pyx_v_t = ((__pyx_v_X_i[(__pyx_v_X_argsorted_i[__pyx_v_a])]) + (((__pyx_v_X_i[(__pyx_v_X_argsorted_i[__pyx_v_b])]) - (__pyx_v_X_i[(__pyx_v_X_argsorted_i[__pyx_v_a])])) / 2.0));
 
-        /* "sklearn/tree/_tree.pyx":587
+        /* "sklearn/tree/_tree.pyx":586
  *                 t = X_i[X_argsorted_i[a]] + \
  *                     ((X_i[X_argsorted_i[b]] - X_i[X_argsorted_i[a]]) / 2.0)
  *                 if t == X_i[X_argsorted_i[b]]:             # <<<<<<<<<<<<<<
@@ -4291,7 +4276,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
         __pyx_t_9 = (__pyx_v_t == (__pyx_v_X_i[(__pyx_v_X_argsorted_i[__pyx_v_b])]));
         if (__pyx_t_9) {
 
-          /* "sklearn/tree/_tree.pyx":588
+          /* "sklearn/tree/_tree.pyx":587
  *                     ((X_i[X_argsorted_i[b]] - X_i[X_argsorted_i[a]]) / 2.0)
  *                 if t == X_i[X_argsorted_i[b]]:
  *                     t = X_i[X_argsorted_i[a]]             # <<<<<<<<<<<<<<
@@ -4303,7 +4288,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
         }
         __pyx_L16:;
 
-        /* "sklearn/tree/_tree.pyx":589
+        /* "sklearn/tree/_tree.pyx":588
  *                 if t == X_i[X_argsorted_i[b]]:
  *                     t = X_i[X_argsorted_i[a]]
  *                 best_i = i             # <<<<<<<<<<<<<<
@@ -4312,7 +4297,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
         __pyx_v_best_i = __pyx_v_i;
 
-        /* "sklearn/tree/_tree.pyx":590
+        /* "sklearn/tree/_tree.pyx":589
  *                     t = X_i[X_argsorted_i[a]]
  *                 best_i = i
  *                 best_t = t             # <<<<<<<<<<<<<<
@@ -4321,7 +4306,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
  */
         __pyx_v_best_t = __pyx_v_t;
 
-        /* "sklearn/tree/_tree.pyx":591
+        /* "sklearn/tree/_tree.pyx":590
  *                 best_i = i
  *                 best_t = t
  *                 best_error = error             # <<<<<<<<<<<<<<
@@ -4333,7 +4318,7 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
       }
       __pyx_L15:;
 
-      /* "sklearn/tree/_tree.pyx":594
+      /* "sklearn/tree/_tree.pyx":593
  * 
  *             # Proceed to the next interval
  *             a = b             # <<<<<<<<<<<<<<
@@ -4346,21 +4331,21 @@ static PyObject *__pyx_pf_7sklearn_4tree_5_tree_2_find_best_split(PyObject *__py
   }
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-  /* "sklearn/tree/_tree.pyx":596
+  /* "sklearn/tree/_tree.pyx":595
  *             a = b
  * 
  *     return best_i, best_t, best_error, initial_error             # <<<<<<<<<<<<<<
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_6 = PyInt_FromLong(__pyx_v_best_i); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_6 = PyInt_FromLong(__pyx_v_best_i); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_5 = PyFloat_FromDouble(__pyx_v_best_t); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_5 = PyFloat_FromDouble(__pyx_v_best_t); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_7 = PyFloat_FromDouble(__pyx_v_best_error); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = PyFloat_FromDouble(__pyx_v_best_error); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_2 = PyFloat_FromDouble(__pyx_v_initial_error); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyFloat_FromDouble(__pyx_v_initial_error); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(((PyObject *)__pyx_t_1));
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6);
   __Pyx_GIVEREF(__pyx_t_6);
@@ -7439,13 +7424,13 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s___error_at_leaf, __pyx_k___error_at_leaf, sizeof(__pyx_k___error_at_leaf), 0, 0, 1, 1},
   {&__pyx_n_s___find_best_split, __pyx_k___find_best_split, sizeof(__pyx_k___find_best_split), 0, 0, 1, 1},
   {&__pyx_n_s__arange, __pyx_k__arange, sizeof(__pyx_k__arange), 0, 0, 1, 1},
+  {&__pyx_n_s__children, __pyx_k__children, sizeof(__pyx_k__children), 0, 0, 1, 1},
   {&__pyx_n_s__criterion, __pyx_k__criterion, sizeof(__pyx_k__criterion), 0, 0, 1, 1},
   {&__pyx_n_s__dtype, __pyx_k__dtype, sizeof(__pyx_k__dtype), 0, 0, 1, 1},
   {&__pyx_n_s__feature, __pyx_k__feature, sizeof(__pyx_k__feature), 0, 0, 1, 1},
   {&__pyx_n_s__float32, __pyx_k__float32, sizeof(__pyx_k__float32), 0, 0, 1, 1},
   {&__pyx_n_s__inf, __pyx_k__inf, sizeof(__pyx_k__inf), 0, 0, 1, 1},
   {&__pyx_n_s__int32, __pyx_k__int32, sizeof(__pyx_k__int32), 0, 0, 1, 1},
-  {&__pyx_n_s__left, __pyx_k__left, sizeof(__pyx_k__left), 0, 0, 1, 1},
   {&__pyx_n_s__max_features, __pyx_k__max_features, sizeof(__pyx_k__max_features), 0, 0, 1, 1},
   {&__pyx_n_s__n_classes, __pyx_k__n_classes, sizeof(__pyx_k__n_classes), 0, 0, 1, 1},
   {&__pyx_n_s__n_samples, __pyx_k__n_samples, sizeof(__pyx_k__n_samples), 0, 0, 1, 1},
@@ -7456,7 +7441,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s__permutation, __pyx_k__permutation, sizeof(__pyx_k__permutation), 0, 0, 1, 1},
   {&__pyx_n_s__random_state, __pyx_k__random_state, sizeof(__pyx_k__random_state), 0, 0, 1, 1},
   {&__pyx_n_s__range, __pyx_k__range, sizeof(__pyx_k__range), 0, 0, 1, 1},
-  {&__pyx_n_s__right, __pyx_k__right, sizeof(__pyx_k__right), 0, 0, 1, 1},
   {&__pyx_n_s__sample_mask, __pyx_k__sample_mask, sizeof(__pyx_k__sample_mask), 0, 0, 1, 1},
   {&__pyx_n_s__threshold, __pyx_k__threshold, sizeof(__pyx_k__threshold), 0, 0, 1, 1},
   {&__pyx_n_s__xrange, __pyx_k__xrange, sizeof(__pyx_k__xrange), 0, 0, 1, 1},
@@ -7466,9 +7450,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
 };
 static int __Pyx_InitCachedBuiltins(void) {
   #if PY_MAJOR_VERSION >= 3
-  __pyx_builtin_xrange = __Pyx_GetName(__pyx_b, __pyx_n_s__range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_xrange = __Pyx_GetName(__pyx_b, __pyx_n_s__range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   #else
-  __pyx_builtin_xrange = __Pyx_GetName(__pyx_b, __pyx_n_s__xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_xrange = __Pyx_GetName(__pyx_b, __pyx_n_s__xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   #endif
   __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_builtin_range = __Pyx_GetName(__pyx_b, __pyx_n_s__range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
@@ -7736,36 +7720,36 @@ PyMODINIT_FUNC PyInit__tree(void)
  * 
  * 
  * def _apply_tree(np.ndarray[DTYPE_t, ndim=2] X,             # <<<<<<<<<<<<<<
- *                 np.ndarray[np.int32_t, ndim=1] left,
- *                 np.ndarray[np.int32_t, ndim=1] right,
+ *                 np.ndarray[np.int32_t, ndim=2] children,
+ *                 np.ndarray[np.int32_t, ndim=1] feature,
  */
   __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_4tree_5_tree__apply_tree, NULL, __pyx_n_s_13); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
   if (PyObject_SetAttr(__pyx_m, __pyx_n_s___apply_tree, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "sklearn/tree/_tree.pyx":420
+  /* "sklearn/tree/_tree.pyx":419
  * 
  * 
  * def _error_at_leaf(np.ndarray[DTYPE_t, ndim=1, mode="c"] y,             # <<<<<<<<<<<<<<
  *                    np.ndarray sample_mask, Criterion criterion,
  *                    int n_samples):
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_4tree_5_tree_1_error_at_leaf, NULL, __pyx_n_s_13); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_4tree_5_tree_1_error_at_leaf, NULL, __pyx_n_s_13); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s___error_at_leaf, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s___error_at_leaf, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "sklearn/tree/_tree.pyx":469
+  /* "sklearn/tree/_tree.pyx":468
  * 
  * 
  * def _find_best_split(np.ndarray[DTYPE_t, ndim=2, mode="fortran"] X,             # <<<<<<<<<<<<<<
  *                      np.ndarray[DTYPE_t, ndim=1, mode="c"] y,
  *                      np.ndarray[np.int32_t, ndim=2, mode="fortran"] X_argsorted,
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_4tree_5_tree_2_find_best_split, NULL, __pyx_n_s_13); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7sklearn_4tree_5_tree_2_find_best_split, NULL, __pyx_n_s_13); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s___find_best_split, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s___find_best_split, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
   /* "sklearn/tree/_tree.pyx":1
diff --git a/sklearn/tree/_tree.pyx b/sklearn/tree/_tree.pyx
index 113b364b08b470de8388685cbe4d1a0a56bfab80..774e5ff5c1ced3e952d7bf2b1c696abd61923d24 100644
--- a/sklearn/tree/_tree.pyx
+++ b/sklearn/tree/_tree.pyx
@@ -396,8 +396,7 @@ cdef class MSE(RegressionCriterion):
 
 
 def _apply_tree(np.ndarray[DTYPE_t, ndim=2] X,
-                np.ndarray[np.int32_t, ndim=1] left,
-                np.ndarray[np.int32_t, ndim=1] right,
+                np.ndarray[np.int32_t, ndim=2] children,
                 np.ndarray[np.int32_t, ndim=1] feature,
                 np.ndarray[np.float64_t, ndim=1] threshold,
                 np.ndarray[np.int32_t, ndim=1] out):
@@ -409,11 +408,11 @@ def _apply_tree(np.ndarray[DTYPE_t, ndim=2] X,
     for i in xrange(n):
         node_id = 0
         # While node_id not a leaf
-        while left[node_id] != -1 and right[node_id] != -1:
+        while children[node_id, 0] != -1 and children[node_id, 1] != -1:
             if X[i, feature[node_id]] <= threshold[node_id]:
-                node_id = left[node_id]
+                node_id = children[node_id, 0]
             else:
-                node_id = right[node_id]
+                node_id = children[node_id, 1]
         out[i] = node_id
 
 
diff --git a/sklearn/tree/tree.py b/sklearn/tree/tree.py
index 246df6ca3fdafcd649c9a9124f57c67fa623f74e..c4e974362efb9303e87097ff987af2611851d165 100644
--- a/sklearn/tree/tree.py
+++ b/sklearn/tree/tree.py
@@ -84,7 +84,7 @@ def export_graphviz(decision_tree, out_file=None, feature_names=None):
     >>> out_file.close()
     """
     def node_to_str(tree, node_id):
-        if tree.left[node_id] == tree.right[node_id] == Tree.LEAF:
+        if tree.children[node_id, 0] == tree.children[node_id, 1] == Tree.LEAF:
             return "error = %s\\nsamples = %s\\nvalue = %s" \
                 % (tree.init_error[node_id], tree.n_samples[node_id],
                    tree.value[node_id])
@@ -101,8 +101,7 @@ def export_graphviz(decision_tree, out_file=None, feature_names=None):
 
     def recurse(tree, node_id):
         assert node_id != -1
-        left_child = tree.left[node_id]
-        right_child = tree.right[node_id]
+        left_child, right_child = tree.children[node_id, :]
         node_data = {
             "current": node_id,
             "current_gv": node_to_str(tree, node_id),
@@ -114,9 +113,11 @@ def export_graphviz(decision_tree, out_file=None, feature_names=None):
 
         out_file.write(GRAPHVIZ_TREE_TEMPLATE % node_data)
 
-        if not (tree.left[left_child] == tree.right[left_child] == Tree.LEAF):
+        if not (tree.children[left_child, 0] == tree.children[left_child, 1] \
+                == Tree.LEAF):
             recurse(tree, left_child)
-        if not (tree.left[right_child] == tree.right[right_child] == Tree.LEAF):
+        if not (tree.children[right_child, 0] == tree.children[right_child, 1] \
+                == Tree.LEAF):
             recurse(tree, right_child)
 
     if out_file is None:
@@ -146,13 +147,10 @@ class Tree(object):
     node_count : int
         Number of nodes (internal nodes + leaves) in the tree.
 
-    left : np.ndarray of int32
-        `left[i]` holds the node id of the left child of node `i`.
-        For leaves `left[i] == Tree.LEAF == -1`.
-
-    right : np.ndarray of int32
-        `right[i]` holds the node id of the right child of node `i`.
-        For leaves `right[i] == Tree.LEAF == -1`.
+    children : np.ndarray, shape=(node_count, 2), dtype=int32
+        `children[i,0]` holds the node id of the left child of node `i`.
+        `children[i,1]` holds the node id of the right child of node `i`.
+        For leaves `children[i,0] == children[i, 1] == Tree.LEAF == -1`.
 
     feature : np.ndarray of int32
         The feature to split on (only for internal nodes).
@@ -181,11 +179,8 @@ class Tree(object):
     def __init__(self, k, capacity=3):
         self.node_count = 0
 
-        self.left = np.empty((capacity,), dtype=np.int32)
-        self.left.fill(Tree.UNDEFINED)
-
-        self.right = np.empty((capacity,), dtype=np.int32)
-        self.right.fill(Tree.UNDEFINED)
+        self.children = np.empty((capacity, 2), dtype=np.int32)
+        self.children.fill(Tree.UNDEFINED)
 
         self.feature = np.empty((capacity,), dtype=np.int32)
         self.feature.fill(Tree.UNDEFINED)
@@ -200,13 +195,12 @@ class Tree(object):
     def resize(self, capacity=None):
         """Resize tree arrays to `capacity`, if `None` double capacity. """
         if capacity is None:
-            capacity = int(self.left.shape[0] * 2.0)
+            capacity = int(self.children.shape[0] * 2.0)
 
-        if capacity == self.left.shape[0]:
+        if capacity == self.children.shape[0]:
             return
 
-        self.left.resize((capacity,), refcheck=False)
-        self.right.resize((capacity,), refcheck=False)
+        self.children.resize((capacity, 2), refcheck=False)
         self.feature.resize((capacity,), refcheck=False)
         self.threshold.resize((capacity,), refcheck=False)
         self.value.resize((capacity, self.value.shape[1]), refcheck=False)
@@ -214,11 +208,16 @@ class Tree(object):
         self.init_error.resize((capacity,), refcheck=False)
         self.n_samples.resize((capacity,), refcheck=False)
 
+        # if capacity smaller than node_count, adjust the counter
+        if capacity < self.node_count:
+            self.node_count = capacity
+
     def add_split_node(self, parent, is_left_child, feature, threshold,
                        best_error, init_error, n_samples, value):
-        """Add a splitting node to the tree. """
+        """Add a splitting node to the tree. The new node registers itself as
+        the child of its parent. """
         node_id = self.node_count
-        if node_id >= self.left.shape[0]:
+        if node_id >= self.children.shape[0]:
             self.resize()
 
         self.feature[node_id] = feature
@@ -232,17 +231,18 @@ class Tree(object):
         # set as left or right child of parent
         if parent > Tree.LEAF:
             if is_left_child:
-                self.left[parent] = node_id
+                self.children[parent, 0] = node_id
             else:
-                self.right[parent] = node_id
+                self.children[parent, 1] = node_id
 
         self.node_count += 1
         return node_id
 
     def add_leaf(self, parent, is_left_child, value, error, n_samples):
-        """Add a leaf to the tree. """
+        """Add a leaf to the tree. The new node registers itself as the
+        child of its parent. """
         node_id = self.node_count
-        if node_id >= self.left.shape[0]:
+        if node_id >= self.children.shape[0]:
             self.resize()
 
         self.value[node_id] = value
@@ -251,19 +251,17 @@ class Tree(object):
         self.best_error[node_id] = error
 
         if is_left_child:
-            self.left[parent] = node_id
+            self.children[parent, 0] = node_id
         else:
-            self.right[parent] = node_id
+            self.children[parent, 1] = node_id
 
-        self.left[node_id] = Tree.LEAF
-        self.right[node_id] = Tree.LEAF
+        self.children[node_id, :] = Tree.LEAF
 
         self.node_count += 1
 
     def predict(self, X):
         out = np.empty((X.shape[0], ), dtype=np.int32)
-        _tree._apply_tree(X, self.left, self.right, self.feature,
-                          self.threshold, out)
+        _tree._apply_tree(X, self.children, self.feature, self.threshold, out)
         return self.value.take(out, axis=0)