
    _-Ph*+                     r    d Z ddlmZ ddlZddlmZ ddlmZ d Z	dd	Z
ddZd ZddZd Zd Zd Zd ZdS )zAlgorithms related to graphs.    )warnN)sparse   )amg_corec                     t          j        |           s(t          j        |           st          j        |           } | j        d         | j        d         k    rt          d          | S )z!Return (square) matrix as sparse.r   r   zexpected square matrix)r   isspmatrix_csrisspmatrix_csc
csr_matrixshape
ValueError)Gs    K/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/pyamg/graph.pyasgraphr   
   sb    !!$$ !(=a(@(@ !a  wqzQWQZ1222H    serialc                     t          |           } | j        d         }t          j        |d          }d|dd<   ||dk    r(t          j        } ||| j        | j        ddd|           n|dk    rGt          j        } ||| j        | j        ddd|t          j	        
                    |          d	  	         nWt          d	| d
          t          j        } ||| j        | j        ||t          j	        
                    |          d           |S )a  Compute a maximal independent vertex set for a graph.

    Parameters
    ----------
    G : sparse matrix
        Symmetric matrix, preferably in sparse CSR or CSC format
        The nonzeros of G represent the edges of an undirected graph.
    algo : {'serial', 'parallel'}
        Algorithm used to compute the MIS
            * serial   : greedy serial algorithm
            * parallel : variant of Luby's parallel MIS algorithm

    Returns
    -------
    S : array
        S[i] = 1 if vertex i is in the MIS
        S[i] = 0 otherwise

    Notes
    -----
    Diagonal entries in the G (self loops) will be ignored.

    Luby's algorithm is significantly more expensive than the
    greedy serial algorithm.

    r   intcdtypeNr   r   parallelzUnknown algorithm ())r   r   npemptyr   maximal_independent_set_serialindptrindices maximal_independent_set_parallelrandomrandr   "maximal_independent_set_k_parallel)r   algokNmisfns         r   maximal_independent_setr'      s   6 	

A	
A
(1F
#
#
#CCFy88BBq!(AIr1a5555Z:BBq!(AIr1abinnQ6G6GLLLL:4:::;;;8
1ah	1c29>>!+<+<bAAAJr   MISc           	      
   t          |           } | j        d         }t          j        |d          }|dk    r%t          j        } ||| j        | j        |           n|dk    rCt          j        } ||| j        | j        |t          j	        
                    |                     n\|dk    rCt          j        } ||| j        | j        |t          j	        
                    |                     nt          d| d          |S )	a  Compute a vertex coloring of a graph.

    Parameters
    ----------
    G : sparse matrix
        Symmetric matrix, preferably in sparse CSR or CSC format
        The nonzeros of G represent the edges of an undirected graph.
    method : string
        Algorithm used to compute the vertex coloring:

            * 'MIS' - Maximal Independent Set
            * 'JP'  - Jones-Plassmann (parallel)
            * 'LDF' - Largest-Degree-First (parallel)

    Returns
    -------
    coloring : array
        An array of vertex colors (integers beginning at 0)

    Notes
    -----
    Diagonal entries in the G (self loops) will be ignored.

    r   r   r   r(   JPLDFzUnknown method (r   )r   r   r   r   r   vertex_coloring_misr   r   vertex_coloring_jones_plassmannr   r    vertex_coloring_LDFr   )r   methodr$   coloringr&   s        r   vertex_coloringr1   F   s    2 	

A	
Ax(((H)
1ah	8,,,,	45
1ah	8RY^^A->->????	5)
1ah	8RY^^A->->????5F555666Or   c                    t          |           } | j        d         }| j        dk    r,| j                                        dk     rt          d          | j        t          k    rt          d          t          j	        |d          }t          j
        |t          j        | j                  }d||<   t          j
        |dd          }|||<   t          j        || j        | j        | j        ||           ||fS )a6  Bellman-Ford iteration.

    Parameters
    ----------
    G : sparse matrix
        Directed graph with positive weights.
    seeds : list
        Starting seeds

    Returns
    -------
    distances : array
        Distance of each point to the nearest seed
    nearest_seed : array
        Index of the nearest seed

    Notes
    -----
    This should be viewed as the transpose of Bellman-Ford in
    scipy.sparse.csgraph. Here, bellman_ford is used to find the shortest path
    from any point *to* the seeds. In csgraph, bellman_ford is used to find
    "the shortest distance from point i to point j".  So csgraph.bellman_ford
    could be run `for seed in seeds`.  Also note that `test_graph.py` tests
    against `csgraph.bellman_ford(G.T)`.

    See Also
    --------
    scipy.sparse.csgraph.bellman_ford
    r   z2Bellman-Ford is defined only for positive weights.z.Bellman-Ford is defined only for real weights.r   r   r   )r   r   nnzdataminr   r   complexr   asarrayfullinfr   bellman_fordr   r   )r   seedsr$   	distancesnearest_seeds        r   r:   r:   s   s    < 	

A	
Auqyy6::<<!QRRRw'IJJJJuF+++E26111IIe71b///LL!QXqy!&)\RRR|$$r   
   c                    t          |           } | j        d         }| j        j        dk    rt	          j        |           } t	          j        |          r=t          j                            |          d|         }|	                    d          }nt	          j
        |d          }t          |          dk     rt          d          |                                dk     r%t          d|                                 d	          |                                |k    r%t          d|                                 d	          t	          j        |d          }t	          j        || j                  }t!          d|dz             D ]g}|                                }t%          j        || j        | j        | j        t          |          |||           ||k                                    r nh||k    rt1          d
           |||fS )a  Perform Lloyd clustering on graph with weighted edges.

    Parameters
    ----------
    G : csr_matrix, csc_matrix
        A sparse NxN matrix where each nonzero entry G[i,j] is the distance
        between nodes i and j.
    seeds : int array
        If seeds is an integer, then its value determines the number of
        clusters.  Otherwise, seeds is an array of unique integers between 0
        and N-1 that will be used as the initial seeds for clustering.
    maxiter : int
        The maximum number of iterations to perform.

    Returns
    -------
    distances : array
        final distances
    clusters : int array
        id of each cluster of points
    seeds : int array
        index of each seed

    Notes
    -----
    If G has complex values, abs(G) is used instead.

    r   cNr   r   r   zat least one seed is requiredzInvalid seed index (r   z3Lloyd clustering reached maxiter (did not converge))r   r   r   kindr   absisscalarr   permutationastypearraylenr   r5   maxr   rangecopyr   lloyd_clusterr   r   r4   allr   )r   r;   maxiterr$   clustersr<   _it
last_seedss           r   rK   rK      s   : 	

A	
Aw|sF1II 
{5 .	%%a((%0V$$f---
5zzA~~8999yy{{Q>		>>>???yy{{a>		>>>???x(((H!'***IQ	""  ZZ\\
q!(AIqv"5zz9h	G 	G 	G Z$$&& 	E	 g~~BCCCx''r   c                 0   t          |           } | j        d         }t          j        || j        j                  }t          j        || j        j                  }d|dd<   t          j        } || j        | j        t          |          ||           ||fS )a  Breadth First search of a graph.

    Parameters
    ----------
    G : csr_matrix, csc_matrix
        A sparse NxN matrix where each nonzero entry G[i,j] is the distance
        between nodes i and j.
    seed : int
        Index of the seed location

    Returns
    -------
    order : int array
        Breadth first order
    level : int array
        Final levels

    Examples
    --------
    0---2
    |  /
    | /
    1---4---7---8---9
    |  /|  /
    | / | /
    3/  6/
    |
    |
    5
    >>> import numpy as np
    >>> import pyamg
    >>> import scipy.sparse as sparse
    >>> edges = np.array([[0,1],[0,2],[1,2],[1,3],[1,4],[3,4],[3,5],
    ...                   [4,6], [4,7], [6,7], [7,8], [8,9]])
    >>> N = np.max(edges.ravel())+1
    >>> data = np.ones((edges.shape[0],))
    >>> A = sparse.coo_matrix((data, (edges[:,0], edges[:,1])), shape=(N,N))
    >>> c, l = pyamg.graph.breadth_first_search(A, 0)
    >>> print(l)
    [0 1 1 2 2 3 3 3 4 5]
    >>> print(c)
    [0 1 2 3 4 5 6 7 8 9]

    r   r   N)
r   r   r   r   r   r   r   breadth_first_searchr   int)r   seedr$   orderlevelBFSs         r   rR   rR      s    Z 	

A	
AHQ''EHQ''EE!!!H

'CC!)SYYu555%<r   c                     t          |           } | j        d         }t          j        || j        j                  }t          j        } ||| j        | j        |           |S )a  Compute the connected components of a graph.

    The connected components of a graph G, which is represented by a
    symmetric sparse matrix, are labeled with the integers 0,1,..(K-1) where
    K is the number of components.

    Parameters
    ----------
    G : symmetric matrix, preferably in sparse CSR or CSC format
        The nonzeros of G represent the edges of an undirected graph.

    Returns
    -------
    components : ndarray
        An array of component labels for each vertex of the graph.

    Notes
    -----
    If the nonzero structure of G is not symmetric, then the
    result is undefined.

    Examples
    --------
    >>> from pyamg.graph import connected_components
    >>> print(connected_components( [[0,1,0],[1,0,1],[0,1,0]] ))
    [0 0 0]
    >>> print(connected_components( [[0,1,0],[1,0,0],[0,0,0]] ))
    [0 0 1]
    >>> print(connected_components( [[0,0,0],[0,0,0],[0,0,0]] ))
    [0 1 2]
    >>> print(connected_components( [[0,1,0,0],[1,0,0,0],[0,0,0,1],[0,0,1,0]] ))
    [0 0 1 1]

    r   )	r   r   r   r   r   r   r   connected_componentsr   )r   r$   
componentsr&   s       r   rY   rY   &  sX    F 	

A	
A!QX^,,J		&BBq!(AIz***r   c                 j    t          |           \  }}}|ddd         }| |ddf         dd|f         S )a
  Symmetric Reverse Cutthill-McKee.

    Parameters
    ----------
    A : sparse matrix
        Sparse matrix

    Returns
    -------
    B : sparse matrix
        Permuted matrix with reordering

    Notes
    -----
    Get a pseudo-peripheral node, then call BFS

    Examples
    --------
    >>> from pyamg import gallery
    >>> from pyamg.graph import symmetric_rcm
    >>> n = 200
    >>> density = 1.0/n
    >>> A = gallery.sprand(n, n, density, format='csr')
    >>> S = A + A.T
    >>> # try the visualizations
    >>> # import matplotlib.pyplot as plt
    >>> # plt.figure()
    >>> # plt.subplot(121)
    >>> # plt.spy(S,marker='.')
    >>> # plt.subplot(122)
    >>> # plt.spy(symmetric_rcm(S),marker='.')

    See Also
    --------
    pseudo_peripheral_node

    Nr   )pseudo_peripheral_node)A
dummy_rootrU   dummy_levelps        r   symmetric_rcmra   T  sF    L &<A%>%>"J{dddAQT7111a4=r   c                    | j         d         }t          j        | j                  }t	          t          j                                        |z            }d}	 t          | |          \  }}|                                }t          j	        ||k              d         }||         }	|	
                                }
t          j	        |	|
k              d         d         }||         }||         |k    r|}||         }n|||fS )a(  Find a pseudo peripheral node.

    Parameters
    ----------
    A : sparse matrix
        Sparse matrix

    Returns
    -------
    x : int
        Location of the node
    order : array
        BFS ordering
    level : array
        BFS levels

    Notes
    -----
    Algorithm in Saad

    r   )r   r   diffr   rS   r   r    rR   rH   wherer5   )r]   nvalencexdeltarU   rV   maxlevel	lastnodeslastnodesvalenceminlastnodesvalenceys               r   r\   r\     s    , 	

AgahG 	BINNq !!AE#+Aq11u 99;;HUh.//2	"9-.2244H%)<<==a@CaL 8eA!HEEeU?"##r   )r   N)r(   )r>   )__doc__warningsr   numpyr   scipyr    r   r   r'   r1   r:   rK   rR   rY   ra   r\    r   r   <module>rt      s    # #                        . . . .b* * * *Z1% 1% 1%hB( B( B( B(J7 7 7t+ + +\* * *Z/# /# /# /# /#r   