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

first cut at 0.7 compatibility #848

Merged
merged 20 commits into from Feb 22, 2018
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 1 addition & 5 deletions .travis.yml
Expand Up @@ -5,13 +5,9 @@ os:
# - osx

julia:
- 0.6
# - 0.6
- nightly

matrix:
allow_failures:
- julia: nightly

notifications:
email: false

Expand Down
2 changes: 1 addition & 1 deletion REQUIRE
@@ -1,4 +1,4 @@
julia 0.6
julia 0.7-
CodecZlib 0.4
DataStructures 0.7
SimpleTraits 0.4.0
21 changes: 17 additions & 4 deletions src/LightGraphs.jl
@@ -1,15 +1,28 @@
__precompile__(true)
module LightGraphs

using SharedArrays
using Random
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will want to dedup these.

import CodecZlib
using DataStructures
using SimpleTraits

using SparseArrays
using LinearAlgebra
using IterativeEigensolvers
using SharedArrays
using Random
using Markdown
using DelimitedFiles
import Base: write, ==, <, *, ≈, convert, isless, issubset, union, intersect,
reverse, reverse!, blkdiag, isassigned, getindex, setindex!, show,
print, copy, in, sum, size, sparse, eltype, length, ndims, transpose,
ctranspose, join, start, next, done, eltype, get, issymmetric, A_mul_B!,
Pair, Tuple, zero
reverse, reverse!, isassigned, getindex, setindex!, show,
print, copy, in, sum, size, eltype, length, ndims, transpose,
ctranspose, join, start, next, done, eltype, get, Pair, Tuple, zero
import Random: GLOBAL_RNG
import Distributed: @parallel, @sync
import SparseArrays: sparse, blkdiag
import LinearAlgebra: issymmetric, mul!

export
# Interface
AbstractGraph, AbstractEdge, AbstractEdgeIter,
Expand Down
3 changes: 3 additions & 0 deletions src/SimpleGraphs/SimpleGraphs.jl
@@ -1,5 +1,8 @@
module SimpleGraphs

using SparseArrays
using LinearAlgebra

import Base:
eltype, show, ==, Pair, Tuple, copy, length, start, next, done, issubset, zero, in

Expand Down
2 changes: 1 addition & 1 deletion src/community/clique_percolation.jl
Expand Up @@ -26,7 +26,7 @@ function clique_percolation end
x[kcliques[i]] = false
end
components = connected_components(h)
communities = [IntSet() for i=1:length(components)]
communities = [BitSet() for i=1:length(components)]
for (i,component) in enumerate(components)
push!(communities[i], vcat(kcliques[component]...)...)
end
Expand Down
2 changes: 1 addition & 1 deletion src/community/cliques.jl
Expand Up @@ -24,7 +24,7 @@ julia> maximal_cliques(g)
"""
function maximal_cliques end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function maximal_cliques{T, AG<:AbstractGraph{T}}(g::AG::(!IsDirected))
@traitfn function maximal_cliques(g::AG::(!IsDirected)) where {T, AG<:AbstractGraph{T}}
# Cache nbrs and find first pivot (highest degree)
maxconn = -1
# uncomment this when https://github.com/JuliaLang/julia/issues/23618 is fixed
Expand Down
2 changes: 1 addition & 1 deletion src/community/label_propagation.jl
Expand Up @@ -12,7 +12,7 @@ the second is the convergence history for each node. Will return after
function label_propagation(g::AbstractGraph{T}, maxiter=1000) where T
n = nv(g)
label = collect(one(T):n)
active_vs = IntSet(vertices(g))
active_vs = BitSet(vertices(g))
c = NeighComm(collect(one(T):n), fill(-1, n), one(T))
convergence_hist = Vector{Int}()
random_order = Vector{T}(n)
Expand Down
4 changes: 2 additions & 2 deletions src/digraph/cycles/hadwick-james.jl
Expand Up @@ -9,7 +9,7 @@ of Hadwick & James.
"""
function simplecycles_hadwick_james end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function simplecycles_hadwick_james{T, AG<:AbstractGraph{T}}(g::AG::IsDirected)
@traitfn function simplecycles_hadwick_james(g::AG::IsDirected) where {T, AG<:AbstractGraph{T}}
nvg = nv(g)
B = Vector{T}[Vector{T}() for i in vertices(g)]
blocked = zeros(Bool, nvg)
Expand Down Expand Up @@ -43,7 +43,7 @@ resetblocked!(blocked) = fill!(blocked, false)
Find circuits in `g` recursively starting from v1.
"""
function circuit_recursive! end
@traitfn function circuit_recursive!{T<:Integer}(g::::IsDirected, v1::T, v2::T, blocked::AbstractVector, B::Vector{Vector{T}}, stack::Vector{T}, cycles::Vector{Vector{T}})
@traitfn function circuit_recursive!(g::::IsDirected, v1::T, v2::T, blocked::AbstractVector, B::Vector{Vector{T}}, stack::Vector{T}, cycles::Vector{Vector{T}}) where T<:Integer
f = false
push!(stack, v2)
blocked[v2] = true
Expand Down
8 changes: 4 additions & 4 deletions src/digraph/cycles/johnson.jl
Expand Up @@ -127,8 +127,8 @@ recursive version. Modify the vector of cycles, when needed.
- [Johnson](http://epubs.siam.org/doi/abs/10.1137/0204007)
"""
function circuit end
@traitfn function circuit{T<:Integer}(v::T, dg::::IsDirected, vis::JohnsonVisitor{T},
allcycles::Vector{Vector{T}}, vmap::Vector{T}, startnode::T = v)
@traitfn function circuit(v::T, dg::::IsDirected, vis::JohnsonVisitor{T},
allcycles::Vector{Vector{T}}, vmap::Vector{T}, startnode::T = v) where T<:Integer
done = false
push!(vis.stack, v)
vis.blocked[v] = true
Expand Down Expand Up @@ -215,8 +215,8 @@ the same as v, otherwise it should be passed.
- [Johnson](http://epubs.siam.org/doi/abs/10.1137/0204007)
"""
function circuit_iter end
@traitfn function circuit_iter{T<:Integer}(v::T, dg::::IsDirected, vis::JohnsonVisitor{T},
vmap::Vector{T}, cycle::Channel, startnode::T = v)
@traitfn function circuit_iter(v::T, dg::::IsDirected, vis::JohnsonVisitor{T},
vmap::Vector{T}, cycle::Channel, startnode::T = v) where T<:Integer
done = false
push!(vis.stack, v)
vis.blocked[v] = true
Expand Down
8 changes: 6 additions & 2 deletions src/linalg/LinAlg.jl
@@ -1,13 +1,17 @@
module LinAlg

using SimpleTraits
using SparseArrays
using LinearAlgebra
using IterativeEigensolvers
using ..LightGraphs

import LightGraphs: IsDirected, adjacency_matrix, laplacian_matrix, laplacian_spectrum, AbstractGraph, inneighbors,
outneighbors, all_neighbors, is_directed, nv, ne, has_edge, vertices

import Base: convert, sparse, size, diag, eltype, ndims, ==, *, .*, issymmetric, A_mul_B!, length, Diagonal

import Base: convert, size, eltype, ndims, ==, *, .*, length
import SparseArrays: sparse, diag
import LinearAlgebra: issymmetric, mul!, Diagonal

export convert,
SparseMatrix,
Expand Down
28 changes: 14 additions & 14 deletions src/linalg/graphmatrices.jl
Expand Up @@ -239,37 +239,37 @@ function *(adjmat::PunchedAdjacency{T}, x::AbstractVector{T}) where T<:Number
return y - dot(adjmat.perron, y) * adjmat.perron
end

function A_mul_B!(Y, A::Adjacency, B)
function mul!(Y, A::Adjacency, B)
# we need to do 3 matrix products
# Y and B can't overlap in any one call to A_mul_B!
# The last call to A_mul_B! must be (Y, postscalefactor, tmp)
# Y and B can't overlap in any one call to mul!
# The last call to mul! must be (Y, postscalefactor, tmp)
# so we need to write to tmp in the second step must be (tmp, A.A, Y)
# and the first step (Y, prescalefactor, B)
tmp1 = Diagonal(prescalefactor(A)) * B
tmp = similar(Y)
A_mul_B!(tmp, A.A, tmp1)
return A_mul_B!(Y, Diagonal(postscalefactor(A)), tmp)
mul!(tmp, A.A, tmp1)
return mul!(Y, Diagonal(postscalefactor(A)), tmp)
end

A_mul_B!(Y, A::CombinatorialAdjacency, B) = A_mul_B!(Y, A.A, B)
mul!(Y, A::CombinatorialAdjacency, B) = mul!(Y, A.A, B)

# You can compute the StochasticAdjacency product without allocating a similar of Y.
# This is true for all Adjacency where the postscalefactor is a Noop
# at time of writing this is just StochasticAdjacency and CombinatorialAdjacency
function A_mul_B!(Y, A::StochasticAdjacency, B)
function mul!(Y, A::StochasticAdjacency, B)
tmp = Diagonal(prescalefactor(A)) * B
A_mul_B!(Y, A.A, tmp)
mul!(Y, A.A, tmp)
return Y
end

function A_mul_B!(Y, adjmat::PunchedAdjacency, x)
function mul!(Y, adjmat::PunchedAdjacency, x)
y = adjmat.A * x
Y[:] = y - dot(adjmat.perron, y) * adjmat.perron
return Y
end

function A_mul_B!(Y, lapl::Laplacian, B)
A_mul_B!(Y, lapl.A, B)
function mul!(Y, lapl::Laplacian, B)
mul!(Y, lapl.A, B)
z = diag(lapl) .* B
Y[:] = z - Y[:]
return Y
Expand All @@ -284,7 +284,7 @@ Return a symmetric version of graph (represented by sparse matrix `A`) as a spar
"""
function symmetrize(A::SparseMatrix, which=:or)
if which == :or
M = A + A'
M = A + sparse(A')
M.nzval[M.nzval .== 2] = 1
return M
end
Expand All @@ -298,7 +298,7 @@ function symmetrize(A::SparseMatrix, which=:or)
else
throw(ArgumentError("$which is not a supported method of symmetrizing a matrix"))
end
M = T + T'
M = T + sparse(T')
return M
end

Expand All @@ -317,7 +317,7 @@ symmetrize(adjmat::CombinatorialAdjacency, which=:or) =


# per #564
@deprecate A_mul_B!(Y, A::Noop, B) None
@deprecate mul!(Y, A::Noop, B) None
@deprecate convert(::Type{Adjacency}, lapl::Laplacian) None
@deprecate convert(::Type{SparseMatrix}, adjmat::CombinatorialAdjacency) sparse(adjmat)

Expand Down
2 changes: 1 addition & 1 deletion src/linalg/nonbacktracking.jl
Expand Up @@ -100,7 +100,7 @@ function *(nbt::Nonbacktracking, x::Vector{T}) where T<:Number
end
return y
end
function A_mul_B!(C, nbt::Nonbacktracking, B)
function mul!(C, nbt::Nonbacktracking, B)
# computs C = A * B
for i in 1:size(B, 2)
C[:, i] = nbt * B[:, i]
Expand Down
8 changes: 4 additions & 4 deletions src/linalg/spectral.jl
Expand Up @@ -73,14 +73,14 @@ for a graph `g`, indexed by `[u, v]` vertices. `T` defaults to `Int` for both gr
### Optional Arguments
`dir=:unspec`: `:unspec`, `:both`, :in`, and `:out` are currently supported.
For undirected graphs, `dir` defaults to `:out`; for directed graphs,
`dir` defaults to `:both`.
`dir` defaults to `:both`.
"""
function laplacian_matrix(g::AbstractGraph{U}, T::DataType=Int; dir::Symbol=:unspec) where U
if dir == :unspec
dir = is_directed(g) ? :both : :out
end
A = adjacency_matrix(g, T; dir=dir)
D = convert(SparseMatrixCSC{T, U}, spdiagm(sum(A, 2)[:]))
D = convert(SparseMatrixCSC{T, U}, Diagonal(sparse(sum(A, 2)[:])))
return D - A
end

Expand Down Expand Up @@ -179,7 +179,7 @@ If `k` is ommitted, uses full spectrum.
function spectral_distance end

# can't use Traitor syntax here (https://github.com/mauro3/SimpleTraits.jl/issues/36)
@traitfn function spectral_distance{G<:AbstractGraph; !IsDirected{G}}(G₁::G, G₂::G, k::Integer)
@traitfn function spectral_distance(G₁::G, G₂::G, k::Integer) where {G<:AbstractGraph; !IsDirected{G}}
A₁ = adjacency_matrix(G₁)
A₂ = adjacency_matrix(G₂)

Expand All @@ -190,7 +190,7 @@ function spectral_distance end
end

# can't use Traitor syntax here (https://github.com/mauro3/SimpleTraits.jl/issues/36)
@traitfn function spectral_distance{G<:AbstractGraph; !IsDirected{G}}(G₁::G, G₂::G)
@traitfn function spectral_distance(G₁::G, G₂::G) where {G<:AbstractGraph; !IsDirected{G}}
nv(G₁) == nv(G₂) || throw(ArgumentError("Spectral distance not defined for |G₁| != |G₂|"))
return spectral_distance(G₁, G₂, nv(G₁))
end
2 changes: 1 addition & 1 deletion src/operators.jl
Expand Up @@ -211,7 +211,7 @@ in the generated graph exceeds the eltype.
"""
function crosspath end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function crosspath{T, AG<:AbstractGraph{T}}(len::Integer, g::AG::(!IsDirected))
@traitfn function crosspath(len::Integer, g::AG::(!IsDirected)) where {T, AG<:AbstractGraph{T}}
p = PathGraph(len)
h = Graph{T}(p)
return cartesian_product(h, g)
Expand Down
4 changes: 2 additions & 2 deletions src/spanningtrees/kruskal.jl
Expand Up @@ -40,10 +40,10 @@ distance matrix `distmx` using [Kruskal's algorithm](https://en.wikipedia.org/wi
"""
function kruskal_mst end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function kruskal_mst{T<:Real, U, AG<:AbstractGraph{U}}(
@traitfn function kruskal_mst(
g::AG::(!IsDirected),
distmx::AbstractMatrix{T} = weights(g)
)
) where {T<:Real, U, AG<:AbstractGraph{U}}

edge_list = Vector{KruskalHeapEntry{T}}()
mst = Vector{Edge}()
Expand Down
4 changes: 2 additions & 2 deletions src/spanningtrees/prim.jl
Expand Up @@ -13,10 +13,10 @@ distance matrix `distmx` using [Prim's algorithm](https://en.wikipedia.org/wiki/
Return a vector of edges.
"""
function prim_mst end
@traitfn function prim_mst{T<:Real, U, AG<:AbstractGraph{U}}(
@traitfn function prim_mst(
g::AG::(!IsDirected),
distmx::AbstractMatrix{T} = weights(g)
)
) where {T<:Real, U, AG<:AbstractGraph{U}}
pq = Vector{PrimHeapEntry{T}}()
mst = Vector{Edge}()
marked = zeros(Bool, nv(g))
Expand Down
4 changes: 2 additions & 2 deletions src/traversals/dfs.jl
Expand Up @@ -12,7 +12,7 @@ Uses DFS.
function is_cyclic end
@traitfn is_cyclic(g::::(!IsDirected)) = ne(g) > 0
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function is_cyclic{T,AG<:AbstractGraph{T}}(g::AG::IsDirected)
@traitfn function is_cyclic(g::AG::IsDirected) where {T, AG<:AbstractGraph{T}}
vcolor = zeros(UInt8, nv(g))
for v in vertices(g)
vcolor[v] != 0 && continue
Expand Down Expand Up @@ -50,7 +50,7 @@ graph `g` as a vector of vertices in topological order.
"""
function toplogical_sort_by_dfs end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function topological_sort_by_dfs{T, AG<:AbstractGraph{T}}(g::AG::IsDirected)
@traitfn function topological_sort_by_dfs(g::AG::IsDirected) where {T, AG<:AbstractGraph{T}}
vcolor = zeros(UInt8, nv(g))
verts = Vector{T}()
for v in vertices(g)
Expand Down
2 changes: 1 addition & 1 deletion src/traversals/diffusion.jl
Expand Up @@ -27,7 +27,7 @@ function diffusion(g::AbstractGraph{T},

# Initialize
watch_set = Set{T}(watch)
infected_vertices = IntSet(initial_infections)
infected_vertices = BitSet(initial_infections)
vertices_per_step::Vector{Vector{T}} = [Vector{T}() for i in 1:n]

# Record initial infection
Expand Down
4 changes: 2 additions & 2 deletions src/traversals/randomwalks.jl
Expand Up @@ -29,7 +29,7 @@ vector of vertices visited in order.
"""
function non_backtracking_randomwalk end
# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function non_backtracking_randomwalk{T, AG<:AbstractGraph{T}}(g::AG::(!IsDirected), s::Integer, niter::Integer)
@traitfn function non_backtracking_randomwalk(g::AG::(!IsDirected), s::Integer, niter::Integer) where {T, AG<:AbstractGraph{T}}
s in vertices(g) || throw(BoundsError())
visited = Vector{T}()
sizehint!(visited, niter)
Expand Down Expand Up @@ -61,7 +61,7 @@ function non_backtracking_randomwalk end
end

# see https://github.com/mauro3/SimpleTraits.jl/issues/47#issuecomment-327880153 for syntax
@traitfn function non_backtracking_randomwalk{T, AG<:AbstractGraph{T}}(g::AG::IsDirected, s::Integer, niter::Integer)
@traitfn function non_backtracking_randomwalk(g::AG::IsDirected, s::Integer, niter::Integer) where {T, AG<:AbstractGraph{T}}
s in vertices(g) || throw(BoundsError())
visited = Vector{T}()
sizehint!(visited, niter)
Expand Down
3 changes: 1 addition & 2 deletions src/utils.jl
Expand Up @@ -42,7 +42,7 @@ Unlike [`sample!`](@ref), does not produce side effects.
"""
sample(a::UnitRange, k::Integer; exclude = ()) = sample!(getRNG(), collect(a), k; exclude = exclude)

getRNG(seed::Integer = -1) = seed >= 0 ? MersenneTwister(seed) : Base.Random.GLOBAL_RNG
getRNG(seed::Integer = -1) = seed >= 0 ? MersenneTwister(seed) : GLOBAL_RNG

"""
insorted(item, collection)
Expand All @@ -53,4 +53,3 @@ Return true if `item` is in sorted collection `collection`.
Does not verify that `collection` is sorted.
"""
insorted(item, collection) = !isempty(searchsorted(collection, item))

2 changes: 1 addition & 1 deletion test/centrality/betweenness.jl
Expand Up @@ -7,7 +7,7 @@

gint = loadgraph(joinpath(testdir, "testdata", "graph-50-500.jgz"), "graph-50-500")

c = vec(readcsv(joinpath(testdir, "testdata", "graph-50-500-bc.txt")))
c = vec(readdlm(joinpath(testdir, "testdata", "graph-50-500-bc.txt"), ','))
for g in testdigraphs(gint)
z = @inferred(betweenness_centrality(g))
zp = @inferred(parallel_betweenness_centrality(g))
Expand Down
2 changes: 1 addition & 1 deletion test/centrality/radiality.jl
@@ -1,7 +1,7 @@
@testset "Radiality" begin
gint = loadgraph(joinpath(testdir, "testdata", "graph-50-500.jgz"), "graph-50-500")

c = vec(readcsv(joinpath(testdir, "testdata", "graph-50-500-rc.txt")))
c = vec(readdlm(joinpath(testdir, "testdata", "graph-50-500-rc.txt"), ','))
for g in testdigraphs(gint)
z = @inferred(radiality_centrality(g))
zp = @inferred(parallel_radiality_centrality(g))
Expand Down
2 changes: 1 addition & 1 deletion test/centrality/stress.jl
@@ -1,7 +1,7 @@
@testset "Stress" begin
gint = loadgraph(joinpath(testdir, "testdata", "graph-50-500.jgz"), "graph-50-500")

c = vec(readcsv(joinpath(testdir, "testdata", "graph-50-500-sc.txt")))
c = vec(readdlm(joinpath(testdir, "testdata", "graph-50-500-sc.txt"), ','))
for g in testdigraphs(gint)
z = @inferred(stress_centrality(g))
zp = @inferred(parallel_stress_centrality(g))
Expand Down
2 changes: 1 addition & 1 deletion test/community/clique_percolation.jl
@@ -1,6 +1,6 @@
@testset "Clique percolation" begin
function setofsets(array_of_arrays)
Set(map(IntSet, array_of_arrays))
Set(map(BitSet, array_of_arrays))
end

function test_cliques(graph, expected)
Expand Down