From 018b3fccc9797f1924548fd0efbba1d2a7baa77d Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 8 Mar 2021 10:08:57 +0100 Subject: [PATCH 1/9] added s_metric method --- src/community/s_metric.jl | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/community/s_metric.jl diff --git a/src/community/s_metric.jl b/src/community/s_metric.jl new file mode 100644 index 000000000..ce1ecc4f9 --- /dev/null +++ b/src/community/s_metric.jl @@ -0,0 +1,33 @@ +""" + s_metric(g;norm=true) + +Return the normalised s-metric of `g`. + +The s-metric is defined as the sum of the product of degrees between pair of nodes +for every edge in `g`. [Ref](https://arxiv.org/abs/cond-mat/0501169) +It is normalised by the maximum s_metric obtained from the family of graph +with similar degree distribution. +s_max is computed from an approximation formula as in https://journals.aps.org/pre/pdf/10.1103/PhysRevE.75.046102 +If `norm=false`, no normalisation is performed. + +# Examples +```jldoctest +julia> using LightGraphs + +julia> s_metric(star_graph(4)) +0.6 +``` +""" + +function s_metric(g::AbstractGraph{T};norm=true) where T + s = zero(T) + for e in edges(g) + s += degree(g,src(e)) * degree(g,dst(e)) + end + if norm + sm = sum(degree(g).^3)/2 + return s/sm + else + return s + end +end From 0187e8930779b738d1e162a1e64be1c78058b371 Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 8 Mar 2021 11:00:00 +0100 Subject: [PATCH 2/9] added rich club metric --- docs/src/community.md | 1 + src/LightGraphs.jl | 3 ++- src/community/rich_club.jl | 23 +++++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/community/rich_club.jl diff --git a/docs/src/community.md b/docs/src/community.md index 2654978ef..69dbce85a 100644 --- a/docs/src/community.md +++ b/docs/src/community.md @@ -19,6 +19,7 @@ Pages = [ "community/label_propagation.jl", "community/modularity.jl", "community/assortativity.jl" + "community/rich_club.jl" ] Private = false ``` diff --git a/src/LightGraphs.jl b/src/LightGraphs.jl index 221092db4..92a58e825 100644 --- a/src/LightGraphs.jl +++ b/src/LightGraphs.jl @@ -114,7 +114,7 @@ barabasi_albert!, static_fitness_model, static_scale_free, kronecker, dorogovtse #community modularity, core_periphery_deg, local_clustering,local_clustering_coefficient, global_clustering_coefficient, triangles, -label_propagation, maximal_cliques, clique_percolation, assortativity, +label_propagation, maximal_cliques, clique_percolation, assortativity,rich_club, #generators complete_graph, star_graph, path_graph, wheel_graph, cycle_graph, @@ -256,6 +256,7 @@ include("community/clustering.jl") include("community/cliques.jl") include("community/clique_percolation.jl") include("community/assortativity.jl") +include("community/rich_club.jl") include("spanningtrees/boruvka.jl") include("spanningtrees/kruskal.jl") include("spanningtrees/prim.jl") diff --git a/src/community/rich_club.jl b/src/community/rich_club.jl new file mode 100644 index 000000000..67e53c27c --- /dev/null +++ b/src/community/rich_club.jl @@ -0,0 +1,23 @@ +""" + rich_club(g,k) + +Return the non-normalised [rich-club coefficient](https://en.wikipedia.org/wiki/Rich-club_coefficient) of graph `g`, +with degree cut-off `k`. + +```jldoctest +julia> using LightGraphs +julia> g = star_graph(5) +julia> rich_club(g,1) +0.4 +``` +""" +function rich_club(g::AbstractGraph{T},k::Int) where T + E = zero(T) + for e in edges(g) + if (degree(g,src(e)) >= k) && (degree(g,dst(e)) >= k ) + E +=1 + end + end + N = count(degree(g) .>= k) + return 2*E / (N*(N-1)) +end From b3c00760cac82c6826c807383b87f7bb75d0691a Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 8 Mar 2021 11:00:00 +0100 Subject: [PATCH 3/9] added rich club metric --- docs/src/community.md | 1 + src/LightGraphs.jl | 3 ++- src/community/rich_club.jl | 23 +++++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/community/rich_club.jl diff --git a/docs/src/community.md b/docs/src/community.md index 2654978ef..69dbce85a 100644 --- a/docs/src/community.md +++ b/docs/src/community.md @@ -19,6 +19,7 @@ Pages = [ "community/label_propagation.jl", "community/modularity.jl", "community/assortativity.jl" + "community/rich_club.jl" ] Private = false ``` diff --git a/src/LightGraphs.jl b/src/LightGraphs.jl index 221092db4..92a58e825 100644 --- a/src/LightGraphs.jl +++ b/src/LightGraphs.jl @@ -114,7 +114,7 @@ barabasi_albert!, static_fitness_model, static_scale_free, kronecker, dorogovtse #community modularity, core_periphery_deg, local_clustering,local_clustering_coefficient, global_clustering_coefficient, triangles, -label_propagation, maximal_cliques, clique_percolation, assortativity, +label_propagation, maximal_cliques, clique_percolation, assortativity,rich_club, #generators complete_graph, star_graph, path_graph, wheel_graph, cycle_graph, @@ -256,6 +256,7 @@ include("community/clustering.jl") include("community/cliques.jl") include("community/clique_percolation.jl") include("community/assortativity.jl") +include("community/rich_club.jl") include("spanningtrees/boruvka.jl") include("spanningtrees/kruskal.jl") include("spanningtrees/prim.jl") diff --git a/src/community/rich_club.jl b/src/community/rich_club.jl new file mode 100644 index 000000000..67e53c27c --- /dev/null +++ b/src/community/rich_club.jl @@ -0,0 +1,23 @@ +""" + rich_club(g,k) + +Return the non-normalised [rich-club coefficient](https://en.wikipedia.org/wiki/Rich-club_coefficient) of graph `g`, +with degree cut-off `k`. + +```jldoctest +julia> using LightGraphs +julia> g = star_graph(5) +julia> rich_club(g,1) +0.4 +``` +""" +function rich_club(g::AbstractGraph{T},k::Int) where T + E = zero(T) + for e in edges(g) + if (degree(g,src(e)) >= k) && (degree(g,dst(e)) >= k ) + E +=1 + end + end + N = count(degree(g) .>= k) + return 2*E / (N*(N-1)) +end From c39cb75d5ab65a938df738bfc9748502e6932e59 Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 8 Mar 2021 11:06:58 +0100 Subject: [PATCH 4/9] Revert "added rich club metric" This reverts commit b3c00760cac82c6826c807383b87f7bb75d0691a. --- docs/src/community.md | 1 - src/LightGraphs.jl | 3 +-- src/community/rich_club.jl | 23 ----------------------- 3 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 src/community/rich_club.jl diff --git a/docs/src/community.md b/docs/src/community.md index 69dbce85a..2654978ef 100644 --- a/docs/src/community.md +++ b/docs/src/community.md @@ -19,7 +19,6 @@ Pages = [ "community/label_propagation.jl", "community/modularity.jl", "community/assortativity.jl" - "community/rich_club.jl" ] Private = false ``` diff --git a/src/LightGraphs.jl b/src/LightGraphs.jl index 92a58e825..221092db4 100644 --- a/src/LightGraphs.jl +++ b/src/LightGraphs.jl @@ -114,7 +114,7 @@ barabasi_albert!, static_fitness_model, static_scale_free, kronecker, dorogovtse #community modularity, core_periphery_deg, local_clustering,local_clustering_coefficient, global_clustering_coefficient, triangles, -label_propagation, maximal_cliques, clique_percolation, assortativity,rich_club, +label_propagation, maximal_cliques, clique_percolation, assortativity, #generators complete_graph, star_graph, path_graph, wheel_graph, cycle_graph, @@ -256,7 +256,6 @@ include("community/clustering.jl") include("community/cliques.jl") include("community/clique_percolation.jl") include("community/assortativity.jl") -include("community/rich_club.jl") include("spanningtrees/boruvka.jl") include("spanningtrees/kruskal.jl") include("spanningtrees/prim.jl") diff --git a/src/community/rich_club.jl b/src/community/rich_club.jl deleted file mode 100644 index 67e53c27c..000000000 --- a/src/community/rich_club.jl +++ /dev/null @@ -1,23 +0,0 @@ -""" - rich_club(g,k) - -Return the non-normalised [rich-club coefficient](https://en.wikipedia.org/wiki/Rich-club_coefficient) of graph `g`, -with degree cut-off `k`. - -```jldoctest -julia> using LightGraphs -julia> g = star_graph(5) -julia> rich_club(g,1) -0.4 -``` -""" -function rich_club(g::AbstractGraph{T},k::Int) where T - E = zero(T) - for e in edges(g) - if (degree(g,src(e)) >= k) && (degree(g,dst(e)) >= k ) - E +=1 - end - end - N = count(degree(g) .>= k) - return 2*E / (N*(N-1)) -end From 34a285846e14b9cf5826af9cf9cb1a20b0f2ad6d Mon Sep 17 00:00:00 2001 From: vboussange Date: Mon, 8 Mar 2021 12:12:52 +0100 Subject: [PATCH 5/9] deleted rich_club that belongs to an other pull requests I have been messing up with the branches in my pull requests, trying to solve this now --- docs/src/community.md | 2 +- src/LightGraphs.jl | 4 ++-- src/community/rich_club.jl | 23 ----------------------- 3 files changed, 3 insertions(+), 26 deletions(-) delete mode 100644 src/community/rich_club.jl diff --git a/docs/src/community.md b/docs/src/community.md index 69dbce85a..306f8cd3f 100644 --- a/docs/src/community.md +++ b/docs/src/community.md @@ -19,7 +19,7 @@ Pages = [ "community/label_propagation.jl", "community/modularity.jl", "community/assortativity.jl" - "community/rich_club.jl" + "community/s_metric.jl" ] Private = false ``` diff --git a/src/LightGraphs.jl b/src/LightGraphs.jl index 92a58e825..e0ef6eaa7 100644 --- a/src/LightGraphs.jl +++ b/src/LightGraphs.jl @@ -114,7 +114,7 @@ barabasi_albert!, static_fitness_model, static_scale_free, kronecker, dorogovtse #community modularity, core_periphery_deg, local_clustering,local_clustering_coefficient, global_clustering_coefficient, triangles, -label_propagation, maximal_cliques, clique_percolation, assortativity,rich_club, +label_propagation, maximal_cliques, clique_percolation, assortativity,s_metric, #generators complete_graph, star_graph, path_graph, wheel_graph, cycle_graph, @@ -256,7 +256,7 @@ include("community/clustering.jl") include("community/cliques.jl") include("community/clique_percolation.jl") include("community/assortativity.jl") -include("community/rich_club.jl") +include("community/s_metric.jl") include("spanningtrees/boruvka.jl") include("spanningtrees/kruskal.jl") include("spanningtrees/prim.jl") diff --git a/src/community/rich_club.jl b/src/community/rich_club.jl deleted file mode 100644 index 67e53c27c..000000000 --- a/src/community/rich_club.jl +++ /dev/null @@ -1,23 +0,0 @@ -""" - rich_club(g,k) - -Return the non-normalised [rich-club coefficient](https://en.wikipedia.org/wiki/Rich-club_coefficient) of graph `g`, -with degree cut-off `k`. - -```jldoctest -julia> using LightGraphs -julia> g = star_graph(5) -julia> rich_club(g,1) -0.4 -``` -""" -function rich_club(g::AbstractGraph{T},k::Int) where T - E = zero(T) - for e in edges(g) - if (degree(g,src(e)) >= k) && (degree(g,dst(e)) >= k ) - E +=1 - end - end - N = count(degree(g) .>= k) - return 2*E / (N*(N-1)) -end From f324304f37feeeb64bd93ca4cd35fb3fe4f9cc4a Mon Sep 17 00:00:00 2001 From: vboussange Date: Thu, 11 Mar 2021 16:20:20 +0100 Subject: [PATCH 6/9] Added tests and corrected s_metric and corresponding documentation --- src/community/s_metric.jl | 10 ++++++---- test/community/s_metric.jl | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 test/community/s_metric.jl diff --git a/src/community/s_metric.jl b/src/community/s_metric.jl index ce1ecc4f9..97a2fb1a5 100644 --- a/src/community/s_metric.jl +++ b/src/community/s_metric.jl @@ -3,11 +3,13 @@ Return the normalised s-metric of `g`. -The s-metric is defined as the sum of the product of degrees between pair of nodes +The s-metric is defined as the sum of the product of degrees between pair of vertices for every edge in `g`. [Ref](https://arxiv.org/abs/cond-mat/0501169) +In directed graphs, the paired values are the out-degree of source vertices +and the in-degree of destination vertices. It is normalised by the maximum s_metric obtained from the family of graph -with similar degree distribution. -s_max is computed from an approximation formula as in https://journals.aps.org/pre/pdf/10.1103/PhysRevE.75.046102 +with similar degree distribution. s_max is computed from an approximation +formula as in https://journals.aps.org/pre/pdf/10.1103/PhysRevE.75.046102 If `norm=false`, no normalisation is performed. # Examples @@ -22,7 +24,7 @@ julia> s_metric(star_graph(4)) function s_metric(g::AbstractGraph{T};norm=true) where T s = zero(T) for e in edges(g) - s += degree(g,src(e)) * degree(g,dst(e)) + s += outdegree(g,src(e)) * indegree(g,dst(e)) end if norm sm = sum(degree(g).^3)/2 diff --git a/test/community/s_metric.jl b/test/community/s_metric.jl new file mode 100644 index 000000000..04fcc5570 --- /dev/null +++ b/test/community/s_metric.jl @@ -0,0 +1,22 @@ +using Random, Statistics + +@testset "S-metric" begin + @testset "Directed ($seed)" for seed in [1, 2, 3], (_n, _ne) in [(14, 18), (10, 22), (7, 16)] + g = erdos_renyi(_n, _ne; is_directed=true, seed=seed) + sm = s_metric(g,norm=false) + sm2 = sum([outdegree(g,src(d)) * indegree(g,dst(d)) for d in edges(g)]) + @test @inferred sm ≈ sm2 + sm = s_metric(g,norm=true) + sm2 /= sum(degree(g).^3)/2 + @test @inferred sm ≈ sm2 + end + @testset "Undirected ($seed)" for seed in [1, 2, 3], (_n, _ne) in [(14, 18), (10, 22), (7, 16)] + g = erdos_renyi(_n, _ne; is_directed=false, seed=seed) + sm = s_metric(g,norm=false) + sm2 = sum([degree(g,src(d)) * degree(g,dst(d)) for d in edges(g)]) + @test @inferred sm ≈ sm2 + sm = s_metric(g,norm=true) + sm2 /= sum(degree(g).^3)/2 + @test @inferred sm ≈ sm2 + end +end From ca654c21ebe644c5267d7fd37d45ecf64e63a00d Mon Sep 17 00:00:00 2001 From: vboussange Date: Thu, 11 Mar 2021 16:22:01 +0100 Subject: [PATCH 7/9] included s_metric in runtests.jl --- test/runtests.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 295e400ef..9c5e16447 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -11,13 +11,13 @@ using Statistics: mean const testdir = dirname(@__FILE__) -testgraphs(g) = is_directed(g) ? [g, DiGraph{UInt8}(g), DiGraph{Int16}(g)] : [g, Graph{UInt8}(g), Graph{Int16}(g)] +testgraphs(g) = is_directed(g) ? [g, DiGraph{UInt8}(g), DiGraph{Int16}(g)] : [g, Graph{UInt8}(g), Graph{Int16}(g)] testgraphs(gs...) = vcat((testgraphs(g) for g in gs)...) testdigraphs = testgraphs # some operations will create a large graph from two smaller graphs. We # might error out on very small eltypes. -testlargegraphs(g) = is_directed(g) ? [g, DiGraph{UInt16}(g), DiGraph{Int32}(g)] : [g, Graph{UInt16}(g), Graph{Int32}(g)] +testlargegraphs(g) = is_directed(g) ? [g, DiGraph{UInt16}(g), DiGraph{Int32}(g)] : [g, Graph{UInt16}(g), Graph{Int32}(g)] testlargegraphs(gs...) = vcat((testlargegraphs(g) for g in gs)...) tests = [ @@ -60,6 +60,7 @@ tests = [ "community/clustering", "community/clique_percolation", "community/assortativity", + "community/s_metric" "centrality/betweenness", "centrality/closeness", "centrality/degree", From 2f72c0b70631f4e9f6e32573e9fe032a242e0047 Mon Sep 17 00:00:00 2001 From: vboussange Date: Thu, 11 Mar 2021 16:23:36 +0100 Subject: [PATCH 8/9] small fix --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 9c5e16447..025fc7f9f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -60,7 +60,7 @@ tests = [ "community/clustering", "community/clique_percolation", "community/assortativity", - "community/s_metric" + "community/s_metric", "centrality/betweenness", "centrality/closeness", "centrality/degree", From 909e2ad14d6d79b1f0eb25d6301a03ee924780d5 Mon Sep 17 00:00:00 2001 From: vboussange Date: Tue, 30 Mar 2021 13:45:09 +0200 Subject: [PATCH 9/9] update spaces --- src/community/s_metric.jl | 6 +++--- test/community/s_metric.jl | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/community/s_metric.jl b/src/community/s_metric.jl index 97a2fb1a5..535ba7a87 100644 --- a/src/community/s_metric.jl +++ b/src/community/s_metric.jl @@ -1,5 +1,5 @@ """ - s_metric(g;norm=true) + s_metric(g; norm=true) Return the normalised s-metric of `g`. @@ -21,10 +21,10 @@ julia> s_metric(star_graph(4)) ``` """ -function s_metric(g::AbstractGraph{T};norm=true) where T +function s_metric(g::AbstractGraph{T}; norm=true) where T s = zero(T) for e in edges(g) - s += outdegree(g,src(e)) * indegree(g,dst(e)) + s += outdegree(g, src(e)) * indegree(g, dst(e)) end if norm sm = sum(degree(g).^3)/2 diff --git a/test/community/s_metric.jl b/test/community/s_metric.jl index 04fcc5570..2b1a58dcb 100644 --- a/test/community/s_metric.jl +++ b/test/community/s_metric.jl @@ -3,19 +3,19 @@ using Random, Statistics @testset "S-metric" begin @testset "Directed ($seed)" for seed in [1, 2, 3], (_n, _ne) in [(14, 18), (10, 22), (7, 16)] g = erdos_renyi(_n, _ne; is_directed=true, seed=seed) - sm = s_metric(g,norm=false) - sm2 = sum([outdegree(g,src(d)) * indegree(g,dst(d)) for d in edges(g)]) + sm = s_metric(g, norm=false) + sm2 = sum([outdegree(g, src(d)) * indegree(g, dst(d)) for d in edges(g)]) @test @inferred sm ≈ sm2 - sm = s_metric(g,norm=true) + sm = s_metric(g, norm=true) sm2 /= sum(degree(g).^3)/2 @test @inferred sm ≈ sm2 end @testset "Undirected ($seed)" for seed in [1, 2, 3], (_n, _ne) in [(14, 18), (10, 22), (7, 16)] g = erdos_renyi(_n, _ne; is_directed=false, seed=seed) - sm = s_metric(g,norm=false) - sm2 = sum([degree(g,src(d)) * degree(g,dst(d)) for d in edges(g)]) + sm = s_metric(g, norm=false) + sm2 = sum([degree(g, src(d)) * degree(g, dst(d)) for d in edges(g)]) @test @inferred sm ≈ sm2 - sm = s_metric(g,norm=true) + sm = s_metric(g, norm=true) sm2 /= sum(degree(g).^3)/2 @test @inferred sm ≈ sm2 end