Skip to content
This repository was archived by the owner on Oct 8, 2021. It is now read-only.

Commit 293d331

Browse files
jpfairbankssbromberger
authored andcommitted
update randgraphs.jl to use Channels over Tasks
Fixes deprecation warnings introduced in: JuliaLang/julia#19841 Changes an API interface: -function Graph(nvg::Int, neg::Int, edgestream::Task) +function Graph(nvg::Int, neg::Int, edgestream::Channel) Iteration over Tasks is deprecated so now we iterate over the Channel.
1 parent de342ea commit 293d331

File tree

2 files changed

+102
-90
lines changed

2 files changed

+102
-90
lines changed

src/generators/randgraphs.jl

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,8 @@ stochastic_block_model(cin::Float64, coff::Float64, n::Vector{Int}; seed::Int =
500500
Returns a Graph generated according to the Stochastic Block Model (SBM).
501501
502502
`c[a,b]` : Mean number of neighbors of a vertex in block `a` belonging to block `b`.
503-
Only the upper triangular part is considered, since the lower traingular is
504-
determined by $c[b,a] = c[a,b] * n[a]/n[b]$.
503+
Only the upper triangular part is considered, since the lower traingular is
504+
determined by $c[b,a] = c[a,b] * n[a]/n[b]$.
505505
`n[a]` : Number of vertices in block `a`
506506
507507
The second form samples from a SBM with `c[a,a]=cin`, and `c[a,b]=coff`.
@@ -552,12 +552,12 @@ function stochastic_block_model{T<:Real}(cint::T, cext::T, n::Vector{Int}; seed:
552552
end
553553

554554
"""
555-
type StochasticBlockModel{T<:Integer,P<:Real}
556-
n::T
557-
nodemap::Array{T}
558-
affinities::Matrix{P}
559-
rng::MersenneTwister
560-
end
555+
type StochasticBlockModel{T<:Integer,P<:Real}
556+
n::T
557+
nodemap::Array{T}
558+
affinities::Matrix{P}
559+
rng::MersenneTwister
560+
end
561561
562562
A type capturing the parameters of the SBM.
563563
Each vertex is assigned to a block and the probability of edge `(i,j)`
@@ -580,7 +580,7 @@ type StochasticBlockModel{T<:Integer,P<:Real}
580580
end
581581

582582
==(sbm::StochasticBlockModel, other::StochasticBlockModel) =
583-
(sbm.n == other.n) && (sbm.nodemap == other.nodemap) && (sbm.affinities == other.affinities)
583+
(sbm.n == other.n) && (sbm.nodemap == other.nodemap) && (sbm.affinities == other.affinities)
584584

585585
"""A constructor for StochasticBlockModel that uses the sizes of the blocks
586586
and the affinity matrix. This construction implies that consecutive
@@ -611,17 +611,17 @@ function sbmaffinity(internalp::Vector{Float64}, externalp::Float64, sizes::Vect
611611
end
612612

613613
function StochasticBlockModel(internalp::Float64,
614-
externalp::Float64,
615-
size::Int,
616-
numblocks::Int;
617-
seed::Int = -1)
614+
externalp::Float64,
615+
size::Int,
616+
numblocks::Int;
617+
seed::Int = -1)
618618
sizes = fill(size, numblocks)
619619
B = sbmaffinity(fill(internalp, numblocks), externalp, sizes)
620620
StochasticBlockModel(sizes, B, seed=seed)
621621
end
622622

623623
function StochasticBlockModel(internalp::Vector{Float64}, externalp::Float64
624-
, sizes::Vector{Int}; seed::Int = -1)
624+
, sizes::Vector{Int}; seed::Int = -1)
625625
B = sbmaffinity(internalp, externalp, sizes)
626626
return StochasticBlockModel(sizes, B, seed=seed)
627627
end
@@ -634,8 +634,8 @@ between is the affinity between the two parts of each bipartite community
634634
intra is the probability of an edge within the parts of the partitions.
635635
636636
This is a specific type of SBM with k/2 blocks each with two halves.
637-
Each half is connected as a random bipartite graph with probability `intra`
638-
The blocks are connected with probability `between`.
637+
Each half is connected as a random bipartite graph with probability `intra`
638+
The blocks are connected with probability `between`.
639639
"""
640640
function nearbipartiteaffinity(sizes::Vector{Int}, between::Float64, intra::Float64)
641641
numblocks = div(length(sizes), 2)
@@ -656,9 +656,12 @@ end
656656

657657
"""Generates a stream of random pairs in 1:n"""
658658
function random_pair(rng::AbstractRNG, n::Int)
659-
while true
660-
produce( rand(rng, 1:n), rand(rng, 1:n) )
659+
f(ch) = begin
660+
while true
661+
put!(ch, Edge(rand(rng, 1:n), rand(rng, 1:n)))
662+
end
661663
end
664+
return f
662665
end
663666

664667

@@ -669,32 +672,36 @@ Take an infinite sample from the sbm.
669672
Pass to `Graph(nvg, neg, edgestream)` to get a Graph object.
670673
"""
671674
function make_edgestream(sbm::StochasticBlockModel)
672-
pairs = @task random_pair(sbm.rng, sbm.n)
673-
for (i,j) in pairs
674-
if i == j
675-
continue
676-
end
677-
p = sbm.affinities[sbm.nodemap[i], sbm.nodemap[j]]
678-
if rand(sbm.rng) < p
679-
produce(i, j)
675+
pairs = Channel(random_pair(sbm.rng, sbm.n), ctype=Edge, csize=32)
676+
edges(ch) = begin
677+
for e in pairs
678+
i, j = Tuple(e)
679+
if i == j
680+
continue
681+
end
682+
p = sbm.affinities[sbm.nodemap[i], sbm.nodemap[j]]
683+
if rand(sbm.rng) < p
684+
put!(ch, e)
685+
end
680686
end
681687
end
688+
return Channel(edges, ctype=Edge, csize=32)
682689
end
683690

684-
function Graph(nvg::Int, neg::Int, edgestream::Task)
691+
function Graph(nvg::Int, neg::Int, edgestream::Channel)
685692
g = Graph(nvg)
686693
# println(g)
687-
for (i,j) in edgestream
694+
for e in edgestream
688695
# print("$count, $i,$j\n")
689-
add_edge!(g, Edge(i, j))
696+
add_edge!(g, e)
690697
ne(g) >= neg && break
691698
end
692699
# println(g)
693700
return g
694701
end
695702

696703
Graph(nvg::Int, neg::Int, sbm::StochasticBlockModel) =
697-
Graph(nvg, neg, @task make_edgestream(sbm))
704+
Graph(nvg, neg, make_edgestream(sbm))
698705

699706
"""counts the number of edges that go between each block"""
700707
function blockcounts(sbm::StochasticBlockModel, A::AbstractMatrix)

test/generators/randgraphs.jl

Lines changed: 65 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
@testset "Randgraphs" begin
2+
@test nv(r1) == 10
3+
@test ne(r1) == 20
4+
@test nv(r2) == 5
5+
@test ne(r2) == 10
26

37
r1 = Graph(10,20)
48
r2 = DiGraph(5,10)
@@ -182,66 +186,67 @@
182186
@test degree(rr, v) == 8
183187
end
184188

185-
rd = random_regular_digraph(10, 8, dir=:out, seed=4)
186-
@test nv(rd) == 10
187-
@test ne(rd) == 80
188-
@test is_directed(rd)
189-
190-
g = stochastic_block_model(2., 3., [100,100])
191-
@test 4.5 < mean(degree(g)) < 5.5
192-
g = stochastic_block_model(3., 4., [100,100,100])
193-
@test 10.5 < mean(degree(g)) < 11.5
194-
195-
function generate_nbp_sbm(numedges, sizes)
196-
density = 1
197-
# print(STDERR, "Generating communites with sizes: $sizes\n")
198-
between = density * 0.90
199-
intra = density * -0.005
200-
noise = density * 0.00501
201-
sbm = nearbipartiteSBM(sizes, between, intra, noise)
202-
edgestream = @task make_edgestream(sbm)
203-
g = Graph(sum(sizes), numedges, edgestream)
204-
return sbm, g
205-
end
189+
function generate_nbp_sbm(numedges, sizes)
190+
density = 1
191+
# print(STDERR, "Generating communites with sizes: $sizes\n")
192+
between = density * 0.90
193+
intra = density * -0.005
194+
noise = density * 0.00501
195+
sbm = nearbipartiteSBM(sizes, between, intra, noise)
196+
edgestream = make_edgestream(sbm)
197+
g = Graph(sum(sizes), numedges, edgestream)
198+
return sbm, g
199+
end
206200

207201

208-
numedges = 100
209-
sizes = [10, 10, 10, 10]
210-
211-
n = sum(sizes)
212-
sbm, g = generate_nbp_sbm(numedges, sizes)
213-
bc = blockcounts(sbm, g)
214-
bp = blockfractions(sbm, g) ./ (sizes * sizes')
215-
ratios = bp ./ (sbm.affinities ./ sum(sbm.affinities))
216-
@test norm(Array(ratios)) < 0.25
217-
218-
sizes = [200, 200, 100]
219-
internaldeg = 15
220-
externaldeg = 6
221-
internalp = Float64[internaldeg/i for i in sizes]
222-
externalp = externaldeg/sum(sizes)
223-
numedges = internaldeg + externaldeg #+ sum(externaldeg.*sizes[2:end])
224-
numedges *= div(sum(sizes), 2)
225-
sbm = StochasticBlockModel(internalp, externalp, sizes)
226-
g = Graph(sum(sizes), numedges, sbm)
227-
@test ne(g) <= numedges
228-
@test nv(g) == sum(sizes)
229-
bc = blockcounts(sbm, g)
230-
bp = blockfractions(sbm, g) ./ (sizes * sizes')
231-
ratios = bp ./ (sbm.affinities ./ sum(sbm.affinities))
232-
@test norm(Array(ratios)) < 0.25
233-
234-
# check that average degree is not too high
235-
# factor of two is cushion for random process
236-
@test mean(degree(g)) <= 4//2*numedges/sum(sizes)
237-
# check that the internal degrees are higher than the external degrees
238-
# 5//4 is cushion for random process.
239-
@test all(sum(bc-diagm(diag(bc)), 1) .<= 5//4 .* diag(bc))
240-
241-
242-
sbm2 = StochasticBlockModel(0.5*ones(4), 0.3, 10*ones(Int,4))
243-
sbm = StochasticBlockModel(0.5, 0.3, 10, 4)
244-
@test sbm == sbm2
245-
sbm.affinities[1,1] = 0
246-
@test sbm != sbm2
202+
function test_sbm(sbm, bp)
203+
@test sum(sbm.affinities) != NaN
204+
@test all(sbm.affinities .> 0)
205+
@test sum(sbm.affinities) != 0
206+
@test all(bp .>= 0)
207+
@test all(bp .!= NaN)
247208
end
209+
210+
numedges = 100
211+
sizes = [10, 10, 10, 10]
212+
213+
n = sum(sizes)
214+
sbm, g = generate_nbp_sbm(numedges, sizes)
215+
@test ne(g) >= 0.9numedges
216+
bc = blockcounts(sbm, g)
217+
bp = blockfractions(sbm, g) ./ (sizes * sizes')
218+
ratios = bp ./ (sbm.affinities ./ sum(sbm.affinities))
219+
test_sbm(sbm, bp)
220+
@test norm(collect(ratios)) < 0.25
221+
222+
sizes = [200, 200, 100]
223+
internaldeg = 15
224+
externaldeg = 6
225+
internalp = Float64[internaldeg/i for i in sizes]
226+
externalp = externaldeg/sum(sizes)
227+
numedges = internaldeg + externaldeg #+ sum(externaldeg.*sizes[2:end])
228+
numedges *= div(sum(sizes), 2)
229+
sbm = StochasticBlockModel(internalp, externalp, sizes)
230+
g = Graph(sum(sizes), numedges, sbm)
231+
@test ne(g) >= 0.9numedges
232+
@test ne(g) <= numedges
233+
@test nv(g) == sum(sizes)
234+
bc = blockcounts(sbm, g)
235+
bp = blockfractions(sbm, g) ./ (sizes * sizes')
236+
test_sbm(sbm, bp)
237+
ratios = bp ./ (sbm.affinities ./ sum(sbm.affinities))
238+
@test norm(collect(ratios)) < 0.25
239+
240+
# check that average degree is not too high
241+
# factor of two is cushion for random process
242+
@test mean(degree(g)) <= 4//2*numedges/sum(sizes)
243+
# check that the internal degrees are higher than the external degrees
244+
# 5//4 is cushion for random process.
245+
@test all(sum(bc-diagm(diag(bc)), 1) .<= 5//4 .* diag(bc))
246+
247+
248+
sbm2 = StochasticBlockModel(0.5*ones(4), 0.3, 10*ones(Int,4))
249+
sbm = StochasticBlockModel(0.5, 0.3, 10, 4)
250+
@test sbm == sbm2
251+
sbm.affinities[1,1] = 0
252+
@test sbm != sbm2

0 commit comments

Comments
 (0)