'Fit MultiTaskElasticNet model with coordinate descent
Parameters
X : ndarray, shape (n_samples, n_features)
Data
y : ndarray, shape (n_samples, n_tasks)
Target. Will be cast to X\'s dtype if necessary
Notes
Coordinate descent is an algorithm that considers each column of
data at a time hence it will automatically convert the X input
as a Fortran-contiguous numpy array if necessary.
To avoid memory re-allocation it is advised to allocate the
initial data in memory directly using that format.'

def fit(self, X, y):

    X = check_array(X, dtype=[np.float64, np.float32], order='F', copy=(self.copy_X and self.fit_intercept))
    y = check_array(y, dtype=X.dtype.type, ensure_2d=False)
    if hasattr(self, 'l1_ratio'):
        model_str = 'ElasticNet'
    else:
        model_str = 'Lasso'
    if (y.ndim == 1):
        raise ValueError(('For    mono-task    outputs,    use    %s' % model_str))
    (n_samples, n_features) = X.shape
    (_, n_tasks) = y.shape
    if (n_samples != y.shape[0]):
        raise ValueError(('X    and    y    have    inconsistent    dimensions    (%d    !=    %d)' % (n_samples, y.shape[0])))
    (X, y, X_offset, y_offset, X_scale) = _preprocess_data(X, y, self.fit_intercept, self.normalize, copy=False)
    if ((not self.warm_start) or (self.coef_ is None)):
        self.coef_ = np.zeros((n_tasks, n_features), dtype=X.dtype.type, order='F')
    l1_reg = ((self.alpha * self.l1_ratio) * n_samples)
    l2_reg = ((self.alpha * (1.0 - self.l1_ratio)) * n_samples)
    self.coef_ = np.asfortranarray(self.coef_)
    if (self.selection not in ['random', 'cyclic']):
        raise ValueError('selection    should    be    either    random    or    cyclic.')
    random = (self.selection == 'random')
    (self.coef_, self.dual_gap_, self.eps_, self.n_iter_) = cd_fast.enet_coordinate_descent_multi_task(self.coef_, l1_reg, l2_reg, X, y, self.max_iter, self.tol, check_random_state(self.random_state), random)
    self._set_intercept(X_offset, y_offset, X_scale)
    if (self.dual_gap_ > self.eps_):
        warnings.warn('Objective    did    not    converge,    you    might    want    to    increase    the    number    of    iterations', ConvergenceWarning)
    return self
