Skip to content

Commit 6d0899b

Browse files
amontoisongdalle
andauthored
Manual graph transposition (#107)
* Add a function transpose_graph * Use the formatter on src/graph.jl * Remove old code * Add unit tests for transpose_graph * No docs --------- Co-authored-by: Guillaume Dalle <22795598+gdalle@users.noreply.github.com>
1 parent 939c9df commit 6d0899b

1 file changed

Lines changed: 46 additions & 3 deletions

File tree

src/graph.jl

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ function Graph{loops}(S::SparseMatrixCSC{Tv,Ti}) where {loops,Tv,Ti}
3030
return Graph{loops,Ti}(S.m, S.n, S.colptr, S.rowval)
3131
end
3232

33+
Base.size(g::Graph) = (g.m, g.n)
3334
SparseArrays.nnz(g::Graph) = length(g.rowval)
3435
SparseArrays.rowvals(g::Graph) = g.rowval
3536
SparseArrays.nzrange(g::Graph, j::Integer) = g.colptr[j]:(g.colptr[j + 1] - 1)
@@ -84,9 +85,51 @@ minimum_degree(g::Graph) = minimum(Base.Fix1(degree, g), vertices(g))
8485
Return a [`Graph`](@ref) corresponding to the transpose of (the underlying matrix of) `g`.
8586
"""
8687
function Base.transpose(g::Graph{loops,T}) where {loops,T}
87-
S = SparseMatrixCSC{T,T}(g.m, g.n, g.colptr, g.rowval, g.rowval)
88-
Sᵀ = convert(SparseMatrixCSC, transpose(S)) # TODO: use ftranspose! without segfault?
89-
return Graph{loops}(Sᵀ)
88+
m, n = size(g)
89+
nnzA = nnz(g)
90+
A_colptr = g.colptr
91+
A_rowval = g.rowval
92+
93+
# Allocate storage for the column pointers and row indices of B = Aᵀ
94+
B_colptr = zeros(T, m + 1)
95+
B_rowval = Vector{T}(undef, nnzA)
96+
97+
# Count the number of non-zeros for each row of A.
98+
# It corresponds to the number of non-zeros for each column of B = Aᵀ.
99+
for k in 1:nnzA
100+
i = A_rowval[k]
101+
B_colptr[i] += 1
102+
end
103+
104+
# Compute the cumulative sum to determine the starting positions of rows in B_rowval
105+
counter = 1
106+
for col in 1:m
107+
nnz_col = B_colptr[col]
108+
B_colptr[col] = counter
109+
counter += nnz_col
110+
end
111+
B_colptr[m + 1] = counter
112+
113+
# Store the row indices for each column of B = Aᵀ
114+
for j in 1:n
115+
for index in A_colptr[j]:(A_colptr[j + 1] - 1)
116+
i = A_rowval[index]
117+
118+
# Update B_rowval for the non-zero B[j,i].
119+
# It corresponds to the non-zero A[i,j].
120+
pos = B_colptr[i]
121+
B_rowval[pos] = j
122+
B_colptr[i] += 1
123+
end
124+
end
125+
126+
# Fix offsets of B_colptr to restore correct starting positions
127+
for col in m:-1:2
128+
B_colptr[col] = B_colptr[col - 1]
129+
end
130+
B_colptr[1] = 1
131+
132+
return Graph{loops,T}(n, m, B_colptr, B_rowval)
90133
end
91134

92135
## Bipartite graph

0 commit comments

Comments
 (0)