'Implement a single boost for regression
Perform a single boost according to the AdaBoost.R2 algorithm and
return the updated sample weights.
Parameters
iboost : int
The index of the current boost iteration.
X : {array-like, sparse matrix} of shape = [n_samples, n_features]
The training input samples. Sparse matrix can be CSC, CSR, COO,
DOK, or LIL. DOK and LIL are converted to CSR.
y : array-like of shape = [n_samples]
The target values (class labels in classification, real numbers in
regression).
sample_weight : array-like of shape = [n_samples]
The current sample weights.
random_state : numpy.RandomState
The current random number generator
Returns
sample_weight : array-like of shape = [n_samples] or None
The reweighted sample weights.
If None then boosting has terminated early.
estimator_weight : float
The weight for the current boost.
If None then boosting has terminated early.
estimator_error : float
The regression error for the current boost.
If None then boosting has terminated early.'

def _boost(self, iboost, X, y, sample_weight, random_state):

    estimator = self._make_estimator(random_state=random_state)
    cdf = stable_cumsum(sample_weight)
    cdf /= cdf[(-1)]
    uniform_samples = random_state.random_sample(X.shape[0])
    bootstrap_idx = cdf.searchsorted(uniform_samples, side='right')
    bootstrap_idx = np.array(bootstrap_idx, copy=False)
    estimator.fit(X[bootstrap_idx], y[bootstrap_idx])
    y_predict = estimator.predict(X)
    error_vect = np.abs((y_predict - y))
    error_max = error_vect.max()
    if (error_max != 0.0):
        error_vect /= error_max
    if (self.loss == 'square'):
        error_vect **= 2
    elif (self.loss == 'exponential'):
        error_vect = (1.0 - np.exp((- error_vect)))
    estimator_error = (sample_weight * error_vect).sum()
    if (estimator_error <= 0):
        return (sample_weight, 1.0, 0.0)
    elif (estimator_error >= 0.5):
        if (len(self.estimators_) > 1):
            self.estimators_.pop((-1))
        return (None, None, None)
    beta = (estimator_error / (1.0 - estimator_error))
    estimator_weight = (self.learning_rate * np.log((1.0 / beta)))
    if (not (iboost == (self.n_estimators - 1))):
        sample_weight *= np.power(beta, ((1.0 - error_vect) * self.learning_rate))
    return (sample_weight, estimator_weight, estimator_error)
