diff env/lib/python3.9/site-packages/networkx/algorithms/reciprocity.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.9/site-packages/networkx/algorithms/reciprocity.py	Mon Mar 22 18:12:50 2021 +0000
@@ -0,0 +1,94 @@
+"""Algorithms to calculate reciprocity in a directed graph."""
+from networkx import NetworkXError
+from ..utils import not_implemented_for
+
+__all__ = ["reciprocity", "overall_reciprocity"]
+
+
+@not_implemented_for("undirected", "multigraph")
+def reciprocity(G, nodes=None):
+    r"""Compute the reciprocity in a directed graph.
+
+    The reciprocity of a directed graph is defined as the ratio
+    of the number of edges pointing in both directions to the total
+    number of edges in the graph.
+    Formally, $r = |{(u,v) \in G|(v,u) \in G}| / |{(u,v) \in G}|$.
+
+    The reciprocity of a single node u is defined similarly,
+    it is the ratio of the number of edges in both directions to
+    the total number of edges attached to node u.
+
+    Parameters
+    ----------
+    G : graph
+       A networkx directed graph
+    nodes : container of nodes, optional (default=whole graph)
+       Compute reciprocity for nodes in this container.
+
+    Returns
+    -------
+    out : dictionary
+       Reciprocity keyed by node label.
+
+    Notes
+    -----
+    The reciprocity is not defined for isolated nodes.
+    In such cases this function will return None.
+
+    """
+    # If `nodes` is not specified, calculate the reciprocity of the graph.
+    if nodes is None:
+        return overall_reciprocity(G)
+
+    # If `nodes` represents a single node in the graph, return only its
+    # reciprocity.
+    if nodes in G:
+        reciprocity = next(_reciprocity_iter(G, nodes))[1]
+        if reciprocity is None:
+            raise NetworkXError("Not defined for isolated nodes.")
+        else:
+            return reciprocity
+
+    # Otherwise, `nodes` represents an iterable of nodes, so return a
+    # dictionary mapping node to its reciprocity.
+    return dict(_reciprocity_iter(G, nodes))
+
+
+def _reciprocity_iter(G, nodes):
+    """ Return an iterator of (node, reciprocity).
+    """
+    n = G.nbunch_iter(nodes)
+    for node in n:
+        pred = set(G.predecessors(node))
+        succ = set(G.successors(node))
+        overlap = pred & succ
+        n_total = len(pred) + len(succ)
+
+        # Reciprocity is not defined for isolated nodes.
+        # Return None.
+        if n_total == 0:
+            yield (node, None)
+        else:
+            reciprocity = 2.0 * float(len(overlap)) / float(n_total)
+            yield (node, reciprocity)
+
+
+@not_implemented_for("undirected", "multigraph")
+def overall_reciprocity(G):
+    """Compute the reciprocity for the whole graph.
+
+    See the doc of reciprocity for the definition.
+
+    Parameters
+    ----------
+    G : graph
+       A networkx graph
+
+    """
+    n_all_edge = G.number_of_edges()
+    n_overlap_edge = (n_all_edge - G.to_undirected().number_of_edges()) * 2
+
+    if n_all_edge == 0:
+        raise NetworkXError("Not defined for empty graphs")
+
+    return float(n_overlap_edge) / float(n_all_edge)