Skip to content

Commit fe64934

Browse files
authored
Implement compress (#58)
* Implement `compress` as a counterpart to `decompress` * Add doctests
1 parent c8c59cc commit fe64934

5 files changed

Lines changed: 161 additions & 23 deletions

File tree

docs/src/api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ row_groups
3232
## Decompression
3333

3434
```@docs
35+
compress
3536
decompress
3637
decompress!
3738
```

src/SparseMatrixColorings.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ include("check.jl")
4848
include("sparsematrixcsc.jl")
4949
include("examples.jl")
5050

51-
@compat public NaturalOrder, RandomOrder, LargestFirst
52-
5351
export ColoringProblem, GreedyColoringAlgorithm, AbstractColoringResult
5452
export coloring
5553
export column_colors, row_colors
5654
export column_groups, row_groups
57-
export decompress, decompress!
55+
export compress, decompress, decompress!
56+
57+
@compat public NaturalOrder, RandomOrder, LargestFirst
5858

5959
end

src/decompression.jl

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,106 @@
1+
"""
2+
compress(A, result::AbstractColoringResult)
3+
4+
Compress `A` into a new matrix `B`, given a coloring `result` of the sparsity pattern of `A`.
5+
6+
Compression means summing either the columns or the rows of `A` which share the same color.
7+
It is undone by calling [`decompress`](@ref).
8+
9+
# Example
10+
11+
```jldoctest
12+
julia> using SparseMatrixColorings, SparseArrays
13+
14+
julia> A = sparse([
15+
0 0 4 6 0 9
16+
1 0 0 0 7 0
17+
0 2 0 0 8 0
18+
0 3 5 0 0 0
19+
]);
20+
21+
julia> result = coloring(A, ColoringProblem(), GreedyColoringAlgorithm());
22+
23+
julia> column_groups(result)
24+
3-element Vector{Vector{Int64}}:
25+
[1, 2, 4]
26+
[3, 5]
27+
[6]
28+
29+
julia> B = compress(A, result)
30+
4×3 Matrix{Int64}:
31+
6 4 9
32+
1 7 0
33+
2 8 0
34+
3 5 0
35+
```
36+
37+
# See also
38+
39+
- [`AbstractColoringResult`](@ref)
40+
"""
41+
function compress end
42+
43+
function compress(A, result::AbstractColoringResult{structure,:column}) where {structure}
44+
group = column_groups(result)
45+
B = stack(group; dims=2) do g
46+
dropdims(sum(A[:, g]; dims=2); dims=2)
47+
end
48+
return B
49+
end
50+
51+
function compress(A, result::AbstractColoringResult{structure,:row}) where {structure}
52+
group = row_groups(result)
53+
B = stack(group; dims=1) do g
54+
dropdims(sum(A[g, :]; dims=1); dims=1)
55+
end
56+
return B
57+
end
58+
159
"""
260
decompress(B::AbstractMatrix, result::AbstractColoringResult)
361
4-
Decompress `B` out-of-place into a new matrix `A`, given a coloring `result` of the sparsity pattern of `A`.
62+
Decompress `B` into a new matrix `A`, given a coloring `result` of the sparsity pattern of `A`.
63+
64+
Compression means summing either the columns or the rows of `A` which share the same color.
65+
It is done by calling [`compress`](@ref).
66+
67+
# Example
68+
69+
```jldoctest
70+
julia> using SparseMatrixColorings, SparseArrays
71+
72+
julia> A = sparse([
73+
0 0 4 6 0 9
74+
1 0 0 0 7 0
75+
0 2 0 0 8 0
76+
0 3 5 0 0 0
77+
]);
78+
79+
julia> result = coloring(A, ColoringProblem(), GreedyColoringAlgorithm());
80+
81+
julia> column_groups(result)
82+
3-element Vector{Vector{Int64}}:
83+
[1, 2, 4]
84+
[3, 5]
85+
[6]
86+
87+
julia> B = compress(A, result)
88+
4×3 Matrix{Int64}:
89+
6 4 9
90+
1 7 0
91+
2 8 0
92+
3 5 0
93+
94+
julia> decompress(B, result)
95+
4×6 SparseMatrixCSC{Int64, Int64} with 9 stored entries:
96+
⋅ ⋅ 4 6 ⋅ 9
97+
1 ⋅ ⋅ ⋅ 7 ⋅
98+
⋅ 2 ⋅ ⋅ 8 ⋅
99+
⋅ 3 5 ⋅ ⋅ ⋅
100+
101+
julia> decompress(B, result) == A
102+
true
103+
```
5104
6105
# See also
7106
@@ -19,7 +118,50 @@ end
19118
result::AbstractColoringResult,
20119
)
21120
22-
Decompress `B` in-place into an existing matrix `A`, given a coloring `result` of the sparsity pattern of `A`.
121+
Decompress `B` in-place into `A`, given a coloring `result` of the sparsity pattern of `A`.
122+
123+
Compression means summing either the columns or the rows of `A` which share the same color.
124+
It is done by calling [`compress`](@ref).
125+
126+
# Example
127+
128+
```jldoctest
129+
julia> using SparseMatrixColorings, SparseArrays
130+
131+
julia> A = sparse([
132+
0 0 4 6 0 9
133+
1 0 0 0 7 0
134+
0 2 0 0 8 0
135+
0 3 5 0 0 0
136+
]);
137+
138+
julia> result = coloring(A, ColoringProblem(), GreedyColoringAlgorithm());
139+
140+
julia> column_groups(result)
141+
3-element Vector{Vector{Int64}}:
142+
[1, 2, 4]
143+
[3, 5]
144+
[6]
145+
146+
julia> B = compress(A, result)
147+
4×3 Matrix{Int64}:
148+
6 4 9
149+
1 7 0
150+
2 8 0
151+
3 5 0
152+
153+
julia> A2 = similar(A);
154+
155+
julia> decompress!(A2, B, result)
156+
4×6 SparseMatrixCSC{Int64, Int64} with 9 stored entries:
157+
⋅ ⋅ 4 6 ⋅ 9
158+
1 ⋅ ⋅ ⋅ 7 ⋅
159+
⋅ 2 ⋅ ⋅ 8 ⋅
160+
⋅ 3 5 ⋅ ⋅ ⋅
161+
162+
julia> A2 == A
163+
true
164+
```
23165
24166
# See also
25167

test/random.jl

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ symmetric_params = vcat(
3838
@testset "A::$(typeof(A))" for A in matrix_versions(A0)
3939
result = coloring(A, problem, algo)
4040
color = column_colors(result)
41-
group = column_groups(result)
42-
B = stack(group; dims=2) do g
43-
dropdims(sum(A[:, g]; dims=2); dims=2)
44-
end
41+
B = compress(A, result)
4542
@test color == column_coloring(A, algo)
4643
@test structurally_orthogonal_columns(A, color)
4744
@test directly_recoverable_columns(A, color)
@@ -60,10 +57,7 @@ end;
6057
@testset "A::$(typeof(A))" for A in matrix_versions(A0)
6158
result = coloring(A, problem, algo)
6259
color = row_colors(result)
63-
group = row_groups(result)
64-
B = stack(group; dims=1) do g
65-
dropdims(sum(A[g, :]; dims=1); dims=1)
66-
end
60+
B = compress(A, result)
6761
@test color == row_coloring(A, algo)
6862
@test structurally_orthogonal_columns(transpose(A), color)
6963
@test directly_recoverable_columns(transpose(A), color)
@@ -88,10 +82,7 @@ end;
8882
@testset "A::$(typeof(A))" for A in matrix_versions(A0)
8983
result = coloring(A, problem, algo)
9084
color = column_colors(result)
91-
group = column_groups(result)
92-
B = stack(group; dims=2) do g
93-
dropdims(sum(A[:, g]; dims=2); dims=2)
94-
end
85+
B = compress(A, result)
9586
if key == :direct
9687
@test color == symmetric_coloring(A, algo)
9788
@test symmetrically_orthogonal_columns(A, color)

test/small.jl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ algo = GreedyColoringAlgorithm()
3535
result0 = DefaultColoringResult{:nonsymmetric,:column,:direct}(A0, color0)
3636
@test structurally_orthogonal_columns(A0, color0)
3737
@test directly_recoverable_columns(A0, color0)
38+
@test compress(A0, result0) == B0
3839
@test decompress(B0, result0) == A0
3940
for A in matrix_versions(A0)
4041
@test decompress!(respectful_similar(A), B0, result0) == A
@@ -55,6 +56,7 @@ end;
5556
result0 = DefaultColoringResult{:nonsymmetric,:row,:direct}(A0, color0)
5657
@test structurally_orthogonal_columns(transpose(A0), color0)
5758
@test directly_recoverable_columns(transpose(A0), color0)
59+
@test compress(A0, result0) == B0
5860
@test decompress(B0, result0) == A0
5961
for A in matrix_versions(A0)
6062
@test decompress!(respectful_similar(A), B0, result0) == A
@@ -68,6 +70,7 @@ end;
6870
result0 = DefaultColoringResult{:symmetric,:column,:direct}(A0, color0)
6971
@test symmetrically_orthogonal_columns(A0, color0)
7072
@test directly_recoverable_columns(A0, color0)
73+
@test compress(A0, result0) == B0
7174
@test decompress(B0, result0) == A0
7275
for A in matrix_versions(A0)
7376
@test decompress!(respectful_similar(A), B0, result0) == A
@@ -84,13 +87,11 @@ end;
8487
structure=:symmetric, partition=:column, decompression=:substitution
8588
),
8689
GreedyColoringAlgorithm(),
87-
) # returns a TreeSetColoringResult
88-
group = column_groups(result)
89-
B = stack(group; dims=2) do g
90-
dropdims(sum(A0[:, g]; dims=2); dims=2)
91-
end
90+
)
91+
B = compress(A0, result)
9292
@test column_colors(result) != color0
9393
@test B != B0
94+
@test compress(A0, result0) == B0
9495
@test decompress(B, result) A0
9596
@test decompress(B0, result0) A0
9697
for A in matrix_versions(A0)
@@ -105,6 +106,7 @@ end;
105106
result0 = DefaultColoringResult{:symmetric,:column,:direct}(A0, color0)
106107
@test symmetrically_orthogonal_columns(A0, color0)
107108
@test directly_recoverable_columns(A0, color0)
109+
@test compress(A0, result0) == B0
108110
@test decompress(B0, result0) == A0
109111
for A in matrix_versions(A0)
110112
@test decompress!(respectful_similar(A), B0, result0) == A
@@ -121,8 +123,10 @@ end;
121123
structure=:symmetric, partition=:column, decompression=:substitution
122124
),
123125
GreedyColoringAlgorithm(),
124-
) # returns a TreeSetColoringResult
126+
)
125127
@test column_colors(result) == color0
128+
@test compress(A0, result0) == B0
129+
@test compress(A0, result) == B0
126130
@test decompress(B0, result0) A0
127131
@test decompress(B0, result) A0
128132
for A in matrix_versions(A0)

0 commit comments

Comments
 (0)