Skip to content

Commit 83a1330

Browse files
authored
Factor out symmetric_coefficient (#29)
* Factor out symmetric_coefficient * Fix docstrings, bump version * Make public
1 parent 8567b7f commit 83a1330

File tree

4 files changed

+78
-35
lines changed

4 files changed

+78
-35
lines changed

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 <22795598+gdalle@users.noreply.github.com>"]
4-
version = "0.3.4"
4+
version = "0.3.5"
55

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

docs/src/api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ decompress_rows
3737
decompress_rows!
3838
decompress_symmetric
3939
decompress_symmetric!
40+
symmetric_coefficient
4041
StarSet
4142
```
4243

src/SparseMatrixColorings.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ include("check.jl")
4646
@compat public decompress_columns, decompress_columns!
4747
@compat public decompress_rows, decompress_rows!
4848
@compat public decompress_symmetric, decompress_symmetric!
49-
@compat public StarSet
49+
@compat public symmetric_coefficient, StarSet
5050

5151
export GreedyColoringAlgorithm
5252
export column_coloring, row_coloring, symmetric_coloring, symmetric_coloring_detailed

src/decompression.jl

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ end
8686
8787
Decompress the small matrix `B` into the tall matrix `A` which must have the same sparsity pattern as `S`.
8888
89-
Here, `color` is a row coloring of `S`, while `B` is a compressed representation of matrix `A` obtained by summing the columns that share the same color.
89+
Here, `color` is a row coloring of `S`, while `B` is a compressed representation of matrix `A` obtained by summing the rows that share the same color.
9090
"""
9191
function decompress_rows! end
9292

@@ -142,7 +142,7 @@ end
142142
143143
Decompress the small matrix `B` into a new tall matrix `A` with the same sparsity pattern as `S`.
144144
145-
Here, `color` is a row coloring of `S`, while `B` is a compressed representation of matrix `A` obtained by summing the columns that share the same color.
145+
Here, `color` is a row coloring of `S`, while `B` is a compressed representation of matrix `A` obtained by summing the rows that share the same color.
146146
"""
147147
function decompress_rows(
148148
S::AbstractMatrix{Bool}, B::AbstractMatrix{R}, color::AbstractVector{<:Integer}
@@ -153,6 +153,73 @@ end
153153

154154
## Symmetric decompression
155155

156+
"""
157+
symmetric_coefficient(
158+
i::Integer, j::Integer,
159+
color::AbstractVector{<:Integer},
160+
group::AbstractVector{<:AbstractVector{<:Integer}},
161+
S::AbstractMatrix{Bool}
162+
)
163+
164+
symmetric_coefficient(
165+
i::Integer, j::Integer,
166+
color::AbstractVector{<:Integer},
167+
star_set::StarSet
168+
)
169+
170+
Return the indices `(k, c)` such that `A[i, j] = B[k, c]`, where `A` is the uncompressed symmetric matrix and `B` is the column-compressed matrix.
171+
172+
The first version corresponds to algorithm `DirectRecover1` in the paper, the second to `DirectRecover2`.
173+
174+
# References
175+
176+
> [_Efficient Computation of Sparse Hessians Using Coloring and Automatic Differentiation_](https://pubsonline.informs.org/doi/abs/10.1287/ijoc.1080.0286), Gebremedhin et al. (2009), Figures 2 and 3
177+
"""
178+
function symmetric_coefficient end
179+
180+
function symmetric_coefficient(
181+
i::Integer,
182+
j::Integer,
183+
color::AbstractVector{<:Integer},
184+
group::AbstractVector{<:AbstractVector{<:Integer}},
185+
S::AbstractMatrix{Bool},
186+
)
187+
for j2 in group[color[j]]
188+
j2 == j && continue
189+
if !iszero(S[i, j2])
190+
return j, color[i]
191+
end
192+
end
193+
return i, color[j]
194+
end
195+
196+
function symmetric_coefficient(
197+
i::Integer, j::Integer, color::AbstractVector{<:Integer}, star_set::StarSet
198+
)
199+
@compat (; star, hub) = star_set
200+
if i == j
201+
# diagonal
202+
return i, color[j]
203+
end
204+
if !haskey(star, (i, j)) # could be optimized
205+
# star only contains one triangle
206+
i, j = j, i
207+
end
208+
star_id = star[i, j]
209+
h = hub[star_id]
210+
if h == 0
211+
# pick arbitrary hub
212+
h = i
213+
end
214+
if h == j
215+
# i is the spoke
216+
return i, color[h]
217+
elseif h == i
218+
# j is the spoke
219+
return j, color[h]
220+
end
221+
end
222+
156223
"""
157224
decompress_symmetric!(
158225
A::AbstractMatrix{R},
@@ -188,18 +255,8 @@ function decompress_symmetric!(
188255
group = color_groups(color)
189256
for ij in findall(!iszero, S)
190257
i, j = Tuple(ij)
191-
j2_exists = false
192-
for j2 in group[color[j]]
193-
j2 == j && continue
194-
if !iszero(S[i, j2])
195-
A[i, j] = A[j, i] = B[j, color[i]]
196-
j2_exists = true
197-
break
198-
end
199-
end
200-
if !j2_exists
201-
A[i, j] = A[j, i] = B[i, color[j]]
202-
end
258+
k, l = symmetric_coefficient(i, j, color, group, S)
259+
A[i, j] = B[k, l]
203260
end
204261
return A
205262
end
@@ -217,25 +274,10 @@ function decompress_symmetric!(
217274
throw(DimensionMismatch("`A` and `S` must have the same sparsity pattern."))
218275
end
219276
A .= zero(R)
220-
for i in axes(A, 1)
221-
if !iszero(S[i, i])
222-
A[i, i] = B[i, color[i]]
223-
end
224-
end
225-
for ((i, j), star_id) in pairs(star)
226-
i == j && continue
227-
h = hub[star_id]
228-
if h == 0
229-
# pick arbitrary hub
230-
h = i
231-
end
232-
if h == j
233-
# i is the spoke
234-
A[i, j] = A[j, i] = B[i, color[h]]
235-
elseif h == i
236-
# j is the spoke
237-
A[i, j] = A[j, i] = B[j, color[h]]
238-
end
277+
for ij in findall(!iszero, S)
278+
i, j = Tuple(ij)
279+
k, l = symmetric_coefficient(i, j, color, star_set)
280+
A[i, j] = B[k, l]
239281
end
240282
return A
241283
end

0 commit comments

Comments
 (0)