@@ -22,7 +22,8 @@ using SparseMatrixColorings:
2222 sparsity_pattern,
2323 column_colors,
2424 row_colors,
25- ncolors
25+ ncolors,
26+ compress
2627using Colors: Colorant, RGB, RGBA, distinguishable_colors
2728
2829const DEFAULT_BACKGROUND = RGBA (0 , 0 , 0 , 0 )
@@ -53,8 +54,8 @@ function SparseMatrixColorings.show_colors(
5354 else
5455 colorscheme = default_colorscheme (ncolors (res), convert (RGB, background))
5556 end
56- out = allocate_output (res, background, scale, pad)
57- return show_colors! (out , res, colorscheme, scale, pad)
57+ outs = allocate_outputs (res, background, scale, pad)
58+ return show_colors! (outs ... , res, colorscheme, scale, pad)
5859end
5960
6061function promote_colors (colorscheme, background)
@@ -65,15 +66,41 @@ function promote_colors(colorscheme, background)
6566 return colorscheme, background
6667end
6768
68- function allocate_output (
69- res:: AbstractColoringResult , background:: Colorant , scale:: Int , pad:: Int
70- )
69+ function allocate_outputs (
70+ res:: Union{AbstractColoringResult{s,:column},AbstractColoringResult{s,:row}} ,
71+ background:: Colorant ,
72+ scale:: Int ,
73+ pad:: Int ,
74+ ) where {s}
75+ A = sparsity_pattern (res)
76+ B = compress (A, res)
77+ Base. require_one_based_indexing (A)
78+ Base. require_one_based_indexing (B)
79+ hA, wA = size (A) .* (scale + pad) .+ pad
80+ hB, wB = size (B) .* (scale + pad) .+ pad
81+ A_img = fill (background, hA, wA)
82+ B_img = fill (background, hB, wB)
83+ return A_img, B_img
84+ end
85+
86+ function allocate_outputs (
87+ res:: AbstractColoringResult{s,:bidirectional} ,
88+ background:: Colorant ,
89+ scale:: Int ,
90+ pad:: Int ,
91+ ) where {s}
7192 A = sparsity_pattern (res)
93+ Br, Bc = compress (A, res)
7294 Base. require_one_based_indexing (A)
73- hi, wi = size (A)
74- h = hi * (scale + pad) + pad
75- w = wi * (scale + pad) + pad
76- return fill (background, h, w)
95+ Base. require_one_based_indexing (Br)
96+ Base. require_one_based_indexing (Bc)
97+ hA, wA = size (A) .* (scale + pad) .+ pad
98+ hBr, wBr = size (Br) .* (scale + pad) .+ pad
99+ hBc, wBc = size (Bc) .* (scale + pad) .+ pad
100+ A_img = fill (background, hA, wA)
101+ Br_img = fill (background, hBr, wBr)
102+ Bc_img = fill (background, hBc, wBc)
103+ return A_img, Br_img, Bc_img
77104end
78105
79106# Given a CartesianIndex I of an entry in the original matrix,
@@ -86,61 +113,120 @@ end
86113# # Implementations for different AbstractColoringResult types start here
87114
88115function show_colors! (
89- out, res:: AbstractColoringResult{s,:column} , colorscheme, scale, pad
116+ A_img:: AbstractMatrix{<:Colorant} ,
117+ B_img:: AbstractMatrix{<:Colorant} ,
118+ res:: AbstractColoringResult{s,:column} ,
119+ colorscheme,
120+ scale,
121+ pad,
90122) where {s}
91- color_indices = mod1 .(column_colors (res), length (colorscheme)) # cycle color indices if necessary
92- colors = colorscheme[color_indices]
93- pattern = sparsity_pattern (res)
94- for I in CartesianIndices (pattern)
95- if ! iszero (pattern[I])
123+ # cycle color indices if necessary
124+ A_color_indices = mod1 .(column_colors (res), length (colorscheme))
125+ B_color_indices = mod1 .(1 : ncolors (res), length (colorscheme))
126+ A_colors = colorscheme[A_color_indices]
127+ B_colors = colorscheme[B_color_indices]
128+ A = sparsity_pattern (res)
129+ B = compress (A, res)
130+ for I in CartesianIndices (A)
131+ if ! iszero (A[I])
132+ r, c = Tuple (I)
133+ area = matrix_entry_area (I, scale, pad)
134+ A_img[area] .= A_colors[c]
135+ end
136+ end
137+ for I in CartesianIndices (B)
138+ if ! iszero (B[I])
96139 r, c = Tuple (I)
97140 area = matrix_entry_area (I, scale, pad)
98- out [area] .= colors [c]
141+ B_img [area] .= B_colors [c]
99142 end
100143 end
101- return out
144+ return A_img, B_img
102145end
103146
104147function show_colors! (
105- out, res:: AbstractColoringResult{s,:row} , colorscheme, scale, pad
148+ A_img:: AbstractMatrix{<:Colorant} ,
149+ B_img:: AbstractMatrix{<:Colorant} ,
150+ res:: AbstractColoringResult{s,:row} ,
151+ colorscheme,
152+ scale,
153+ pad,
106154) where {s}
107- color_indices = mod1 .(row_colors (res), length (colorscheme)) # cycle color indices if necessary
108- colors = colorscheme[color_indices]
109- pattern = sparsity_pattern (res)
110- for I in CartesianIndices (pattern)
111- if ! iszero (pattern[I])
155+ # cycle color indices if necessary
156+ A_color_indices = mod1 .(row_colors (res), length (colorscheme))
157+ B_color_indices = mod1 .(1 : ncolors (res), length (colorscheme))
158+ A_colors = colorscheme[A_color_indices]
159+ B_colors = colorscheme[B_color_indices]
160+ A = sparsity_pattern (res)
161+ B = compress (A, res)
162+ for I in CartesianIndices (A)
163+ if ! iszero (A[I])
112164 r, c = Tuple (I)
113165 area = matrix_entry_area (I, scale, pad)
114- out [area] .= colors [r]
166+ A_img [area] .= A_colors [r]
115167 end
116168 end
117- return out
169+ for I in CartesianIndices (B)
170+ if ! iszero (B[I])
171+ r, c = Tuple (I)
172+ area = matrix_entry_area (I, scale, pad)
173+ B_img[area] .= B_colors[r]
174+ end
175+ end
176+ return A_img, B_img
118177end
119178
120179function show_colors! (
121- out, res:: AbstractColoringResult{s,:bidirectional} , colorscheme, scale, pad
180+ A_img:: AbstractMatrix{<:Colorant} ,
181+ Br_img:: AbstractMatrix{<:Colorant} ,
182+ Bc_img:: AbstractMatrix{<:Colorant} ,
183+ res:: AbstractColoringResult{s,:bidirectional} ,
184+ colorscheme,
185+ scale,
186+ pad,
122187) where {s}
123188 scale < 3 && throw (ArgumentError (" `scale` has to be ≥ 3 to visualize bicoloring" ))
124- ccolor_indices = mod1 .( column_colors (res), length (colorscheme)) # cycle color indices if necessary
189+ # cycle color indices if necessary
125190 row_shift = maximum (column_colors (res))
126- rcolor_indices = mod1 .(row_shift .+ row_colors (res), length (colorscheme)) # cycle color indices if necessary
127- ccolors = colorscheme[ccolor_indices]
128- rcolors = colorscheme[rcolor_indices]
129- pattern = sparsity_pattern (res)
130- for I in CartesianIndices (pattern)
131- if ! iszero (pattern[I])
191+ A_ccolor_indices = mod1 .(column_colors (res), length (colorscheme))
192+ A_rcolor_indices = mod1 .(row_shift .+ row_colors (res), length (colorscheme))
193+ B_ccolor_indices = mod1 .(1 : maximum (column_colors (res)), length (colorscheme))
194+ B_rcolor_indices =
195+ mod1 .((row_shift + 1 ): (row_shift + maximum (row_colors (res))), length (colorscheme))
196+ A_ccolors = colorscheme[A_ccolor_indices]
197+ A_rcolors = colorscheme[A_rcolor_indices]
198+ B_ccolors = colorscheme[B_ccolor_indices]
199+ B_rcolors = colorscheme[B_rcolor_indices]
200+ A = sparsity_pattern (res)
201+ Br, Bc = compress (A, res)
202+ for I in CartesianIndices (A)
203+ if ! iszero (A[I])
132204 r, c = Tuple (I)
133205 area = matrix_entry_area (I, scale, pad)
134206 for i in axes (area, 1 ), j in axes (area, 2 )
135207 if j > i
136- out [area[i, j]] = ccolors [c]
208+ A_img [area[i, j]] = A_ccolors [c]
137209 elseif i > j
138- out [area[i, j]] = rcolors [r]
210+ A_img [area[i, j]] = A_rcolors [r]
139211 end
140212 end
141213 end
142214 end
143- return out
215+ for I in CartesianIndices (Br)
216+ if ! iszero (Br[I])
217+ r, c = Tuple (I)
218+ area = matrix_entry_area (I, scale, pad)
219+ Br_img[area] .= B_rcolors[r]
220+ end
221+ end
222+ for I in CartesianIndices (Bc)
223+ if ! iszero (Bc[I])
224+ r, c = Tuple (I)
225+ area = matrix_entry_area (I, scale, pad)
226+ Bc_img[area] .= B_ccolors[c]
227+ end
228+ end
229+ return A_img, Br_img, Bc_img
144230end
145231
146232end # module
0 commit comments