Skip to content

Commit 08a29bf

Browse files
committed
Compute the number of self-loops
1 parent cba4d7b commit 08a29bf

3 files changed

Lines changed: 24 additions & 31 deletions

File tree

src/graph.jl

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ function build_edge_to_index(S::SparsityPatternCSC{T}) where {T}
179179
# edge_to_index gives an index for each edge
180180
edge_to_index = Vector{T}(undef, nnz(S))
181181
offsets = zeros(T, S.n)
182+
nb_self_loops = 0
182183
counter = 0
183184
rvS = rowvals(S)
184185
for j in axes(S, 2)
@@ -193,10 +194,11 @@ function build_edge_to_index(S::SparsityPatternCSC{T}) where {T}
193194
elseif i == j
194195
# this should never be used, make sure it errors
195196
edge_to_index[k] = 0
197+
nb_self_loops += 1
196198
end
197199
end
198200
end
199-
return edge_to_index
201+
return edge_to_index, nb_self_loops
200202
end
201203

202204
## Adjacency graph
@@ -227,16 +229,23 @@ The adjacency graph of a symmetric matrix `A ∈ ℝ^{n × n}` is `G(A) = (V, E)
227229
struct AdjacencyGraph{T<:Integer,augmented_graph}
228230
S::SparsityPatternCSC{T}
229231
edge_to_index::Vector{T}
232+
nb_self_loops::Int
230233
end
231234

232235
Base.eltype(::AdjacencyGraph{T}) where {T} = T
233236

234237
function AdjacencyGraph(
235238
S::SparsityPatternCSC{T},
236-
edge_to_index::Vector{T}=build_edge_to_index(S);
239+
edge_to_index::Vector{T},
240+
nb_self_loops::Int;
237241
augmented_graph::Bool=false,
238242
) where {T}
239-
return AdjacencyGraph{T,augmented_graph}(S, edge_to_index)
243+
return AdjacencyGraph{T,augmented_graph}(S, edge_to_index, nb_self_loops)
244+
end
245+
246+
function AdjacencyGraph(S::SparsityPatternCSC; augmented_graph::Bool=false)
247+
edge_to_index, nb_self_loops = build_edge_to_index(S)
248+
return AdjacencyGraph(S, edge_to_index, nb_self_loops; augmented_graph)
240249
end
241250

242251
function AdjacencyGraph(A::SparseMatrixCSC; augmented_graph::Bool=false)

src/interface.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ function _coloring(
323323
forced_colors::Union{AbstractVector{<:Integer},Nothing}=nothing,
324324
) where {R}
325325
A_and_Aᵀ, edge_to_index = bidirectional_pattern(A; symmetric_pattern)
326-
ag = AdjacencyGraph(A_and_Aᵀ, edge_to_index; augmented_graph=true)
326+
ag = AdjacencyGraph(A_and_Aᵀ, edge_to_index, 0; augmented_graph=true)
327327
outputs_by_order = map(algo.orders) do order
328328
vertices_in_order = vertices(ag, order)
329329
_color, _star_set = star_coloring(
@@ -372,7 +372,7 @@ function _coloring(
372372
symmetric_pattern::Bool,
373373
) where {R}
374374
A_and_Aᵀ, edge_to_index = bidirectional_pattern(A; symmetric_pattern)
375-
ag = AdjacencyGraph(A_and_Aᵀ, edge_to_index; augmented_graph=true)
375+
ag = AdjacencyGraph(A_and_Aᵀ, edge_to_index, 0; augmented_graph=true)
376376
outputs_by_order = map(algo.orders) do order
377377
vertices_in_order = vertices(ag, order)
378378
_color, _tree_set = acyclic_coloring(ag, vertices_in_order, algo.postprocessing)

src/result.jl

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -334,16 +334,15 @@ function star_csc_indices(
334334
decompression_uplo::Symbol,
335335
) where {T}
336336
(; star, hub) = star_set
337-
S = pattern(ag)
338-
edge_to_index = edge_indices(ag)
337+
(; S, edge_to_index, nb_self_loops) = ag
339338
n = S.n
340339
rvS = rowvals(S)
341-
l = 0
342-
if augmented_graph(ag) && (decompression_uplo != :F)
343-
compressed_indices = zeros(T, nnz(S) ÷ 2)
344-
else
345-
compressed_indices = zeros(T, nnz(S)) # needs to be independent from the storage in the graph, in case the graph gets reused
340+
nb_indices = nnz(S)
341+
if decompression_uplo != :F
342+
nb_indices = (nb_indices - nb_self_loops) ÷ 2 + nb_self_loops
346343
end
344+
compressed_indices = zeros(T, nb_indices) # needs to be independent from the storage in the graph, in case the graph gets reused
345+
l = 0
347346
for j in axes(S, 2)
348347
for k in nzrange(S, j)
349348
i = rvS[k]
@@ -374,9 +373,6 @@ function star_csc_indices(
374373
end
375374
end
376375
end
377-
if !augmented_graph(ag) && (decompression_uplo != :F)
378-
resize!(compressed_indices, l)
379-
end
380376
return compressed_indices
381377
end
382378

@@ -422,26 +418,14 @@ function TreeSetColoringResult(
422418
decompression_uplo::Symbol=:F,
423419
) where {T<:Integer,R}
424420
(; reverse_bfs_orders, tree_edge_indices, nt) = tree_set
425-
(; S) = ag
421+
(; S, nb_self_loops) = ag
426422
nvertices = length(color)
427423
group = group_by_color(T, color)
428424
rv = rowvals(S)
429425

430-
ndiag = 0
431-
if !augmented_graph(ag)
432-
for j in axes(S, 2)
433-
for k in nzrange(S, j)
434-
i = rv[k]
435-
if i == j
436-
ndiag += 1
437-
end
438-
end
439-
end
440-
end
441-
442426
# Vector for the decompression of the diagonal coefficients
443-
diagonal_indices = Vector{T}(undef, ndiag)
444-
diagonal_nzind = (decompression_uplo == :F) ? Vector{T}(undef, ndiag) : T[]
427+
diagonal_indices = Vector{T}(undef, nb_self_loops)
428+
diagonal_nzind = (decompression_uplo == :F) ? Vector{T}(undef, nb_self_loops) : T[]
445429

446430
if !augmented_graph(ag)
447431
l = 0
@@ -460,7 +444,7 @@ function TreeSetColoringResult(
460444
end
461445

462446
# Vectors for the decompression of the off-diagonal coefficients
463-
nedges = (nnz(S) - ndiag) ÷ 2
447+
nedges = (nnz(S) - nb_self_loops) ÷ 2
464448
lower_triangle_offsets = decompression_uplo == :U ? T[] : Vector{T}(undef, nedges)
465449
upper_triangle_offsets = decompression_uplo == :L ? T[] : Vector{T}(undef, nedges)
466450

0 commit comments

Comments
 (0)