
    Vh                        d Z ddlZddlmZ g dZ ed       ej                  d      dd              Z ed       ej                  d      dd	              Z ed       ej                  d      dd
              Z	y)zTrophic levels    N)not_implemented_for)trophic_levelstrophic_differencestrophic_incoherence_parameter
undirectedweight)
edge_attrsc                    | j                   D cg c]  \  }}|dk(  s| }}}|st        j                  d      t        j                  | |      D ch c]  }|D ]  }|  }}}t	        |      t	        | j
                        k7  rt        j                  d      ddl}t        j                  | |      j                  j                         }	|j                  |	d      }
|	|
dk7     dd|
dk7  f   }||
|
dk7     dd|j                  f   z  }|j                  d   }|j                  |      }	 |j                  j                  ||z
        }|j                  d      dz   }i }d	 | j                   D        }|D ]  }d||<   	 d
 | j                   D        }t#        |      D ]  \  }}|j%                  |      ||<    |S c c}}w c c}}w # |j                  j                   $ r}d}t        j                  |      |d}~ww xY w)a  Compute the trophic levels of nodes.

    The trophic level of a node $i$ is

    .. math::

        s_i = 1 + \frac{1}{k^{in}_i} \sum_{j} a_{ij} s_j

    where $k^{in}_i$ is the in-degree of i

    .. math::

        k^{in}_i = \sum_{j} a_{ij}

    and nodes with $k^{in}_i = 0$ have $s_i = 1$ by convention.

    These are calculated using the method outlined in Levine [1]_.

    Parameters
    ----------
    G : DiGraph
        A directed networkx graph

    Returns
    -------
    nodes : dict
        Dictionary of nodes with trophic level as the value.

    References
    ----------
    .. [1] Stephen Levine (1980) J. theor. Biol. 83, 195-207
    r   z|This graph has no basal nodes (nodes with no incoming edges).Trophic levels are not defined without at least one basal node.)sourceszTrophic levels are only defined for graphs where every node has a path from a basal node (basal nodes are nodes with no incoming edges).Nr      )axisc              3   2   K   | ]  \  }}|d k(  s|  ywr   N .0node_iddegrees      V/home/dcms/DCMS/lib/python3.12/site-packages/networkx/algorithms/centrality/trophic.py	<genexpr>z!trophic_levels.<locals>.<genexpr>[   s     O&6Q;WO   c              3   2   K   | ]  \  }}|d k7  s|  ywr   r   r   s      r   r   z!trophic_levels.<locals>.<genexpr>`   s     ROGVfPQkRr   )	in_degreenxNetworkXError
bfs_layerslennodesnumpyadjacency_matrixTtoarraysumnewaxisshapeeyelinalginvLinAlgError	enumerateitem)Gr   ndegbasal_nodeslayernodereachable_nodesnparowsumpnnierrmsgylevelszero_node_idsr   nonzero_node_idss                        r   r   r   	   s%   H $%;;;C#(1;K;N
 	
 --;?EDHO  ?s177|+P
 	

  	Af-//779A VVAAVF	&A+q&A+~&A	F6Q;2::..A 
B
r
A	-IIMM!a%  	
1AF PAKKOM  w Sq{{R 01 $
7&&)w$ Mo <4 99   -) 	
 s#,-s(   GGG
4G H)HHc                 l    t        | |      }i }| j                  D ]  \  }}||   ||   z
  |||f<    |S )as  Compute the trophic differences of the edges of a directed graph.

    The trophic difference $x_ij$ for each edge is defined in Johnson et al.
    [1]_ as:

    .. math::
        x_ij = s_j - s_i

    Where $s_i$ is the trophic level of node $i$.

    Parameters
    ----------
    G : DiGraph
        A directed networkx graph

    Returns
    -------
    diffs : dict
        Dictionary of edges with trophic differences as the value.

    References
    ----------
    .. [1] Samuel Johnson, Virginia Dominguez-Garcia, Luca Donetti, Miguel A.
        Munoz (2014) PNAS "Trophic coherence determines food-web stability"
    r   )r   edges)r-   r   r=   diffsuvs         r   r   r   g   sK    8 Af-FE .1q	F1I-q!f.L    c                 .   ddl }|rt        | |      }nQt        t        j                  |             }|r"| j                         }|j                  |       n| }t        ||      }t        |j                  t        |j                                           S )a+  Compute the trophic incoherence parameter of a graph.

    Trophic coherence is defined as the homogeneity of the distribution of
    trophic distances: the more similar, the more coherent. This is measured by
    the standard deviation of the trophic differences and referred to as the
    trophic incoherence parameter $q$ by [1].

    Parameters
    ----------
    G : DiGraph
        A directed networkx graph

    cannibalism: Boolean
        If set to False, self edges are not considered in the calculation

    Returns
    -------
    trophic_incoherence_parameter : float
        The trophic coherence of a graph

    References
    ----------
    .. [1] Samuel Johnson, Virginia Dominguez-Garcia, Luca Donetti, Miguel A.
        Munoz (2014) PNAS "Trophic coherence determines food-web stability"
    r   Nr   )
r    r   listr   selfloop_edgescopyremove_edges_fromfloatstdvalues)r-   r   cannibalismr4   rB   
self_loopsG_2s          r   r   r      s{    8 #Af5 "++A./
&&(C!!*- C#C7U\\^,-..rE   r   )r   F)
__doc__networkxr   networkx.utilsr   __all___dispatchabler   r   r   r   rE   r   <module>rV      s      .
T \"X&Y ' #Yx \"X& ' #B \"X&)/ ' #)/rE   