Skip to content

Commit 2fe30ea

Browse files
ViralBShahclaude
andauthored
Fix the pagerank and triangle centrality examples (#162)
* Fix the pagerank and triangle centrality examples - pagerank: drop the removed `GBArray` annotation and import `second`. - triangle_centrality: pass the Descriptor as `desc=` and import `second`. Use `-` (eadd) instead of `.-`, which broadcasts as emul and dropped vertices that are in no triangle but have triangle neighbours. - triangle_centrality1: multiply by the pattern of T (`(+, second)`) instead of its triangle counts, as in the definition. - Add reference headers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Test pagerank and triangle centrality and list them in the docs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 605a518 commit 2fe30ea

4 files changed

Lines changed: 35 additions & 6 deletions

File tree

‎docs/src/examples.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ Unless noted otherwise `A` is the adjacency matrix of an undirected graph with `
2222
| Triangle counting (Sandia) | `Sandia.jl` | `sandia(A)` | |
2323
| Triangle counting (CMU) | `CMU.jl` | `cmu(A, n)` | |
2424
| Triangles per vertex | `NodeWiseTriangleCount.jl` | `nodewise_tc(A)` | |
25+
| Triangle centrality | `triangle_centrality.jl` | `triangle_centrality(A)`, `triangle_centrality1(A)` | `A` has unit weights. |
2526
| k-truss | `KTruss.jl` | `ktruss(A, k)` | Returns the truss with edge supports as values. |
2627
| BFS parents | `BFSParents.jl` | `bfs_parents(A, s, n)` | The parent of the source is `0`. |
2728
| Multi-source BFS parents | `BFSParentsMultiSource.jl` | `ms_bfsp(A, S, n, s)` | Row `i` of the `s × n` matrix `S` marks source `i`. |
2829
| Multi-source BFS levels | `BFSLevelsMultiSource.jl` | `ms_bfsl(A, S, n, s)` | `A` and `S` are `Bool`. Sources are level `1`, unreachable vertices `0`. |
2930
| Bellman-Ford | `BellmanFord.jl` | `bellmanford(A, s, n)` | `A[i,j]` is the weight of edge `i → j`, with explicit zeros on the diagonal. |
3031
| Floyd-Warshall | `FloydWarshall.jl` | `floydwarshall(A, n)` | Same input as Bellman-Ford. |
3132
| 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. |
33+
| PageRank | `pagerank.jl` | `pagerank(A)` | `A[i,j]` is the edge `i → j`. Returns `(ranks, iterations)`. Ranks of dangling vertices are not redistributed. |
3234
| Community detection by label propagation | `CDLP.jl` | `cdlp(A, n, t)` | Runs `t` iterations. Every vertex must have a neighbour. |
3335

3436
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}`.

‎examples/pagerank.jl‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1+
#=
2+
PageRank (GAP benchmark variant, dangling vertices are not redistributed):
3+
- Reference: https://doi.org/10.1109/HPEC49654.2021.9622789, https://en.wikipedia.org/wiki/PageRank
4+
=#
5+
16
using SuiteSparseGraphBLAS
7+
using SuiteSparseGraphBLAS: second
8+
9+
#A is the adjacency matrix (A[i,j] is the edge i->j), d the out-degrees, Output: ranks and number of iterations
210
function pagerank(
3-
A::SuiteSparseGraphBLAS.GBArray,
11+
A,
412
d = reduce(+, A; dims=2),
513
α = 0.85,
614
maxiters = 100,

‎examples/triangle_centrality.jl‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1+
#=
2+
Triangle centrality:
3+
- Reference: https://arxiv.org/abs/2105.00110, https://doi.org/10.1109/HPEC49654.2021.9622789
4+
=#
5+
16
using SuiteSparseGraphBLAS
2-
using SuiteSparseGraphBLAS: pair
7+
using SuiteSparseGraphBLAS: pair, second
8+
9+
#A is the adjacency matrix of an undirected graph with unit weights, Output: triangle centrality of each vertex
310
function triangle_centrality1(A)
411
T = *(A, A', (+, *), mask=A)
512
y = reduce(+, T, dims=2)
613
k = reduce(+, y)
7-
return (3 * *(A, y) - 2 * *(T, y) .+ y) ./ k
14+
return (3 * *(A, y) - 2 * *(T, y, (+, second)) .+ y) ./ k
815
end
916

1017
function triangle_centrality(A)
11-
T = *(A, A', (+, pair), mask=A, Descriptor(structural_mask=true))
18+
T = *(A, A', (+, pair), mask=A, desc=Descriptor(structural_mask=true))
1219
y = reduce(+, T, dims=2)
1320
k = reduce(+, y)
14-
return (3.0 * *(A, y) .- (2.0 * *(T, y, (+, second))) .+ y) ./ k
21+
return (3.0 * *(A, y) - (2.0 * *(T, y, (+, second))) .+ y) ./ k
1522
end

‎test/examples.jl‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ using SuiteSparseGraphBLAS, SparseArrays, LinearAlgebra, Test
33

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

@@ -59,4 +59,16 @@ end
5959
@test diag(Matrix(cdlp(T, 6, 2))) == [1, 1, 1, 4, 4, 4]
6060
@test diag(Matrix(cdlp(A, 5, 1))) == [2, 1, 1, 2, 4]
6161
end
62+
63+
@testset "centrality" begin
64+
Af = GBMatrix(sym(ones(6)))
65+
# Vertex 5 is in no triangle and only sees the triangles of its neighbour 4.
66+
@test collect(triangle_centrality(Af)) ≈ [5/6, 1, 1, 5/6, 1/2]
67+
@test collect(triangle_centrality1(Af)) ≈ [5/6, 1, 1, 5/6, 1/2]
68+
# PageRank is uniform on a directed cycle, otherwise compare with dense power iteration.
69+
@test collect(pagerank(GBMatrix([1, 2, 3, 4], [2, 3, 4, 1], 1.0))[1]) ≈ fill(0.25, 4)
70+
M = Matrix(sym(ones(6))); x = fill(0.2, 5)
71+
for _ in 1:100; x = 0.15 / 5 .+ 0.85 .* (M' * (x ./ vec(sum(M, dims=2)))); end
72+
@test collect(pagerank(Af)[1]) ≈ x atol=1e-5
73+
end
6274
end

0 commit comments

Comments
 (0)