ó
 ,ľ[c           @   ső   d  Z  d d l m Z d d l m Z d d l m Z d d l Z d d l m	 Z	 d d l
 m Z d d l m Z d	 d
 d g Z d e	 f d     YZ d   Z d   Z d   Z d   Z e d  e d     Z e d    Z d d  Z d S(   sH   Functions for measuring the quality of a partition (into
communities).

i˙˙˙˙(   t   division(   t   wraps(   t   productN(   t   NetworkXError(   t   not_implemented_for(   t   is_partitiont   coveraget
   modularityt   performancet   NotAPartitionc           B   s   e  Z d  Z d   Z RS(   s6   Raised if a given collection is not a partition.

    c         C   s2   d } | j  | |  } t t |   j |  d  S(   Ns+   {} is not a valid partition of the graph {}(   t   formatt   superR	   t   __init__(   t   selft   Gt
   collectiont   msg(    (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyR      s    (   t   __name__t
   __module__t   __doc__R   (    (    (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyR	      s   c            s   t       f d    } | S(   sJ  Decorator that raises an exception if a partition is not a valid
    partition of the nodes of a graph.

    Raises :exc:`networkx.NetworkXError` if the partition is not valid.

    This decorator should be used on functions whose first two arguments
    are a graph and a partition of the nodes of that graph (in that
    order)::

        >>> @require_partition
        ... def foo(G, partition):
        ...     print('partition is valid!')
        ...
        >>> G = nx.complete_graph(5)
        >>> partition = [{0, 1}, {2, 3}, {4}]
        >>> foo(G, partition)
        partition is valid!
        >>> partition = [{0}, {2, 3}, {4}]
        >>> foo(G, partition)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
          ...
        NetworkXError: `partition` is not a valid partition of the nodes of G
        >>> partition = [{0, 1}, {1, 2, 3}, {4}]
        >>> foo(G, partition)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
          ...
        NetworkXError: `partition` is not a valid partition of the nodes of G

    c             s/   t  |  d    s" t j d   n    |  |   S(   Ni   s6   `partition` is not a valid partition of the nodes of G(   R   t   nxR   (   t   argst   kw(   t   func(    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyt   new_funcD   s    (   R   (   R   R   (    (   R   sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyt   require_partition%   s    c            s   t    f d   | D  S(   s9  Returns the number of intra-community edges according to the given
    partition of the nodes of `G`.

    `G` must be a NetworkX graph.

    `partition` must be a partition of the nodes of `G`.

    The "intra-community edges" are those edges joining a pair of nodes
    in the same block of the partition.

    c         3   s$   |  ] }   j  |  j   Vq d  S(   N(   t   subgrapht   size(   t   .0t   block(   R   (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pys	   <genexpr>Z   s    (   t   sum(   R   t	   partition(    (   R   sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyt   intra_community_edgesN   s    c         C   sT   |  j    r. t j |  | d t j   j   St j |  | d t j   j   Sd S(   sÎ  Returns the number of inter-community edges according to the given
    partition of the nodes of `G`.

    `G` must be a NetworkX graph.

    `partition` must be a partition of the nodes of `G`.

    The *inter-community edges* are those edges joining a pair of nodes
    in different blocks of the partition.

    Implementation note: this function creates an intermediate graph
    that may require the same amount of memory as required to store
    `G`.

    t   create_usingN(   t   is_directedR   t   quotient_grapht   MultiDiGraphR   t
   MultiGraph(   R   R   (    (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyt   inter_community_edges]   s    "c         C   s   t  t j |   |  S(   sH  Returns the number of inter-community non-edges according to the
    given partition of the nodes of `G`.

    `G` must be a NetworkX graph.

    `partition` must be a partition of the nodes of `G`.

    A *non-edge* is a pair of nodes (undirected if `G` is undirected)
    that are not adjacent in `G`. The *inter-community non-edges* are
    those non-edges on a pair of nodes in different blocks of the
    partition.

    Implementation note: this function creates two intermediate graphs,
    which may require up to twice the amount of memory as required to
    store `G`.

    (   R&   R   t
   complement(   R   R   (    (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyt   inter_community_non_edges{   s    t
   multigraphc         C   s]   t  |  |  } t |  |  } t |   } | | d } |  j   sQ | d } n  | | | S(   s  Returns the performance of a partition.

    The *performance* of a partition is the ratio of the number of
    intra-community edges plus inter-community non-edges with the total
    number of potential edges.

    Parameters
    ----------
    G : NetworkX graph
        A simple graph (directed or undirected).

    partition : sequence

        Partition of the nodes of `G`, represented as a sequence of
        sets of nodes. Each block of the partition represents a
        community.

    Returns
    -------
    float
        The performance of the partition, as defined above.

    Raises
    ------
    NetworkXError
        If `partition` is not a valid partition of the nodes of `G`.

    References
    ----------
    .. [1] Santo Fortunato.
           "Community Detection in Graphs".
           *Physical Reports*, Volume 486, Issue 3--5 pp. 75--174
           <https://arxiv.org/abs/0906.0612>

    i   i   (   R    R(   t   lenR"   (   R   R   t   intra_edgest   inter_edgest   nt   total_pairs(    (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyR      s    (c         C   s#   t  |  |  } |  j   } | | S(   s  Returns the coverage of a partition.

    The *coverage* of a partition is the ratio of the number of
    intra-community edges to the total number of edges in the graph.

    Parameters
    ----------
    G : NetworkX graph

    partition : sequence
        Partition of the nodes of `G`, represented as a sequence of
        sets of nodes. Each block of the partition represents a
        community.

    Returns
    -------
    float
        The coverage of the partition, as defined above.

    Raises
    ------
    NetworkXError
        If `partition` is not a valid partition of the nodes of `G`.

    Notes
    -----
    If `G` is a multigraph, the multiplicity of edges is counted.

    References
    ----------
    .. [1] Santo Fortunato.
           "Community Detection in Graphs".
           *Physical Reports*, Volume 486, Issue 3--5 pp. 75--174
           <https://arxiv.org/abs/0906.0612>

    (   R    t   number_of_edges(   R   R   R+   t   total_edges(    (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyR   Ď   s    &t   weightc            s˙   t    |  s! t   |   n    j      j      j d   }  r t   j d     t   j d     d |  n, t   j d       d d |          f d    t	  f d   | D  } |  S(   s#  Returns the modularity of the given partition of the graph.

    Modularity is defined in [1]_ as

    .. math::

        Q = \frac{1}{2m} \sum_{ij} \left( A_{ij} - \frac{k_ik_j}{2m}\right)
            \delta(c_i,c_j)

    where $m$ is the number of edges, $A$ is the adjacency matrix of
    `G`, $k_i$ is the degree of $i$ and $\delta(c_i, c_j)$
    is 1 if $i$ and $j$ are in the same community and 0 otherwise.

    Parameters
    ----------
    G : NetworkX Graph

    communities : list
        List of sets of nodes of `G` representing a partition of the
        nodes.

    Returns
    -------
    Q : float
        The modularity of the paritition.

    Raises
    ------
    NotAPartition
        If `communities` is not a partition of the nodes of `G`.

    Examples
    --------
    >>> G = nx.barbell_graph(3, 0)
    >>> nx.algorithms.community.modularity(G, [{0, 1, 2}, {3, 4, 5}])
    0.35714285714285704

    References
    ----------
    .. [1] M. E. J. Newman *Networks: An Introduction*, page 224.
       Oxford University Press, 2011.

    R1   i   i   c            sŁ   yQ  r6 t   f d     |  | j   D  } n   |  | j  d  } Wn t k
 rj d } n X|  | k r  r | d 9} n  |  |   |  S(   Nc         3   s'   |  ] \ } } | j    d   Vq d S(   i   N(   t   get(   R   t   kt   d(   R1   (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pys	   <genexpr>8  s    i   i    i   (   R   t   itemsR2   t   KeyError(   t   ut   vt   w(   R   t   directedt	   in_degreeR)   t   normt
   out_degreeR1   (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyt   val5  s    -
c         3   s=   |  ]3 } t  | d  d D] \ } }   | |  Vq q d S(   t   repeati   N(   R   (   R   t   cR7   R8   (   R>   (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pys	   <genexpr>B  s    (
   R   R	   t   is_multigraphR"   R   t   dictR=   R;   t   degreeR   (   R   t   communitiesR1   t   mt   Q(    (   R   R:   R;   R)   R<   R=   R>   R1   sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyR   ú   s    ,!(   R   t
   __future__R    t	   functoolsR   t	   itertoolsR   t   networkxR   R   t   networkx.utilsR   t-   networkx.algorithms.community.community_utilsR   t   __all__R	   R   R    R&   R(   R   R   R   (    (    (    sD   lib/python2.7/site-packages/networkx/algorithms/community/quality.pyt   <module>   s"   	)				6+