def test_distance_matrix_equal_across_objects(random_paths): """test that the distance matrix is the same if constructed from to path objects with the same paths but different instances""" p1 = random_paths(40, 20, num_nodes=9) p2 = random_paths(40, 20, num_nodes=9) hon1 = pp.HigherOrderNetwork(paths=p1, k=1) hon2 = pp.HigherOrderNetwork(paths=p2, k=1) d_matrix1 = shortest_paths.distance_matrix(hon1) d_matrix2 = shortest_paths.distance_matrix(hon2) assert d_matrix1 == d_matrix2
def test_distance_matrix_first_order_eq_dist_matrix(random_paths, paths, num_nodes): """test that the distance matrix of k=1 is equal to distance_matrix_first_order""" p = random_paths(paths, 10, num_nodes) hon = pp.HigherOrderNetwork(p, k=1) dist = shortest_paths.distance_matrix(hon) dist_alt = shortest_paths.distance_matrix(hon) m = dict_of_dicts_to_matrix(dist) m_alt = dict_of_dicts_to_matrix(dist_alt) assert np.allclose(m, m_alt)
def test_distance_matrix_first_order(random_paths, n_nodes, k, paths, e_sum): p = random_paths(paths, 10, n_nodes) hon_k, hon_1 = pp.HigherOrderNetwork(p, k=k), pp.HigherOrderNetwork(p, k=1) dist_k = shortest_paths.distance_matrix(hon_k) dist_1 = shortest_paths.distance_matrix(hon_1) total_distance = 0 for source, target in itertools.product(hon_1.nodes, hon_1.nodes): dist_st = dist_k[source][target] assert dist_1[source][target] <= dist_k[source][target], \ "not all distances at order k are at least as long as at order 1" if dist_st < np.inf: total_distance += dist_st assert total_distance == e_sum
def closeness_centrality(network: Network, normalized: bool = False) -> Dict: """Calculates the closeness centrality of all nodes. .. note:: If `normalized=False` (Default) for each node v the closeness centrality is given as 1/sum_w(dist(v,w)) where dist(v,w) is the shortest path distance between v and w. For `normalized=True` the counter is multiplied by n-1 where n is the number of nodes in the network. Shortest path distances are calculated using the function `shortest_paths.distance_matrix`. Parameters ---------- network : Network The :py:class:`Network` object that contains the network normalized : bool If True the resulting centralities will be normalized based on the average shortest path length. Examples -------- Compute closeness centrality in a simple network >>> import pathpy as pp >>> net = pp.Network(directed=False) >>> net.add_edge('a', 'x') >>> net.add_edge('x', 'b') >>> c = pp.algorithms.centralities.closeness_centrality(net) >>> c['a'] 0.3333333333333333 """ distances = shortest_paths.distance_matrix(network) cl: defaultdict = defaultdict(float) mapping = {v: k for k, v in network.nodes.index.items()} n = network.number_of_nodes() # calculate closeness values for d in range(n): for x in range(n): if d != x and distances[d, x] < np.inf: cl[mapping[x]] += distances[d, x] # assign centrality zero to nodes not occurring # on higher-order shortest paths for v in network.nodes.uids: cl[v] += 0.0 if cl[v] > 0.0: cl[v] = 1.0 / cl[v] if normalized: cl[v] *= n-1 return cl
def test_distance_matrix(random_paths, paths, n_nodes, k, e_var, e_sum): p = random_paths(paths, 20, num_nodes=n_nodes) hon = pp.HigherOrderNetwork(paths=p, k=k) d_matrix = shortest_paths.distance_matrix(hon) np_matrix = dict_of_dicts_to_matrix(d_matrix) assert np.var(np_matrix) == pytest.approx(e_var) assert np.sum(np_matrix) == e_sum
def test_distance_matrix_from_file(path_from_edge_file): p = path_from_edge_file hon = pp.HigherOrderNetwork(paths=p, k=1) d_matrix = shortest_paths.distance_matrix(hon) np_matrix = dict_of_dicts_to_matrix(d_matrix) assert np.sum(np_matrix) == 8 assert np.min(np_matrix) == 0 assert np.max(np_matrix) == 2
def _cl_paths(paths: PathCollection, normalized: bool = False, disconnected=False, weight: Optional[str] = None, count: bool = False) -> Dict: """Betweenness Centrality for Paths.""" if disconnected and normalized: raise ParameterError( 'No meaningful definition for normalized closeness centrality in disconnected networks' ) node_centralities = defaultdict(lambda: 0) distances = shortest_paths.distance_matrix(paths, weight=weight, count=count) n = len(paths.nodes) for v in paths.nodes: for w in paths.nodes: if v != w: if w in distances[v]: dist = distances[v][w] else: dist = np.inf if disconnected: node_centralities[v] += 1.0 / dist else: node_centralities[v] += dist for v in paths.nodes: # assign zero value to nodes not occurring node_centralities[v] += 0 if not disconnected: if node_centralities[v] > 0: node_centralities[v] = 1.0 / node_centralities[v] else: node_centralities[v] = np.inf # normalize if normalized: node_centralities[v] *= n - 1 return node_centralities
def _cl_network(network: BaseNetwork, normalized: bool = False, disconnected=False, weight: Optional[str] = None, count: bool = False) -> Dict: """Calculates the closeness centrality of all nodes. .. note:: If `normalized=False` (Default) for each node v the closeness centrality is given as 1/sum_w(dist(v,w)) where dist(v,w) is the shortest path distance between v and w. For `normalized=True` the counter is multiplied by n-1 where n is the number of nodes in the network. Shortest path distances are calculated using the function `shortest_paths.distance_matrix`. Parameters ---------- network : Network The :py:class:`Network` object that contains the network normalized : bool If True the resulting centralities will be normalized based on the average shortest path length. Examples -------- Compute closeness centrality in a simple network >>> import pathpy as pp >>> net = pp.Network(directed=False) >>> net.add_edge('a', 'x') >>> net.add_edge('x', 'b') >>> c = pp.algorithms.centralities.closeness_centrality(net) >>> c['a'] 0.3333333333333333 """ distances = shortest_paths.distance_matrix(network, weight=weight, count=count) cl: defaultdict = defaultdict(float) if disconnected and normalized: raise ParameterError( 'No meaningful definition for normalized closeness centrality in disconnected networks' ) mapping = {v: k for k, v in network.nodes.index.items()} n = network.number_of_nodes() for v in range(n): for w in range(n): if v != w: if disconnected: cl[mapping[v]] += 1.0 / distances[v, w] else: cl[mapping[v]] += distances[v, w] for v in network.nodes.uids: # assign centrality zero to nodes not occurring on shortest path cl[v] += 0.0 if not disconnected: cl[v] = 1.0 / cl[v] # normalize if normalized: cl[v] *= n - 1 return cl