|
| 1 | +""" |
| 2 | + SimpleWeightedGraphs |
| 3 | +
|
| 4 | +A package for graphs with edge weights, stored as sparse adjacency matrices. |
| 5 | +""" |
1 | 6 | module SimpleWeightedGraphs
|
2 | 7 |
|
3 |
| -using Graphs |
4 | 8 | using LinearAlgebra
|
5 | 9 | using Markdown
|
6 |
| -using SparseArrays |
7 |
| - |
8 |
| -import Base: |
9 |
| - convert, eltype, show, ==, Pair, Tuple, copy, length, issubset, zero |
10 |
| - |
11 |
| -import Graphs: |
12 |
| - _NI, AbstractGraph, AbstractEdge, AbstractEdgeIter, |
13 |
| - src, dst, edgetype, nv, ne, vertices, edges, is_directed, |
14 |
| - add_vertex!, add_edge!, rem_vertex!, rem_edge!, |
15 |
| - has_vertex, has_edge, inneighbors, outneighbors, |
16 |
| - indegree, outdegree, degree, has_self_loops, num_self_loops, |
17 |
| - |
18 |
| - add_vertices!, adjacency_matrix, laplacian_matrix, weights, |
19 |
| - connected_components, cartesian_product, |
20 |
| - |
21 |
| - AbstractGraphFormat, loadgraph, loadgraphs, savegraph, |
22 |
| - pagerank, induced_subgraph |
23 |
| - |
24 |
| -export |
25 |
| - AbstractSimpleWeightedGraph, |
26 |
| - AbstractSimpleWeightedEdge, |
27 |
| - SimpleWeightedEdge, |
28 |
| - SimpleWeightedGraph, |
29 |
| - SimpleWeightedGraphEdge, |
30 |
| - SimpleWeightedDiGraph, |
31 |
| - SimpleWeightedDiGraphEdge, |
32 |
| - weight, |
33 |
| - weighttype, |
34 |
| - get_weight, |
35 |
| - WGraph, |
36 |
| - WDiGraph, |
37 |
| - SWGFormat, |
38 |
| - degree_matrix |
39 |
| - |
| 10 | +using SparseArrays: SparseMatrixCSC, sparse, spzeros, nnz, findnz, spdiagm, nzrange |
| 11 | + |
| 12 | +using Graphs: Graphs |
| 13 | +using Graphs: AbstractGraph, AbstractEdge, AbstractEdgeIter, AbstractGraphFormat |
| 14 | +using Graphs: SimpleGraph, SimpleDiGraph |
| 15 | +using Graphs: src, dst |
| 16 | +using Graphs: edgetype, is_directed, nv, ne, vertices, edges |
| 17 | +using Graphs: add_vertex!, add_vertices!, add_edge!, rem_vertex!, rem_edge! |
| 18 | +using Graphs: has_vertex, has_edge, inneighbors, outneighbors |
| 19 | +using Graphs: indegree, outdegree, degree, has_self_loops, num_self_loops |
| 20 | +using Graphs: adjacency_matrix, laplacian_matrix, weights |
| 21 | +using Graphs: connected_components, cartesian_product, induced_subgraph, pagerank |
| 22 | +using Graphs: loadgraph, loadgraphs, savegraph |
| 23 | +using Graphs: _NI |
| 24 | + |
| 25 | +export AbstractSimpleWeightedGraph, AbstractSimpleWeightedEdge |
| 26 | +export SimpleWeightedGraph, SimpleWeightedDiGraph |
| 27 | +export SimpleWeightedEdge, SimpleWeightedGraphEdge, SimpleWeightedDiGraphEdge |
| 28 | +export WGraph, WDiGraph, SWGFormat |
| 29 | +export weight, weighttype, get_weight, degree_matrix |
| 30 | + |
| 31 | +include("utils.jl") |
40 | 32 | include("simpleweightededge.jl")
|
41 |
| - |
42 |
| -""" |
43 |
| - AbstractSimpleWeightedGraph |
44 |
| -
|
45 |
| -An abstract type representing a simple graph structure. |
46 |
| -AbstractSimpleWeightedGraphs must have the following elements: |
47 |
| -- weightmx::AbstractSparseMatrix{Real} |
48 |
| -""" |
49 |
| -abstract type AbstractSimpleWeightedGraph{T<:Integer,U<:Real} <: AbstractGraph{T} end |
50 |
| - |
51 |
| -function show(io::IO, g::AbstractSimpleWeightedGraph{T, U}) where T where U |
52 |
| - dir = is_directed(g) ? "directed" : "undirected" |
53 |
| - print(io, "{$(nv(g)), $(ne(g))} $dir simple $T graph with $U weights") |
54 |
| -end |
55 |
| - |
56 |
| -# conversion to SparseMatrixCSC |
57 |
| -convert(::Type{SparseMatrixCSC{T, U}}, g::AbstractSimpleWeightedGraph) where T<:Real where U<:Integer = SparseMatrixCSC{T, U}(g.weights) |
58 |
| - |
59 |
| - |
60 |
| -### INTERFACE |
61 |
| - |
62 |
| -nv(g::AbstractSimpleWeightedGraph{T, U}) where T where U = T(size(weights(g), 1)) |
63 |
| -vertices(g::AbstractSimpleWeightedGraph{T, U}) where T where U = one(T):nv(g) |
64 |
| -eltype(x::AbstractSimpleWeightedGraph{T, U}) where T where U = T |
65 |
| -weighttype(x::AbstractSimpleWeightedGraph{T, U}) where T where U = U |
66 |
| - |
67 |
| -# handles single-argument edge constructors such as pairs and tuples |
68 |
| -has_edge(g::AbstractSimpleWeightedGraph{T, U}, x) where T where U = has_edge(g, edgetype(g)(x)) |
69 |
| -add_edge!(g::AbstractSimpleWeightedGraph{T, U}, x) where T where U = add_edge!(g, edgetype(g)(x)) |
70 |
| - |
71 |
| -# handles two-argument edge constructors like src,dst |
72 |
| -has_edge(g::AbstractSimpleWeightedGraph, x, y) = has_edge(g, edgetype(g)(x, y, 0)) |
73 |
| -add_edge!(g::AbstractSimpleWeightedGraph, x, y) = add_edge!(g, edgetype(g)(x, y, 1)) |
74 |
| -add_edge!(g::AbstractSimpleWeightedGraph, x, y, z) = add_edge!(g, edgetype(g)(x, y, z)) |
75 |
| - |
76 |
| -function issubset(g::T, h::T) where T<:AbstractSimpleWeightedGraph |
77 |
| - (gmin, gmax) = extrema(vertices(g)) |
78 |
| - (hmin, hmax) = extrema(vertices(h)) |
79 |
| - return (hmin <= gmin <= gmax <= hmax) && issubset(edges(g), edges(h)) |
80 |
| -end |
81 |
| - |
82 |
| -has_vertex(g::AbstractSimpleWeightedGraph, v::Integer) = v in vertices(g) |
83 |
| - |
84 |
| -function rem_edge!(g::AbstractSimpleWeightedGraph{T, U}, u::Integer, v::Integer) where {T, U} |
85 |
| - rem_edge!(g, edgetype(g)(T(u), T(v), one(U))) |
86 |
| -end |
87 |
| - |
88 |
| -get_weight(g::AbstractSimpleWeightedGraph, u::Integer, v::Integer) = weights(g)[v, u] |
89 |
| - |
90 |
| -zero(g::T) where T<:AbstractSimpleWeightedGraph = T() |
91 |
| - |
92 |
| -# TODO: manipulte SparseMatrixCSC directly |
93 |
| -add_vertex!(g::AbstractSimpleWeightedGraph) = add_vertices!(g, 1) |
94 |
| - |
95 |
| -copy(g::T) where T <: AbstractSimpleWeightedGraph = T(copy(weights(g))) |
96 |
| - |
97 |
| - |
98 |
| -const SimpleWeightedGraphEdge = SimpleWeightedEdge |
99 |
| -const SimpleWeightedDiGraphEdge = SimpleWeightedEdge |
| 33 | +include("abstractsimpleweightedgraph.jl") |
100 | 34 | include("simpleweighteddigraph.jl")
|
101 | 35 | include("simpleweightedgraph.jl")
|
| 36 | +include("conversion.jl") |
102 | 37 | include("overrides.jl")
|
103 | 38 | include("persistence.jl")
|
104 | 39 |
|
105 |
| -const WGraph = SimpleWeightedGraph |
106 |
| -const WDiGraph = SimpleWeightedDiGraph |
107 |
| - |
108 |
| - |
109 |
| -# return the index in nzval of mat[i, j] |
110 |
| -# we assume bounds are already checked |
111 |
| -# see https://github.com/JuliaSparse/SparseArrays.jl/blob/fa547689947fadd6c2f3d09ddfcb5f26536f18c8/src/sparsematrix.jl#L2492 for implementation |
112 |
| -@inbounds function _get_nz_index!(mat::SparseMatrixCSC, i::Integer, j::Integer) |
113 |
| - # r1 and r2 are start and end of the column |
114 |
| - r1 = Int(mat.colptr[j]) |
115 |
| - r2 = Int(mat.colptr[j+1]-1) |
116 |
| - (r1 > r2) && return 0 # column is empty so we have a non structural zero |
117 |
| - # search if i correspond to a stored value |
118 |
| - indx = searchsortedfirst(mat.rowval, i, r1, r2, Base.Forward) |
119 |
| - ((indx > r2) || (mat.rowval[indx] != i)) && return 0 |
120 |
| - return indx |
121 |
| -end |
122 |
| - |
123 |
| -SimpleWeightedDiGraph(g::SimpleWeightedGraph) = SimpleWeightedDiGraph(copy(g.weights)) |
124 |
| -function SimpleWeightedDiGraph{T, U}(g::SimpleWeightedGraph) where {T<:Integer, U<:Real} |
125 |
| - return SimpleWeightedDiGraph(SparseMatrixCSC{U, T}(copy(g.weights))) |
126 | 40 | end
|
127 |
| - |
128 |
| -SimpleWeightedGraph(g::SimpleWeightedDiGraph) = SimpleWeightedGraph(g.weights .+ g.weights') |
129 |
| - |
130 |
| -function SimpleWeightedGraph{T, U}(g::SimpleWeightedDiGraph) where {T<:Integer, U<:Real} |
131 |
| - return SimpleWeightedGraph(SparseMatrixCSC{U, T}(g.weights .+ g.weights')) |
132 |
| -end |
133 |
| - |
134 |
| -end # module |
0 commit comments