def active_support_elastic_net(self, X, y, alpha, tau=1.0,
                                   algorithm='lasso_lars', support_init='L2',
                                   support_size=100, maxiter=40,
                                   maxiter_lasso=1000):
        """
        Source: https://github.com/ChongYou/subspace-clustering/blob/master/cluster/selfrepresentation.py
            An active support based algorithm for solving the elastic net optimization problem
            min_{c} tau ||c||_1 + (1-tau)/2 ||c||_2^2 + alpha / 2 ||y - c X ||_2^2.
        
        Parameters
        -----------
        X : array-like, shape (n_samples, n_features)

        y : array-like, shape (1, n_features)

        alpha : float

        tau : float, default 1.0

        algorithm : string, default ``spams``
            Algorithm for computing solving the subproblems. Either lasso_lars
            or lasso_cd or spams
            (installation of spams package is required).
            Note: ``lasso_lars`` and ``lasso_cd`` only support tau = 1.

        support_init: string, default ``knn``
            This determines how the active support is initialized.
            It can be either ``knn`` or ``L2``.

        support_size: int, default 100
            This determines the size of the working set.
            A small support_size decreases the runtime per iteration while
            increase the number of iterations.

        maxiter: int default 40
            Termination condition for active support update.
        
        Returns
        -------
        c : shape n_samples
            The optimal solution to the optimization problem.
        """
        n_samples = X.shape[0]

        if n_samples <= support_size:  # skip active support search for small scale data
            supp = np.arange(n_samples,
                             dtype=int)  # this results in the following iteration to converge in 1 iteration
        else:
            if support_init == 'L2':
                L2sol = np.linalg.solve(
                    np.identity(y.shape[1]) * alpha + np.dot(X.T, X), y.T)
                c0 = np.dot(X, L2sol)[:, 0]
                supp = np.argpartition(-np.abs(c0), support_size)[
                       0:support_size]
            elif support_init == 'knn':
                supp = np.argpartition(-np.abs(np.dot(y, X.T)[0]),
                                       support_size)[0:support_size]

        curr_obj = float("inf")
        for _ in range(maxiter):
            Xs = X[supp, :]

            ## Removed the original option to use 'spams' since this would
            # require the spams dependency
            # if algorithm == 'spams':
            #     cs = spams.lasso(np.asfortranarray(y.T), D=np.asfortranarray(Xs.T), 
            #                      lambda1=tau*alpha, lambda2=(1.0-tau)*alpha)
            #     cs = np.asarray(cs.todense()).T
            # else:
            cs = sparse_encode(y, Xs, algorithm=algorithm, alpha=alpha,
                               max_iter=maxiter_lasso)

            delta = (y - np.dot(cs, Xs)) / alpha

            obj = tau * np.sum(np.abs(cs[0])) + (1.0 - tau) / 2.0 * np.sum(
                np.power(cs[0], 2.0)) + alpha / 2.0 * np.sum(
                np.power(delta, 2.0))
            if curr_obj - obj < 1.0e-10 * curr_obj:
                break
            curr_obj = obj

            coherence = np.abs(np.dot(delta, X.T))[0]
            coherence[supp] = 0
            addedsupp = np.nonzero(coherence > tau + 1.0e-10)[0]

            if addedsupp.size == 0:  # converged
                break

            # Find the set of nonzero entries of cs.
            activesupp = supp[np.abs(cs[0]) > 1.0e-10]

            if activesupp.size > 0.8 * support_size:  # this suggests that support_size is too small and needs to be increased
                support_size = min(
                    [round(max([activesupp.size, support_size]) * 1.1),
                     n_samples])

            if addedsupp.size + activesupp.size > support_size:
                ord = np.argpartition(-coherence[addedsupp],
                                      support_size - activesupp.size)[
                      0:support_size - activesupp.size]
                addedsupp = addedsupp[ord]

            supp = np.concatenate([activesupp, addedsupp])

        c = np.zeros(n_samples)
        c[supp] = cs
        return c

        Source: https://github.com/ChongYou/subspace-clustering/blob/master/cluster/selfrepresentation.py
            An active support based algorithm for solving the elastic net optimization problem
            min_{c} tau ||c||_1 + (1-tau)/2 ||c||_2^2 + alpha / 2 ||y - c X ||_2^2.
        
        Parameters
        -----------
        X : array-like, shape (n_samples, n_features)

        y : array-like, shape (1, n_features)

        alpha : float

        tau : float, default 1.0

        algorithm : string, default ``spams``
            Algorithm for computing solving the subproblems. Either lasso_lars
            or lasso_cd or spams
            (installation of spams package is required).
            Note: ``lasso_lars`` and ``lasso_cd`` only support tau = 1.

        support_init: string, default ``knn``
            This determines how the active support is initialized.
            It can be either ``knn`` or ``L2``.

        support_size: int, default 100
            This determines the size of the working set.
            A small support_size decreases the runtime per iteration while
            increase the number of iterations.

        maxiter: int default 40
            Termination condition for active support update.
        
        Returns
        -------
        c : shape n_samples
            The optimal solution to the optimization problem.
        
pyod/models/rgraph.py