Skip to content

Commit 4c35a89

Browse files
Make squash specialized on simple graphs (#93)
- Squash for abstract graphs is now marked as deprecated. - Add an `alwayscopy` argument to `squash` to indicate that `squash` should make a copy even if the resulting graph has the same eltype.
1 parent 3e4d7ef commit 4c35a89

File tree

6 files changed

+69
-8
lines changed

6 files changed

+69
-8
lines changed

src/SimpleGraphs/SimpleGraphs.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ import Graphs:
1313
src, dst, edgetype, nv, ne, vertices, edges, is_directed,
1414
has_vertex, has_edge, inneighbors, outneighbors, all_neighbors,
1515
deepcopy_adjlist, indegree, outdegree, degree, has_self_loops,
16-
num_self_loops, insorted
16+
num_self_loops, insorted, squash
1717

1818
using Random: GLOBAL_RNG, AbstractRNG
1919

2020
export AbstractSimpleGraph, AbstractSimpleEdge,
2121
SimpleEdge, SimpleGraph, SimpleGraphFromIterator, SimpleGraphEdge,
2222
SimpleDiGraph, SimpleDiGraphFromIterator, SimpleDiGraphEdge,
23-
add_vertex!, add_edge!, rem_vertex!, rem_vertices!, rem_edge!,
23+
add_vertex!, add_edge!, rem_vertex!, rem_vertices!, rem_edge!, squash,
2424
# randgraphs
2525
erdos_renyi, expected_degree_graph, watts_strogatz, random_regular_graph,
2626
random_regular_digraph, random_configuration_model, random_tournament_digraph,
@@ -214,6 +214,7 @@ include("./simpleedge.jl")
214214
include("./simpledigraph.jl")
215215
include("./simplegraph.jl")
216216
include("./simpleedgeiter.jl")
217+
include("./specializations.jl")
217218
include("./generators/deprecations.jl")
218219
include("./generators/staticgraphs.jl")
219220
include("./generators/randgraphs.jl")

src/SimpleGraphs/specializations.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
"""
3+
squash(g::Union{SimpleGraph, SimpleDiGraph}; alwayscopy=true)
4+
5+
Specialised version of `Graphs.squash` for `SimpleGraph` and `SimpleDiGraph`.
6+
If `alwayscopy` is `true`, the resulting graph will always be a copy, otherwise
7+
it can also be the original graph.
8+
"""
9+
function Graphs.squash(g::Union{SimpleGraph, SimpleDiGraph}; alwayscopy::Bool=true)
10+
11+
G = is_directed(g) ? SimpleDiGraph : SimpleGraph
12+
T = eltype(g)
13+
14+
(!alwayscopy && T <: Union{Int8, UInt8}) && return g
15+
nv(g) < typemax(Int8) && return G{Int8}(g)
16+
nv(g) < typemax(UInt8) && return G{UInt8}(g)
17+
(!alwayscopy && T <: Union{Int16, UInt16}) && return g
18+
nv(g) < typemax(Int16) && return G{Int16}(g)
19+
nv(g) < typemax(UInt16) && return G{UInt16}(g)
20+
(!alwayscopy && T <: Union{Int32, UInt32}) && return g
21+
nv(g) < typemax(Int32) && return G{Int32}(g)
22+
nv(g) < typemax(UInt32) && return G{UInt32}(g)
23+
(!alwayscopy && T <: Union{Int64, UInt64}) && return g
24+
nv(g) < typemax(Int64) && return G{Int64}(g)
25+
nv(g) < typemax(UInt64) && return G{UInt64}(g)
26+
27+
return alwayscopy ? copy(g) : g
28+
end
29+

src/core.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,10 +389,22 @@ ne(g) / (nv(g) * (nv(g) - 1))
389389
"""
390390
squash(g)
391391
392-
Return a copy of a graph with the smallest practical type that
392+
Return a copy of a graph with the smallest practical eltype that
393393
can accommodate all vertices.
394+
395+
May also return the original graph if the eltype does not change.
394396
"""
395397
function squash(g::AbstractGraph)
398+
399+
# TODO this version check can be removed when we increase the required Julia version
400+
deprecation_msg = "squash(::AbstractGraph) is deprecated in favor of methods that specialize on the graph type."
401+
if VERSION >= v"1.5.2"
402+
Base.depwarn(deprecation_msg, :squash; force=true)
403+
else
404+
Base.depwarn(deprecation_msg, :squash)
405+
end
406+
407+
396408
gtype = is_directed(g) ? DiGraph : Graph
397409
validtypes = [UInt8, UInt16, UInt32, UInt64, Int64]
398410
nvg = nv(g)

test/core.jl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,4 @@
9191
end
9292

9393
end
94-
@testset "squash" begin
95-
@testset "$g" for g in testgraphs(g5w, g5wd)
96-
@test eltype(squash(g)) == UInt8
97-
end
98-
end
9994
end

test/simplegraphs/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ const simple_tests = [
8484
"simplegraphs",
8585
"simpleedge",
8686
"simpleedgeiter",
87+
"specializations",
8788
"generators/randgraphs",
8889
"generators/staticgraphs",
8990
"generators/smallgraphs",

test/simplegraphs/specializations.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
@testset "squash" begin
3+
@testset "$g_in, kwargs=$kwargs" for kwargs in [(), (alwayscopy=false,), (alwayscopy=true,)], (g_in, g_expected) in [
4+
(SimpleGraph{Int64}(), SimpleGraph{Int8}()),
5+
(SimpleDiGraph{UInt8}(), kwargs == (alwayscopy=false,) ? SimpleDiGraph{UInt8}() : SimpleDiGraph{Int8}()) ,
6+
(path_graph(Int16(126)), path_graph(Int8(126))),
7+
(path_digraph(Int16(127)), path_digraph(UInt8(127))),
8+
(path_graph(Int16(254)), path_graph(UInt8(254))),
9+
(path_digraph(Int16(255)), path_digraph(Int16(255))),
10+
(path_graph(UInt16(255)), kwargs == (alwayscopy=false,) ? path_graph(UInt16(255)) : path_graph(Int16(255))),
11+
(star_graph(Int16(32766)), star_graph(Int16(32766))),
12+
(star_digraph(Int32(32767)), star_digraph(UInt16(32767))),
13+
(cycle_graph(Int128(123)), cycle_graph(Int8(123))),
14+
]
15+
g_actual = squash(g_in; kwargs...)
16+
@test typeof(g_actual) === typeof(g_expected)
17+
@test g_actual == g_expected
18+
if kwargs == (alwayscopy=false,) && typeof(g_in) === typeof(g_actual)
19+
@test g_in === g_actual
20+
end
21+
end
22+
end
23+

0 commit comments

Comments
 (0)