def METHOD_NAME(self, x, y, w, get_grad):
    # Some optimizers need to do something before a prediction is made
    self.optimizer.look_ahead(w=self._weights)
    # Calculate the gradient
    gradient, loss_gradient = get_grad(x, y, w)
    # Update the intercept
    self.intercept -= self._get_intercept_update(loss_gradient)
    # Update the weights
    self.optimizer.step(w=self._weights, g=gradient)
    # Apply L1 cumulative penalty if applicable
    if self.l1 != 0.0:
        # This should be called after the learning_rate update in case of adaptive learning rate
        self.max_cum_l1 = self.max_cum_l1 + self.l1 * self.optimizer.learning_rate
        self._update_weights(x)
    return self