Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/networkx/algorithms/centrality/trophic.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 """Trophic levels""" | |
2 import networkx as nx | |
3 | |
4 from networkx.utils import not_implemented_for | |
5 | |
6 __all__ = ["trophic_levels", "trophic_differences", "trophic_incoherence_parameter"] | |
7 | |
8 | |
9 @not_implemented_for("undirected") | |
10 def trophic_levels(G, weight="weight"): | |
11 r"""Compute the trophic levels of nodes. | |
12 | |
13 The trophic level of a node $i$ is | |
14 | |
15 .. math:: | |
16 | |
17 s_i = 1 + \frac{1}{k^{in}_i} \sum_{j} a_{ij} s_j | |
18 | |
19 where $k^{in}_i$ is the in-degree of i | |
20 | |
21 .. math:: | |
22 | |
23 k^{in}_i = \sum_{j} a_{ij} | |
24 | |
25 and nodes with $k^{in}_i = 0$ have $s_i = 1$ by convention. | |
26 | |
27 These are calculated using the method outlined in Levine [1]_. | |
28 | |
29 Parameters | |
30 ---------- | |
31 G : DiGraph | |
32 A directed networkx graph | |
33 | |
34 Returns | |
35 ------- | |
36 nodes : dict | |
37 Dictionary of nodes with trophic level as the vale. | |
38 | |
39 References | |
40 ---------- | |
41 .. [1] Stephen Levine (1980) J. theor. Biol. 83, 195-207 | |
42 """ | |
43 try: | |
44 import numpy as np | |
45 except ImportError as e: | |
46 raise ImportError("trophic_levels() requires NumPy: http://numpy.org/") from e | |
47 | |
48 # find adjacency matrix | |
49 a = nx.adjacency_matrix(G, weight=weight).T.toarray() | |
50 | |
51 # drop rows/columns where in-degree is zero | |
52 rowsum = np.sum(a, axis=1) | |
53 p = a[rowsum != 0][:, rowsum != 0] | |
54 # normalise so sum of in-degree weights is 1 along each row | |
55 p = p / rowsum[rowsum != 0][:, np.newaxis] | |
56 | |
57 # calculate trophic levels | |
58 nn = p.shape[0] | |
59 i = np.eye(nn) | |
60 try: | |
61 n = np.linalg.inv(i - p) | |
62 except np.linalg.LinAlgError as err: | |
63 # LinAlgError is raised when there is a non-basal node | |
64 msg = ( | |
65 "Trophic levels are only defined for graphs where every " | |
66 + "node has a path from a basal node (basal nodes are nodes " | |
67 + "with no incoming edges)." | |
68 ) | |
69 raise nx.NetworkXError(msg) from err | |
70 y = n.sum(axis=1) + 1 | |
71 | |
72 levels = {} | |
73 | |
74 # all nodes with in-degree zero have trophic level == 1 | |
75 zero_node_ids = (node_id for node_id, degree in G.in_degree if degree == 0) | |
76 for node_id in zero_node_ids: | |
77 levels[node_id] = 1 | |
78 | |
79 # all other nodes have levels as calculated | |
80 nonzero_node_ids = (node_id for node_id, degree in G.in_degree if degree != 0) | |
81 for i, node_id in enumerate(nonzero_node_ids): | |
82 levels[node_id] = y[i] | |
83 | |
84 return levels | |
85 | |
86 | |
87 @not_implemented_for("undirected") | |
88 def trophic_differences(G, weight="weight"): | |
89 r"""Compute the trophic differences of the edges of a directed graph. | |
90 | |
91 The trophic difference $x_ij$ for each edge is defined in Johnson et al. | |
92 [1]_ as: | |
93 | |
94 .. math:: | |
95 x_ij = s_j - s_i | |
96 | |
97 Where $s_i$ is the trophic level of node $i$. | |
98 | |
99 Parameters | |
100 ---------- | |
101 G : DiGraph | |
102 A directed networkx graph | |
103 | |
104 Returns | |
105 ------- | |
106 diffs : dict | |
107 Dictionary of edges with trophic differences as the value. | |
108 | |
109 References | |
110 ---------- | |
111 .. [1] Samuel Johnson, Virginia Dominguez-Garcia, Luca Donetti, Miguel A. | |
112 Munoz (2014) PNAS "Trophic coherence determines food-web stability" | |
113 """ | |
114 levels = trophic_levels(G, weight=weight) | |
115 diffs = {} | |
116 for u, v in G.edges: | |
117 diffs[(u, v)] = levels[v] - levels[u] | |
118 return diffs | |
119 | |
120 | |
121 @not_implemented_for("undirected") | |
122 def trophic_incoherence_parameter(G, weight="weight", cannibalism=False): | |
123 r"""Compute the trophic incoherence parameter of a graph. | |
124 | |
125 Trophic coherence is defined as the homogeneity of the distribution of | |
126 trophic distances: the more similar, the more coherent. This is measured by | |
127 the standard deviation of the trophic differences and referred to as the | |
128 trophic incoherence parameter $q$ by [1]. | |
129 | |
130 Parameters | |
131 ---------- | |
132 G : DiGraph | |
133 A directed networkx graph | |
134 | |
135 cannibalism: Boolean | |
136 If set to False, self edges are not considered in the calculation | |
137 | |
138 Returns | |
139 ------- | |
140 trophic_incoherence_parameter : float | |
141 The trophic coherence of a graph | |
142 | |
143 References | |
144 ---------- | |
145 .. [1] Samuel Johnson, Virginia Dominguez-Garcia, Luca Donetti, Miguel A. | |
146 Munoz (2014) PNAS "Trophic coherence determines food-web stability" | |
147 """ | |
148 try: | |
149 import numpy as np | |
150 except ImportError as e: | |
151 raise ImportError( | |
152 "trophic_incoherence_parameter() requires NumPy: " "http://scipy.org/" | |
153 ) from e | |
154 | |
155 if cannibalism: | |
156 diffs = trophic_differences(G, weight=weight) | |
157 else: | |
158 # If no cannibalism, remove self-edges | |
159 self_loops = list(nx.selfloop_edges(G)) | |
160 if self_loops: | |
161 # Make a copy so we do not change G's edges in memory | |
162 G_2 = G.copy() | |
163 G_2.remove_edges_from(self_loops) | |
164 else: | |
165 # Avoid copy otherwise | |
166 G_2 = G | |
167 diffs = trophic_differences(G_2, weight=weight) | |
168 return np.std(list(diffs.values())) |