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

WIP: LightGraphs Abstraction #541

Merged
merged 65 commits into from
Mar 29, 2017
Merged
Changes from 1 commit
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
2c45b45
benchmarks
sbromberger Mar 9, 2017
811c509
add edgetype benchmark
jpfairbanks Mar 10, 2017
c704c68
Merge branch 'master' into sbromberger/benchmarks
sbromberger Mar 10, 2017
8e4489b
simplegraphs abstraction
sbromberger Mar 10, 2017
5765fa0
Edge is no longer a Pair
sbromberger Mar 6, 2017
bfb0751
Merge branch 'sbromberger/benchmarks' of github.com:JuliaGraphs/Light…
sbromberger Mar 12, 2017
6124998
pkgbenchmarks
sbromberger Mar 12, 2017
4944904
Merge branch 'master' into sbromberger/benchmarks
sbromberger Mar 13, 2017
6afd3dc
Merge branch 'master' into sbromberger/simplegraphs
sbromberger Mar 13, 2017
748aa61
f
sbromberger Mar 13, 2017
3cb3aa3
remove data files from benchmarks
sbromberger Mar 13, 2017
8aee9a8
simplegraphs, take 2
sbromberger Mar 14, 2017
2bbafc5
more changes
sbromberger Mar 14, 2017
8f1c2af
reshuffle
sbromberger Mar 14, 2017
ced3ee7
fix tests
sbromberger Mar 14, 2017
1f6b891
more tests
sbromberger Mar 14, 2017
8922fed
abstractions
sbromberger Mar 14, 2017
3099034
more tests
sbromberger Mar 15, 2017
c1c2e4e
tests and fixes
sbromberger Mar 15, 2017
a8a015e
trait fixes and tests - unrolling
sbromberger Mar 16, 2017
914c47d
persistence and floyd-warshall
sbromberger Mar 16, 2017
1f7a269
make(di)graphs, through spanningtrees
sbromberger Mar 17, 2017
ee54466
moved cliques, testing through connectivity.jl
sbromberger Mar 17, 2017
38bf233
@jpfairbanks first round of review
sbromberger Mar 17, 2017
a723a09
Merge branch 'sbromberger/benchmarks' into sbromberger/simplegraphs
sbromberger Mar 17, 2017
1e22b2c
another fix
sbromberger Mar 17, 2017
893987d
all tests
sbromberger Mar 17, 2017
d7e8013
new simpletraits
sbromberger Mar 17, 2017
7b953ee
first cut at 0.6 compat
sbromberger Mar 18, 2017
de342ea
squash
sbromberger Mar 18, 2017
293d331
update randgraphs.jl to use Channels over Tasks
jpfairbanks Mar 13, 2017
ccb0429
got rid of tasks in randgraphs
sbromberger Mar 19, 2017
b147c81
graph -> g
sbromberger Mar 19, 2017
5578ab7
Add tutorials to section on docs (#547)
ChrisRackauckas Mar 19, 2017
dee0528
type -> mutable struct
sbromberger Mar 19, 2017
f62eac8
Merge branch 'master' into sbromberger/simplegraphs
sbromberger Mar 19, 2017
8165d33
more type -> mutable struct, plus OF detection for add_vertex!
sbromberger Mar 19, 2017
32feb92
Merge branch 'sbromberger/simplegraphs' of github.com:JuliaGraphs/Lig…
sbromberger Mar 19, 2017
7298222
foo{T}(x::T) -> foo(x::T) where T
sbromberger Mar 20, 2017
3e3b34b
test negative cycles
sbromberger Mar 20, 2017
1ad6e72
test coverage
sbromberger Mar 20, 2017
97517a4
manual cherry-pick of #551
sbromberger Mar 20, 2017
bcbe2a9
simplegraph/ -> simplegraphs, optimization for is_connected, some typ…
sbromberger Mar 20, 2017
f06aa93
re-add b-f tests
sbromberger Mar 20, 2017
c61011f
Inferred (#554)
sbromberger Mar 21, 2017
faff97a
Merge branch 'master' into sbromberger/simplegraphs
sbromberger Mar 21, 2017
e6ce33d
redo graphmatrices tests
sbromberger Mar 22, 2017
c192929
Merge branch 'sbromberger/simplegraphs' of github.com:JuliaGraphs/Lig…
sbromberger Mar 22, 2017
9df52ad
linalg test fix
sbromberger Mar 22, 2017
91df2ab
loosen type restrictions in randgraphs functions
sbromberger Mar 22, 2017
ce00535
readall -> readstring, and comment rationalization in randgraphs
sbromberger Mar 23, 2017
3d770d5
Fixes #555: graphmatrices convert incorrect on CA (#560)
jpfairbanks Mar 23, 2017
ab176b8
fixes #564
sbromberger Mar 23, 2017
49b160c
one more test
sbromberger Mar 23, 2017
dfe72cb
removed nv() and vertices() (#565)
sbromberger Mar 23, 2017
4345a3e
simpleedge tests
sbromberger Mar 26, 2017
23e7123
test coverage
sbromberger Mar 26, 2017
0e21aa3
short circuit B-F negative cycles, plus tests
sbromberger Mar 26, 2017
bcbd873
more test coverage
sbromberger Mar 26, 2017
e733cfe
more test coverage
sbromberger Mar 26, 2017
727fe47
Docs (#567)
sbromberger Mar 27, 2017
e20781c
doc fixes
sbromberger Mar 27, 2017
d8d12ce
1.0 -> 0.8
sbromberger Mar 28, 2017
969b6b2
docfix and benchmarks
sbromberger Mar 28, 2017
2e1ae20
doc fixes
sbromberger Mar 28, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
trait fixes and tests - unrolling
sbromberger committed Mar 16, 2017
commit a8a015eb179beadeca9cb5e68ea68ff45612f8e6
10 changes: 9 additions & 1 deletion src/centrality/pagerank.jl
Original file line number Diff line number Diff line change
@@ -6,7 +6,10 @@
iterations (`n`), and convergence threshold (`ϵ`). If convergence is not
reached within `n` iterations, an error will be returned.
"""
function pagerank(g::DiGraph, α=0.85, n=100, ϵ = 1.0e-6)
function pagerank end

#TODO: re-roll this to @traitfn function pagerank{G<:AbstractGraph; IsDirected{G}}(g::G, α=0.85, n=100, ϵ = 1.0e-6)
@traitfn function pagerank{G<:AbstractGraph; IsDirected{G}}(g::G, α, n, ϵ)
A = adjacency_matrix(g,:in,Float64)
S = vec(sum(A,1))
S = 1./S
@@ -29,3 +32,8 @@ function pagerank(g::DiGraph, α=0.85, n=100, ϵ = 1.0e-6)
end
error("Pagerank did not converge after $n iterations.")
end

### TODO: remove these when re-rolled.
@traitfn pagerank{G<:AbstractGraph; IsDirected{G}}(g::G, α, n) = pagerank(g, α, n, 1e-6)
@traitfn pagerank{G<:AbstractGraph; IsDirected{G}}(g::G, α) = pagerank(g, α, 100, 1e-6)
@traitfn pagerank{G<:AbstractGraph; IsDirected{G}}(g::G) = pagerank(g, 0.85, 100, 1e-6)
47 changes: 29 additions & 18 deletions src/linalg/spectral.jl
Original file line number Diff line number Diff line change
@@ -59,23 +59,25 @@ function adjacency_matrix(g::AbstractGraph, dir::Symbol=:out, T::DataType=Int)
return spmx
end

adjacency_matrix(g::Graph, T::DataType=Int) = adjacency_matrix(g, :out, T)
adjacency_matrix(g::AbstractGraph, T::DataType) = adjacency_matrix(g, :out, T)

### TODO: re-roll this to be
# function adjacency_matrix(g::AbstractGraph, dir::Symbol=:out, T::DataType=Int)
# @traitfn adjacency_matrix{G<:AbstractGraph; !IsDirected{G}}(g::G, T::DataType) = adjacency_matrix(g, :out, T)
# @traitfn adjacency_matrix{G<:AbstractGraph; !IsDirected{G}}(g::G) = adjacency_matrix(g, :out, Int)

"""Returns a sparse [Laplacian matrix](https://en.wikipedia.org/wiki/Laplacian_matrix)
for a graph `g`, indexed by `[u, v]` vertices. For undirected graphs, `dir`
defaults to `:out`; for directed graphs, `dir` defaults to `:both`. `T`
defaults to `Int` for both graph types.
"""
function laplacian_matrix(g::Graph, dir::Symbol=:out, T::DataType=Int)
A = adjacency_matrix(g, dir, T)
D = spdiagm(sum(A,2)[:])
return D - A
end

function laplacian_matrix(g::DiGraph, dir::Symbol=:both, T::DataType=Int)
A = adjacency_matrix(g, dir, T)
D = spdiagm(sum(A,2)[:])
return D - A
function laplacian_matrix(g::AbstractGraph, dir::Symbol=:unspec, T::DataType=Int)
if dir == :unspec
dir = is_directed(g)? :both : :out
end
A = adjacency_matrix(g, dir, T)
D = spdiagm(sum(A,2)[:])
return D - A
end

doc"""Returns the eigenvalues of the Laplacian matrix for a graph `g`, indexed
@@ -84,24 +86,31 @@ by vertex. Warning: Converts the matrix to dense with $nv^2$ memory usage. Use
eigenvalues/eigenvectors. Default values for `dir` and `T` are the same as
`laplacian_matrix`.
"""
laplacian_spectrum(g::Graph, dir::Symbol=:out, T::DataType=Int) = eigvals(full(laplacian_matrix(g, dir, T)))
laplacian_spectrum(g::DiGraph, dir::Symbol=:both, T::DataType=Int) = eigvals(full(laplacian_matrix(g, dir, T)))
laplacian_spectrum(g::AbstractGraph, dir::Symbol=:unspec, T::DataType=Int) = eigvals(full(laplacian_matrix(g, dir, T)))

doc"""Returns the eigenvalues of the adjacency matrix for a graph `g`, indexed
by vertex. Warning: Converts the matrix to dense with $nv^2$ memory usage. Use
`eigs(adjacency_matrix(g);kwargs...)` to compute some of the
eigenvalues/eigenvectors. Default values for `dir` and `T` are the same as
`adjacency_matrix`.
"""
adjacency_spectrum(g::Graph, dir::Symbol=:out, T::DataType=Int) = eigvals(full(adjacency_matrix(g, dir, T)))
adjacency_spectrum(g::DiGraph, dir::Symbol=:both, T::DataType=Int) = eigvals(full(adjacency_matrix(g, dir, T)))
function adjacency_spectrum end

#TODO: Re-roll this to adjacency_spectrum(g::Graph, dir::Symbol=:out, T::DataType=Int) = eigvals(full(adjacency_matrix(g, dir, T)))
@traitfn adjacency_spectrum{G<:AbstractGraph; !IsDirected{G}}(g::G, dir::Symbol, T::DataType) = eigvals(full(adjacency_matrix(g, dir, T)))
@traitfn adjacency_spectrum{G<:AbstractGraph; !IsDirected{G}}(g::G, dir::Symbol) = adjacency_spectrum(g, dir, Int)
@traitfn adjacency_spectrum{G<:AbstractGraph; !IsDirected{G}}(g::G) = adjacency_spectrum(g, :out, Int)

#TODO: Re-roll this to adjacency_spectrum(g::DiGraph, dir::Symbol=:both, T::DataType=Int) = eigvals(full(adjacency_matrix(g, dir, T)))
@traitfn adjacency_spectrum{G<:AbstractGraph; IsDirected{G}}(g::G, dir::Symbol, T::DataType) = eigvals(full(adjacency_matrix(g, dir, T)))
@traitfn adjacency_spectrum{G<:AbstractGraph; IsDirected{G}}(g::G, dir::Symbol) = adjacency_spectrum(g, dir, Int)
@traitfn adjacency_spectrum{G<:AbstractGraph; IsDirected{G}}(g::G,) = adjacency_spectrum(g, :both, Int)

"""Returns a sparse node-arc incidence matrix for a graph, indexed by
`[v, i]`, where `i` is in `1:ne(g)`, indexing an edge `e`. For
directed graphs, a value of `-1` indicates that `src(e) == v`, while a
value of `1` indicates that `dst(e) == v`. Otherwise, the value is
`0`. For undirected graphs, if the optional keyword `oriented` is `false`,
`0`. For undirected graphs, if the optional keyword `oriented` is `false`,
both entries are `1`, otherwise, an arbitrary orientation is chosen.
"""
function incidence_matrix(g::AbstractGraph, T::DataType=Int; oriented=false)
@@ -141,7 +150,9 @@ For further details, please refer to:
JOVANOVIC, I.; STANIC, Z., 2014. Spectral Distances of
Graphs Based on their Different Matrix Representations
"""
function spectral_distance(G₁::Graph, G₂::Graph, k::Integer)
function spectral_distance end

@traitfn function spectral_distance{G<:AbstractGraph; !IsDirected{G}}(G₁::G, G₂::G, k::Integer)
A₁ = adjacency_matrix(G₁)
A₂ = adjacency_matrix(G₂)

@@ -151,7 +162,7 @@ function spectral_distance(G₁::Graph, G₂::Graph, k::Integer)
sumabs(λ₁ - λ₂)
end

function spectral_distance(G₁::Graph, G₂::Graph)
@traitfn function spectral_distance{G<:AbstractGraph; !IsDirected{G}}(G₁::G, G₂::G)
@assert nv(G₁) == nv(G₂) "spectral distance not defined for |G₁| != |G₂|"
spectral_distance(G₁, G₂, nv(G₁))
end
112 changes: 56 additions & 56 deletions test/flow/push_relabel.jl
Original file line number Diff line number Diff line change
@@ -16,72 +16,72 @@
add_edge!(flow_graph,u,v)
capacity_matrix[u,v] = f
end
for g in (flow_graph, DiGraph{UInt8}(flow_graph), DiGraph{Int16}(flow_graph))
residual_graph = LightGraphs.residual(g)

residual_graph = LightGraphs.residual(flow_graph)
# Test enqueue_vertex
Q = Array{Int,1}()
excess = [0, 1, 0, 1]
active = [false, false, true, true]
@test LightGraphs.enqueue_vertex!(Q, 1, active, excess) == nothing
@test LightGraphs.enqueue_vertex!(Q, 3, active, excess) == nothing
@test LightGraphs.enqueue_vertex!(Q, 4, active, excess) == nothing
@test length(Q) == 0
@test LightGraphs.enqueue_vertex!(Q, 2, active, excess) == nothing
@test length(Q) == 1

# Test enqueue_vertex
Q = Array{Int,1}()
excess = [0, 1, 0, 1]
active = [false, false, true, true]
@test LightGraphs.enqueue_vertex!(Q, 1, active, excess) == nothing
@test LightGraphs.enqueue_vertex!(Q, 3, active, excess) == nothing
@test LightGraphs.enqueue_vertex!(Q, 4, active, excess) == nothing
@test length(Q) == 0
@test LightGraphs.enqueue_vertex!(Q, 2, active, excess) == nothing
@test length(Q) == 1
# Test push_flow
Q = Array{Int,1}()
excess = [15, 1, 1, 0, 0, 0, 0, 0]
height = [8, 0, 0, 0, 0, 0, 0, 0]
active = [true, false, false, false, false, false, false, true]
flow_matrix = zeros(Int, 8, 8)
@test LightGraphs.push_flow!(residual_graph, 1, 2, capacity_matrix, flow_matrix, excess, height, active, Q) == nothing
@test length(Q) == 1
@test flow_matrix[1,2] == 10
@test LightGraphs.push_flow!(residual_graph, 2, 3, capacity_matrix, flow_matrix, excess, height, active, Q) == nothing
@test length(Q) == 1
@test flow_matrix[2,3] == 0

# Test push_flow
Q = Array{Int,1}()
excess = [15, 1, 1, 0, 0, 0, 0, 0]
height = [8, 0, 0, 0, 0, 0, 0, 0]
active = [true, false, false, false, false, false, false, true]
flow_matrix = zeros(Int, 8, 8)
@test LightGraphs.push_flow!(residual_graph, 1, 2, capacity_matrix, flow_matrix, excess, height, active, Q) == nothing
@test length(Q) == 1
@test flow_matrix[1,2] == 10
@test LightGraphs.push_flow!(residual_graph, 2, 3, capacity_matrix, flow_matrix, excess, height, active, Q) == nothing
@test length(Q) == 1
@test flow_matrix[2,3] == 0
# Test gap
Q = Array{Int,1}()
excess = [15, 1, 1, 0, 0, 0, 0, 0]
height = [8, 2, 2, 1, 3, 3, 4, 5]
active = [true, false, false, false, false, false, false, true]
count = [0, 1, 2, 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
flow_matrix = zeros(Int, 8, 8)

# Test gap
Q = Array{Int,1}()
excess = [15, 1, 1, 0, 0, 0, 0, 0]
height = [8, 2, 2, 1, 3, 3, 4, 5]
active = [true, false, false, false, false, false, false, true]
count = [0, 1, 2, 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
flow_matrix = zeros(Int, 8, 8)
@test LightGraphs.gap!(residual_graph, 1, excess, height, active, count, Q) == nothing
@test length(Q) == 2

@test LightGraphs.gap!(residual_graph, 1, excess, height, active, count, Q) == nothing
@test length(Q) == 2
# Test relabel
Q = Array{Int,1}()
excess = [15, 1, 1, 0, 0, 0, 0, 0]
height = [8, 1, 1, 1, 1, 1, 1, 0]
active = [true, false, false, false, false, false, false, true]
count = [1, 6, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
flow_matrix = zeros(Int, 8, 8)

# Test relabel
Q = Array{Int,1}()
excess = [15, 1, 1, 0, 0, 0, 0, 0]
height = [8, 1, 1, 1, 1, 1, 1, 0]
active = [true, false, false, false, false, false, false, true]
count = [1, 6, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
flow_matrix = zeros(Int, 8, 8)
@test LightGraphs.relabel!(residual_graph, 2, capacity_matrix, flow_matrix, excess, height, active, count, Q) == nothing
@test length(Q) == 1

@test LightGraphs.relabel!(residual_graph, 2, capacity_matrix, flow_matrix, excess, height, active, count, Q) == nothing
@test length(Q) == 1
# Test discharge
Q = Array{Int,1}()
excess = [50, 1, 1, 0, 0, 0, 0, 0]
height = [8, 0, 0, 0, 0, 0, 0, 0]
active = [true, false, false, false, false, false, false, true]
count = [7, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
flow_matrix = zeros(Int, 8, 8)

# Test discharge
Q = Array{Int,1}()
excess = [50, 1, 1, 0, 0, 0, 0, 0]
height = [8, 0, 0, 0, 0, 0, 0, 0]
active = [true, false, false, false, false, false, false, true]
count = [7, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
flow_matrix = zeros(Int, 8, 8)
@test LightGraphs.discharge!(residual_graph, 1, capacity_matrix, flow_matrix, excess, height, active, count, Q) == nothing
@test length(Q) == 3

@test LightGraphs.discharge!(residual_graph, 1, capacity_matrix, flow_matrix, excess, height, active, count, Q) == nothing
@test length(Q) == 3

# Test with default distances
@test LightGraphs.push_relabel(residual_graph, 1, 8, LightGraphs.DefaultCapacity(residual_graph))[1] == 3

# Test with capacity matrix
@test LightGraphs.push_relabel(residual_graph, 1, 8, capacity_matrix)[1] == 28
# Test with default distances
@test LightGraphs.push_relabel(residual_graph, 1, 8, LightGraphs.DefaultCapacity(residual_graph))[1] == 3

# Test with capacity matrix
@test LightGraphs.push_relabel(residual_graph, 1, 8, capacity_matrix)[1] == 28
end
# Non regression test added for #448
M448 =[0 1 0 0 1 1
1 0 0 0 1 0