Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/src/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ Unless noted otherwise `A` is the adjacency matrix of an undirected graph with `
| Triangle counting (Sandia) | `Sandia.jl` | `sandia(A)` | |
| Triangle counting (CMU) | `CMU.jl` | `cmu(A, n)` | |
| Triangles per vertex | `NodeWiseTriangleCount.jl` | `nodewise_tc(A)` | |
| Triangle centrality | `triangle_centrality.jl` | `triangle_centrality(A)`, `triangle_centrality1(A)` | `A` has unit weights. |
| k-truss | `KTruss.jl` | `ktruss(A, k)` | Returns the truss with edge supports as values. |
| BFS parents | `BFSParents.jl` | `bfs_parents(A, s, n)` | The parent of the source is `0`. |
| Multi-source BFS parents | `BFSParentsMultiSource.jl` | `ms_bfsp(A, S, n, s)` | Row `i` of the `s × n` matrix `S` marks source `i`. |
| Multi-source BFS levels | `BFSLevelsMultiSource.jl` | `ms_bfsl(A, S, n, s)` | `A` and `S` are `Bool`. Sources are level `1`, unreachable vertices `0`. |
| Bellman-Ford | `BellmanFord.jl` | `bellmanford(A, s, n)` | `A[i,j]` is the weight of edge `i → j`, with explicit zeros on the diagonal. |
| Floyd-Warshall | `FloydWarshall.jl` | `floydwarshall(A, n)` | Same input as Bellman-Ford. |
| Prim's minimum spanning tree | `BasicPrim.jl`, `AdvancedPrim.jl` | `b_prim(A, n, zeros(n))`, `a_prim(A, n, zeros(n))` | `A` is dense, with `Inf` where there is no edge and zeros on the diagonal. |
| PageRank | `pagerank.jl` | `pagerank(A)` | `A[i,j]` is the edge `i → j`. Returns `(ranks, iterations)`. Ranks of dangling vertices are not redistributed. |
| Community detection by label propagation | `CDLP.jl` | `cdlp(A, n, t)` | Runs `t` iterations. Every vertex must have a neighbour. |

The graph below has edges `1-2`, `1-3`, `2-3`, `2-4`, `3-4` and `4-5`, and two triangles, `{1,2,3}` and `{2,3,4}`.
Expand Down
10 changes: 9 additions & 1 deletion examples/pagerank.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
#=
PageRank (GAP benchmark variant, dangling vertices are not redistributed):
- Reference: https://doi.org/10.1109/HPEC49654.2021.9622789, https://en.wikipedia.org/wiki/PageRank
=#

using SuiteSparseGraphBLAS
using SuiteSparseGraphBLAS: second

#A is the adjacency matrix (A[i,j] is the edge i->j), d the out-degrees, Output: ranks and number of iterations
function pagerank(
A::SuiteSparseGraphBLAS.GBArray,
A,
d = reduce(+, A; dims=2),
α = 0.85,
maxiters = 100,
Expand Down
15 changes: 11 additions & 4 deletions examples/triangle_centrality.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
#=
Triangle centrality:
- Reference: https://arxiv.org/abs/2105.00110, https://doi.org/10.1109/HPEC49654.2021.9622789
=#

using SuiteSparseGraphBLAS
using SuiteSparseGraphBLAS: pair
using SuiteSparseGraphBLAS: pair, second

#A is the adjacency matrix of an undirected graph with unit weights, Output: triangle centrality of each vertex
function triangle_centrality1(A)
T = *(A, A', (+, *), mask=A)
y = reduce(+, T, dims=2)
k = reduce(+, y)
return (3 * *(A, y) - 2 * *(T, y) .+ y) ./ k
return (3 * *(A, y) - 2 * *(T, y, (+, second)) .+ y) ./ k
end

function triangle_centrality(A)
T = *(A, A', (+, pair), mask=A, Descriptor(structural_mask=true))
T = *(A, A', (+, pair), mask=A, desc=Descriptor(structural_mask=true))
y = reduce(+, T, dims=2)
k = reduce(+, y)
return (3.0 * *(A, y) .- (2.0 * *(T, y, (+, second))) .+ y) ./ k
return (3.0 * *(A, y) - (2.0 * *(T, y, (+, second))) .+ y) ./ k
end
14 changes: 13 additions & 1 deletion test/examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ using SuiteSparseGraphBLAS, SparseArrays, LinearAlgebra, Test

for f in ["AdvancedPrim", "BasicPrim", "BellmanFord", "BFSLevelsMultiSource", "BFSParents",
"BFSParentsMultiSource", "CDLP", "CMU", "Cohen", "FloydWarshall", "KTruss",
"NodeWiseTriangleCount", "Sandia"]
"NodeWiseTriangleCount", "Sandia", "pagerank", "triangle_centrality"]
include(joinpath(@__DIR__, "..", "examples", "$f.jl"))
end

Expand Down Expand Up @@ -59,4 +59,16 @@ end
@test diag(Matrix(cdlp(T, 6, 2))) == [1, 1, 1, 4, 4, 4]
@test diag(Matrix(cdlp(A, 5, 1))) == [2, 1, 1, 2, 4]
end

@testset "centrality" begin
Af = GBMatrix(sym(ones(6)))
# Vertex 5 is in no triangle and only sees the triangles of its neighbour 4.
@test collect(triangle_centrality(Af)) ≈ [5/6, 1, 1, 5/6, 1/2]
@test collect(triangle_centrality1(Af)) ≈ [5/6, 1, 1, 5/6, 1/2]
# PageRank is uniform on a directed cycle, otherwise compare with dense power iteration.
@test collect(pagerank(GBMatrix([1, 2, 3, 4], [2, 3, 4, 1], 1.0))[1]) ≈ fill(0.25, 4)
M = Matrix(sym(ones(6))); x = fill(0.2, 5)
for _ in 1:100; x = 0.15 / 5 .+ 0.85 .* (M' * (x ./ vec(sum(M, dims=2)))); end
@test collect(pagerank(Af)[1]) ≈ x atol=1e-5
end
end
Loading