From a47eb58c22ee029670a277fbc5acf782452341b1 Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Mon, 8 Feb 2021 20:48:39 -0500 Subject: [PATCH 01/37] Update documenter.yml changing stable branch to master. --- .github/workflows/documenter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/documenter.yml b/.github/workflows/documenter.yml index c20535b2a..6d1887873 100644 --- a/.github/workflows/documenter.yml +++ b/.github/workflows/documenter.yml @@ -1,7 +1,7 @@ name: Documenter on: push: - branches: [stable] + branches: [master] tags: [v*] pull_request: From f74950584cdcd2d62d27cfd79964b1ceb59a8531 Mon Sep 17 00:00:00 2001 From: Magnus Lie Hetland Date: Wed, 10 Feb 2021 10:13:10 +0100 Subject: [PATCH 02/37] Rewrite watts_strogatz --- src/SimpleGraphs/generators/randgraphs.jl | 79 ++++++++++++++++------- 1 file changed, 54 insertions(+), 25 deletions(-) diff --git a/src/SimpleGraphs/generators/randgraphs.jl b/src/SimpleGraphs/generators/randgraphs.jl index 26c4b7360..aebc27b97 100644 --- a/src/SimpleGraphs/generators/randgraphs.jl +++ b/src/SimpleGraphs/generators/randgraphs.jl @@ -223,8 +223,24 @@ end watts_strogatz(n, k, β) Return a [Watts-Strogatz](https://en.wikipedia.org/wiki/Watts_and_Strogatz_model) -small model random graph with `n` vertices, each with degree `k`. Edges are -randomized per the model based on probability `β`. +small world random graph with `n` vertices, each with expected degree `k` (or `k +- 1` if `k` is odd). Edges are randomized per the model based on probability `β`. + +The algorithm proceeds as follows. First, a perfect 1-lattice is constructed, +where each vertex has exacly `div(k, 2)` neighbors on each side (i.e., `k` or `k +- 1` in total). Then the following steps are repeated for a hop length `i` of +`1` through `div(k, 2)`. + +1. Consider each vertex `s` in turn, along with the edge to its `i`th nearest + neighbor `t`, in a clockwise sense. + +2. Generate a uniformly random number `r`. If `r ≥ β`, then the edge `(s, t)` is + left unaltered. Otherwise, the edge is deleted and *rewired* so that `s` is + connected to some vertex `d`, chosen uniformly at random from the entire + graph, excluding `s` and its neighbors. (Note that `t` is a valid candidate.) + +For `β = 1`, the graph will remain a 1-lattice, and for `β = 0`, all edges will +be rewired randomly. ### Optional Arguments - `is_directed=false`: if true, return a directed graph. @@ -237,40 +253,53 @@ julia> watts_strogatz(10, 4, 0.3) julia> watts_strogatz(Int8(10), 4, 0.8, is_directed=true, seed=123) {10, 20} directed simple Int8 graph + +### References +- Collective dynamics of ‘small-world’ networks, Duncan J. Watts, Steven H. Strogatz. [https://doi.org/10.1038/30918](https://doi.org/10.1038/30918) +- Small Worlds, Duncan J. watts. [https://en.wikipedia.org/wiki/Special:BookSources?isbn=978-0691005416](https://en.wikipedia.org/wiki/Special:BookSources?isbn=978-0691005416) ``` """ function watts_strogatz(n::Integer, k::Integer, β::Real; is_directed=false, seed::Int=-1) + @assert k < n - if is_directed - g = SimpleDiGraph(n) - else - g = SimpleGraph(n) + + if k == n - 1 && iseven(k) + return is_directed ? complete_digraph(n) : complete_graph(n) end + + g = is_directed ? SimpleDiGraph(n) : SimpleGraph(n) + rng = getRNG(seed) - for s in 1:n - for i in 1:(floor(Integer, k / 2)) - target = ((s + i - 1) % n) + 1 - if rand(rng) > β && !has_edge(g, s, target) # TODO: optimize this based on return of add_edge! - add_edge!(g, s, target) - else - while true - d = target - while d == target - d = rand(rng, 1:(n - 1)) - if s < d - d += 1 - end - end - if s != d - add_edge!(g, s, d) && break - end - end - end + + target(s, i) = ((s + i - 1) % n) + 1 + + # Phase 1: + + for i = 1:div(k, 2), s = 1:n + add_edge!(g, s, target(s, i)) + end + + # Phase 2: + + for i = 1:div(k, 2), s = 1:n + + (rand(rng) < β && degree(g, s) < n - 1) || continue + + t = target(s, i) + + for d in randperm(rng, n) + d == s && continue + d == t && break + add_edge!(g, s, d) && rem_edge!(g, s, t) && break end + end + return g + end + function _suitable(edges::Set{SimpleEdge{T}}, potential_edges::Dict{T,T}) where T <: Integer isempty(potential_edges) && return true list = keys(potential_edges) From b675b3afaaf4b96c10967441f19c92e5746d2849 Mon Sep 17 00:00:00 2001 From: Magnus Lie Hetland Date: Wed, 10 Feb 2021 17:47:19 +0100 Subject: [PATCH 03/37] Use in-place random permutation --- src/SimpleGraphs/generators/randgraphs.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/SimpleGraphs/generators/randgraphs.jl b/src/SimpleGraphs/generators/randgraphs.jl index aebc27b97..d69b95f6f 100644 --- a/src/SimpleGraphs/generators/randgraphs.jl +++ b/src/SimpleGraphs/generators/randgraphs.jl @@ -1,5 +1,5 @@ using Random: - AbstractRNG, MersenneTwister, randperm, seed!, shuffle! + AbstractRNG, MersenneTwister, randperm, randperm!, seed!, shuffle! using Statistics: mean using LightGraphs: @@ -281,13 +281,16 @@ function watts_strogatz(n::Integer, k::Integer, β::Real; is_directed=false, see # Phase 2: + ns = collect(1:n) + for i = 1:div(k, 2), s = 1:n (rand(rng) < β && degree(g, s) < n - 1) || continue t = target(s, i) - for d in randperm(rng, n) + randperm!(rng, ns) + for d in ns d == s && continue d == t && break add_edge!(g, s, d) && rem_edge!(g, s, t) && break From d6812b9d842404d3a65c1a89f559e4edc0d1fb56 Mon Sep 17 00:00:00 2001 From: Magnus Lie Hetland Date: Wed, 10 Feb 2021 18:05:23 +0100 Subject: [PATCH 04/37] Swap randperm! for trial and error --- src/SimpleGraphs/generators/randgraphs.jl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/SimpleGraphs/generators/randgraphs.jl b/src/SimpleGraphs/generators/randgraphs.jl index d69b95f6f..53505da0f 100644 --- a/src/SimpleGraphs/generators/randgraphs.jl +++ b/src/SimpleGraphs/generators/randgraphs.jl @@ -1,5 +1,5 @@ using Random: - AbstractRNG, MersenneTwister, randperm, randperm!, seed!, shuffle! + AbstractRNG, MersenneTwister, randperm, seed!, shuffle! using Statistics: mean using LightGraphs: @@ -281,16 +281,14 @@ function watts_strogatz(n::Integer, k::Integer, β::Real; is_directed=false, see # Phase 2: - ns = collect(1:n) - for i = 1:div(k, 2), s = 1:n (rand(rng) < β && degree(g, s) < n - 1) || continue t = target(s, i) - randperm!(rng, ns) - for d in ns + while true + d = rand(1:n) d == s && continue d == t && break add_edge!(g, s, d) && rem_edge!(g, s, t) && break From 46c9bdadeb80d334ba7fc48082d639225be4ef8a Mon Sep 17 00:00:00 2001 From: Magnus Lie Hetland Date: Sun, 14 Feb 2021 11:48:26 +0100 Subject: [PATCH 05/37] Rewrite short-circuit and add comments --- src/SimpleGraphs/generators/randgraphs.jl | 30 ++++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/SimpleGraphs/generators/randgraphs.jl b/src/SimpleGraphs/generators/randgraphs.jl index 53505da0f..21f7c4a60 100644 --- a/src/SimpleGraphs/generators/randgraphs.jl +++ b/src/SimpleGraphs/generators/randgraphs.jl @@ -260,9 +260,10 @@ julia> watts_strogatz(Int8(10), 4, 0.8, is_directed=true, seed=123) ``` """ function watts_strogatz(n::Integer, k::Integer, β::Real; is_directed=false, seed::Int=-1) - @assert k < n + # If we have n - 1 neighbors (exactly k/2 on each side), then the graph is + # necessarily complete. No need to run the Watts-Strogatz procedure: if k == n - 1 && iseven(k) return is_directed ? complete_digraph(n) : complete_graph(n) end @@ -271,33 +272,44 @@ function watts_strogatz(n::Integer, k::Integer, β::Real; is_directed=false, see rng = getRNG(seed) + # The ith next vertex, in clockwise order. + # (Reduce to zero-based indexing, so the modulo works, by subtracting 1 + # before and adding 1 after.) target(s, i) = ((s + i - 1) % n) + 1 - # Phase 1: + # Phase 1: For each step size i, add an edge from each vertex s to the ith + # next vertex, in clockwise order. for i = 1:div(k, 2), s = 1:n add_edge!(g, s, target(s, i)) end - # Phase 2: + # Phase 2: For each step size i and each vertex s, consider the edge to the + # ith next vertex, in clockwise order. With probability β, delete the edge + # and rewire it to any (valid) target, chosen uniformly at random. for i = 1:div(k, 2), s = 1:n + # We only rewire with a probability β, and we only worry about rewiring + # if there is some vertex not connected to s; otherwise, the only valid + # rewiring is to reconnect to the ith next vertex, and there is no work + # to do. (rand(rng) < β && degree(g, s) < n - 1) || continue t = target(s, i) while true - d = rand(1:n) - d == s && continue - d == t && break - add_edge!(g, s, d) && rem_edge!(g, s, t) && break + d = rand(1:n) # Tentative new target + d == s && continue # Self-loops prohibited + d == t && break # Rewired to original target + if add_edge!(g, s, d) # Was this valid (i.e., unconnected)? + rem_edge!(g, s, t) # True rewiring: Delete original edge + break # We found a valid target + end end end - return g - end From 2548008e555c46ec50601fe47fa66269b87f8f57 Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Mon, 15 Feb 2021 14:26:06 +0100 Subject: [PATCH 06/37] fix #1489 (#1524) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix #1489 * Update src/linalg/spectral.jl Co-authored-by: Mathieu Besançon * Update src/linalg/spectral.jl Co-authored-by: Mathieu Besançon * Update src/linalg/spectral.jl * Update src/linalg/spectral.jl Co-authored-by: Simon Schoelly * Testing incidence matrix size with isolated vertices Co-authored-by: Mathieu Besançon Co-authored-by: Simon Schoelly --- src/linalg/spectral.jl | 34 +++++++--------------------------- test/linalg/spectral.jl | 10 ++++++++++ 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/linalg/spectral.jl b/src/linalg/spectral.jl index 5f6534f80..80e12e075 100644 --- a/src/linalg/spectral.jl +++ b/src/linalg/spectral.jl @@ -153,34 +153,14 @@ between `v` and `i`. """ function incidence_matrix(g::AbstractGraph, T::DataType=Int; oriented=false) isdir = is_directed(g) - n_v = nv(g) n_e = ne(g) - nz = 2 * n_e - - # every col has the same 2 entries - colpt = collect(1:2:(nz + 1)) - nzval = repeat([(isdir || oriented) ? -one(T) : one(T), one(T)], n_e) - - # iterate over edges for row indices - rowval = zeros(Int, nz) - i = 1 - for u in vertices(g) - for v in outneighbors(g, u) - if isdir || u < v # add every edge only once - if u > v - v, u = u, v - # need to make sure that columns of the CSC matrix are sorted - nzval[2 * i - 1], nzval[2 * i] = nzval[2 * i], nzval[2 * i - 1] - end - rowval[2 * i - 1] = u - rowval[2 * i] = v - i += 1 - end - end - end - - spmx = SparseMatrixCSC(n_v, n_e, colpt, rowval, nzval) - return spmx + I = vcat(src.(edges(g)), dst.(edges(g))) + J = vcat(1:n_e, 1:n_e) + V = vcat( + (isdir || oriented) ? -fill(one(T), n_e) : fill(one(T), n_e), + fill(one(T), n_e), + ) + return sparse(I, J, V, nv(g), ne(g)) end """ diff --git a/test/linalg/spectral.jl b/test/linalg/spectral.jl index 593229db2..e24315128 100644 --- a/test/linalg/spectral.jl +++ b/test/linalg/spectral.jl @@ -129,6 +129,16 @@ Matrix(nbt::Nonbacktracking) = Matrix(sparse(nbt)) @test incidence_matrix(g; oriented=true)[2, 1] == 1 @test incidence_matrix(g; oriented=true)[3, 1] == 0 end + + # Check size of incidence matrix with isolated vertices + g6 = complete_graph(4) + for k = 1:3 + add_vertex!(g6) + end + for g in testgraphs(g6) + @test size(incidence_matrix(g6)) == (7, 6) + end + # TESTS FOR Nonbacktracking operator. n = 10; k = 5 From 2fa13a40947608c791d76e4d14af1fc56ba93d5a Mon Sep 17 00:00:00 2001 From: Helios De Rosario Date: Mon, 15 Feb 2021 23:38:45 +0100 Subject: [PATCH 07/37] add assortativity (#1513) * add assortativity * add assortativity in docs * fix assortativity test with wheel_graph * variables of assortativity as Int64+ * tests with @inferred Co-authored-by: Seth Bromberger --- docs/src/community.md | 3 +- src/LightGraphs.jl | 3 +- src/community/assortativity.jl | 53 +++++++++++++++++++++++++++++++++ test/community/assortativity.jl | 23 ++++++++++++++ test/runtests.jl | 1 + 5 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 src/community/assortativity.jl create mode 100644 test/community/assortativity.jl diff --git a/docs/src/community.md b/docs/src/community.md index beafa88fb..2654978ef 100644 --- a/docs/src/community.md +++ b/docs/src/community.md @@ -17,7 +17,8 @@ Pages = [ "community/clustering.jl", "community/core-periphery.jl", "community/label_propagation.jl", - "community/modularity.jl" + "community/modularity.jl", + "community/assortativity.jl" ] Private = false ``` diff --git a/src/LightGraphs.jl b/src/LightGraphs.jl index c01e39066..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, +label_propagation, maximal_cliques, clique_percolation, assortativity, #generators complete_graph, star_graph, path_graph, wheel_graph, cycle_graph, @@ -255,6 +255,7 @@ include("community/core-periphery.jl") include("community/clustering.jl") include("community/cliques.jl") include("community/clique_percolation.jl") +include("community/assortativity.jl") include("spanningtrees/boruvka.jl") include("spanningtrees/kruskal.jl") include("spanningtrees/prim.jl") diff --git a/src/community/assortativity.jl b/src/community/assortativity.jl new file mode 100644 index 000000000..0d17ae5f4 --- /dev/null +++ b/src/community/assortativity.jl @@ -0,0 +1,53 @@ +""" + assortativity(g) + +Return the [assortativity coefficient](https://en.wikipedia.org/wiki/Assortativity) +of graph `g`, defined as the Pearson correlation of excess degree between +the end vertices of all the edges of the graph. + +The excess degree is equal to the degree of linked vertices minus one, +i.e. discounting the edge that links the pair. +In directed graphs, the paired values are the out-degree of source vertices +and the in-degree of destination vertices. + +# Examples +```jldoctest +julia> using LightGraphs + +julia> assortativity(star_graph(4)) +-1.0 +``` +""" +function assortativity(g::AbstractGraph{T}) where T + P = promote_type(Int64, T) # at least Int64 to reduce risk of overflow + nue = ne(g) + sjk = sj = sk = sjs = sks = zero(P) + for d in edges(g) + j = P(outdegree(g, src(d)) - 1) + k = P(indegree(g, dst(d)) - 1) + sjk += j*k + sj += j + sk += k + sjs += j^2 + sks += k^2 + end + return assortativity_coefficient(g, sjk, sj, sk, sjs, sks, nue) +end + +#= +assortativity coefficient for directed graphs: +see equation (21) in M. E. J. Newman: Mixing patterns in networks, Phys. Rev. E 67, 026126 (2003), +http://arxiv.org/abs/cond-mat/0209450 +=# +@traitfn function assortativity_coefficient(g::::IsDirected, sjk, sj, sk, sjs, sks, nue) + return (sjk - sj*sk/nue) / sqrt((sjs - sj^2/nue)*(sks - sk^2/nue)) +end + +#= +assortativity coefficient for undirected graphs: +see equation (4) in M. E. J. Newman: Assortative mixing in networks, Phys. Rev. Lett. 89, 208701 (2002), +http://arxiv.org/abs/cond-mat/0205405/ +=# +@traitfn function assortativity_coefficient(g::::(!IsDirected), sjk, sj, sk, sjs, sks, nue) + return (sjk/nue - ((sj + sk)/(2*nue))^2) / ((sjs + sks)/(2*nue) - ((sj + sk)/(2*nue))^2) +end diff --git a/test/community/assortativity.jl b/test/community/assortativity.jl new file mode 100644 index 000000000..720668945 --- /dev/null +++ b/test/community/assortativity.jl @@ -0,0 +1,23 @@ +using Random, Statistics + +@testset "Assortativity" begin + # Test definition of assortativity as Pearson correlation coefficient + # between excess of degrees + @testset "Small graphs" for n = 5:10 + @test @inferred assortativity(wheel_graph(n)) ≈ -1/3 + end + @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) + assort = assortativity(g) + x = [outdegree(g, src(d))-1 for d in edges(g)] + y = [indegree(g, dst(d))-1 for d in edges(g)] + @test @inferred assort ≈ cor(x, y) + 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) + assort = assortativity(g) + x = [outdegree(g, src(d))-1 for d in edges(g)] + y = [indegree(g, dst(d))-1 for d in edges(g)] + @test @inferred assort ≈ cor([x;y], [y;x]) + end +end diff --git a/test/runtests.jl b/test/runtests.jl index ddfe24d3b..295e400ef 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -59,6 +59,7 @@ tests = [ "community/modularity", "community/clustering", "community/clique_percolation", + "community/assortativity", "centrality/betweenness", "centrality/closeness", "centrality/degree", From 344b1b69a125692aaac059172f1fdcf55f2e8c16 Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Mon, 15 Feb 2021 23:17:44 -0500 Subject: [PATCH 08/37] Update ci-nightly.yml --- .github/workflows/ci-nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-nightly.yml b/.github/workflows/ci-nightly.yml index 845d2b5dc..67d92f28f 100644 --- a/.github/workflows/ci-nightly.yml +++ b/.github/workflows/ci-nightly.yml @@ -23,5 +23,6 @@ jobs: # remove this after 2.0 - name: test package run: julia --color=yes --project -e 'using Pkg; Pkg.test(coverage=true, julia_args=["--depwarn=no"])' + continue-on-error: true # uncomment after 2.0 # - uses: julia-actions/julia-runtest@latest From c137610300f117fc88f6634b9351066ef09576d4 Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Mon, 15 Feb 2021 23:22:47 -0500 Subject: [PATCH 09/37] Update documenter.yml (#1527) * Update documenter.yml * Update documenter.yml * Update documenter.yml --- .github/workflows/documenter.yml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/documenter.yml b/.github/workflows/documenter.yml index 6d1887873..43fe90fb8 100644 --- a/.github/workflows/documenter.yml +++ b/.github/workflows/documenter.yml @@ -1,20 +1,21 @@ -name: Documenter +name: Documentation + on: push: - branches: [master] - tags: [v*] + branches: + - master + tags: '*' pull_request: jobs: - docs: - name: Documentation + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: julia-actions/setup-julia@latest - with: - version: 1.4 - - uses: julia-actions/julia-docdeploy@releases/v1 + - name: Install dependencies + run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()' + - name: Build and deploy env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # If authenticating with GitHub Actions token + run: julia --project=docs/ docs/make.jl From fe35817ab0de689486185df52795e6022e0ac407 Mon Sep 17 00:00:00 2001 From: Ryan Birmingham Date: Tue, 16 Feb 2021 00:04:38 -0500 Subject: [PATCH 10/37] BenchmarkTools for Core --- benchmark/benchmarks.jl | 30 ++++++++------------------- benchmark/core.jl | 45 +++++++++++++++++------------------------ 2 files changed, 27 insertions(+), 48 deletions(-) diff --git a/benchmark/benchmarks.jl b/benchmark/benchmarks.jl index e3797875a..6b9d8c4c5 100644 --- a/benchmark/benchmarks.jl +++ b/benchmark/benchmarks.jl @@ -1,36 +1,22 @@ -using PkgBenchmark +using BenchmarkTools using LightGraphs -testdatadir = joinpath(dirname(@__FILE__), "..", "test", "testdata") -benchdatadir = joinpath(dirname(@__FILE__), "data") -paramsfile = joinpath(benchdatadir, "params.jld") - -println("testdatadir = $testdatadir") -println("paramsfile = $paramsfile") - -dg1fn = joinpath(testdatadir, "graph-5k-50k.jgz") - DIGRAPHS = Dict{String,DiGraph}( "complete100" => complete_digraph(100), - "5000-50000" => LightGraphs.load(dg1fn)["graph-5000-50000"], "path500" => path_digraph(500) ) GRAPHS = Dict{String,Graph}( "complete100" => complete_graph(100), "tutte" => smallgraph(:tutte), - "path500" => path_graph(500), - "5000-49947" => SimpleGraph(DIGRAPHS["5000-50000"]) + "path500" => path_graph(500) ) -@benchgroup "LightGraphsBenchmarks" begin - include("core.jl") - include("parallel/egonets.jl") - include("insertions.jl") - include("edges.jl") - include("centrality.jl") - include("connectivity.jl") - include("traversals.jl") -end +suite = BenchmarkGroup() +include("core.jl") + + +tune!(suite); +results = run(suite, verbose = true, seconds = 10) diff --git a/benchmark/core.jl b/benchmark/core.jl index 5446dbf72..10cfceb59 100644 --- a/benchmark/core.jl +++ b/benchmark/core.jl @@ -1,4 +1,13 @@ -function bench_iteredges(g::AbstractGraph) +suite["core"] = BenchmarkGroup(["nv", "edges", "has_edge"]) + + +# nv +suite["core"]["nv"] = BenchmarkGroup(["graphs", "digraphs"]) +suite["core"]["nv"]["graphs"] = @benchmarkable [nv(g) for (n,g) in $GRAPHS] +suite["core"]["nv"]["digraphs"] = @benchmarkable [nv(g) for (n,g) in $DIGRAPHS] + +# iterate edges +function iter_edges(g::AbstractGraph) i = 0 for e in edges(g) i += 1 @@ -6,8 +15,12 @@ function bench_iteredges(g::AbstractGraph) return i end -function bench_has_edge(g::AbstractGraph) - seed!(1) +suite["core"]["edges"] = BenchmarkGroup(["graphs", "digraphs"]) +suite["core"]["edges"]["graphs"] = @benchmarkable [iter_edges(g) for (n,g) in $GRAPHS] +suite["core"]["edges"]["digraphs"] = @benchmarkable [iter_edges(g) for (n,g) in $DIGRAPHS] + +# has edge +function all_has_edge(g::AbstractGraph) nvg = nv(g) srcs = rand([1:nvg;], cld(nvg, 4)) dsts = rand([1:nvg;], cld(nvg, 4)) @@ -20,26 +33,6 @@ function bench_has_edge(g::AbstractGraph) return i end - -EDGEFNS = [ - bench_iteredges, - bench_has_edge -] - -@benchgroup "edges" begin - - for fun in EDGEFNS - @benchgroup "$fun" begin - @benchgroup "graph" begin - for (name, g) in GRAPHS - @bench "$name" $fun($g) - end - end - @benchgroup "digraph" begin - for (name, g) in DIGRAPHS - @bench "$name" $fun($g) - end - end # digraph - end # fun - end -end # edges +suite["core"]["has_edge"] = BenchmarkGroup(["graphs", "digraphs"]) +suite["core"]["has_edge"]["graphs"] = @benchmark [all_has_edge(g) for (n,g) in $GRAPHS] +suite["core"]["has_edge"]["digraphs"] = @benchmark [all_has_edge(g) for (n,g) in $DIGRAPHS] From b968f0e020b770680e96bd2a75406c8e6ef59a58 Mon Sep 17 00:00:00 2001 From: Magnus Lie Hetland Date: Tue, 16 Feb 2021 12:17:21 +0100 Subject: [PATCH 11/37] Add @inline to target in watts_strogatz --- src/SimpleGraphs/generators/randgraphs.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SimpleGraphs/generators/randgraphs.jl b/src/SimpleGraphs/generators/randgraphs.jl index 21f7c4a60..49f0560a3 100644 --- a/src/SimpleGraphs/generators/randgraphs.jl +++ b/src/SimpleGraphs/generators/randgraphs.jl @@ -275,7 +275,7 @@ function watts_strogatz(n::Integer, k::Integer, β::Real; is_directed=false, see # The ith next vertex, in clockwise order. # (Reduce to zero-based indexing, so the modulo works, by subtracting 1 # before and adding 1 after.) - target(s, i) = ((s + i - 1) % n) + 1 + @inline target(s, i) = ((s + i - 1) % n) + 1 # Phase 1: For each step size i, add an edge from each vertex s to the ith # next vertex, in clockwise order. From 53f30d3103a90781d8ae4a3b7a3b8ab4a49997a4 Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Tue, 16 Feb 2021 08:54:00 -0500 Subject: [PATCH 12/37] Update Project.toml --- docs/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Project.toml b/docs/Project.toml index 627801d40..48e2de9da 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -2,4 +2,4 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" [compat] -Documenter = "~0.23.4" +Documenter = "~0.26.2" From 67a7f3dbcc59789c410f129221b150ae2122f29e Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Wed, 17 Feb 2021 16:21:44 -0500 Subject: [PATCH 13/37] Update ci-nightly.yml --- .github/workflows/ci-nightly.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci-nightly.yml b/.github/workflows/ci-nightly.yml index 67d92f28f..09677119c 100644 --- a/.github/workflows/ci-nightly.yml +++ b/.github/workflows/ci-nightly.yml @@ -24,5 +24,3 @@ jobs: - name: test package run: julia --color=yes --project -e 'using Pkg; Pkg.test(coverage=true, julia_args=["--depwarn=no"])' continue-on-error: true - # uncomment after 2.0 - # - uses: julia-actions/julia-runtest@latest From c2a05e7af5000ef20e98017b8fbeda597d4d83fd Mon Sep 17 00:00:00 2001 From: Magnus Lie Hetland Date: Thu, 18 Feb 2021 11:04:27 +0100 Subject: [PATCH 14/37] Correct markdown in watts_strogatz docstring --- src/SimpleGraphs/generators/randgraphs.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SimpleGraphs/generators/randgraphs.jl b/src/SimpleGraphs/generators/randgraphs.jl index 49f0560a3..716940376 100644 --- a/src/SimpleGraphs/generators/randgraphs.jl +++ b/src/SimpleGraphs/generators/randgraphs.jl @@ -227,8 +227,8 @@ small world random graph with `n` vertices, each with expected degree `k` (or `k - 1` if `k` is odd). Edges are randomized per the model based on probability `β`. The algorithm proceeds as follows. First, a perfect 1-lattice is constructed, -where each vertex has exacly `div(k, 2)` neighbors on each side (i.e., `k` or `k -- 1` in total). Then the following steps are repeated for a hop length `i` of +where each vertex has exacly `div(k, 2)` neighbors on each side (i.e., `k` or +`k - 1` in total). Then the following steps are repeated for a hop length `i` of `1` through `div(k, 2)`. 1. Consider each vertex `s` in turn, along with the edge to its `i`th nearest @@ -253,11 +253,11 @@ julia> watts_strogatz(10, 4, 0.3) julia> watts_strogatz(Int8(10), 4, 0.8, is_directed=true, seed=123) {10, 20} directed simple Int8 graph +``` ### References - Collective dynamics of ‘small-world’ networks, Duncan J. Watts, Steven H. Strogatz. [https://doi.org/10.1038/30918](https://doi.org/10.1038/30918) - Small Worlds, Duncan J. watts. [https://en.wikipedia.org/wiki/Special:BookSources?isbn=978-0691005416](https://en.wikipedia.org/wiki/Special:BookSources?isbn=978-0691005416) -``` """ function watts_strogatz(n::Integer, k::Integer, β::Real; is_directed=false, seed::Int=-1) @assert k < n From add6c6e788afb45586693ff4a7493d3be1f63a6d Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Thu, 18 Feb 2021 09:52:37 -0500 Subject: [PATCH 15/37] Update README.md Remove gitter link --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index cdb63f269..48b9c6e78 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![Build Status](https://travis-ci.org/JuliaGraphs/LightGraphs.jl.svg?branch=master)](https://travis-ci.org/JuliaGraphs/LightGraphs.jl) [![codecov.io](http://codecov.io/github/JuliaGraphs/LightGraphs.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaGraphs/LightGraphs.jl?branch=master) [![](https://img.shields.io/badge/docs-latest-blue.svg)](https://juliagraphs.github.io/LightGraphs.jl/latest) -[![Join the chat at https://gitter.im/JuliaGraphs/LightGraphs.jl](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JuliaGraphs/LightGraphs.jl) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.889971.svg)](https://doi.org/10.5281/zenodo.889971) LightGraphs offers both (a) a set of simple, concrete graph implementations -- `Graph` From a818a073c4049483bf457391dc97aebe864d2ac7 Mon Sep 17 00:00:00 2001 From: Julia Belyakova Date: Thu, 18 Feb 2021 12:06:29 -0500 Subject: [PATCH 16/37] use getfield instead of eval for getting type by name --- src/persistence/lg.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/persistence/lg.jl b/src/persistence/lg.jl index e87267778..8bc587e81 100644 --- a/src/persistence/lg.jl +++ b/src/persistence/lg.jl @@ -63,7 +63,7 @@ function _parse_header(s::AbstractString) if occursin(",", graphname) # version number and type graphname, _ver, _dtype, graphcode = split(graphname, r"s*,s*") ver = parse(Int, _ver) - dtype = eval(Symbol(_dtype)) + dtype = getfield(Main, Symbol(_dtype)) addl_info = true end n_v = parse(Int, nvstr) From ff2cdc6b666dffed8794d8c989503934c5796df1 Mon Sep 17 00:00:00 2001 From: Jonas Schulze Date: Wed, 3 Mar 2021 20:58:13 +0100 Subject: [PATCH 17/37] Fix nested list --- docs/src/developing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/developing.md b/docs/src/developing.md index f02c76193..60a28c523 100644 --- a/docs/src/developing.md +++ b/docs/src/developing.md @@ -17,7 +17,7 @@ within the LightGraphs package should just work: - [`outneighbors`](@ref) - [`vertices`](@ref) - [`is_directed`](@ref): Note that since LightGraphs uses traits to determine directedness, `is_directed` for a `CustomGraph` type -should be implemented with **both** of the following signatures: + should be implemented with **both** of the following signatures: - `is_directed(::Type{CustomGraph})::Bool` (example: `is_directed(::Type{<:CustomGraph}) = false`) - `is_directed(g::CustomGraph)::Bool` - [`zero`](@ref) From d5cb99dda9b862b48d14ca6a5db4061419a684ea Mon Sep 17 00:00:00 2001 From: Jonas Schulze Date: Wed, 3 Mar 2021 21:07:30 +0100 Subject: [PATCH 18/37] Attach docstrings to functions This fixes all occurrences of ```bash pcregrep -Mris "\"\"\"\n\nfunc" . ``` --- src/connectivity.jl | 2 -- src/shortestpaths/spfa.jl | 1 - 2 files changed, 3 deletions(-) diff --git a/src/connectivity.jl b/src/connectivity.jl index 0c597b489..c927bed15 100644 --- a/src/connectivity.jl +++ b/src/connectivity.jl @@ -216,7 +216,6 @@ julia> strongly_connected_components(g) ``` """ - function strongly_connected_components end # see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax @traitfn function strongly_connected_components(g::AG::IsDirected) where {T<:Integer, AG <: AbstractGraph{T}} @@ -374,7 +373,6 @@ julia> strongly_connected_components_kosaraju(g) ``` """ - function strongly_connected_components_kosaraju end @traitfn function strongly_connected_components_kosaraju(g::AG::IsDirected) where {T<:Integer, AG <: AbstractGraph{T}} diff --git a/src/shortestpaths/spfa.jl b/src/shortestpaths/spfa.jl index 8dec12856..f3f1859aa 100644 --- a/src/shortestpaths/spfa.jl +++ b/src/shortestpaths/spfa.jl @@ -41,7 +41,6 @@ julia> spfa_shortest_paths(gx, 1, d) ``` """ - function spfa_shortest_paths( graph::AbstractGraph{U}, source::Integer, From 93b736fbc50a8034b54cae78717a0eac7d7dcdd8 Mon Sep 17 00:00:00 2001 From: Ryan Birmingham Date: Fri, 5 Mar 2021 19:40:48 -0500 Subject: [PATCH 19/37] use github action ci badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48b9c6e78..a89ec3b06 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LightGraphs -[![Build Status](https://travis-ci.org/JuliaGraphs/LightGraphs.jl.svg?branch=master)](https://travis-ci.org/JuliaGraphs/LightGraphs.jl) +![Build Status](https://github.com/JuliaGraphs/LightGraphs.jl/actions/workflows/ci-nightly.yml/badge.svg?branch=stable) [![codecov.io](http://codecov.io/github/JuliaGraphs/LightGraphs.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaGraphs/LightGraphs.jl?branch=master) [![](https://img.shields.io/badge/docs-latest-blue.svg)](https://juliagraphs.github.io/LightGraphs.jl/latest) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.889971.svg)](https://doi.org/10.5281/zenodo.889971) From 11ada9142f7dd41794b5d8e13d206293e12996ad Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Sat, 6 Mar 2021 13:07:17 -0500 Subject: [PATCH 20/37] Revert "Nightly Stable Badge" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a89ec3b06..48b9c6e78 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LightGraphs -![Build Status](https://github.com/JuliaGraphs/LightGraphs.jl/actions/workflows/ci-nightly.yml/badge.svg?branch=stable) +[![Build Status](https://travis-ci.org/JuliaGraphs/LightGraphs.jl.svg?branch=master)](https://travis-ci.org/JuliaGraphs/LightGraphs.jl) [![codecov.io](http://codecov.io/github/JuliaGraphs/LightGraphs.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaGraphs/LightGraphs.jl?branch=master) [![](https://img.shields.io/badge/docs-latest-blue.svg)](https://juliagraphs.github.io/LightGraphs.jl/latest) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.889971.svg)](https://doi.org/10.5281/zenodo.889971) From e7669f2e4ec196cb13b75b0bfda23237dc4882a2 Mon Sep 17 00:00:00 2001 From: Ryan Birmingham Date: Sat, 6 Mar 2021 15:23:02 -0500 Subject: [PATCH 21/37] button with link in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48b9c6e78..2ebcf8235 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LightGraphs -[![Build Status](https://travis-ci.org/JuliaGraphs/LightGraphs.jl.svg?branch=master)](https://travis-ci.org/JuliaGraphs/LightGraphs.jl) +[![Build Status](https://github.com/JuliaGraphs/LightGraphs.jl/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/JuliaGraphs/LightGraphs.jl/actions/workflows/ci.yml?query=branch%3Amaster) [![codecov.io](http://codecov.io/github/JuliaGraphs/LightGraphs.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaGraphs/LightGraphs.jl?branch=master) [![](https://img.shields.io/badge/docs-latest-blue.svg)](https://juliagraphs.github.io/LightGraphs.jl/latest) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.889971.svg)](https://doi.org/10.5281/zenodo.889971) From 92cd78b5f16b1f1b163aec1314a33640f0ccf1b6 Mon Sep 17 00:00:00 2001 From: Matthew Wigginton Conway Date: Fri, 2 Apr 2021 16:48:57 -0400 Subject: [PATCH 22/37] correct type annotations for enumerate_paths, fixes #1552 --- src/shortestpaths/bellman-ford.jl | 4 ++-- test/shortestpaths/dijkstra.jl | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/shortestpaths/bellman-ford.jl b/src/shortestpaths/bellman-ford.jl index 9b4d3e0cf..9dcce4a2c 100644 --- a/src/shortestpaths/bellman-ford.jl +++ b/src/shortestpaths/bellman-ford.jl @@ -110,7 +110,7 @@ will return a vector (indexed by destination vertex) of paths from source `v` to all other vertices. In addition, `enumerate_paths(state, v, d)` will return a vector representing the path from vertex `v` to vertex `d`. """ -function enumerate_paths(state::AbstractPathState, vs::Vector{<:Integer}) +function enumerate_paths(state::AbstractPathState, vs::AbstractVector{<:Integer}) parents = state.parents T = eltype(parents) @@ -131,6 +131,6 @@ function enumerate_paths(state::AbstractPathState, vs::Vector{<:Integer}) return all_paths end -enumerate_paths(state::AbstractPathState, v) = enumerate_paths(state, [v])[1] +enumerate_paths(state::AbstractPathState, v::Integer) = enumerate_paths(state, [v])[1] enumerate_paths(state::AbstractPathState) = enumerate_paths(state, [1:length(state.parents);]) diff --git a/test/shortestpaths/dijkstra.jl b/test/shortestpaths/dijkstra.jl index 43695597d..b1bb4945d 100644 --- a/test/shortestpaths/dijkstra.jl +++ b/test/shortestpaths/dijkstra.jl @@ -17,6 +17,9 @@ @test @inferred(enumerate_paths(z)) == enumerate_paths(y) @test @inferred(enumerate_paths(z))[4] == enumerate_paths(z, 4) == + # test that we can pass a range into enumerate_paths - previously this caused + # infinite recursion - see #1552 + enumerate_paths(z, 3:4)[2] == enumerate_paths(y, 4) == [2, 3, 4] end From 6cf43375f561c3ec334ffc094be93792e4b47f04 Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Thu, 15 Apr 2021 16:53:30 -0400 Subject: [PATCH 23/37] Update ci.yml get rid of codecov token. Not needed for public repos. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f379e68ad..af12fa0ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,5 +27,5 @@ jobs: # - uses: julia-actions/julia-runtest@latest - uses: julia-actions/julia-uploadcodecov@latest env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + # CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} if: ${{ matrix.julia-version == '1' && matrix.os =='ubuntu-latest' }} From 05c80bb7b2899e09b9975968543ed8c8ecd9c912 Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Fri, 16 Apr 2021 19:14:56 -0400 Subject: [PATCH 24/37] Update ci.yml --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af12fa0ec..af2fcc514 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,5 @@ jobs: # uncomment after 2.0 # - uses: julia-actions/julia-runtest@latest - uses: julia-actions/julia-uploadcodecov@latest - env: # CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} if: ${{ matrix.julia-version == '1' && matrix.os =='ubuntu-latest' }} From 1769686f7997af4a0960d6e085a3416111312ed4 Mon Sep 17 00:00:00 2001 From: angsttomato <61888970+angsttomato@users.noreply.github.com> Date: Sat, 22 May 2021 11:38:02 +0300 Subject: [PATCH 25/37] Small typo fix --- docs/src/graphtypes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/graphtypes.md b/docs/src/graphtypes.md index 2e3b0b9b0..e1d9bd540 100644 --- a/docs/src/graphtypes.md +++ b/docs/src/graphtypes.md @@ -13,4 +13,4 @@ These are general guidelines to help you select the proper graph type. - In general, prefer the native `SimpleGraphs`/`SimpleDiGraphs` structures in [LightGraphs.jl](https://github.com/JuliaGraphs/LightGraphs.jl). - If you need edge weights and don't require large numbers of graph modifications, use [SimpleWeightedGraphs](https://github.com/JuliaGraphs/SimpleWeightedGraphs.jl). - If you need labeling of vertices or edges, use [MetaGraphs](https://github.com/JuliaGraphs/MetaGraphs.jl). -- If you work with very large graphs (billons to tens of billions of edges) and don't need mutability, use [StaticGraphs](https://github.com/JuliaGraphs/StaticGraphs.jl). +- If you work with very large graphs (billions to tens of billions of edges) and don't need mutability, use [StaticGraphs](https://github.com/JuliaGraphs/StaticGraphs.jl). From 82c9020967d905830dd8643097020c61a8731916 Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Fri, 4 Jun 2021 13:47:10 +0200 Subject: [PATCH 26/37] Add degree to vertex properties --- docs/src/basicproperties.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/basicproperties.md b/docs/src/basicproperties.md index 991cc8ab7..093c1a9a1 100644 --- a/docs/src/basicproperties.md +++ b/docs/src/basicproperties.md @@ -21,6 +21,7 @@ Note: to use the `has_edge(g, e)` method safely, it is important to understand t - `all_neighbors`: Returns array of all neighbors (both `inneighbors` and `outneighbors`). For undirected graphs, equivalent to `neighbors`. - `inneighbors`: Return array of in-neighbors. Equivalent to `neighbors` for undirected graphs. - `outneighbors`: Return array of out-neighbors. Equivalent to `neighbors` for undirected graphs. +- `degree`: Return the sum of incoming and outgoing edges. Equivalent to the number of connected edges for undirected graphs. ## Edge Properties From 3ec4f6477f54ba059522f7a86e93f8162e15bf50 Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Fri, 4 Jun 2021 14:10:28 +0200 Subject: [PATCH 27/37] Update make.jl --- docs/make.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/make.jl b/docs/make.jl index 8e1fa35a4..fa49e75d6 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -19,6 +19,7 @@ makedocs( "Making and Modifying Graphs" => "generators.md", "Reading / Writing Graphs" => "persistence.md", "Operators" => "operators.md", + "Core functions" => "core.md", "Plotting Graphs" => "plotting.md", "Path and Traversal" => "pathing.md", "Coloring" => "coloring.md", From 6c36687db6af49b50d49a8afbfa78e2a15e94276 Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Fri, 4 Jun 2021 14:11:17 +0200 Subject: [PATCH 28/37] revert adding degree to vertex properties --- docs/src/basicproperties.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/basicproperties.md b/docs/src/basicproperties.md index 093c1a9a1..991cc8ab7 100644 --- a/docs/src/basicproperties.md +++ b/docs/src/basicproperties.md @@ -21,7 +21,6 @@ Note: to use the `has_edge(g, e)` method safely, it is important to understand t - `all_neighbors`: Returns array of all neighbors (both `inneighbors` and `outneighbors`). For undirected graphs, equivalent to `neighbors`. - `inneighbors`: Return array of in-neighbors. Equivalent to `neighbors` for undirected graphs. - `outneighbors`: Return array of out-neighbors. Equivalent to `neighbors` for undirected graphs. -- `degree`: Return the sum of incoming and outgoing edges. Equivalent to the number of connected edges for undirected graphs. ## Edge Properties From 5d2b80ab3d33d134c88312a1b9518ec3682c44ad Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Fri, 4 Jun 2021 08:49:36 -0400 Subject: [PATCH 29/37] Update make.jl --- docs/make.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index fa49e75d6..7e8deaaec 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -19,7 +19,7 @@ makedocs( "Making and Modifying Graphs" => "generators.md", "Reading / Writing Graphs" => "persistence.md", "Operators" => "operators.md", - "Core functions" => "core.md", + "Core Functions" => "core.md", "Plotting Graphs" => "plotting.md", "Path and Traversal" => "pathing.md", "Coloring" => "coloring.md", From 97bb937eb309fef2a505a72b24db557cd40cf06c Mon Sep 17 00:00:00 2001 From: Nikos Pitsianis Date: Sun, 13 Jun 2021 18:22:25 +0300 Subject: [PATCH 30/37] added SGtSNEpi.jl as a graph plot suggestion --- docs/src/plotting.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/src/plotting.md b/docs/src/plotting.md index 7ce7248ee..063231b1c 100644 --- a/docs/src/plotting.md +++ b/docs/src/plotting.md @@ -66,3 +66,22 @@ end The above code produces the following output: ![alt tag](https://raw.githubusercontent.com/abhijithanilkumar/NetworkViz.jl/master/examples/networkviz.gif) + + +## [SGtSNEpi.jl](https://github.com/fcdimitr/SGtSNEpi.jl) +SGtSNEpi.jl is a high-performance software for swift embedding of a large, sparse graph into a d-dimensional space (d = 1,2,3). The [Makie](http://makie.juliaplots.org) plotting ecosystem is used for interactive plots. + +```julia + +using GLMakie, SGtSNEpi, SNAPDatasets + +GLMakie.activate!() + +g = loadsnap(:as_caida) +y = sgtsnepi(g); +show_embedding(y) +``` + +The above code produces the following output: + +![alt tag](https://raw.githubusercontent.com/abhijithanilkumar/NetworkViz.jl/master/examples/networkviz.gif) From 10842dd8812f9beff9a184bcb9d3c61dc77f9d39 Mon Sep 17 00:00:00 2001 From: Dimitris Floros Date: Sun, 13 Jun 2021 18:49:44 +0300 Subject: [PATCH 31/37] added 2D/3D embedding visualizations --- docs/src/plotting.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/src/plotting.md b/docs/src/plotting.md index 063231b1c..f9dd29a1e 100644 --- a/docs/src/plotting.md +++ b/docs/src/plotting.md @@ -72,7 +72,6 @@ The above code produces the following output: SGtSNEpi.jl is a high-performance software for swift embedding of a large, sparse graph into a d-dimensional space (d = 1,2,3). The [Makie](http://makie.juliaplots.org) plotting ecosystem is used for interactive plots. ```julia - using GLMakie, SGtSNEpi, SNAPDatasets GLMakie.activate!() @@ -84,4 +83,11 @@ show_embedding(y) The above code produces the following output: -![alt tag](https://raw.githubusercontent.com/abhijithanilkumar/NetworkViz.jl/master/examples/networkviz.gif) +![alt tag](https://github.com/fcdimitr/SGtSNEpi.jl/raw/master/docs/src/assets/as_caida.png) + +SGtSNEpi.jl enables 3D graph embedding as well. The 3D embedding of +the weighted undirected graph +[ML\_Graph/optdigits\_10NN](https://sparse.tamu.edu/ML_Graph/optdigits_10NN) +is shown below: + +![alt tag](https://fcdimitr.github.io/SGtSNEpi.jl/v0.1.0/sgtsnepi-animation.gif) From a873866a30f61260b4e965d927c5b41a173b91cb Mon Sep 17 00:00:00 2001 From: Dimitris Floros Date: Sun, 13 Jun 2021 18:53:49 +0300 Subject: [PATCH 32/37] Explanation of visualization arguments --- docs/src/plotting.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/src/plotting.md b/docs/src/plotting.md index f9dd29a1e..e7a10f8cb 100644 --- a/docs/src/plotting.md +++ b/docs/src/plotting.md @@ -78,7 +78,11 @@ GLMakie.activate!() g = loadsnap(:as_caida) y = sgtsnepi(g); -show_embedding(y) +show_embedding(y; + A = adjacency_matrix(g), # show edges on embedding + mrk_size = 1, # control marker size + lwd_in = 0.01, lwd_out = 0.001, # control line widths + edge_alpha = 0.03 ) # control line transparency ``` The above code produces the following output: From 12868ca1701d32449fae3a8e826efb5aa3ec62c1 Mon Sep 17 00:00:00 2001 From: Dimitris Floros Date: Sun, 13 Jun 2021 19:00:37 +0300 Subject: [PATCH 33/37] fixed --- docs/src/plotting.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/plotting.md b/docs/src/plotting.md index e7a10f8cb..bc27cdce7 100644 --- a/docs/src/plotting.md +++ b/docs/src/plotting.md @@ -80,9 +80,9 @@ g = loadsnap(:as_caida) y = sgtsnepi(g); show_embedding(y; A = adjacency_matrix(g), # show edges on embedding - mrk_size = 1, # control marker size - lwd_in = 0.01, lwd_out = 0.001, # control line widths - edge_alpha = 0.03 ) # control line transparency + mrk_size = 1, # control node sizes + lwd_in = 0.01, lwd_out = 0.001, # control edge widths + edge_alpha = 0.03 ) # control edge transparency ``` The above code produces the following output: From 90989ef1248115c8735bff2f5d5775329b7f4eb0 Mon Sep 17 00:00:00 2001 From: Nikos Pitsianis Date: Sun, 13 Jun 2021 19:17:58 +0300 Subject: [PATCH 34/37] optdigits graph info --- docs/src/plotting.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/src/plotting.md b/docs/src/plotting.md index bc27cdce7..b97ec9eb9 100644 --- a/docs/src/plotting.md +++ b/docs/src/plotting.md @@ -89,9 +89,6 @@ The above code produces the following output: ![alt tag](https://github.com/fcdimitr/SGtSNEpi.jl/raw/master/docs/src/assets/as_caida.png) -SGtSNEpi.jl enables 3D graph embedding as well. The 3D embedding of -the weighted undirected graph -[ML\_Graph/optdigits\_10NN](https://sparse.tamu.edu/ML_Graph/optdigits_10NN) -is shown below: +SGtSNEpi.jl enables 3D graph embedding as well. The 3D embedding of the weighted undirected graph [ML\_Graph/optdigits\_10NN](https://sparse.tamu.edu/ML_Graph/optdigits_10NN) is shown below. It consists of 26,475 nodes and 53,381 edges. Nodes are colored according to labels provided with the dataset. ![alt tag](https://fcdimitr.github.io/SGtSNEpi.jl/v0.1.0/sgtsnepi-animation.gif) From 1477bbc5c3a142ff3243176c74f2368467140a3b Mon Sep 17 00:00:00 2001 From: George Datseris Date: Fri, 20 Aug 2021 11:43:24 +0300 Subject: [PATCH 35/37] fix typo in docstring of watts strogatz --- src/SimpleGraphs/generators/randgraphs.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SimpleGraphs/generators/randgraphs.jl b/src/SimpleGraphs/generators/randgraphs.jl index 716940376..cd6fc9036 100644 --- a/src/SimpleGraphs/generators/randgraphs.jl +++ b/src/SimpleGraphs/generators/randgraphs.jl @@ -223,8 +223,8 @@ end watts_strogatz(n, k, β) Return a [Watts-Strogatz](https://en.wikipedia.org/wiki/Watts_and_Strogatz_model) -small world random graph with `n` vertices, each with expected degree `k` (or `k -- 1` if `k` is odd). Edges are randomized per the model based on probability `β`. +small world random graph with `n` vertices, each with expected degree `k` +(or `k - 1` if `k` is odd). Edges are randomized per the model based on probability `β`. The algorithm proceeds as follows. First, a perfect 1-lattice is constructed, where each vertex has exacly `div(k, 2)` neighbors on each side (i.e., `k` or From 712b8d12a7dab60a8f42b9e9105e9d94521a065d Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Mon, 30 Aug 2021 15:36:21 +0200 Subject: [PATCH 36/37] Add topological_sort_by_dfs to docs on traversals Solves #1566 --- docs/src/pathing.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/pathing.md b/docs/src/pathing.md index bde4c1cbf..5c0d2734c 100644 --- a/docs/src/pathing.md +++ b/docs/src/pathing.md @@ -32,6 +32,7 @@ Any graph traversal will traverse an edge only if it is present in the graph. W ```@docs bfs_tree +topological_sort_by_dfs dfs_tree maximum_adjacency_visit bfs_parents From b6a6a55d272198ee70fa80990d89eab3c6f87c01 Mon Sep 17 00:00:00 2001 From: James Date: Fri, 8 Oct 2021 10:37:07 -0400 Subject: [PATCH 37/37] Add archive note to README So long Seth, and thanks for all the fish. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2ebcf8235..72322e3e5 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ [![](https://img.shields.io/badge/docs-latest-blue.svg)](https://juliagraphs.github.io/LightGraphs.jl/latest) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.889971.svg)](https://doi.org/10.5281/zenodo.889971) +**Project Status:** As of 8 October 2021 LightGraphs is no longer under active development. It will remain available on Github at [sbromberger/LightGraphs.jl](https://github.com/sbromberger/LightGraphs.jl). The JuliaGraphs organization will continue to maintain packages that use LightGraphs and transition development over the long term. + LightGraphs offers both (a) a set of simple, concrete graph implementations -- `Graph` (for undirected graphs) and `DiGraph` (for directed graphs), and (b) an API for the development of more sophisticated graph implementations under the `AbstractGraph`