Skip to content

Commit 3711558

Browse files
amontoisongdalle
andauthored
Update decompression_single_color! for star coloring (#217)
* Update decompression_single_color! for star coloring * Remove the vector spokes * Update src/decompression.jl --------- Co-authored-by: Guillaume Dalle <22795598+gdalle@users.noreply.github.com>
1 parent 8b18bfd commit 3711558

2 files changed

Lines changed: 34 additions & 65 deletions

File tree

src/coloring.jl

Lines changed: 13 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ function star_coloring(g::AdjacencyGraph, order::AbstractOrder, postprocessing::
8787
star = Dict{Tuple{Int,Int},Int}()
8888
sizehint!(star, ne)
8989
hub = Int[] # one hub for each star, including the trivial ones
90-
nb_spokes = Int[] # number of spokes for each star
9190
vertices_in_order = vertices(g, order)
9291

9392
for v in vertices_in_order
@@ -119,9 +118,9 @@ function star_coloring(g::AdjacencyGraph, order::AbstractOrder, postprocessing::
119118
break
120119
end
121120
end
122-
_update_stars!(star, hub, nb_spokes, g, v, color, first_neighbor)
121+
_update_stars!(star, hub, g, v, color, first_neighbor)
123122
end
124-
star_set = StarSet(star, hub, nb_spokes)
123+
star_set = StarSet(star, hub)
125124
if postprocessing
126125
# Reuse the vector forbidden_colors to compute offsets during post-processing
127126
postprocess!(color, star_set, g, forbidden_colors)
@@ -143,30 +142,6 @@ struct StarSet
143142
star::Dict{Tuple{Int,Int},Int}
144143
"a mapping from star indices to their hub (undefined hubs for single-edge stars are the negative value of one of the vertices, picked arbitrarily)"
145144
hub::Vector{Int}
146-
"a mapping from star indices to the vector of their spokes"
147-
spokes::Vector{Vector{Int}}
148-
end
149-
150-
function StarSet(star::Dict{Tuple{Int,Int},Int}, hub::Vector{Int}, nb_spokes::Vector{Int})
151-
# Create a list of spokes for each star, preallocating their sizes based on nb_spokes
152-
spokes = [Vector{Int}(undef, ns) for ns in nb_spokes]
153-
154-
# Reuse nb_spokes as counters to track the current index while filling the spokes
155-
fill!(nb_spokes, 0)
156-
157-
for ((i, j), s) in pairs(star)
158-
h = abs(hub[s])
159-
nb_spokes[s] += 1
160-
index = nb_spokes[s]
161-
162-
# Assign the non-hub vertex (spoke) to the correct position in spokes
163-
if i == h
164-
spokes[s][index] = j
165-
elseif j == h
166-
spokes[s][index] = i
167-
end
168-
end
169-
return StarSet(star, hub, spokes)
170145
end
171146

172147
_sort(u, v) = (min(u, v), max(u, v))
@@ -193,7 +168,6 @@ function _update_stars!(
193168
# modified
194169
star::Dict{<:Tuple,<:Integer},
195170
hub::AbstractVector{<:Integer},
196-
nb_spokes::AbstractVector{<:Integer},
197171
# not modified
198172
g::AdjacencyGraph,
199173
v::Integer,
@@ -209,7 +183,6 @@ function _update_stars!(
209183
wx = _sort(w, x)
210184
star_wx = star[wx]
211185
hub[star_wx] = w # this may already be true
212-
nb_spokes[star_wx] += 1
213186
star[vw] = star_wx
214187
x_exists = true
215188
break
@@ -221,11 +194,9 @@ function _update_stars!(
221194
vq = _sort(v, q)
222195
star_vq = star[vq]
223196
hub[star_vq] = v # this may already be true
224-
nb_spokes[star_vq] += 1
225197
star[vw] = star_vq
226198
else # vw forms a new star
227199
push!(hub, -max(v, w)) # star is trivial (composed only of two vertices) so we set the hub to a negative value, but it allows us to choose one of the two vertices
228-
push!(nb_spokes, 1)
229200
star[vw] = length(hub)
230201
end
231202
end
@@ -586,7 +557,7 @@ function postprocess!(
586557

587558
if star_or_tree_set isa StarSet
588559
# only the colors of the hubs are used
589-
(; hub, spokes) = star_or_tree_set
560+
(; star, hub) = star_or_tree_set
590561
nb_trivial_stars = 0
591562

592563
# Iterate through all non-trivial stars
@@ -601,19 +572,17 @@ function postprocess!(
601572

602573
# Process the trivial stars (if any)
603574
if nb_trivial_stars > 0
604-
for s in eachindex(hub)
605-
j = hub[s]
606-
if j < 0
607-
i = spokes[s][1]
608-
j = abs(j)
609-
if color_used[color[i]]
610-
# Make i the hub to avoid possibly adding one more used color
611-
# Switch it with the (only) spoke
612-
hub[s] = i
613-
spokes[s][1] = j
575+
for ((i, j), s) in pairs(star)
576+
h = hub[s]
577+
if h < 0
578+
h = abs(h)
579+
spoke = i == h ? j : i
580+
if color_used[color[spoke]]
581+
# Switch the hub and the spoke to possibly avoid adding one more used color
582+
hub[s] = spoke
614583
else
615-
# Keep j as the hub
616-
color_used[color[j]] = true
584+
# Keep the current hub
585+
color_used[color[h]] = true
617586
end
618587
end
619588
end

src/decompression.jl

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -455,30 +455,30 @@ function decompress_single_color!(
455455
result::StarSetColoringResult,
456456
uplo::Symbol=:F,
457457
)
458-
(; ag, color, group, star_set) = result
459-
(; hub, spokes) = star_set
458+
(; ag, compressed_indices, group) = result
460459
(; S) = ag
461460
uplo == :F && check_same_pattern(A, S)
462461

463-
# Recover the diagonal coefficients of A
464-
if has_diagonal(ag)
465-
for i in group[c]
466-
if !iszero(S[i, i])
467-
A[i, i] = b[i]
468-
end
469-
end
470-
end
471-
472-
# Recover the off-diagonal coefficients of A
473-
for s in eachindex(hub, spokes)
474-
j = abs(hub[s])
475-
if color[j] == c
476-
for i in spokes[s]
477-
if in_triangle(i, j, uplo)
478-
A[i, j] = b[i]
479-
end
480-
if in_triangle(j, i, uplo)
481-
A[j, i] = b[i]
462+
offset = (c - 1) * S.n
463+
lower_index = offset + 1
464+
upper_index = c * S.n
465+
rvS = rowvals(S)
466+
for j in group[c]
467+
for k in nzrange(S, j)
468+
if lower_index <= compressed_indices[k] <= upper_index
469+
l = compressed_indices[k] - offset
470+
i = rvS[k]
471+
if i == j
472+
# Recover the diagonal coefficients of A
473+
A[i, i] = b[l]
474+
else
475+
# Recover the off-diagonal coefficients of A
476+
if in_triangle(i, j, uplo)
477+
A[i, j] = b[l]
478+
end
479+
if in_triangle(j, i, uplo)
480+
A[j, i] = b[l]
481+
end
482482
end
483483
end
484484
end

0 commit comments

Comments
 (0)