From b23b4a636787d6cd31ec4f9de09ecd7ca0469717 Mon Sep 17 00:00:00 2001 From: Silmathoron Date: Thu, 8 Oct 2020 12:07:15 +0200 Subject: [PATCH] fixed clustering for node subset --- nngt/analysis/clustering.py | 16 +++++++++------- testing/test_analysis.py | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/nngt/analysis/clustering.py b/nngt/analysis/clustering.py index ad3a1b06..d5a76c6a 100644 --- a/nngt/analysis/clustering.py +++ b/nngt/analysis/clustering.py @@ -24,6 +24,7 @@ import numpy as np import nngt +from nngt.lib import nonstring_container __all__ = [ @@ -295,6 +296,8 @@ def local_clustering(g, nodes=None, directed=True, weights=None, directed *= g.is_directed() weighted = weights not in (None, False) + triplets, triangles = None, None + if not directed and not weighted: # undirected binary clustering uses the library method return local_clustering_binary_undirected(g, nodes=nodes) @@ -302,15 +305,14 @@ def local_clustering(g, nodes=None, directed=True, weights=None, # directed clustering triangles = triangle_count(g, nodes=nodes, mode=mode) triplets = triplet_count(g, nodes, mode=mode).astype(float) + else: + triangles, triplets = _triangles_and_triplets( + g, directed, weights, method, mode, combine_weights, nodes) + if nonstring_container(triplets): triplets[triangles == 0] = 1 - - return triangles / triplets - - triangles, triplets = _triangles_and_triplets( - g, directed, weights, method, mode, combine_weights, nodes) - - triplets[triangles == 0] = 1 + elif triangles == 0: + return 0 return triangles / triplets diff --git a/testing/test_analysis.py b/testing/test_analysis.py index ca2dd350..41dc44ea 100644 --- a/testing/test_analysis.py +++ b/testing/test_analysis.py @@ -325,12 +325,25 @@ def test_clustering_parameters(): cc_bu = na.local_clustering_binary_undirected(g) for m in methods: + # combine for combine in ("sum", "max", "min", "mean"): cc_wu = na.local_clustering(g, directed=False, weights=True, combine_weights=combine, method=m) assert np.all(np.isclose(cc_wu, cc_bu)) + # subset of nodes + nodes = [1, [1, 2]] + + for n in nodes: + cc = na.local_clustering_binary_undirected(g, nodes=n) + + assert np.all(np.isclose(cc, cc_bu[n])) + + cc = na.local_clustering(g, nodes=n, method=m) + + assert np.all(np.isclose(cc, cc_bu[n])) + # check different but equivalent matrices for m in methods: W = np.array([ @@ -358,6 +371,16 @@ def test_clustering_parameters(): assert np.all(np.isclose(cc_sum, cc_sym)) + # subset of nodes + nodes = [1, [1, 2]] + + cc_dir = na.local_clustering(g, weights="weight", method=m) + + for n in nodes: + cc = na.local_clustering(g, nodes=n, weights="weight", method=m) + + assert np.all(np.isclose(cc, cc_dir[n])) + @pytest.mark.mpi_skip def test_partial_directed_clustering(): @@ -610,11 +633,11 @@ def test_swp(): if __name__ == "__main__": if not nngt.get_config("mpi"): - test_binary_undirected_clustering() - test_weighted_undirected_clustering() - test_weighted_directed_clustering() - test_reciprocity() - test_iedges() - test_swp() - test_partial_directed_clustering() + # ~ test_binary_undirected_clustering() + # ~ test_weighted_undirected_clustering() + # ~ test_weighted_directed_clustering() + # ~ test_reciprocity() + # ~ test_iedges() + # ~ test_swp() + # ~ test_partial_directed_clustering() test_clustering_parameters()