docs: def fit(self, X, y, recycle=True, **grow_params):
  
          """Build a linear mixed forest of trees from the training set (X, y).
  
          Parameters
          ----------
          X : array-like of shape = [n_samples, n_features]
              The training input samples.
  
          y : array-like, shape = [n_samples] or [n_samples, 1]
              The real valued targets
  
          Returns
          -------
          self : object
              Returns self.
          """
          if isinstance(self.kernel, str) and self.kernel == 'data':
              self.kernel = SC.estimateKernel(X, maf=1.0/X.shape[0])
          elif isinstance(self.kernel, str) and self.kernel == 'iid':
              self.kernel = SP.identity(X.shape[0])
          # Use dedicated part of data as background model
          elif self.kernel.size == X.shape[1]:
              tmp_ind = self.kernel
              self.kernel = utils.estimateKernel(X[:, self.kernel],
                                                 maf=1.0/X.shape[0])
              X = X[:, ~tmp_ind]
          # Extract and reshape data
          self.y = y.reshape(-1, 1)
          self.X = X
          self.n, self.m = self.X.shape
          if self.delta is None:
              self.BLUP = BLUP.BLUP()
              if self.verbose > 1:
                  print('fitting BLUP')
              self.BLUP.fit(XTrain=self.X, yTrain=self.y, KTrain=self.kernel,
                            delta=self.delta)
              if self.verbose > 1:
                  print('done fitting BLUP')
              # Update delta if it used to be 'None'
              self.delta = self.BLUP.delta
          self.max_features = SP.maximum(SP.int_(self.ratio_features*self.m), 1)
          self.var_used = SP.zeros(self.m)
          self.log_importance = SP.zeros(self.m)
          self.depth = 0
  
          if self.verbose > 0:
              print(('log(delta) fitted to ', SP.log(self.delta)))
  
          # Initialize individual trees
          if recycle and self.trees != []:
              for tree in self.trees:
                  tree.cut_to_stump()
          else:
              n_trees = 0
              self.trees = []
              while n_trees < self.n_estimators:
                  if self.verbose > 1:
                      print(('init. tree number ', n_trees))
                  subsample = self.tree_sample()
                  tree = MixedForestTree(self, subsample)
                  self.trees.append(tree)
                  n_trees += 1
  
          # Fitting with optimal depth constraint
          if self.fit_optimal_depth or self.update_delta:
              self.opt_depth = 0
              self.min_oob_err = self.get_oob_error(self.depth)
              if self.verbose > 0:
                  print(('initial oob error is:', self.min_oob_err))
              grow_further = True
              curr_depth = self.depth
              while grow_further:
                  # Updating ensemble increasing its depth by one
                  self.further(depth=self.depth+1)
                  if self.update_delta:
                      self.delta = self.delta_update()
                      if self.verbose > 0:
                          print(('delta was fitted to', self.delta))
                  if self.verbose > 0:
                      print(('depth is:', self.depth))
                  oob_err = self.get_oob_error(self.depth)
                  if self.verbose > 0:
                      print(('oob error is:', oob_err))
                  if oob_err < self.min_oob_err:
                      self.min_oob_err = oob_err
                      self.opt_depth = self.depth
                  # Decide whether tree needs to be furthered
                  grow_further = (curr_depth < self.depth) and\
                      (self.depth < self.max_depth)
                  if self.build_to_opt_depth and (self.depth >= self.min_depth):
                      grow_further = grow_further and\
                          (oob_err == self.min_oob_err)
                      pass
                  curr_depth = self.depth
          #####################################################
          # Growing full tree one by one
          else:
              self.further(depth=self.max_depth)
          return self