From b36ecfabeced9ad13a2722b656f379de083082c2 Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 8 Mar 2021 10:08:57 +0100 Subject: [PATCH 1/8] 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 0ce7f464c1fd12f3969f6d79cd4e046b63b1711e Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 8 Mar 2021 11:00:00 +0100 Subject: [PATCH 2/8] added rich club metric --- docs/src/community.md | 1 + src/Graphs.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 359f33f9f..7a2ee5cf4 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/Graphs.jl b/src/Graphs.jl index ca07d57c0..e4febaca8 100644 --- a/src/Graphs.jl +++ b/src/Graphs.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 7f53baeec247df89768095cd57b7ad3629f174cc Mon Sep 17 00:00:00 2001 From: Victor Date: Mon, 8 Mar 2021 11:06:58 +0100 Subject: [PATCH 3/8] Revert "added rich club metric" This reverts commit b3c00760cac82c6826c807383b87f7bb75d0691a. --- docs/src/community.md | 1 - src/Graphs.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 7a2ee5cf4..359f33f9f 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/Graphs.jl b/src/Graphs.jl index e4febaca8..ca07d57c0 100644 --- a/src/Graphs.jl +++ b/src/Graphs.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 857421ae895707a58da3780eb36c857add16ff41 Mon Sep 17 00:00:00 2001 From: vboussange Date: Mon, 8 Mar 2021 12:12:52 +0100 Subject: [PATCH 4/8] 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 | 1 + src/Graphs.jl | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/src/community.md b/docs/src/community.md index 359f33f9f..bf5930ec0 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/s_metric.jl" ] Private = false ``` diff --git a/src/Graphs.jl b/src/Graphs.jl index ca07d57c0..81b699905 100644 --- a/src/Graphs.jl +++ b/src/Graphs.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,s_metric, #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/s_metric.jl") include("spanningtrees/boruvka.jl") include("spanningtrees/kruskal.jl") include("spanningtrees/prim.jl") From 4acfd1f193c980566787a8460364f4154d0f126d Mon Sep 17 00:00:00 2001 From: vboussange Date: Thu, 11 Mar 2021 16:20:20 +0100 Subject: [PATCH 5/8] 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 7edd9496320f4c863282778d39187e1999092c9e Mon Sep 17 00:00:00 2001 From: vboussange Date: Thu, 11 Mar 2021 16:22:01 +0100 Subject: [PATCH 6/8] 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 303ae1584..79ad1e463 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 c01ad23bb954161ff9a14797464ff0490d4fdf7e Mon Sep 17 00:00:00 2001 From: vboussange Date: Thu, 11 Mar 2021 16:23:36 +0100 Subject: [PATCH 7/8] small fix --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 79ad1e463..462d1ba68 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 007de78f19bba70b6a2f1aefcdfb2850de2b55e7 Mon Sep 17 00:00:00 2001 From: vboussange Date: Tue, 30 Mar 2021 13:45:09 +0200 Subject: [PATCH 8/8] 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