diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3e45726..bc9266f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -26,16 +26,7 @@ jobs: with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 - env: - cache-name: cache-artifacts - with: - path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} - restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- - ${{ runner.os }}- + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 @@ -50,6 +41,7 @@ jobs: - uses: julia-actions/setup-julia@v2 with: version: '1' + - uses: julia-actions/cache@v2 - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-docdeploy@v1 env: diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index 23e8588..b07dc83 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -15,7 +15,7 @@ jobs: run: which julia continue-on-error: true - name: Install Julia, but only if it is not already available in the PATH - uses: julia-actions/setup-julia@v1 + uses: julia-actions/setup-julia@v2 with: version: '1' arch: ${{ runner.arch }} diff --git a/docs/Project.toml b/docs/Project.toml index fc87afd..e34f61c 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -5,10 +5,12 @@ GraphMakie = "1ecd5474-83a3-4783-bb4f-06765db800d2" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" NetworkLayout = "46757867-2c16-5918-afeb-47bfcb05e46a" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" [compat] -CairoMakie = "0.10" +CairoMakie = "0.11" Documenter = "1" GraphMakie = "0.5" Graphs = "1.9" NetworkLayout = "0.4" +StableRNGs = "1.0.1" diff --git a/docs/make.jl b/docs/make.jl index 6b373ee..ba9db70 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -3,7 +3,9 @@ using NetworkLayout using Graphs using GraphMakie using CairoMakie +using StableRNGs +NetworkLayout.DEFAULT_RNG[] = StableRNG DocMeta.setdocmeta!(NetworkLayout, :DocTestSetup, :(using NetworkLayout); recursive=true) makedocs(; modules=[NetworkLayout], diff --git a/docs/src/index.md b/docs/src/index.md index 79b5977..6e9ed50 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -10,7 +10,7 @@ All example images on this page are created using [`Makie.jl`](https://github.co ```@example layouts using CairoMakie CairoMakie.activate!(type="png") # hide -set_theme!(resolution=(800, 400)) #hide +set_theme!(size=(800, 400)) #hide using NetworkLayout using GraphMakie, Graphs nothing #hide @@ -167,7 +167,7 @@ hidedecorations!(ax); hidespines!(ax); f #hide f #hide ``` ```@example layouts -set_theme!(resolution=(800, 800)) #hide +set_theme!(size=(800, 800)) #hide using Random; Random.seed!(5) # hide layout = Spectral() f, ax, p = graphplot(g, layout=layout, node_size=0.0, edge_width=1.0) @@ -201,11 +201,11 @@ nothing #hide ``` Example animation on how those keyword arguments effect different iterative layouts: ```@example layouts -springl = Spring(;initialpos, pin, seed=11) #2 +springl = Spring(;initialpos, pin, seed=2) sfdpl = SFDP(;initialpos, pin, tol=0.0) stressl = Stress(;initialpos, pin, reltols=0.0, abstolx=0.0, iterations=100) -f = Figure(resolution=(1200,500)) +f = Figure(size=(1200,500)) ax1 = f[1,1] = Axis(f; title="Spring") ax2 = f[1,2] = Axis(f; title="SFDP") ax3 = f[1,3] = Axis(f; title="Stress") diff --git a/src/sfdp.jl b/src/sfdp.jl index a052500..b9a9379 100644 --- a/src/sfdp.jl +++ b/src/sfdp.jl @@ -76,12 +76,12 @@ function Base.iterate(iter::LayoutIterator{<:SFDP{Dim,Ptype,T}}) where {Dim,Ptyp pin = [get(algo.pin, i, SVector{Dim,Bool}(false for _ in 1:Dim)) for i in 1:N] # iteratorstate: (#iter, energy, step, progress, old pos, pin, stopflag) - return startpos, (1, typemax(T), one(T), 0, startpos, pin, false) + return startpos, (1, typemax(T), one(T), 0, startpos, pin, rng, false) end function Base.iterate(iter::LayoutIterator{<:SFDP}, state) algo, adj_matrix = iter.algorithm, iter.adj_matrix - iter, energy0, step, progress, locs0, pin, stopflag = state + iter, energy0, step, progress, locs0, pin, rng, stopflag = state K, C, tol = algo.K, algo.C, algo.tol # stop if stopflag (tol reached) or nr of iterations reached @@ -109,9 +109,7 @@ function Base.iterate(iter::LayoutIterator{<:SFDP}, state) end if any(isnan, force) # if two points are at the exact same location use random force in any direction - # copy rng from alg struct to not advance the "initial" rng state - # otherwise algo(g)==algo(g) might be broken - force += randn(copy(algo.rng), Ftype) + force = randn(rng, Ftype) end mask = (!).(pin[i]) # where pin=true mask will multiply with 0 locs[i] = locs[i] .+ (step .* (force ./ norm(force))) .* mask @@ -124,7 +122,7 @@ function Base.iterate(iter::LayoutIterator{<:SFDP}, state) stopflag = true end - return locs, (iter + 1, energy, step, progress, locs, pin, stopflag) + return locs, (iter + 1, energy, step, progress, locs, pin, rng, stopflag) end # Calculate Attractive force diff --git a/src/spring.jl b/src/spring.jl index 5eb14f4..b0b26d0 100644 --- a/src/spring.jl +++ b/src/spring.jl @@ -75,12 +75,12 @@ function Base.iterate(iter::LayoutIterator{<:Spring{Dim,Ptype}}) where {Dim,Ptyp pin = [get(algo.pin, i, SVector{Dim,Bool}(false for _ in 1:Dim)) for i in 1:N] # iteratorstate: #iter nr, old pos, pin - return (startpos, (1, startpos, pin)) + return (startpos, (1, startpos, pin, rng)) end function Base.iterate(iter::LayoutIterator{<:Spring}, state) algo, adj_matrix = iter.algorithm, iter.adj_matrix - iteration, old_pos, pin = state + iteration, old_pos, pin, rng = state iteration >= algo.iterations && return nothing # The optimal distance bewteen vertices @@ -114,9 +114,7 @@ function Base.iterate(iter::LayoutIterator{<:Spring}, state) else # if two points are at the exact same location # use random force in any direction - # copy rng from alg struct to not advance the "initial" rng state - # otherwise algo(g)==algo(g) might be broken - force_vec += randn(copy(algo.rng), Ftype) + force_vec += randn(rng, Ftype) end end @@ -134,5 +132,5 @@ function Base.iterate(iter::LayoutIterator{<:Spring}, state) locs[i] += force[i] .* scale .* mask end - return locs, (iteration + 1, locs, pin) + return locs, (iteration + 1, locs, pin, rng) end