Skip to content

Commit 665e9e9

Browse files
committed
new staticgraphs
1 parent 38b7b13 commit 665e9e9

16 files changed

+493
-25
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*.jl.cov
22
*.jl.*.cov
33
*.jl.mem
4+
.DS_Store

.travis.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
language: julia
33
os:
44
- linux
5-
- osx
5+
# - osx
66
julia:
77
- 0.6
8-
- nightly
8+
# - nightly
99
notifications:
1010
email: false
1111
git:
@@ -29,7 +29,5 @@ git:
2929
#script:
3030
# - julia -e 'Pkg.clone(pwd()); Pkg.build("StaticGraphs"); Pkg.test("StaticGraphs"; coverage=true)'
3131
after_success:
32-
# push coverage results to Coveralls
33-
- julia -e 'cd(Pkg.dir("StaticGraphs")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
3432
# push coverage results to Codecov
3533
- julia -e 'cd(Pkg.dir("StaticGraphs")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'

LICENSE.md

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,49 @@ The StaticGraphs.jl package is licensed under the MIT "Expat" License:
22

33
> Copyright (c) 2017: Seth Bromberger.
44
>
5-
> Permission is hereby granted, free of charge, to any person obtaining a copy
6-
> of this software and associated documentation files (the "Software"), to deal
7-
> in the Software without restriction, including without limitation the rights
8-
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9-
> copies of the Software, and to permit persons to whom the Software is
10-
> furnished to do so, subject to the following conditions:
11-
>
12-
> The above copyright notice and this permission notice shall be included in all
13-
> copies or substantial portions of the Software.
14-
>
15-
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16-
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18-
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19-
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5+
> Permission is hereby granted, free of charge, to any person obtaining
6+
> a copy of this software and associated documentation files (the
7+
> "Software"), to deal in the Software without restriction, including
8+
> without limitation the rights to use, copy, modify, merge, publish,
9+
> distribute, sublicense, and/or sell copies of the Software, and to
10+
> permit persons to whom the Software is furnished to do so, subject to
11+
> the following conditions:
12+
13+
> The above copyright notice and this permission notice shall be
14+
> included in all copies or substantial portions of the Software.
15+
16+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20+
> BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21+
> ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22+
> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2123
> SOFTWARE.
24+
25+
26+
This package uses code derived from RigidBodyDynamics.jl:
27+
28+
The RigidBodyDynamics.jl package is licensed under the MIT "Expat" License:
29+
30+
> Copyright (c) 2016: Twan Koolen.
2231
>
32+
> Permission is hereby granted, free of charge, to any person obtaining
33+
> a copy of this software and associated documentation files (the
34+
> "Software"), to deal in the Software without restriction, including
35+
> without limitation the rights to use, copy, modify, merge, publish,
36+
> distribute, sublicense, and/or sell copies of the Software, and to
37+
> permit persons to whom the Software is furnished to do so, subject to
38+
> the following conditions:
39+
40+
> The above copyright notice and this permission notice shall be
41+
> included in all copies or substantial portions of the Software.
42+
43+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
44+
> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
45+
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
46+
> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
47+
> BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
48+
> ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49+
> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
50+
> SOFTWARE.

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,4 @@
22

33
[![Build Status](https://travis-ci.org/sbromberger/StaticGraphs.jl.svg?branch=master)](https://travis-ci.org/sbromberger/StaticGraphs.jl)
44

5-
[![Coverage Status](https://coveralls.io/repos/sbromberger/StaticGraphs.jl/badge.svg?branch=master&service=github)](https://coveralls.io/github/sbromberger/StaticGraphs.jl?branch=master)
6-
75
[![codecov.io](http://codecov.io/github/sbromberger/StaticGraphs.jl/coverage.svg?branch=master)](http://codecov.io/github/sbromberger/StaticGraphs.jl?branch=master)

REQUIRE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
julia 0.6
2+
LightGraphs 0.10.5

src/StaticGraphs.jl

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,107 @@
11
module StaticGraphs
22

3-
# package code goes here
3+
using LightGraphs
4+
5+
import Base:
6+
convert, eltype, show, ==, Pair, Tuple, in, copy, length, start, next, done, issubset, zero, one,
7+
size, getindex, setindex!, length, IndexStyle
8+
9+
import LightGraphs:
10+
_NI, _insert_and_dedup!, AbstractEdge, AbstractEdgeIter,
11+
src, dst, edgetype, nv, ne, vertices, edges, is_directed,
12+
has_vertex, has_edge, in_neighbors, out_neighbors,
13+
indegree, outdegree, degree, insorted,
14+
15+
AbstractGraphFormat, loadgraph, savegraph
16+
17+
import LightGraphs.SimpleGraphs:
18+
AbstractSimpleGraph,
19+
fadj,
20+
badj,
21+
SimpleEdge,
22+
AbstractSimpleEdge
23+
24+
export
25+
AbstractStaticGraph,
26+
StaticEdge,
27+
StaticGraph,
28+
StaticDiGraph,
29+
StaticDiGraphEdge,
30+
# weight,
31+
# weighttype,
32+
# get_weight,
33+
out_edges,
34+
in_edges,
35+
SGraph,
36+
SDiGraph,
37+
SGFormat,
38+
SDGFormat
39+
40+
include("utils.jl")
41+
42+
const StaticEdgeIter{G} = LightGraphs.SimpleGraphs.SimpleEdgeIter{G}
43+
const AbstractStaticEdge = AbstractSimpleEdge
44+
const StaticEdge = SimpleEdge
45+
46+
"""
47+
AbstractStaticGraph
48+
49+
An abstract type representing a simple graph structure.
50+
AbstractStaticGraphs must have the following elements:
51+
- weightmx::AbstractSparseMatrix{Real}
52+
"""
53+
abstract type AbstractStaticGraph <: AbstractSimpleGraph end
54+
55+
function show(io::IO, g::AbstractStaticGraph)
56+
if is_directed(g)
57+
dir = "directed"
58+
else
59+
dir = "undirected"
60+
end
61+
if nv(g) == 0
62+
print(io, "empty $dir simple static $(eltype(g)) graph")
63+
else
64+
print(io, "{$(nv(g)), $(ne(g))} $dir simple static $(eltype(g)) graph")
65+
end
66+
end
67+
68+
@inline function _fvrange(g::AbstractStaticGraph, s::Integer)
69+
@inbounds r_start = g.f_ind[s]
70+
@inbounds r_end = g.f_ind[s + 1] - 1
71+
return r_start:r_end
72+
end
73+
74+
@inline function fadj(g::AbstractStaticGraph, s::Integer)
75+
r = _fvrange(g, s)
76+
return fastview(g.f_vec, r)
77+
end
78+
79+
nv(g::AbstractStaticGraph) = length(g.f_ind) - 1
80+
vertices(g::AbstractStaticGraph) = one(eltype(g)):nv(g)
81+
eltype(x::AbstractStaticGraph) = eltype(x.f_vec)
82+
83+
has_edge(g::AbstractStaticGraph, e::AbstractStaticEdge) =
84+
insorted(dst(e), neighbors(g, src(e)))
85+
86+
edgetype(g::AbstractStaticGraph) = StaticEdge
87+
edges(g::AbstractStaticGraph) = StaticEdgeIter(g)
88+
89+
has_vertex(g::AbstractStaticGraph, v::Integer) = v in vertices(g)
90+
91+
out_neighbors(g::AbstractStaticGraph, v::Integer) = fadj(g, v)
92+
in_neighbors(g::AbstractStaticGraph, v::Integer) = badj(g, v)
93+
94+
zero(g::T) where T<:AbstractStaticGraph = T()
95+
96+
copy(g::T) where T <: AbstractStaticGraph = T(copy(g.f_vec), copy(g.f_ind))
97+
98+
const StaticGraphEdge = StaticEdge
99+
const StaticDiGraphEdge = StaticEdge
100+
include("staticgraph.jl")
101+
include("staticdigraph.jl")
102+
include("persistence.jl")
103+
104+
const SGraph = StaticGraph
105+
const SDiGraph = StaticDiGraph
4106

5107
end # module

src/overrides.jl

Whitespace-only changes.

src/persistence.jl

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# StaticGraphs are binary files with the following format:
2+
# f_vec, 0, f_ind
3+
# StaticDiGraphs have the following format:
4+
# f_vec, 0, f_ind, 0, b_vec, 0, b_ind
5+
6+
abstract type StaticGraphFormat <: AbstractGraphFormat end
7+
struct SGFormat{T<:Integer} <: StaticGraphFormat end
8+
struct SDGFormat{T<:Integer} <: StaticGraphFormat end
9+
10+
SGFormat() = SGFormat{Int64}()
11+
SGFormat(T::DataType) = SGFormat{T}()
12+
13+
SDGFormat() = SDGFormat{Int64}()
14+
SDGFormat(T::DataType) = SDGFormat{T}()
15+
16+
17+
function savesg(fn::AbstractString, g::StaticGraph, T::DataType)
18+
open(fn, "w+") do io
19+
arr = vcat(g.f_vec, [0], g.f_ind)
20+
v = Mmap.mmap(io, Vector{T}, length(arr))
21+
for i = 1:length(arr)
22+
@inbounds v[i] = arr[i]
23+
end
24+
Mmap.sync!(v)
25+
end
26+
return 1
27+
end
28+
29+
function savesg(fn::AbstractString, g::StaticDiGraph, T::DataType)
30+
open(fn, "w+") do io
31+
farr = vcat(g.f_vec, [0], g.f_ind)
32+
barr = vcat(g.b_vec, [0], g.b_ind)
33+
arr = vcat(farr, [0], barr)
34+
v = Mmap.mmap(io, Vector{T}, length(arr))
35+
for i = 1:length(arr)
36+
@inbounds v[i] = arr[i]
37+
end
38+
Mmap.sync!(v)
39+
end
40+
return 1
41+
end
42+
43+
function loadsg(fn::AbstractString, ::SGFormat{T}) where T <: Integer
44+
open(fn, "r") do io
45+
arr = Mmap.mmap(io, Vector{T})
46+
zeroind = findfirst(arr, 0)
47+
StaticGraph{T}(arr[1:zeroind-1], arr[zeroind+1:end])
48+
end
49+
end
50+
51+
function loadsg(fn::AbstractString, ::SDGFormat{T}) where T <: Integer
52+
open(fn, "r") do io
53+
arr = Mmap.mmap(io, Vector{T})
54+
(z1, z2, z3) = findin(arr, 0)
55+
f_arr = fastview(arr, 1:(z1 - 1))
56+
f_ind = fastview(arr, (z1 + 1):(z2 - 1))
57+
b_arr = fastview(arr, (z2 + 1):(z3 - 1))
58+
b_ind = fastview(arr, (z3 + 1):length(arr))
59+
StaticDiGraph{T}(f_arr, f_ind, b_arr, b_ind)
60+
end
61+
end
62+
63+
loadgraph(fn::AbstractString, gname::String, s::T) where T <: StaticGraphFormat = loadsg(fn, s)
64+
savegraph(fn::AbstractString, g::AbstractStaticGraph, gname::String) = savegraph(fn, g)
65+
savegraph(fn::AbstractString, g::AbstractStaticGraph) = savesg(fn, g, eltype(g))

src/staticdigraph.jl

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""
2+
StaticDiGraph{T}
3+
4+
A type representing a static directed graph.
5+
"""
6+
struct StaticDiGraph{T<:Integer} <: AbstractStaticGraph
7+
f_vec::Vector{T}
8+
f_ind::Vector{T}
9+
b_vec::Vector{T}
10+
b_ind::Vector{T}
11+
end
12+
13+
@inline function _bvrange(g::StaticDiGraph, s)
14+
@inbounds r_start = g.b_ind[s]
15+
@inbounds r_end = g.b_ind[s + 1] - 1
16+
return r_start:r_end
17+
end
18+
19+
@inline function badj(g::StaticDiGraph, s)
20+
r = _bvrange(g, s)
21+
return fastview(g.b_vec, r)
22+
end
23+
24+
ne(g::StaticDiGraph) = length(g.f_vec)
25+
26+
# sorted src, dst vectors for forward and backward edgelists.
27+
function StaticDiGraph(n_v, f_ss::Vector{T}, f_ds::Vector{T}, b_ss::Vector{T}, b_ds::Vector{T}) where T <: Integer
28+
length(f_ss) == length(f_ds) == length(b_ss) == length(b_ds) || error("source and destination vectors must be equal length")
29+
(n_v == 0 || length(f_ss) == 0) && return StaticDiGraph(T[], T[1], T[], T[1])
30+
f_ind = [searchsortedfirst(f_ss, x) for x in 1:n_v]
31+
push!(f_ind, length(f_ss)+1)
32+
b_ind = [searchsortedfirst(b_ss, x) for x in 1:n_v]
33+
push!(b_ind, length(b_ss)+1)
34+
return StaticDiGraph{T}(f_ds, f_ind, b_ds, b_ind)
35+
end
36+
37+
# sorted src, dst tuples for forward and backward
38+
function StaticDiGraph(n_v, f_sd::Vector{Tuple{T, T}}, b_sd::Vector{Tuple{T, T}}) where T <: Integer
39+
f_ss = [x[1] for x in f_sd]
40+
f_ds = [x[2] for x in f_sd]
41+
b_ss = [x[1] for x in b_sd]
42+
b_ds = [x[2] for x in b_sd]
43+
44+
StaticDiGraph(n_v, f_ss, f_ds, b_ss, b_ds)
45+
end
46+
47+
function StaticDiGraph(g::LightGraphs.SimpleGraphs.SimpleDiGraph)
48+
f_sd = [Tuple(e) for e in edges(g)]
49+
b_sd = sort([Tuple(reverse(e)) for e in edges(g)])
50+
51+
StaticDiGraph(nv(g), f_sd, b_sd)
52+
end
53+
54+
#
55+
==(g::StaticDiGraph, h::StaticDiGraph) = g.f_vec == h.f_vec && g.f_ind == h.f_ind && g.b_vec == h.b_vec && g.b_ind == h.b_ind
56+
57+
degree(g::StaticDiGraph, v::Integer) = indegree(g, v) + outdegree(g, v)
58+
degree(g::StaticDiGraph) = [degree(g, v) for v in vertices(g)]
59+
indegree(g::StaticDiGraph, v::Integer) = length(_bvrange(g, v))
60+
indegree(g::StaticDiGraph) = [indegree(g, v) for v in vertices(g)]
61+
outdegree(g::StaticDiGraph, v::Integer) = length(_fvrange(g, v))
62+
outdegree(g::StaticDiGraph) = [outdegree(g, v) for v in vertices(g)]
63+
64+
65+
"""
66+
is_directed(g)
67+
68+
Return `true` if `g` is a directed graph.
69+
"""
70+
is_directed(::Type{StaticDiGraph}) = true
71+
is_directed(::Type{StaticDiGraph{T}}) where T = true
72+
is_directed(g::StaticDiGraph) = true

0 commit comments

Comments
 (0)