Skip to content

Commit 361e53e

Browse files
committed
Add BandedMatrices
1 parent 45b16a3 commit 361e53e

7 files changed

Lines changed: 141 additions & 28 deletions

File tree

.github/workflows/Test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
runs-on: ubuntu-latest
2121
strategy:
2222
matrix:
23-
julia-version: ['lts', '1', 'pre']
23+
julia-version: ['1', 'pre'] # TODO: do we drop 'lts'?
2424

2525
steps:
2626
- uses: actions/checkout@v4

Project.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,23 @@ DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
1010
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
1111
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1212
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
13+
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
1314
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1415

16+
[weakdeps]
17+
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
18+
19+
[extensions]
20+
SparseMatrixColoringsBandedMatricesExt = "BandedMatrices"
21+
1522
[compat]
1623
ADTypes = "1.2.1"
24+
BandedMatrices = "1.7.5"
1725
Compat = "3.46,4.2"
18-
DocStringExtensions = "0.8,0.9"
1926
DataStructures = "0.18"
27+
DocStringExtensions = "0.8,0.9"
2028
LinearAlgebra = "<0.0.1, 1"
2129
Random = "<0.0.1, 1"
30+
Requires = "1.3.0"
2231
SparseArrays = "<0.0.1, 1"
2332
julia = "1.6"
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
module SparseMatrixColoringsBandedMatricesExt
2+
3+
if isdefined(Base, :get_extension)
4+
using BandedMatrices: BandedMatrix, bandwidths, bandrange
5+
using SparseMatrixColorings:
6+
BipartiteGraph,
7+
ColoringProblem,
8+
ColumnColoringResult,
9+
GreedyColoringAlgorithm,
10+
RowColoringResult,
11+
column_colors,
12+
cycle_range,
13+
row_colors
14+
import SparseMatrixColorings as SMC
15+
else
16+
using ..BandedMatrices: BandedMatrix, bandwidths, bandrange
17+
using ..SparseMatrixColorings:
18+
BipartiteGraph,
19+
ColoringProblem,
20+
ColumnColoringResult,
21+
GreedyColoringAlgorithm,
22+
RowColoringResult,
23+
column_colors,
24+
cycle_range,
25+
row_colors
26+
import ..SparseMatrixColorings as SMC
27+
end
28+
29+
#=
30+
This code is partially taken from ArrayInterface.jl and FiniteDiff.jl
31+
https://github.com/JuliaArrays/ArrayInterface.jl
32+
https://github.com/JuliaDiff/FiniteDiff.jl
33+
=#
34+
35+
function SMC.coloring(
36+
A::BandedMatrix,
37+
::ColoringProblem{:nonsymmetric,:column},
38+
algo::GreedyColoringAlgorithm;
39+
kwargs...,
40+
)
41+
l, u = bandwidths(A)
42+
width = u + l + 1
43+
color = cycle_range(width, size(A, 2))
44+
bg = BipartiteGraph(A)
45+
return ColumnColoringResult(A, bg, color)
46+
end
47+
48+
function SMC.coloring(
49+
A::BandedMatrix,
50+
::ColoringProblem{:nonsymmetric,:row},
51+
algo::GreedyColoringAlgorithm;
52+
kwargs...,
53+
)
54+
l, u = bandwidths(A)
55+
width = u + l + 1
56+
color = cycle_range(width, size(A, 1))
57+
bg = BipartiteGraph(A)
58+
return RowColoringResult(A, bg, color)
59+
end
60+
61+
function SMC.decompress!(A::BandedMatrix, B::AbstractMatrix, result::ColumnColoringResult)
62+
color = column_colors(result)
63+
m, n = size(A)
64+
l, u = bandwidths(A)
65+
for j in axes(A, 2)
66+
c = color[j]
67+
for i in max(1, j - u):min(m, j + l)
68+
A[i, j] = B[i, c]
69+
end
70+
end
71+
return A
72+
end
73+
74+
function SMC.decompress!(A::BandedMatrix, B::AbstractMatrix, result::RowColoringResult)
75+
color = row_colors(result)
76+
m, n = size(A)
77+
l, u = bandwidths(A)
78+
for i in axes(A, 1)
79+
c = color[i]
80+
for j in max(1, i - l):min(n, i + u)
81+
A[i, j] = B[c, j]
82+
end
83+
end
84+
return A
85+
end
86+
87+
end

src/SparseMatrixColorings.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,15 @@ export column_colors, row_colors
6565
export column_groups, row_groups
6666
export compress, decompress, decompress!, decompress_single_color!
6767

68+
if !isdefined(Base, :get_extension)
69+
using Requires
70+
end
71+
72+
@static if !isdefined(Base, :get_extension)
73+
function __init__()
74+
@require BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
75+
return include("../ext/SparseMatrixColoringsBandedMatricesExt.jl")
76+
end
77+
end
78+
6879
end

src/structured.jl

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#=
22
This code is partially taken from ArrayInterface.jl
33
https://github.com/JuliaArrays/ArrayInterface.jl
4-
5-
Question: when decompressing, should we always assume that the coloring was optimal?
64
=#
75

86
"""
@@ -42,19 +40,15 @@ function coloring(
4240
return RowColoringResult(A, bg, color)
4341
end
4442

45-
function decompress!(
46-
A::Diagonal{R}, B::AbstractMatrix{R}, result::ColumnColoringResult
47-
) where {R<:Real}
43+
function decompress!(A::Diagonal, B::AbstractMatrix, result::ColumnColoringResult)
4844
color = column_colors(result)
4945
for j in axes(A, 2)
5046
A[j, j] = B[j, color[j]]
5147
end
5248
return A
5349
end
5450

55-
function decompress!(
56-
A::Diagonal{R}, B::AbstractMatrix{R}, result::RowColoringResult
57-
) where {R<:Real}
51+
function decompress!(A::Diagonal, B::AbstractMatrix, result::RowColoringResult)
5852
color = row_colors(result)
5953
for i in axes(A, 1)
6054
A[i, i] = B[color[i], i]
@@ -86,9 +80,7 @@ function coloring(
8680
return RowColoringResult(A, bg, color)
8781
end
8882

89-
function decompress!(
90-
A::Bidiagonal{R}, B::AbstractMatrix{R}, result::ColumnColoringResult
91-
) where {R<:Real}
83+
function decompress!(A::Bidiagonal, B::AbstractMatrix, result::ColumnColoringResult)
9284
color = column_colors(result)
9385
for j in axes(A, 2)
9486
c = color[j]
@@ -102,9 +94,7 @@ function decompress!(
10294
return A
10395
end
10496

105-
function decompress!(
106-
A::Bidiagonal{R}, B::AbstractMatrix{R}, result::RowColoringResult
107-
) where {R<:Real}
97+
function decompress!(A::Bidiagonal, B::AbstractMatrix, result::RowColoringResult)
10898
color = row_colors(result)
10999
for i in axes(A, 1)
110100
c = color[i]
@@ -142,9 +132,7 @@ function coloring(
142132
return RowColoringResult(A, bg, color)
143133
end
144134

145-
function decompress!(
146-
A::Tridiagonal{R}, B::AbstractMatrix{R}, result::ColumnColoringResult
147-
) where {R<:Real}
135+
function decompress!(A::Tridiagonal, B::AbstractMatrix, result::ColumnColoringResult)
148136
color = column_colors(result)
149137
for j in axes(A, 2)
150138
c = color[j]
@@ -159,9 +147,7 @@ function decompress!(
159147
return A
160148
end
161149

162-
function decompress!(
163-
A::Tridiagonal{R}, B::AbstractMatrix{R}, result::RowColoringResult
164-
) where {R<:Real}
150+
function decompress!(A::Tridiagonal, B::AbstractMatrix, result::RowColoringResult)
165151
color = row_colors(result)
166152
for i in axes(A, 1)
167153
c = color[i]

test/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[deps]
22
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
33
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
4+
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
45
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
56
Chairmarks = "0ca39b1e-fe0b-4e98-acfc-b1656634c4de"
67
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"

test/structured.jl

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using BandedMatrices: BandedMatrix, brand
12
using LinearAlgebra
23
using SparseMatrixColorings
34
using SparseMatrixColorings: cycle_range
@@ -25,15 +26,15 @@ end
2526
# column
2627
result = coloring(A, column_problem, algo)
2728
B = compress(A, result)
28-
@test size(B, 2) == 1
2929
D = decompress(B, result)
30+
@test size(B, 2) == 1
3031
@test D == A
3132
@test D isa Diagonal
3233
# row
3334
result = coloring(A, row_problem, algo)
3435
B = compress(A, result)
35-
@test size(B, 1) == 1
3636
D = decompress(B, result)
37+
@test size(B, 1) == 1
3738
@test D == A
3839
@test D isa Diagonal
3940
end
@@ -47,15 +48,15 @@ end
4748
# column
4849
result = coloring(A, column_problem, algo)
4950
B = compress(A, result)
50-
@test size(B, 2) == 2
5151
D = decompress(B, result)
52+
@test size(B, 2) == 2
5253
@test D == A
5354
@test D isa Bidiagonal
5455
# row
5556
result = coloring(A, row_problem, algo)
5657
B = compress(A, result)
57-
@test size(B, 1) == 2
5858
D = decompress(B, result)
59+
@test size(B, 1) == 2
5960
@test D == A
6061
@test D isa Bidiagonal
6162
end
@@ -70,16 +71,34 @@ end
7071
# column
7172
result = coloring(A, column_problem, algo)
7273
B = compress(A, result)
73-
@test size(B, 2) == min(n, 3)
7474
D = decompress(B, result)
75+
@test size(B, 2) == min(n, 3)
7576
@test D == A
7677
@test D isa Tridiagonal # row
7778
result = coloring(A, row_problem, algo)
7879
B = compress(A, result)
79-
@test size(B, 1) == min(n, 3)
8080
D = decompress(B, result)
81+
@test size(B, 1) == min(n, 3)
8182
@test D == A
8283
@test D isa Tridiagonal
8384
end
8485
end
8586
end
87+
88+
@testset "BandedMatrices" begin
89+
for (m, n) in [(10, 20), (20, 10)], l in 0:5, u in 0:5
90+
A = brand(m, n, l, u)
91+
# column
92+
result = coloring(A, column_problem, algo)
93+
B = compress(A, result)
94+
D = decompress(B, result)
95+
@test D == A
96+
@test D isa BandedMatrix
97+
# row
98+
result = coloring(A, row_problem, algo)
99+
B = compress(A, result)
100+
D = decompress(B, result)
101+
@test D == A
102+
@test D isa BandedMatrix
103+
end
104+
end

0 commit comments

Comments
 (0)