def eigen_decomposition(G, n_components=<NUM_LIT:8>, eigen_solver='<STR_LIT>',<EOL>random_state=None,<EOL>drop_first=True, largest=True, solver_kwds=None):
n_nodes = G.shape[<NUM_LIT:0>]<EOL>if drop_first:<EOL><INDENT>n_components = n_components + <NUM_LIT:1><EOL><DEDENT>eigen_solver, solver_kwds = check_eigen_solver(eigen_solver, solver_kwds,<EOL>size=n_nodes,<EOL>nvec=n_components)<EOL>random_state = check_random_state(random_state)<EOL>if sparse.issparse(G):<EOL><INDENT>if G.getformat() is not '<STR_LIT>':<EOL><INDENT>G.tocsr()<EOL><DEDENT><DEDENT>G = G.astype(np.float)<EOL>is_symmetric = _is_symmetric(G)<EOL>if eigen_solver == '<STR_LIT>':<EOL><INDENT>v0 = random_state.uniform(-<NUM_LIT:1>, <NUM_LIT:1>, G.shape[<NUM_LIT:0>])<EOL>if is_symmetric:<EOL><INDENT>if largest:<EOL><INDENT>which = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>which = '<STR_LIT>'<EOL><DEDENT>lambdas, diffusion_map = eigsh(G, k=n_components, which=which,<EOL>v0=v0,**(solver_kwds or {}))<EOL><DEDENT>else:<EOL><INDENT>if largest:<EOL><INDENT>which = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>which = '<STR_LIT>'<EOL><DEDENT>lambdas, diffusion_map = eigs(G, k=n_components, which=which,<EOL>**(solver_kwds or {}))<EOL><DEDENT>lambdas = np.real(lambdas)<EOL>diffusion_map = np.real(diffusion_map)<EOL><DEDENT>elif eigen_solver == '<STR_LIT>':<EOL><INDENT>if solver_kwds is not None:<EOL><INDENT>amg_kwds = {}<EOL>lobpcg_kwds = solver_kwds.copy()<EOL>for kwd in AMG_KWDS:<EOL><INDENT>if kwd in solver_kwds.keys():<EOL><INDENT>amg_kwds[kwd] = solver_kwds[kwd]<EOL>del lobpcg_kwds[kwd]<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>amg_kwds = None<EOL>lobpcg_kwds = None<EOL><DEDENT>if not is_symmetric:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if not sparse.issparse(G):<EOL><INDENT>warnings.warn("<STR_LIT>")<EOL><DEDENT>ml = smoothed_aggregation_solver(check_array(G, accept_sparse = ['<STR_LIT>']),**(amg_kwds or {}))<EOL>M = ml.aspreconditioner()<EOL>n_find = min(n_nodes, <NUM_LIT:5> + <NUM_LIT:2>*n_components)<EOL>X = random_state.rand(n_nodes, n_find)<EOL>X[:, <NUM_LIT:0>] = (G.diagonal()).ravel()<EOL>lambdas, diffusion_map = lobpcg(G, X, M=M, largest=largest,**(lobpcg_kwds or {}))<EOL>sort_order = np.argsort(lambdas)<EOL>if largest:<EOL><INDENT>lambdas = lambdas[sort_order[::-<NUM_LIT:1>]]<EOL>diffusion_map = diffusion_map[:, sort_order[::-<NUM_LIT:1>]]<EOL><DEDENT>else:<EOL><INDENT>lambdas = lambdas[sort_order]<EOL>diffusion_map = diffusion_map[:, sort_order]<EOL><DEDENT>lambdas = lambdas[:n_components]<EOL>diffusion_map = diffusion_map[:, :n_components]<EOL><DEDENT>elif eigen_solver == "<STR_LIT>":<EOL><INDENT>if not is_symmetric:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>n_find = min(n_nodes, <NUM_LIT:5> + <NUM_LIT:2>*n_components)<EOL>X = random_state.rand(n_nodes, n_find)<EOL>lambdas, diffusion_map = lobpcg(G, X, largest=largest,**(solver_kwds or {}))<EOL>sort_order = np.argsort(lambdas)<EOL>if largest:<EOL><INDENT>lambdas = lambdas[sort_order[::-<NUM_LIT:1>]]<EOL>diffusion_map = diffusion_map[:, sort_order[::-<NUM_LIT:1>]]<EOL><DEDENT>else:<EOL><INDENT>lambdas = lambdas[sort_order]<EOL>diffusion_map = diffusion_map[:, sort_order]<EOL><DEDENT>lambdas = lambdas[:n_components]<EOL>diffusion_map = diffusion_map[:, :n_components]<EOL><DEDENT>elif eigen_solver == '<STR_LIT>':<EOL><INDENT>if sparse.isspmatrix(G):<EOL><INDENT>G = G.todense()<EOL><DEDENT>if is_symmetric:<EOL><INDENT>lambdas, diffusion_map = eigh(G,**(solver_kwds or {}))<EOL><DEDENT>else:<EOL><INDENT>lambdas, diffusion_map = eig(G,**(solver_kwds or {}))<EOL>sort_index = np.argsort(lambdas)<EOL>lambdas = lambdas[sort_index]<EOL>diffusion_map[:,sort_index]<EOL><DEDENT>if largest:<EOL><INDENT>lambdas = lambdas[::-<NUM_LIT:1>] <EOL>diffusion_map = diffusion_map[:, ::-<NUM_LIT:1>] <EOL><DEDENT>lambdas = lambdas[:n_components]<EOL>diffusion_map = diffusion_map[:, :n_components]<EOL><DEDENT>return (lambdas, diffusion_map)<EOL>
Function to compute the eigendecomposition of a square matrix.

Parameters
----------
G : array_like or sparse matrix
    The square matrix for which to compute the eigen-decomposition.
n_components : integer, optional
    The number of eigenvectors to return
eigen_solver : {'auto', 'dense', 'arpack', 'lobpcg', or 'amg'}
    'auto' :
        attempt to choose the best method for input data (default)
    'dense' :
        use standard dense matrix operations for the eigenvalue decomposition.
        For this method, M must be an array or matrix type.
        This method should be avoided for large problems.
    'arpack' :
        use arnoldi iteration in shift-invert mode. For this method,
        M may be a dense matrix, sparse matrix, or general linear operator.
        Warning: ARPACK can be unstable for some problems.  It is best to
        try several random seeds in order to check results.
    'lobpcg' :
        Locally Optimal Block Preconditioned Conjugate Gradient Method.
        A preconditioned eigensolver for large symmetric positive definite
        (SPD) generalized eigenproblems.
    'amg' :
        Algebraic Multigrid solver (requires ``pyamg`` to be installed)
        It can be faster on very large, sparse problems, but may also lead
        to instabilities.
random_state : int seed, RandomState instance, or None (default)
    A pseudo random number generator used for the initialization of the
    lobpcg eigen vectors decomposition when eigen_solver == 'amg'.
    By default, arpack is used.
solver_kwds : any additional keyword arguments to pass to the selected eigen_solver

Returns
-------
lambdas, diffusion_map : eigenvalues, eigenvectors