
    h.                     @   S r SSKJr  SSKrSSKJr  SSKJr  SSKJ	r	  SS/r
 " S	 S
\5      rS r\	" \S5      r\R                  S 5       r\R                  S 5       r\R                  S 5       r\R                  " SS9SS j5       r\\R                  S 5       5       rg)zHFunctions for measuring the quality of a partition (into
communities).

    )combinationsN)NetworkXError)is_partition)argmap
modularitypartition_qualityc                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )NotAPartition   z0Raised if a given collection is not a partition.c                 2   > U SU 3n[         TU ]  U5        g )Nz' is not a valid partition of the graph )super__init__)selfG
collectionmsg	__class__s       W/var/www/html/env/lib/python3.13/site-packages/networkx/algorithms/community/quality.pyr   NotAPartition.__init__   s!    CA3G     )__name__
__module____qualname____firstlineno____doc__r   __static_attributes____classcell__)r   s   @r   r
   r
      s    : r   r
   c                 T    [        X5      (       a  X4$ [        R                  " S5      e)a  Decorator to check that a valid partition is input to a function

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)
    Traceback (most recent call last):
      ...
    networkx.exception.NetworkXError: `partition` is not a valid partition of the nodes of G
    >>> partition = [{0, 1}, {1, 2, 3}, {4}]
    >>> foo(G, partition)
    Traceback (most recent call last):
      ...
    networkx.exception.NetworkXError: `partition` is not a valid partition of the nodes of G

z6`partition` is not a valid partition of the nodes of G)r   nxr   r   	partitions     r   _require_partitionr#      s)    : A!!|


S
TTr   )r      c                 .   ^  [        U 4S jU 5       5      $ )a2  Returns the number of intra-community edges for a partition of `G`.

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

partition : iterable of sets of nodes
    This 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   b   >#    U  H$  nTR                  U5      R                  5       v   M&     g 7fN)subgraphsize).0blockr   s     r   	<genexpr>(intra_community_edges.<locals>.<genexpr>L   s&     ?YEqzz% %%''Ys   ,/)sumr!   s   ` r   intra_community_edgesr/   =   s     ?Y???r   c                     U R                  5       (       a  [        R                  O[        R                  n[        R                  " XUS9R                  5       $ )a  Returns the number of inter-community edges for a partition of `G`.
according to the given
partition of the nodes of `G`.

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

partition : iterable of sets of nodes
    This 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 that of `G`.

)create_using)is_directedr    MultiDiGraph
MultiGraphquotient_graphr)   )r   r"   MGs      r   inter_community_edgesr7   O   s9    8 MMOOBQ;@@BBr   c                 B    [        [        R                  " U 5      U5      $ )aK  Returns the number of inter-community non-edges according to the
given partition of the nodes of `G`.

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

partition : iterable of sets of nodes
    This 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`.

)r7   r    
complementr!   s     r   inter_community_non_edgesr:   o   s    < !q!19==r   weight)
edge_attrsc                    ^ ^^^^^^	^
 [        U[        5      (       d  [        U5      n[        T U5      (       d  [        T U5      eT R	                  5       mT(       aR  [        T R                  TS95      m
[        T R                  TS95      m[        T
R                  5       5      mSTS-  -  m	O@[        T R                  TS95      =m
m[        T
R                  5       5      nUS-  mSUS-  -  m	U UUUU	U
UU4S jn[        [        XQ5      5      $ )a/  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} - \gamma\frac{k_ik_j}{2m}\right)
        \delta(c_i,c_j)

where $m$ is the number of edges (or sum of all edge weights as in [5]_),
$A$ is the adjacency matrix of `G`, $k_i$ is the (weighted) degree of $i$,
$\gamma$ is the resolution parameter, and $\delta(c_i, c_j)$ is 1 if $i$ and
$j$ are in the same community else 0.

According to [2]_ (and verified by some algebra) this can be reduced to

.. math::
   Q = \sum_{c=1}^{n}
   \left[ \frac{L_c}{m} - \gamma\left( \frac{k_c}{2m} \right) ^2 \right]

where the sum iterates over all communities $c$, $m$ is the number of edges,
$L_c$ is the number of intra-community links for community $c$,
$k_c$ is the sum of degrees of the nodes in community $c$,
and $\gamma$ is the resolution parameter.

The resolution parameter sets an arbitrary tradeoff between intra-group
edges and inter-group edges. More complex grouping patterns can be
discovered by analyzing the same network with multiple values of gamma
and then combining the results [3]_. That said, it is very common to
simply use gamma=1. More on the choice of gamma is in [4]_.

The second formula is the one actually used in calculation of the modularity.
For directed graphs the second formula replaces $k_c$ with $k^{in}_c k^{out}_c$.

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

communities : list or iterable of set of nodes
    These node sets must represent a partition of G's nodes.

weight : string or None, optional (default="weight")
    The edge attribute that holds the numerical value used
    as a weight. If None or an edge does not have that attribute,
    then that edge has weight 1.

resolution : float (default=1)
    If resolution is less than 1, modularity favors larger communities.
    Greater than 1 favors smaller communities.

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

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

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

References
----------
.. [1] M. E. J. Newman "Networks: An Introduction", page 224.
   Oxford University Press, 2011.
.. [2] Clauset, Aaron, Mark EJ Newman, and Cristopher Moore.
   "Finding community structure in very large networks."
   Phys. Rev. E 70.6 (2004). <https://arxiv.org/abs/cond-mat/0408187>
.. [3] Reichardt and Bornholdt "Statistical Mechanics of Community Detection"
   Phys. Rev. E 74, 016110, 2006. https://doi.org/10.1103/PhysRevE.74.016110
.. [4] M. E. J. Newman, "Equivalence between modularity optimization and
   maximum likelihood methods for community detection"
   Phys. Rev. E 94, 052315, 2016. https://doi.org/10.1103/PhysRevE.94.052315
.. [5] Blondel, V.D. et al. "Fast unfolding of communities in large
   networks" J. Stat. Mech 10008, 1-12 (2008).
   https://doi.org/10.1088/1742-5468/2008/10/P10008
)r;   r$      c           	         >^ [        U 5      m[        U4S jTR                  TTSS9 5       5      n[        U
4S jT 5       5      nT(       a  [        U4S jT 5       5      OUnUT-  TU-  U-  T	-  -
  $ )Nc              3   <   >#    U  H  u  po2T;   d  M  Uv   M     g 7fr'   r   )r*   uvwtcomms       r   r,   =modularity.<locals>.community_contribution.<locals>.<genexpr>   s     X%JrSWi""%Js   	r$   )datadefaultc              3   .   >#    U  H
  nTU   v   M     g 7fr'   r   )r*   rA   
out_degrees     r   r,   rE      s     9DqZ]D   c              3   .   >#    U  H
  nTU   v   M     g 7fr'   r   )r*   rA   	in_degrees     r   r,   rE      s     7$QIaL$rJ   )setr.   edges)	communityL_cout_degree_sumin_degree_sumrD   r   directedrL   mnormrI   
resolutionr;   s       @r   community_contribution*modularity.<locals>.community_contribution   sm    9~XQWWTW%JXX9D99;C7$77Qwn4}DtKKKr   )
isinstancelistr   r
   r2   dictrI   rL   r.   valuesdegreemap)r   communitiesr;   rV   deg_sumrW   rS   rL   rT   rU   rI   s   ` ``  @@@@@r   r   r      s    j k4((;';''A{++}}H!,,f,56
F34	
!!#$1a4x!%ahhfh&=!>>
Yj'')*aK7A:~L L s)788r   c                 "   0 n[        U5       H  u  p4U H  nX2U'   M	     M     U R                  5       (       d7  [        S [        US5       5       5      nU R	                  5       (       a  US-  nOSn[        U 5      nXwS-
  -  nU R	                  5       (       d  US-  nSn	Un
U R                  5        H  nX+S      X+S      :X  a  U	S-  n	M  U
S-  n
M!     U	[        U R                  5      -  nU R                  5       (       a  SnX4$ X-   U-  nX4$ )a  Returns the coverage and performance of a partition of G.

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

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

This algorithm has complexity $O(C^2 + L)$ where C is the number of communities and L is the number of links.

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

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

Returns
-------
(float, float)
    The (coverage, performance) tuple 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;
    - for coverage, the multiplicity of edges is counted
    - for performance, the result is -1 (total number of possible edges is not defined)

References
----------
.. [1] Santo Fortunato.
       "Community Detection in Graphs".
       *Physical Reports*, Volume 486, Issue 3--5 pp. 75--174
       <https://arxiv.org/abs/0906.0612>
c              3   T   #    U  H  u  p[        U5      [        U5      -  v   M      g 7fr'   )len)r*   p1p2s      r   r,   $partition_quality.<locals>.<genexpr>9  s#      -
,F&"CGc"g,Fs   &(r>   r   r$   g      )	enumerateis_multigraphr.   r   r2   rc   rN   )r   r"   node_communityirO   nodepossible_inter_community_edgesntotal_pairsr/   r:   ecoverageperformances                 r   r   r     s8   ^ N!),D#$4   -
 ??), -
,8A,F-
 *
& ==??*a/*)*& 	AA1u+K==?? > WWYA$>A$#77!Q&!%*%	  %s177|3H    -HKW  r   )r;   r$   )r   	itertoolsr   networkxr    r   -networkx.algorithms.community.community_utilsr   networkx.utils.decoratorsr   __all__r
   r#   require_partition_dispatchabler/   r7   r:   r   r   r   r   r   <module>ry      s   
 #  " F ,,
-M UD -v6  @ @" C C> > >@ X&n9 'n9b V!  V!r   