Skip to content

Commit 33a1ef1

Browse files
authored
Add a file postprocessing.jl (#275)
1 parent 17bc044 commit 33a1ef1

File tree

3 files changed

+147
-147
lines changed

3 files changed

+147
-147
lines changed

src/SparseMatrixColorings.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ include("graph.jl")
4747
include("forest.jl")
4848
include("order.jl")
4949
include("coloring.jl")
50+
include("postprocessing.jl")
5051
include("result.jl")
5152
include("matrices.jl")
5253
include("interface.jl")

src/coloring.jl

Lines changed: 0 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -643,150 +643,3 @@ function TreeSet(
643643

644644
return TreeSet(reverse_bfs_orders, is_star, tree_edge_indices, nt)
645645
end
646-
647-
## Postprocessing, mirrors decompression code
648-
649-
function postprocess!(
650-
color::AbstractVector{<:Integer},
651-
star_or_tree_set::Union{StarSet,TreeSet},
652-
g::AdjacencyGraph,
653-
offsets::AbstractVector{<:Integer},
654-
)
655-
S = pattern(g)
656-
edge_to_index = edge_indices(g)
657-
# flag which colors are actually used during decompression
658-
nb_colors = maximum(color)
659-
color_used = zeros(Bool, nb_colors)
660-
661-
# nonzero diagonal coefficients force the use of their respective color (there can be no neutral colors if the diagonal is fully nonzero)
662-
if has_diagonal(g)
663-
for i in axes(S, 1)
664-
if !iszero(S[i, i])
665-
color_used[color[i]] = true
666-
end
667-
end
668-
end
669-
670-
if star_or_tree_set isa StarSet
671-
# only the colors of the hubs are used
672-
(; star, hub) = star_or_tree_set
673-
nb_trivial_stars = 0
674-
675-
# Iterate through all non-trivial stars
676-
for s in eachindex(hub)
677-
h = hub[s]
678-
if h > 0
679-
color_used[color[h]] = true
680-
else
681-
nb_trivial_stars += 1
682-
end
683-
end
684-
685-
# Process the trivial stars (if any)
686-
if nb_trivial_stars > 0
687-
rvS = rowvals(S)
688-
for j in axes(S, 2)
689-
for k in nzrange(S, j)
690-
i = rvS[k]
691-
if i > j
692-
index_ij = edge_to_index[k]
693-
s = star[index_ij]
694-
h = hub[s]
695-
if h < 0
696-
h = abs(h)
697-
spoke = h == j ? i : j
698-
if color_used[color[spoke]]
699-
# Switch the hub and the spoke to possibly avoid adding one more used color
700-
hub[s] = spoke
701-
else
702-
# Keep the current hub
703-
color_used[color[h]] = true
704-
end
705-
end
706-
end
707-
end
708-
end
709-
end
710-
else
711-
# only the colors of non-leaf vertices are used
712-
(; reverse_bfs_orders, is_star, tree_edge_indices, nt) = star_or_tree_set
713-
nb_trivial_trees = 0
714-
715-
# Iterate through all non-trivial trees
716-
for k in 1:nt
717-
# Position of the first edge in the tree
718-
first = tree_edge_indices[k]
719-
720-
# Total number of edges in the tree
721-
ne_tree = tree_edge_indices[k + 1] - first
722-
723-
# Check if we have more than one edge in the tree (non-trivial tree)
724-
if ne_tree > 1
725-
# Determine if the tree is a star
726-
if is_star[k]
727-
# It is a non-trivial star and only the color of the hub is needed
728-
(_, hub) = reverse_bfs_orders[first]
729-
color_used[color[hub]] = true
730-
else
731-
# It is not a star and both colors are needed during the decompression
732-
(i, j) = reverse_bfs_orders[first]
733-
color_used[color[i]] = true
734-
color_used[color[j]] = true
735-
end
736-
else
737-
nb_trivial_trees += 1
738-
end
739-
end
740-
741-
# Process the trivial trees (if any)
742-
if nb_trivial_trees > 0
743-
for k in 1:nt
744-
# Position of the first edge in the tree
745-
first = tree_edge_indices[k]
746-
747-
# Total number of edges in the tree
748-
ne_tree = tree_edge_indices[k + 1] - first
749-
750-
# Check if we have exactly one edge in the tree
751-
if ne_tree == 1
752-
(i, j) = reverse_bfs_orders[first]
753-
if color_used[color[i]]
754-
# Make i the root to avoid possibly adding one more used color
755-
# Switch it with the (only) leaf
756-
reverse_bfs_orders[first] = (j, i)
757-
else
758-
# Keep j as the root
759-
color_used[color[j]] = true
760-
end
761-
end
762-
end
763-
end
764-
end
765-
766-
# if at least one of the colors is useless, modify the color assignments of vertices
767-
if any(!, color_used)
768-
num_colors_useless = 0
769-
770-
# determine what are the useless colors and compute the offsets
771-
for ci in 1:nb_colors
772-
if color_used[ci]
773-
offsets[ci] = num_colors_useless
774-
else
775-
num_colors_useless += 1
776-
end
777-
end
778-
779-
# assign the neutral color to every vertex with a useless color and remap the colors
780-
for i in eachindex(color)
781-
ci = color[i]
782-
if !color_used[ci]
783-
# assign the neutral color
784-
color[i] = 0
785-
else
786-
# remap the color to not have any gap
787-
color[i] -= offsets[ci]
788-
end
789-
end
790-
end
791-
return color
792-
end

src/postprocessing.jl

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
## Postprocessing
2+
3+
function postprocess!(
4+
color::AbstractVector{<:Integer},
5+
star_or_tree_set::Union{StarSet,TreeSet},
6+
g::AdjacencyGraph,
7+
offsets::AbstractVector{<:Integer},
8+
)
9+
S = pattern(g)
10+
edge_to_index = edge_indices(g)
11+
# flag which colors are actually used during decompression
12+
nb_colors = maximum(color)
13+
color_used = zeros(Bool, nb_colors)
14+
15+
# nonzero diagonal coefficients force the use of their respective color (there can be no neutral colors if the diagonal is fully nonzero)
16+
if has_diagonal(g)
17+
for i in axes(S, 1)
18+
if !iszero(S[i, i])
19+
color_used[color[i]] = true
20+
end
21+
end
22+
end
23+
24+
if star_or_tree_set isa StarSet
25+
# only the colors of the hubs are used
26+
(; star, hub) = star_or_tree_set
27+
nb_trivial_stars = 0
28+
29+
# Iterate through all non-trivial stars
30+
for s in eachindex(hub)
31+
h = hub[s]
32+
if h > 0
33+
color_used[color[h]] = true
34+
else
35+
nb_trivial_stars += 1
36+
end
37+
end
38+
39+
# Process the trivial stars (if any)
40+
if nb_trivial_stars > 0
41+
rvS = rowvals(S)
42+
for j in axes(S, 2)
43+
for k in nzrange(S, j)
44+
i = rvS[k]
45+
if i > j
46+
index_ij = edge_to_index[k]
47+
s = star[index_ij]
48+
h = hub[s]
49+
if h < 0
50+
h = abs(h)
51+
spoke = h == j ? i : j
52+
if color_used[color[spoke]]
53+
# Switch the hub and the spoke to possibly avoid adding one more used color
54+
hub[s] = spoke
55+
else
56+
# Keep the current hub
57+
color_used[color[h]] = true
58+
end
59+
end
60+
end
61+
end
62+
end
63+
end
64+
else
65+
# only the colors of non-leaf vertices are used
66+
(; reverse_bfs_orders, is_star, tree_edge_indices, nt) = star_or_tree_set
67+
nb_trivial_trees = 0
68+
69+
# Iterate through all non-trivial trees
70+
for k in 1:nt
71+
# Position of the first edge in the tree
72+
first = tree_edge_indices[k]
73+
74+
# Total number of edges in the tree
75+
ne_tree = tree_edge_indices[k + 1] - first
76+
77+
# Check if we have more than one edge in the tree (non-trivial tree)
78+
if ne_tree > 1
79+
# Determine if the tree is a star
80+
if is_star[k]
81+
# It is a non-trivial star and only the color of the hub is needed
82+
(_, hub) = reverse_bfs_orders[first]
83+
color_used[color[hub]] = true
84+
else
85+
# It is not a star and both colors are needed during the decompression
86+
(i, j) = reverse_bfs_orders[first]
87+
color_used[color[i]] = true
88+
color_used[color[j]] = true
89+
end
90+
else
91+
nb_trivial_trees += 1
92+
end
93+
end
94+
95+
# Process the trivial trees (if any)
96+
if nb_trivial_trees > 0
97+
for k in 1:nt
98+
# Position of the first edge in the tree
99+
first = tree_edge_indices[k]
100+
101+
# Total number of edges in the tree
102+
ne_tree = tree_edge_indices[k + 1] - first
103+
104+
# Check if we have exactly one edge in the tree
105+
if ne_tree == 1
106+
(i, j) = reverse_bfs_orders[first]
107+
if color_used[color[i]]
108+
# Make i the root to avoid possibly adding one more used color
109+
# Switch it with the (only) leaf
110+
reverse_bfs_orders[first] = (j, i)
111+
else
112+
# Keep j as the root
113+
color_used[color[j]] = true
114+
end
115+
end
116+
end
117+
end
118+
end
119+
120+
# if at least one of the colors is useless, modify the color assignments of vertices
121+
if any(!, color_used)
122+
num_colors_useless = 0
123+
124+
# determine what are the useless colors and compute the offsets
125+
for ci in 1:nb_colors
126+
if color_used[ci]
127+
offsets[ci] = num_colors_useless
128+
else
129+
num_colors_useless += 1
130+
end
131+
end
132+
133+
# assign the neutral color to every vertex with a useless color and remap the colors
134+
for i in eachindex(color)
135+
ci = color[i]
136+
if !color_used[ci]
137+
# assign the neutral color
138+
color[i] = 0
139+
else
140+
# remap the color to not have any gap
141+
color[i] -= offsets[ci]
142+
end
143+
end
144+
end
145+
return color
146+
end

0 commit comments

Comments
 (0)