Skip to content

Commit 947a213

Browse files
authored
Revamp graph structures (#2)
* Start revamping graph * Revamp graph structures * Fix docs * Fix README
1 parent 3bcb5f9 commit 947a213

20 files changed

Lines changed: 437 additions & 245 deletions

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ pkg> add https://github.com/gdalle/SparseMatrixColorings.jl
1717

1818
## Background
1919

20-
The algorithms implemented in this package are all taken from the following survey:
20+
The algorithms implemented in this package are mainly taken from the following articles:
2121

2222
> [_What Color Is Your Jacobian? Graph Coloring for Computing Derivatives_](https://epubs.siam.org/doi/10.1137/S0036144504444711), Gebremedhin et al. (2005)
2323
24-
Some parts of the survey (like definitions and theorems) are also copied verbatim or referred to by their number in the documentation.
24+
> [ColPack: Software for graph coloring and related problems in scientific computing](https://dl.acm.org/doi/10.1145/2513109.2513110), Gebremedhin et al. (2013)
25+
26+
Some parts of the articles (like definitions) are thus copied verbatim in the documentation.
2527

2628
## Alternatives
2729

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
DocumenterInterLinks = "d12716ef-a0f6-4df4-a9f1-a5a34e75c656"
34
SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35"

docs/make.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using Documenter
2+
using DocumenterInterLinks
23
using SparseMatrixColorings
34

5+
links = InterLinks("ADTypes" => "https://sciml.github.io/ADTypes.jl/stable/")
6+
47
cp(joinpath(@__DIR__, "..", "README.md"), joinpath(@__DIR__, "src", "index.md"); force=true)
58

69
makedocs(;
@@ -9,6 +12,7 @@ makedocs(;
912
sitename="SparseMatrixColorings.jl",
1013
format=Documenter.HTML(),
1114
pages=["Home" => "index.md", "API reference" => "api.md"],
15+
plugins=[links],
1216
)
1317

1418
deploydocs(; repo="github.com/gdalle/SparseMatrixColorings.jl", devbranch="main")

src/SparseMatrixColorings.jl

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,24 @@
33
44
Coloring algorithms for sparse Jacobian and Hessian matrices.
55
6-
The algorithms implemented in this package are all taken from the following survey:
6+
The algorithms implemented in this package are mainly taken from the following articles:
77
88
> [_What Color Is Your Jacobian? Graph Coloring for Computing Derivatives_](https://epubs.siam.org/doi/10.1137/S0036144504444711), Gebremedhin et al. (2005)
99
10-
Some parts of the survey (like definitions and theorems) are also copied verbatim or referred to by their number in the documentation.
10+
> [ColPack: Software for graph coloring and related problems in scientific computing](https://dl.acm.org/doi/10.1145/2513109.2513110), Gebremedhin et al. (2013)
11+
12+
Some parts of the articles (like definitions) are thus copied verbatim in the documentation.
1113
"""
1214
module SparseMatrixColorings
1315

1416
using ADTypes: ADTypes, AbstractColoringAlgorithm
15-
using LinearAlgebra: Transpose, parent, transpose
16-
using Random: AbstractRNG
17-
using SparseArrays: SparseMatrixCSC, nzrange, rowvals
18-
19-
include("utils.jl")
20-
21-
include("bipartite_graph.jl")
22-
include("adjacency_graph.jl")
23-
24-
include("distance2_coloring.jl")
25-
include("star_coloring.jl")
17+
using LinearAlgebra: Diagonal, Transpose, checksquare, parent, transpose
18+
using Random: AbstractRNG, default_rng, randperm
19+
using SparseArrays: SparseArrays, SparseMatrixCSC, nzrange, rowvals, spzeros
2620

21+
include("graph.jl")
22+
include("order.jl")
23+
include("coloring.jl")
2724
include("adtypes.jl")
2825
include("check.jl")
2926

src/adjacency_graph.jl

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/adtypes.jl

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,32 @@ Matrix coloring algorithm for sparse Jacobians and Hessians.
55
66
Compatible with the [ADTypes.jl coloring framework](https://sciml.github.io/ADTypes.jl/stable/#Coloring-algorithm).
77
8+
# Constructor
9+
10+
GreedyColoringAlgorithm(order::AbstractOrder=NaturalOrder())
11+
812
# Implements
913
10-
- `ADTypes.column_coloring` with a partial distance-2 coloring of the bipartite graph
11-
- `ADTypes.row_coloring` with a partial distance-2 coloring of the bipartite graph
12-
- `ADTypes.symmetric_coloring` with a star coloring of the adjacency graph
14+
- [`ADTypes.column_coloring`](@extref ADTypes) and [`ADTypes.row_coloring`](@extref ADTypes) with a partial distance-2 coloring of the bipartite graph
15+
- [`ADTypes.symmetric_coloring`](@extref ADTypes) with a star coloring of the adjacency graph
1316
"""
14-
struct GreedyColoringAlgorithm <: ADTypes.AbstractColoringAlgorithm end
17+
struct GreedyColoringAlgorithm{O<:AbstractOrder} <: ADTypes.AbstractColoringAlgorithm
18+
order::O
19+
end
20+
21+
GreedyColoringAlgorithm() = GreedyColoringAlgorithm(NaturalOrder())
1522

16-
function ADTypes.column_coloring(A::AbstractMatrix, ::GreedyColoringAlgorithm)
17-
g = BipartiteGraph(A)
18-
return distance2_column_coloring(g)
23+
function ADTypes.column_coloring(A::AbstractMatrix, algo::GreedyColoringAlgorithm)
24+
bg = BipartiteGraph(A)
25+
return partial_distance2_coloring(bg, Val(2), algo.order)
1926
end
2027

21-
function ADTypes.row_coloring(A::AbstractMatrix, ::GreedyColoringAlgorithm)
22-
g = BipartiteGraph(A)
23-
return distance2_row_coloring(g)
28+
function ADTypes.row_coloring(A::AbstractMatrix, algo::GreedyColoringAlgorithm)
29+
bg = BipartiteGraph(A)
30+
return partial_distance2_coloring(bg, Val(1), algo.order)
2431
end
2532

26-
function ADTypes.symmetric_coloring(A::AbstractMatrix, ::GreedyColoringAlgorithm)
27-
g = AdjacencyGraph(A)
28-
return star_coloring(g)
33+
function ADTypes.symmetric_coloring(A::AbstractMatrix, algo::GreedyColoringAlgorithm)
34+
ag = AdjacencyGraph(A)
35+
return star_coloring(ag, algo.order)
2936
end

src/bipartite_graph.jl

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/check.jl

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
"""
2-
check_structurally_orthogonal_columns(A, colors; verbose=false)
2+
check_structurally_orthogonal_columns(
3+
A::AbstractMatrix, colors::AbstractVector{<:Integer}
4+
verbose=false
5+
)
36
47
Return `true` if coloring the columns of the matrix `A` with the vector `colors` results in a partition that is structurally orthogonal, and `false` otherwise.
58
6-
Def 3.2: A partition of the columns of a matrix `A` is _structurally orthogonal_ if, for every nonzero element `A[i, j]`, the group containing column `A[:, j]` has no other column with a nonzero in row `i`.
9+
A partition of the columns of a matrix `A` is _structurally orthogonal_ if, for every nonzero element `A[i, j]`, the group containing column `A[:, j]` has no other column with a nonzero in row `i`.
710
8-
Thm 3.5: The function [`distance2_column_coloring`](@ref) applied to the [`BipartiteGraph`](@ref) of `A` should return a suitable coloring.
11+
!!! warning
12+
This function is not coded with efficiency in mind, it is designed for small-scale tests.
913
"""
1014
function check_structurally_orthogonal_columns(
11-
A::AbstractMatrix, colors::AbstractVector{<:Integer}; verbose=false
15+
A::AbstractMatrix, colors::AbstractVector{<:Integer}; verbose::Bool=false
1216
)
1317
for c in unique(colors)
1418
js = filter(j -> colors[j] == c, axes(A, 2))
@@ -23,16 +27,20 @@ function check_structurally_orthogonal_columns(
2327
end
2428

2529
"""
26-
check_structurally_orthogonal_rows(A, colors; verbose=false)
30+
check_structurally_orthogonal_rows(
31+
A::AbstractMatrix, colors::AbstractVector{<:Integer};
32+
verbose=false
33+
)
2734
2835
Return `true` if coloring the rows of the matrix `A` with the vector `colors` results in a partition that is structurally orthogonal, and `false` otherwise.
2936
30-
Def 3.2: A partition of the rows of a matrix `A` is _structurally orthogonal_ if, for every nonzero element `A[i, j]`, the group containing row `A[i, :]` has no other row with a nonzero in column `j`.
37+
A partition of the rows of a matrix `A` is _structurally orthogonal_ if, for every nonzero element `A[i, j]`, the group containing row `A[i, :]` has no other row with a nonzero in column `j`.
3138
32-
Thm 3.5: The function [`distance2_row_coloring`](@ref) applied to the [`BipartiteGraph`](@ref) of `A` should return a suitable coloring.
39+
!!! warning
40+
This function is not coded with efficiency in mind, it is designed for small-scale tests.
3341
"""
3442
function check_structurally_orthogonal_rows(
35-
A::AbstractMatrix, colors::AbstractVector{<:Integer}; verbose=false
43+
A::AbstractMatrix, colors::AbstractVector{<:Integer}; verbose::Bool=false
3644
)
3745
for c in unique(colors)
3846
is = filter(i -> colors[i] == c, axes(A, 1))
@@ -47,17 +55,23 @@ function check_structurally_orthogonal_rows(
4755
end
4856

4957
"""
50-
check_symmetrically_orthogonal(A, colors; verbose=false)
58+
check_symmetrically_orthogonal(
59+
A::AbstractMatrix, colors::AbstractVector{<:Integer};
60+
verbose=false
61+
)
5162
5263
Return `true` if coloring the columns of the symmetric matrix `A` with the vector `colors` results in a partition that is symmetrically orthogonal, and `false` otherwise.
5364
54-
Def 4.2: A partition of the columns of a symmetrix matrix `A` is _symmetrically orthogonal_ if, for every nonzero element `A[i, j]`, either
65+
A partition of the columns of a symmetrix matrix `A` is _symmetrically orthogonal_ if, for every nonzero element `A[i, j]`, either
5566
5667
1. the group containing the column `A[:, j]` has no other column with a nonzero in row `i`
5768
2. the group containing the column `A[:, i]` has no other column with a nonzero in row `j`
69+
70+
!!! warning
71+
This function is not coded with efficiency in mind, it is designed for small-scale tests.
5872
"""
5973
function check_symmetrically_orthogonal(
60-
A::AbstractMatrix, colors::AbstractVector{<:Integer}; verbose=false
74+
A::AbstractMatrix, colors::AbstractVector{<:Integer}; verbose::Bool=false
6175
)
6276
for i in axes(A, 2), j in axes(A, 2)
6377
if !iszero(A[i, j])

src/coloring.jl

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""
2+
partial_distance2_coloring(bg::BipartiteGraph, ::Val{side}, order::AbstractOrder)
3+
4+
Compute a distance-2 coloring of the given `side` (`1` or `2`) in the bipartite graph `bg` and return a vector of integer colors.
5+
6+
A _distance-2 coloring_ is such that two vertices have different colors if they are at distance at most 2.
7+
8+
The vertices are colored in a greedy fashion, following the `order` supplied.
9+
10+
# See also
11+
12+
- [`BipartiteGraph`](@ref)
13+
- [`AbstractOrder`](@ref)
14+
"""
15+
function partial_distance2_coloring(
16+
bg::BipartiteGraph, ::Val{side}, order::AbstractOrder
17+
) where {side}
18+
other_side = 3 - side
19+
colors = zeros(Int, length(bg, Val(side)))
20+
forbidden_colors = zeros(Int, length(bg, Val(side)))
21+
for v in vertices(bg, Val(side), order)
22+
for w in neighbors(bg, Val(side), v)
23+
for x in neighbors(bg, Val(other_side), w)
24+
if !iszero(colors[x])
25+
forbidden_colors[colors[x]] = v
26+
end
27+
end
28+
end
29+
for c in eachindex(forbidden_colors)
30+
if forbidden_colors[c] != v
31+
colors[v] = c
32+
break
33+
end
34+
end
35+
end
36+
return colors
37+
end
38+
39+
"""
40+
star_coloring(ag::AdjacencyGraph, order::AbstractOrder)
41+
42+
Compute a star coloring of all vertices in the adjacency graph `ag` and return a vector of integer colors.
43+
44+
A _star coloring_ is a distance-1 coloring such that every path on 4 vertices uses at least 3 colors.
45+
46+
The vertices are colored in a greedy fashion, following the `order` supplied.
47+
48+
# See also
49+
50+
- [`AdjacencyGraph`](@ref)
51+
- [`AbstractOrder`](@ref)
52+
"""
53+
function star_coloring(ag::AdjacencyGraph, order::AbstractOrder)
54+
n = length(ag)
55+
colors = zeros(Int, n)
56+
forbidden_colors = zeros(Int, n)
57+
for v in vertices(ag, order)
58+
for w in neighbors(ag, v)
59+
if !iszero(colors[w]) # w is colored
60+
forbidden_colors[colors[w]] = v
61+
end
62+
for x in neighbors(ag, w)
63+
if !iszero(colors[x]) && iszero(colors[w]) # w is not colored
64+
forbidden_colors[colors[x]] = v
65+
else
66+
for y in neighbors(ag, x)
67+
if !iszero(colors[y]) && y != w
68+
if colors[y] == colors[w]
69+
forbidden_colors[colors[x]] = v
70+
break
71+
end
72+
end
73+
end
74+
end
75+
end
76+
end
77+
for c in eachindex(forbidden_colors)
78+
if forbidden_colors[c] != v
79+
colors[v] = c
80+
break
81+
end
82+
end
83+
end
84+
return colors
85+
end

0 commit comments

Comments
 (0)