You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Create a list of spokes for each star, preallocating their sizes based on nb_spokes
152
155
spokes = [Vector{Int}(undef, ns) for ns in nb_spokes]
153
156
154
157
# Reuse nb_spokes as counters to track the current index while filling the spokes
155
158
fill!(nb_spokes, 0)
156
159
157
-
for ((i, j), s) inpairs(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
160
+
rvS =rowvals(S)
161
+
for j inaxes(S, 2)
162
+
for k innzrange(S, j)
163
+
i = rvS[k]
164
+
i >= j &&continue
165
+
e = edgeindex[k]
166
+
s = star[e]
167
+
h =abs(hub[s])
168
+
nb_spokes[s] +=1
169
+
index = nb_spokes[s]
170
+
171
+
# Assign the non-hub vertex (spoke) to the correct position in spokes
172
+
if i == h
173
+
spokes[s][index] = j
174
+
elseif j == h
175
+
spokes[s][index] = i
176
+
end
167
177
end
168
178
end
169
179
returnStarSet(star, hub, spokes)
@@ -182,6 +192,7 @@ function _treat!(
182
192
color::AbstractVector{<:Integer},
183
193
)
184
194
for x inneighbors(g, w)
195
+
x == w &&continue
185
196
iszero(color[x]) &&continue
186
197
forbidden_colors[color[x]] = v
187
198
end
@@ -191,7 +202,7 @@ end
191
202
192
203
function_update_stars!(
193
204
# modified
194
-
star::Dict{<:Tuple,<:Integer},
205
+
star::Vector{Int},
195
206
hub::AbstractVector{<:Integer},
196
207
nb_spokes::AbstractVector{<:Integer},
197
208
# not modified
@@ -200,33 +211,32 @@ function _update_stars!(
200
211
color::AbstractVector{<:Integer},
201
212
first_neighbor::AbstractVector{<:Tuple},
202
213
)
203
-
for w inneighbors(g, v)
214
+
for (w, e_vw) inneighbors_and_edgeinds(g, v)
215
+
w == v &&continue
204
216
iszero(color[w]) &&continue
205
-
vw =_sort(v, w)
206
217
x_exists =false
207
-
for x inneighbors(g, w)
218
+
for (x, e_wx) inneighbors_and_edgeinds(g, w)
219
+
x == w &&continue
208
220
if x != v && color[x] == color[v] # vw, wx ∈ E
209
-
wx =_sort(w, x)
210
-
star_wx = star[wx]
221
+
star_wx = star[e_wx]
211
222
hub[star_wx] = w # this may already be true
212
223
nb_spokes[star_wx] +=1
213
-
star[vw] = star_wx
224
+
star[e_vw] = star_wx
214
225
x_exists =true
215
226
break
216
227
end
217
228
end
218
229
if!x_exists
219
-
(p, q) = first_neighbor[color[w]]
230
+
(p, q, e_pq) = first_neighbor[color[w]]
220
231
if p == v && q != w # vw, vq ∈ E and color[w] = color[q]
221
-
vq =_sort(v, q)
222
-
star_vq = star[vq]
232
+
star_vq = star[e_pq]
223
233
hub[star_vq] = v # this may already be true
224
234
nb_spokes[star_vq] +=1
225
-
star[vw] = star_vq
235
+
star[e_vw] = star_vq
226
236
else# vw forms a new star
227
237
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
238
push!(nb_spokes, 1)
229
-
star[vw] =length(hub)
239
+
star[e_vw] =length(hub)
230
240
end
231
241
end
232
242
end
@@ -249,7 +259,7 @@ This function corresponds to algorithm `DirectRecover2` in the paper.
249
259
> [_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), Figure 3
Copy file name to clipboardExpand all lines: src/graph.jl
+36-5Lines changed: 36 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -182,17 +182,44 @@ The adjacency graph of a symmetric matrix `A ∈ ℝ^{n × n}` is `G(A) = (V, E)
182
182
# Fields
183
183
184
184
- `S::SparsityPatternCSC{T}`: Underlying sparsity pattern, whose diagonal is empty whenever `has_diagonal` is `false`
185
+
- `edgeindex::Vector{T}`: a vector mapping each nonzero of `S` to a unique edge index (ignoring diagonal and accounting for symmetry, so that `(i, j)` and `(j, i)` get the same index)
185
186
186
187
# References
187
188
188
189
> [_What Color Is Your Jacobian? SparsityPatternCSC Coloring for Computing Derivatives_](https://epubs.siam.org/doi/10.1137/S0036144504444711), Gebremedhin et al. (2005)
189
190
"""
190
191
struct AdjacencyGraph{T,has_diagonal}
191
192
S::SparsityPatternCSC{T}
193
+
edgeindex::Vector{T}
194
+
end
195
+
196
+
functionbuild_edgeindex(S::SparsityPatternCSC{T}) where {T}
197
+
offsets =zeros(T, size(S, 1))
198
+
edgeindex =Vector{T}(undef, nnz(S))
199
+
counter =zero(T)
200
+
rvS =rowvals(S)
201
+
for j inaxes(S, 2)
202
+
for k innzrange(S, j)
203
+
i = rvS[k]
204
+
if i > j
205
+
counter +=1
206
+
# index lower triangle
207
+
edgeindex[k] = counter
208
+
# index upper triangle
209
+
k2 = S.colptr[i] + offsets[i]
210
+
edgeindex[k2] = counter
211
+
offsets[i] +=1
212
+
elseif i == j
213
+
# this should never be used, make sure it errors
214
+
edgeindex[k] =-1
215
+
end
216
+
end
217
+
end
218
+
return edgeindex
192
219
end
193
220
194
221
functionAdjacencyGraph(S::SparsityPatternCSC{T}; has_diagonal::Bool=true) where {T}
0 commit comments