U
    ¹mœdÅ  ã                   @   s\   d Z ddlZddlmZ dddgZedƒdd	d„ƒZedƒdd
d„ƒZedƒddd„ƒZdS )zTrophic levelsé    N)Únot_implemented_forÚtrophic_levelsÚtrophic_differencesÚtrophic_incoherence_parameterZ
undirectedÚweightc              
   C   s.  ddl }tj| |d�j ¡ }|j|dd�}||dk dd…|dkf }|||dk dd…|jf  }|jd }| |¡}z|j	 
|| ¡}W n6 |j	jk
rÂ }	 zd}
t |
¡|	‚W 5 d}	~	X Y nX |jdd�d }i }dd„ | jD ƒ}|D ]}d||< qìd	d„ | jD ƒ}t|ƒD ]\}}|| ||< �q|S )
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   N©r   é   )ZaxiszˆTrophic levels are only defined for graphs where every node has a path from a basal node (basal nodes are nodes with no incoming edges).c                 s   s   | ]\}}|d kr|V  qdS ©r   N© ©Ú.0Únode_idZdegreer
   r
   ú_/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/networkx/algorithms/centrality/trophic.pyÚ	<genexpr>G   s      z!trophic_levels.<locals>.<genexpr>c                 s   s   | ]\}}|d kr|V  qdS r	   r
   r   r
   r
   r   r   L   s      )ÚnumpyÚnxZadjacency_matrixÚTZtoarrayÚsumZnewaxisÚshapeÚeyeZlinalgÚinvZLinAlgErrorZNetworkXErrorZ	in_degreeÚ	enumerate)ÚGr   ÚnpÚaZrowsumÚpÚnnÚiÚnÚerrÚmsgÚyÚlevelsZzero_node_idsr   Znonzero_node_idsr
   r
   r   r      s,    "

ÿ
c                 C   s<   t | |d�}i }| jD ] \}}|| ||  |||f< q|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Úvr
   r
   r   r   S   s
    Fc                 C   sb   ddl }|rt| |d�}n6tt | ¡ƒ}|r@|  ¡ }| |¡ n| }t||d�}| t| ¡ ƒ¡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   Zselfloop_edgesÚcopyZremove_edges_fromZstdÚvalues)r   r   Zcannibalismr   r$   Z
self_loopsZG_2r
   r
   r   r   u   s    )r   )r   )r   F)	Ú__doc__Znetworkxr   Znetworkx.utilsr   Ú__all__r   r   r   r
   r
   r
   r   Ú<module>   s   
J!