Skip to content

Commit e15141a

Browse files
committed
Use generic graphs for testing
1 parent 6816f1b commit e15141a

11 files changed

+125
-79
lines changed

src/Test/Test.jl

+11-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module Test
88

99
using Graphs
1010

11-
export GenericEdge, GenericGraph, GenericDiGraph
11+
export GenericEdge, GenericGraph, GenericDiGraph, generic_graph
1212

1313
"""
1414
GenericEdge <: Graphs.AbstractEdge
@@ -46,6 +46,16 @@ struct GenericDiGraph{T} <: Graphs.AbstractGraph{T}
4646
g::SimpleDiGraph{T}
4747
end
4848

49+
"""
50+
generic_graph(g::Union{SimpleGraph, SimpleDiGraph})
51+
52+
Return either a GenericGraph or GenericDiGraph that wraps a copy of g.
53+
"""
54+
function generic_graph(g::Union{SimpleGraph, SimpleDiGraph})
55+
g = copy(g)
56+
return is_directed(g) ? GenericDiGraph(g) : GenericGraph(g)
57+
end
58+
4959
Graphs.is_directed(::Type{<:GenericGraph}) = false
5060
Graphs.is_directed(::Type{<:GenericDiGraph}) = true
5161

src/degeneracy.jl

+4
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ Int64[]
324324
```
325325
"""
326326
function k_corona(g::AbstractGraph, k; corenum=core_number(g))
327+
328+
# TODO k_corona does not correctly work for all AbstractGraph as
329+
# it relies on induced_subgraph, which does not work on any AbstractGraph
330+
327331
kcore = k_core(g, k)
328332
kcoreg = g[kcore]
329333
kcoredeg = degree(kcoreg)

src/operators.jl

+8-14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# TODO most of the operators here do not work with any AbstractGraph yet
2+
# as they require cloning and modifying graphs.
3+
14
"""
25
complement(g)
36
@@ -402,25 +405,16 @@ end
402405
# """Provides multiplication of a graph `g` by a vector `v` such that spectral
403406
# graph functions in [GraphMatrices.jl](https://github.com/jpfairbanks/GraphMatrices.jl) can utilize Graphs natively.
404407
# """
405-
function *(g::Graph, v::Vector{T}) where {T<:Real}
406-
length(v) == nv(g) || throw(ArgumentError("Vector size must equal number of vertices"))
407-
y = zeros(T, nv(g))
408-
for e in edges(g)
409-
i = src(e)
410-
j = dst(e)
411-
y[i] += v[j]
412-
y[j] += v[i]
413-
end
414-
return y
415-
end
416-
417-
function *(g::DiGraph, v::Vector{T}) where {T<:Real}
408+
function *(g::AbstractGraph, v::Vector{T}) where {T<:Real}
418409
length(v) == nv(g) || throw(ArgumentError("Vector size must equal number of vertices"))
419410
y = zeros(T, nv(g))
420411
for e in edges(g)
421412
i = src(e)
422413
j = dst(e)
423414
y[i] += v[j]
415+
if !is_directed(g)
416+
y[j] += v[i]
417+
end
424418
end
425419
return y
426420
end
@@ -481,7 +475,7 @@ julia> size(g, 3)
481475
1
482476
```
483477
"""
484-
size(g::Graph, dim::Int) = (dim == 1 || dim == 2) ? nv(g) : 1
478+
size(g::AbstractGraph, dim::Int) = (dim == 1 || dim == 2) ? nv(g) : 1
485479

486480
"""
487481
sum(g)

src/traversals/bfs.jl

+5-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ function _bfs_parents(g::AbstractGraph{T}, source, neighborfn::Function) where {
5555
end
5656
while !isempty(cur_level)
5757
@inbounds for v in cur_level
58-
@inbounds @simd for i in neighborfn(g, v)
58+
# TODO we previously used @simd on the loop below, but this would fail
59+
# if the result of neighorfn(g, v) would not implement firstindex
60+
# If @simd really has a performance advantage, then maybe we make
61+
# two different cases here.
62+
@inbounds for i in neighborfn(g, v)
5963
if !visited[i]
6064
push!(next_level, i)
6165
parents[i] = v

test/connectivity.jl

+44-26
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
add_edge!(gx, 8, 9)
88
add_edge!(gx, 10, 9)
99

10-
for g in testgraphs(gx)
10+
for g in test_generic_graphs(gx)
1111
@test @inferred(!is_connected(g))
1212
cc = @inferred(connected_components(g))
1313
label = zeros(eltype(g), nv(g))
@@ -20,18 +20,18 @@
2020
@test cclab[8] == [8, 9, 10]
2121
@test length(cc) >= 3 && sort(cc[3]) == [8, 9, 10]
2222
end
23-
for g in testgraphs(g6)
23+
for g in test_generic_graphs(g6)
2424
@test @inferred(is_connected(g))
2525
end
2626

2727
g10 = SimpleDiGraph(4)
2828
add_edge!(g10, 1, 3)
2929
add_edge!(g10, 2, 4)
30-
for g in testdigraphs(g10)
30+
for g in test_generic_graphs(g10)
3131
@test @inferred(is_bipartite(g))
3232
end
3333
add_edge!(g10, 1, 4)
34-
for g in testdigraphs(g10)
34+
for g in test_generic_graphs(g10)
3535
@test @inferred(is_bipartite(g))
3636
end
3737

@@ -45,7 +45,7 @@
4545
end
4646
if !has_edge(g, i, j)
4747
add_edge!(g, i, j)
48-
@test @inferred(is_bipartite(g))
48+
@test @inferred(is_bipartite(GenericDiGraph(g)))
4949
end
5050
end
5151
end
@@ -66,7 +66,7 @@
6666
add_edge!(h, 7, 6)
6767
add_edge!(h, 8, 4)
6868
add_edge!(h, 8, 7)
69-
for g in testdigraphs(h)
69+
for g in test_generic_graphs(h)
7070
@test @inferred(is_weakly_connected(g))
7171
scc = @inferred(strongly_connected_components(g))
7272
scc_k = @inferred(strongly_connected_components_kosaraju(g))
@@ -77,15 +77,27 @@
7777
@test length(wcc) == 1 && length(wcc[1]) == nv(g)
7878
end
7979

80-
function scc_ok(graph)
80+
function scc_ok(graph::GenericDiGraph)
8181
# Check that all SCC really are strongly connected
82+
83+
# TODO it might be better if we did not have to unwrap the GenericDiGraph
84+
# (and we somehow might prevent this in the future) but currently the methods
85+
# used in this utility test function do not work with GenericDiGraph yet.
86+
graph = graph.g
87+
8288
scc = @inferred(strongly_connected_components(graph))
8389
scc_as_subgraphs = map(i -> graph[i], scc)
8490
return all(is_strongly_connected, scc_as_subgraphs)
8591
end
8692

87-
function scc_k_ok(graph)
93+
function scc_k_ok(graph::GenericDiGraph)
8894
# Check that all SCC really are strongly connected
95+
96+
# TODO it might be better if we did not have to unwrap the GenericDiGraph
97+
# (and we somehow might prevent this in the future) but currently the methods
98+
# used in this utility test function do not work with GenericDiGraph yet.
99+
graph = graph.g
100+
89101
scc_k = @inferred(strongly_connected_components_kosaraju(graph))
90102
scc_k_as_subgraphs = map(i -> graph[i], scc_k)
91103
return all(is_strongly_connected, scc_k_as_subgraphs)
@@ -97,7 +109,7 @@
97109
add_edge!(h, 4, 2)
98110
add_edge!(h, 2, 3)
99111
add_edge!(h, 1, 3)
100-
for g in testdigraphs(h)
112+
for g in test_generic_graphs(h)
101113
@test scc_ok(g)
102114
@test scc_k_ok(g)
103115
end
@@ -107,14 +119,14 @@
107119
add_edge!(h2, 2, 4)
108120
add_edge!(h2, 4, 3)
109121
add_edge!(h2, 1, 3)
110-
for g in testdigraphs(h2)
122+
for g in test_generic_graphs(h2)
111123
@test scc_ok(g)
112124
@test scc_k_ok(g)
113125
end
114126

115127
# Test case for empty graph
116128
h = SimpleDiGraph(0)
117-
for g in testdigraphs(h)
129+
for g in test_generic_graphs(h)
118130
scc = @inferred(strongly_connected_components(g))
119131
scc_k = @inferred(strongly_connected_components_kosaraju(g))
120132
@test length(scc) == 0
@@ -123,7 +135,7 @@
123135

124136
# Test case for graph with one vertex
125137
h = SimpleDiGraph(1)
126-
for g in testdigraphs(h)
138+
for g in test_generic_graphs(h)
127139
scc = @inferred(strongly_connected_components(g))
128140
scc_k = @inferred(strongly_connected_components_kosaraju(g))
129141
@test length(scc) == 1 && scc[1] == [1]
@@ -139,7 +151,7 @@
139151
add_edge!(h, 2, 3)
140152
add_edge!(h, 2, 1)
141153

142-
for g in testdigraphs(h)
154+
for g in test_generic_graphs(h)
143155
scc = @inferred(strongly_connected_components(g))
144156
scc_k = @inferred(strongly_connected_components_kosaraju(g))
145157
@test length(scc) == 2
@@ -159,7 +171,7 @@
159171
add_edge!(h, 3, 5)
160172
add_edge!(h, 5, 6)
161173
add_edge!(h, 6, 4)
162-
for g in testdigraphs(h)
174+
for g in test_generic_graphs(h)
163175
scc = @inferred(strongly_connected_components(g))
164176
scc_k = @inferred(strongly_connected_components_kosaraju(g))
165177
@test length(scc) == 1 && sort(scc[1]) == [1:6;]
@@ -171,7 +183,7 @@
171183
add_edge!(h, 2, 3)
172184
add_edge!(h, 3, 1)
173185
add_edge!(h, 4, 1)
174-
for g in testdigraphs(h)
186+
for g in test_generic_graphs(h)
175187
scc = @inferred(strongly_connected_components(g))
176188
scc_k = @inferred(strongly_connected_components_kosaraju(g))
177189
@test length(scc) == 2 && sort(scc[1]) == [1:3;] && sort(scc[2]) == [4]
@@ -200,7 +212,7 @@
200212
add_edge!(h, 11, 12)
201213
add_edge!(h, 12, 10)
202214

203-
for g in testdigraphs(h)
215+
for g in test_generic_graphs(h)
204216
scc = @inferred(strongly_connected_components(g))
205217
scc_k = @inferred(strongly_connected_components_kosaraju(g))
206218
@test length(scc) == 4
@@ -224,44 +236,50 @@
224236
fig1[[3, 4, 9, 10, 11, 13, 18, 19, 22, 24]] = [
225237
0.5, 0.4, 0.1, 1.0, 1.0, 0.2, 0.3, 0.2, 1.0, 0.3
226238
]
227-
fig1 = SimpleDiGraph(fig1)
239+
fig1 = GenericDiGraph(SimpleDiGraph(fig1))
228240
scc_fig1 = Vector[[2, 5], [1, 3, 4]]
229241

230242
# figure 2 example
231243
fig2 = spzeros(5, 5)
232244
fig2[[3, 10, 11, 13, 14, 17, 18, 19, 22]] .= 1
233-
fig2 = SimpleDiGraph(fig2)
245+
fig2 = GenericDiGraph(SimpleDiGraph(fig2))
234246

235247
# figure 3 example
236248
fig3 = spzeros(8, 8)
237249
fig3[[
238250
1, 7, 9, 13, 14, 15, 18, 20, 23, 27, 28, 31, 33, 34, 37, 45, 46, 49, 57, 63, 64
239251
]] .= 1
240-
fig3 = SimpleDiGraph(fig3)
252+
fig3 = GenericDiGraph(SimpleDiGraph(fig3))
241253
scc_fig3 = Vector[[3, 4], [2, 5, 6], [8], [1, 7]]
242254
fig3_cond = SimpleDiGraph(4)
243255
add_edge!(fig3_cond, 4, 3)
244256
add_edge!(fig3_cond, 2, 1)
245257
add_edge!(fig3_cond, 4, 1)
246258
add_edge!(fig3_cond, 4, 2)
259+
fig3_cond
247260

248261
# construct a n-number edge ring graph (period = n)
249262
n = 10
250263
n_ring = cycle_digraph(n)
251264
n_ring_shortcut = copy(n_ring)
252265
add_edge!(n_ring_shortcut, 1, 4)
266+
n_ring = GenericDiGraph(n_ring)
267+
n_ring_shortcut = GenericDiGraph(n_ring_shortcut)
253268

254269
# figure 8 example
255270
fig8 = spzeros(6, 6)
256271
fig8[[2, 10, 13, 21, 24, 27, 35]] .= 1
257-
fig8 = SimpleDiGraph(fig8)
272+
fig8 = GenericDiGraph(SimpleDiGraph(fig8))
258273

259274
@test Set(@inferred(strongly_connected_components(fig1))) == Set(scc_fig1)
260275
@test Set(@inferred(strongly_connected_components(fig3))) == Set(scc_fig3)
261276

262277
@test @inferred(period(n_ring)) == n
263278
@test @inferred(period(n_ring_shortcut)) == 2
264279

280+
# TODO condensation currently returns a SimpleDiGraph, even if the input graph
281+
# is a GenericDiGraph, so we compare with a SimpleDiGraph in this test,
282+
# but one should think, if the condensation should not also be a GenericDiGraph
265283
@test @inferred(condensation(fig3)) == fig3_cond
266284

267285
@test @inferred(attracting_components(fig1)) == Vector[[2, 5]]
@@ -270,7 +288,7 @@
270288
g10dists = ones(10, 10)
271289
g10dists[1, 2] = 10.0
272290
g10 = star_graph(10)
273-
for g in testgraphs(g10)
291+
for g in test_generic_graphs(g10)
274292
@test @inferred(neighborhood_dists(g, 1, 0)) == [(1, 0)]
275293
@test length(@inferred(neighborhood(g, 1, 1))) == 10
276294
@test length(@inferred(neighborhood(g, 1, 1, g10dists))) == 9
@@ -280,8 +298,8 @@
280298
@test length(@inferred(neighborhood(g, 2, -1))) == 0
281299
end
282300
g10 = star_digraph(10)
283-
for g in testdigraphs(g10)
284-
@test @inferred(neighborhood_dists(g10, 1, 0, dir=:out)) == [(1, 0)]
301+
for g in test_generic_graphs(g10)
302+
@test @inferred(neighborhood_dists(g, 1, 0, dir=:out)) == [(1, 0)]
285303
@test length(@inferred(neighborhood(g, 1, 1, dir=:out))) == 10
286304
@test length(@inferred(neighborhood(g, 1, 1, g10dists, dir=:out))) == 9
287305
@test length(@inferred(neighborhood(g, 2, 1, dir=:out))) == 1
@@ -301,7 +319,7 @@
301319
##@test !@inferred(isgraphical([2]))
302320

303321
# Test simple digraphicality
304-
sdg = SimpleDiGraph(10, 90)
322+
sdg = GenericDiGraph(SimpleDiGraph(10, 90))
305323
@test @inferred(isdigraphical(indegree(sdg), outdegree(sdg)))
306324
@test !@inferred(isdigraphical([1, 1, 1], [1, 1, 0]))
307325
@test @inferred(isdigraphical(Integer[], Integer[]))
@@ -314,14 +332,14 @@
314332

315333
# 1116
316334
gc = cycle_graph(4)
317-
for g in testgraphs(gc)
335+
for g in test_generic_graphs(gc)
318336
z = @inferred(neighborhood(g, 3, 3))
319337
@test (z == [3, 2, 4, 1] || z == [3, 4, 2, 1])
320338
end
321339

322340
gd = SimpleDiGraph([0 1 1 0; 0 0 0 1; 0 0 0 1; 0 0 0 0])
323341
add_edge!(gd, 1, 4)
324-
for g in testdigraphs(gd)
342+
for g in test_generic_graphs(gd)
325343
z = @inferred(neighborhood_dists(g, 1, 4))
326344
@test (4, 1) z
327345
@test (4, 2) z

0 commit comments

Comments
 (0)