Skip to content

Commit 9d1889e

Browse files
authored
feat: allow neutral colors and postprocessing (#166)
1 parent 0794c68 commit 9d1889e

13 files changed

Lines changed: 478 additions & 249 deletions

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "SparseMatrixColorings"
22
uuid = "0a514795-09f3-496d-8182-132a7b665d35"
33
authors = ["Guillaume Dalle", "Alexis Montoison"]
4-
version = "0.4.12"
4+
version = "0.4.13"
55

66
[deps]
77
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"

docs/src/vis.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,17 @@ Finally, a background color can be passed via the `background` keyword argument.
6161
We demonstrate this on a bidirectional coloring.
6262

6363
```@example img
64-
6564
S = sparse([
6665
1 1 1 1 1 1 1 1 1
6766
1 0 0 0 0 0 0 0 1
6867
1 0 0 0 0 0 0 0 1
6968
1 0 0 0 0 0 0 0 1
7069
1 0 0 0 0 0 0 0 1
71-
1 0 0 0 0 0 0 0 1
7270
1 1 1 1 1 1 1 1 1
7371
])
7472
7573
problem_bi = ColoringProblem(; structure=:nonsymmetric, partition=:bidirectional)
76-
algo_bi = GreedyColoringAlgorithm(RandomOrder(StableRNG(0)); decompression=:direct)
74+
algo_bi = GreedyColoringAlgorithm(RandomOrder(StableRNG(0)); postprocessing=true, decompression=:direct)
7775
result_bi = coloring(S, problem_bi, algo_bi)
7876
7977
A_img, Br_img, Bc_img = show_colors(

ext/SparseMatrixColoringsColorsExt.jl

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ function show_colors!(
131131
if !iszero(A[I])
132132
r, c = Tuple(I)
133133
area = matrix_entry_area(I, scale, pad)
134-
A_img[area] .= A_colors[c]
134+
if column_colors(res)[c] > 0
135+
A_img[area] .= A_colors[c]
136+
end
135137
end
136138
end
137139
for I in CartesianIndices(B)
@@ -163,7 +165,9 @@ function show_colors!(
163165
if !iszero(A[I])
164166
r, c = Tuple(I)
165167
area = matrix_entry_area(I, scale, pad)
166-
A_img[area] .= A_colors[r]
168+
if row_colors(res)[r] > 0
169+
A_img[area] .= A_colors[r]
170+
end
167171
end
168172
end
169173
for I in CartesianIndices(B)
@@ -205,9 +209,13 @@ function show_colors!(
205209
area = matrix_entry_area(I, scale, pad)
206210
for i in axes(area, 1), j in axes(area, 2)
207211
if j > i
208-
A_img[area[i, j]] = A_ccolors[c]
212+
if column_colors(res)[c] > 0
213+
A_img[area[i, j]] = A_ccolors[c]
214+
end
209215
elseif i > j
210-
A_img[area[i, j]] = A_rcolors[r]
216+
if row_colors(res)[r] > 0
217+
A_img[area[i, j]] = A_rcolors[r]
218+
end
211219
end
212220
end
213221
end

src/check.jl

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -105,23 +105,10 @@ function symmetrically_orthogonal_columns(
105105
for i in axes(A, 2), j in axes(A, 2)
106106
iszero(A[i, j]) && continue
107107
ci, cj = color[i], color[j]
108-
gi, gj = group[ci], group[cj]
109-
A_gj_rowi = view(A, i, gj)
110-
A_gi_rowj = view(A, j, gi)
111-
nonzeros_gj_rowi = count(!iszero, A_gj_rowi)
112-
nonzeros_gi_rowj = count(!iszero, A_gi_rowj)
113-
if nonzeros_gj_rowi > 1 && nonzeros_gi_rowj > 1
114-
if verbose
115-
gj_incompatible_columns = gj[findall(!iszero, A_gj_rowi)]
116-
gi_incompatible_columns = gi[findall(!iszero, A_gi_rowj)]
117-
@warn """
118-
For coefficient (i=$i, j=$j) with column colors (ci=$ci, cj=$cj):
119-
- In color ci=$ci, columns $gi_incompatible_columns all have nonzeros in row j=$j.
120-
- In color cj=$cj, columns $gj_incompatible_columns all have nonzeros in row i=$i.
121-
"""
122-
end
123-
return false
124-
end
108+
check = _bilateral_check(
109+
A; i, j, ci, cj, row_group=group, column_group=group, verbose
110+
)
111+
!check && return false
125112
end
126113
return true
127114
end
@@ -156,6 +143,62 @@ function structurally_biorthogonal(
156143
for i in axes(A, 1), j in axes(A, 2)
157144
iszero(A[i, j]) && continue
158145
ci, cj = row_color[i], column_color[j]
146+
check = _bilateral_check(A; i, j, ci, cj, row_group, column_group, verbose)
147+
!check && return false
148+
end
149+
return true
150+
end
151+
152+
function _bilateral_check(
153+
A::AbstractMatrix;
154+
i::Integer,
155+
j::Integer,
156+
ci::Integer,
157+
cj::Integer,
158+
row_group::AbstractVector,
159+
column_group::AbstractVector,
160+
verbose::Bool,
161+
)
162+
if ci == 0 && cj == 0
163+
if verbose
164+
@warn """
165+
For coefficient (i=$i, j=$j) with colors (ci=$ci, cj=$cj):
166+
- Row color ci=$ci is neutral.
167+
- Column color cj=$cj is neutral.
168+
"""
169+
end
170+
return false
171+
elseif ci == 0 && cj != 0
172+
gj = column_group[cj]
173+
A_gj_rowi = view(A, i, gj)
174+
nonzeros_gj_rowi = count(!iszero, A_gj_rowi)
175+
if nonzeros_gj_rowi > 1
176+
if verbose
177+
gj_incompatible_columns = gj[findall(!iszero, A_gj_rowi)]
178+
@warn """
179+
For coefficient (i=$i, j=$j) with colors (ci=$ci, cj=$cj):
180+
- Row color ci=$ci is neutral.
181+
- In column color cj=$cj, columns $gj_incompatible_columns all have nonzeros in row i=$i.
182+
"""
183+
end
184+
return false
185+
end
186+
elseif ci != 0 && cj == 0
187+
gi = row_group[ci]
188+
A_gi_columnj = view(A, gi, j)
189+
nonzeros_gi_columnj = count(!iszero, A_gi_columnj)
190+
if nonzeros_gi_columnj > 1
191+
if verbose
192+
gi_incompatible_rows = gi[findall(!iszero, A_gi_columnj)]
193+
@warn """
194+
For coefficient (i=$i, j=$j) with colors (ci=$ci, cj=$cj):
195+
- In row color ci=$ci, rows $gi_incompatible_rows all have nonzeros in column j=$j.
196+
- Column color cj=$cj is neutral.
197+
"""
198+
end
199+
return false
200+
end
201+
else
159202
gi, gj = row_group[ci], column_group[cj]
160203
A_gj_rowi = view(A, i, gj)
161204
A_gi_columnj = view(A, gi, j)
@@ -166,7 +209,7 @@ function structurally_biorthogonal(
166209
gj_incompatible_columns = gj[findall(!iszero, A_gj_rowi)]
167210
gi_incompatible_rows = gi[findall(!iszero, A_gi_columnj)]
168211
@warn """
169-
For coefficient (i=$i, j=$j) with row color ci=$ci and column color cj=$cj:
212+
For coefficient (i=$i, j=$j) with colors (ci=$ci, cj=$cj):
170213
- In row color ci=$ci, rows $gi_incompatible_rows all have nonzeros in column j=$j.
171214
- In column color cj=$cj, columns $gj_incompatible_columns all have nonzeros in row i=$i.
172215
"""
@@ -199,12 +242,16 @@ function directly_recoverable_columns(
199242
return false
200243
end
201244
group = group_by_color(color)
202-
B = stack(group; dims=2) do g
203-
dropdims(sum(A[:, g]; dims=2); dims=2)
245+
B = if isempty(group)
246+
similar(A, size(A, 1), 0)
247+
else
248+
stack(group; dims=2) do g
249+
dropdims(sum(A[:, g]; dims=2); dims=2)
250+
end
204251
end
205252
A_unique = Set(unique(A))
206253
B_unique = Set(unique(B))
207-
if !issubset(A_unique, B_unique)
254+
if !issubset(A_unique, push!(B_unique, zero(eltype(B))))
208255
if verbose
209256
@warn "Coefficients $(sort(collect(setdiff(A_unique, B_unique)))) are not directly recoverable."
210257
return false

0 commit comments

Comments
 (0)