From 82799ea738f69df436764911f01ebab1e851ed8b Mon Sep 17 00:00:00 2001 From: Samuel Esposito <40698384+samuel-esp@users.noreply.github.com> Date: Sun, 12 Sep 2021 14:23:11 +0200 Subject: [PATCH 1/3] new examples added --- examples/AdvancedPrim.jl | 49 ++++++++++++++++++ examples/BFSLevelsMultiSource.jl | 47 ++++++++++++++++++ examples/BFSParents.jl | 74 ++++++++++++++++++++++++++++ examples/BFSParentsMultiSource.jl | 71 ++++++++++++++++++++++++++ examples/BasicPrim.jl | 44 +++++++++++++++++ examples/BellmanFord.jl | 27 ++++++++++ examples/CDLP.jl | 82 +++++++++++++++++++++++++++++++ examples/CMU.jl | 33 +++++++++++++ examples/Cohen.jl | 29 +++++++++++ examples/FloydWarshall.jl | 27 ++++++++++ examples/KTruss.jl | 27 ++++++++++ examples/NodeWiseTriangleCount.jl | 20 ++++++++ examples/Sandia.jl | 24 +++++++++ 13 files changed, 554 insertions(+) create mode 100644 examples/AdvancedPrim.jl create mode 100644 examples/BFSLevelsMultiSource.jl create mode 100644 examples/BFSParents.jl create mode 100644 examples/BFSParentsMultiSource.jl create mode 100644 examples/BasicPrim.jl create mode 100644 examples/BellmanFord.jl create mode 100644 examples/CDLP.jl create mode 100644 examples/CMU.jl create mode 100644 examples/Cohen.jl create mode 100644 examples/FloydWarshall.jl create mode 100644 examples/KTruss.jl create mode 100644 examples/NodeWiseTriangleCount.jl create mode 100644 examples/Sandia.jl diff --git a/examples/AdvancedPrim.jl b/examples/AdvancedPrim.jl new file mode 100644 index 00000000..83eea02d --- /dev/null +++ b/examples/AdvancedPrim.jl @@ -0,0 +1,49 @@ +#= +AdvancedPrim: +- Julia version: +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra + +function stoppingCondition(m, n) + +infinito = true + +for i = 1:n + if(m[i] == 0.0) + return false + end +end + return infinito +end + +#A is the input matrix, n is the number of nodes, m is the source matrix. Output: minimum spanning tree and minimum spanning tree cost +function a_prim(A, n, m) + + d = GBVector{Float64}(n) + + weight = 0.0 + + d = A[1,:] + mst = GBVector{Float64}(n) #minimum spanning tree + + while(stoppingCondition(m, n) == false) + + u = argmin(m'+d) + m[u[2]] = Inf + push!(mst, d[u[2]]) + weight = weight + d[u[2]] + print("WEIGHT: ") + print(weight) + d = emul(d, A[u[1],:], BinaryOps.MIN) + print(" ITERATION FINISHED") + print("\n\n\n") + end + + return weight, mst + +end \ No newline at end of file diff --git a/examples/BFSLevelsMultiSource.jl b/examples/BFSLevelsMultiSource.jl new file mode 100644 index 00000000..78aeaab9 --- /dev/null +++ b/examples/BFSLevelsMultiSource.jl @@ -0,0 +1,47 @@ +#= +BFSLevelsMultiSource: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra + +#A is the input matrix, S is the source matrix, and n is the number of nodes, s is the number of sources in the matrix S, Output: Levels matrix +function ms_bfsl(A, S, n, s) + + #this vector allows to check if a value is already present inside the distance matrix, + #if it's present we don't want it to be changed + levels = GBVector{Int64}(n) + for i = 1:n + levels[i] = i + end + + #distance matrix + distance = GBMatrix{Int64}(s, n) + for i = 1:s + for j = 1:n + distance[i, j] = 0 + end + end + + for level = 1:n-1 + + for i = 1:s + for j = 1:n + if(S[i, j]!=0 && distance[i, j] ∉ levels) #* + distance[i, j] = level #* + end + end + end + + + S = mul(S, A, Semirings.LOR_LAND, mask=distance, desc=Descriptors.RC) + + end + + return distance + +end \ No newline at end of file diff --git a/examples/BFSParents.jl b/examples/BFSParents.jl new file mode 100644 index 00000000..c41dbb5c --- /dev/null +++ b/examples/BFSParents.jl @@ -0,0 +1,74 @@ +#= +BFSParents: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra + +#function to insert inside the result array +function insert(p, result) + for i=1:length(p) + if(p[i]!=nothing && result[i]==nothing) + result[i] = p[i] + end + end + + return result + +end + +#function to update visited nodes +function updateVisited(f, visited) + for i=1:length(f) + if(f[i]!=nothing) + visited[i] = true + end + end + + return visited + +end + +#A is the input matrix, s is the source node, and n is the number of nodes, Output: parent matrix +function bfs_parents(A, s, n) + + index = GBVector{Int64}(n) + for i = 1:n + index[i] = i + end + + #wavefront vector -> w[s]=source node insrted in wavefront + f = GBVector{Int64}(n) + f[s] = 1 + + #parent vector -> p[s]=1 because the source is already visited + p = GBVector{Int64}(n) + + #result vector -> result[s]=0 because the parent of the source is considered node 0 + result = GBVector{Int64}(n) + result[s] = 0 + + #visited vector -> v[s]=1 because the source is already visited + visited = GBVector{Bool}(n) + visited[s] = true + + for i = 1:n-1 + f = mul(f, A, Semirings.MIN_FIRST, mask=p, desc=Descriptors.SC) + p = f[:, mask=f, desc=Descriptors.S] + f = index[:, mask=f, desc=Descriptors.S] + result = insert(p, result) + visited = updateVisited(f, visited) + unvisited = filter(x -> x!=true, visited) + if(isempty(unvisited)) + break + end + + end + + return result + +end \ No newline at end of file diff --git a/examples/BFSParentsMultiSource.jl b/examples/BFSParentsMultiSource.jl new file mode 100644 index 00000000..2f4d1b81 --- /dev/null +++ b/examples/BFSParentsMultiSource.jl @@ -0,0 +1,71 @@ +#= +BFSParentsMultiSource: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra + +function insert(P, R, s, n) + for i = 1:s + for j = 1:n + if(P[i, j]!=nothing && R[i, j]==nothing) #* + R[i, j] = P[i, j] + end + end + end + + return R + +end + +#A is the input matrix, S are the sources, n is the number of nodes, s is the number of sources, Output: Parents matrix +function ms_bfsp(A, S, n, s) + + index = GBMatrix{Int64}(s, n) + for i = 1:n + for j = 1:s + index[j, i] = i + end + end + + #frontier matrix -> F=S source nodes insrted in frontier + F = GBMatrix{Int64}(n, n) + F = S + + #parent matrix -> P[S]=S because the source is already visited + P = GBMatrix{Int64}(n, n) + P = S + + #result matrix -> R[S]=0 because the parents of the source are considered node 0 + R = GBMatrix{Int64}(s, n) + LR = GBMatrix{Int64}(s, n) + R = copy(S) + for i = 1:n + for j = 1:s + if(R[j, i]!=nothing) + R[j, i] = 0 + end + end + end + + + for i = 1:n-1 + F = mul(F, A, Semirings.MIN_FIRST, mask=P, desc=Descriptors.RC) + P = F[:, :, mask=F, desc=Descriptors.S] + F = index[:, :, mask=F, desc=Descriptors.S] + R = insert(P, R, s, n) + if(R == LR) + break + end + LR = copy(R) + + end + + return R + +end + diff --git a/examples/BasicPrim.jl b/examples/BasicPrim.jl new file mode 100644 index 00000000..aba2ac2d --- /dev/null +++ b/examples/BasicPrim.jl @@ -0,0 +1,44 @@ +#= +BasicPrim: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays + +function stoppingCondition(m, n) + +infinito = true + +for i = 1:n + if(m[i] == 0.0) + return false + end +end + return infinito +end + +#A is the input matrix, n is the number of nodes, m is the source matrix Output: minimum spanning tree cost +function b_prim(A, n, m) + + d = GBVector{Float64}(n) + + weight = 0.0 + + d = A[1,:] + print("INITIAL WEIGHT: ") + print(weight) + print("\n\n") + while(stoppingCondition(m, n) == false) + + u = argmin(m'+d) + m[u[2]] = Inf + weight = weight + d[u[2]] + d = emul(d, A[u[1],:], BinaryOps.MIN) + end + + return weight + +end \ No newline at end of file diff --git a/examples/BellmanFord.jl b/examples/BellmanFord.jl new file mode 100644 index 00000000..4bcc45b6 --- /dev/null +++ b/examples/BellmanFord.jl @@ -0,0 +1,27 @@ +#= +BellmanFord: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays + +#A is the input matrix, s is the source node, and n is the number of nodes, Output: Shortest path from source node +function bellmanford(A, s, n) + + #vector init +inf + d = GBVector{Float64}(n) + for i = 1:n + d[i] = Inf + end + + d[s]=0.0 + for i = 1:n + d = mul(d, A, Semirings.MIN_PLUS, mask=d, desc=Descriptors.S) + end + + return d + +end \ No newline at end of file diff --git a/examples/CDLP.jl b/examples/CDLP.jl new file mode 100644 index 00000000..b13bc3ff --- /dev/null +++ b/examples/CDLP.jl @@ -0,0 +1,82 @@ +#= +CDLP: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra +using DataStructures + +#minMode function: given a collection [1, 5, 5, 3, 3, 7] will return 3 because the highest repetition is 2 +#and the lowest most repeated number is 3 +function minMode(c) + + minVal = -1 + i = 0 + + for row in eachrow(c) + i = i+1 + row = collect(row) + temp = filter(x -> x!=0, row) + count = counter(temp) + sortedCollection = sort(collect(count), by=x->x[2], rev=true) + minVal = sortedCollection[1][1] + repetitions = sortedCollection[1][2] + for (key, value) in sortedCollection + if(value == repetitions) + if(key < minVal) + minVal = key + end + end + end + + end + + return minVal +end + +#can be useful to tweak the algorithm +function diag_conversion(lab, n) +for i = 1:n + for j = 1:n + if(i==j) + lab[i,j]=i + else + lab[i,j]=0 + end + end + end + return lab +end + +#A is the input matrix, n is the number of nodes, t the number of iterations Output: label propagation matrix +function cdlp(A, n, t) + + lab = GBMatrix{Int64}(n,n) + + for i = 1:n + for j = 1:n + if(i==j) + lab[i,j]=i + else + lab[i,j]=0 + end + end + end + + for k = 1:t + F = mul(A, lab, Semirings.PLUS_TIMES) + for i = 1:n + r = F[i,:] + r = sort(r, dims=2) + lab[i, i] = minMode(r) + end + + end + + return lab + +end \ No newline at end of file diff --git a/examples/CMU.jl b/examples/CMU.jl new file mode 100644 index 00000000..7c56b4ac --- /dev/null +++ b/examples/CMU.jl @@ -0,0 +1,33 @@ +#= +CMU: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra + +#A is the input matrix, n is the number of nodes in the original matrix, Output: Triangle Count +function cmu(A, n) + + t = 0 + + for i = 2:n-1 + + #rpva + A20 = A[i+1:n,begin:i] + a10 = A[begin:i, i] + a12 = A[i, i+1:n] + + partial1 = mul(a10', A20', Semirings.PLUS_TIMES) + partial2 = mul(partial1, a12', Semirings.PLUS_TIMES) + + t = t + partial2[1] + end + + print(t) + + return t +end \ No newline at end of file diff --git a/examples/Cohen.jl b/examples/Cohen.jl new file mode 100644 index 00000000..50d48065 --- /dev/null +++ b/examples/Cohen.jl @@ -0,0 +1,29 @@ +#= +Cohen: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra + +##A is the input matrix, Output: Triangle Count +function cohen(A) + + #extracting lower matrix from input matrix + L = tril(A) + + + #extracting upper matrix from input matrix + U = triu(A') + + B = mul(L, U, Semirings.PLUS_TIMES) + C = emul(B, A, BinaryOps.TIMES) + result = reduce(Monoids.PLUS_MONOID[Float64], C, dims=:) + result = result /2 + + return result + +end \ No newline at end of file diff --git a/examples/FloydWarshall.jl b/examples/FloydWarshall.jl new file mode 100644 index 00000000..fe084f52 --- /dev/null +++ b/examples/FloydWarshall.jl @@ -0,0 +1,27 @@ +#= +FloydWarshall: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays + +#A is the input matrix for Floyd-Warshall multiple sources multiple destinations, Output: shortest paths +function floydwarshall(A, n) + + #distance matrix = input matrix + D = A + result = GBMatrix{Int64}(n, n) + + + for i = 1:n + partial = mul(D[:,i], D[i,:], Semirings.MIN_PLUS) + D = emul(D, partial, BinaryOps.MIN) + result = partial + end + + return result + +end \ No newline at end of file diff --git a/examples/KTruss.jl b/examples/KTruss.jl new file mode 100644 index 00000000..f705e20b --- /dev/null +++ b/examples/KTruss.jl @@ -0,0 +1,27 @@ +#= +KTruss: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra + +#A is the original matrix, k is the requested truss, n the nodes in the original matrix, Output: K-Truss graph +function ktruss(A, k, n) + + C = A + for i = 1:n-1 + C = mul(C, C, Semirings.PLUS_LAND, mask=C) + C = select(SelectOps.GE, C, k-2) + print(C) + end + + return C + +end + +#*** +#optional: we could also tell the algorithm to stop if the non zero values didn't change from the previous iteration \ No newline at end of file diff --git a/examples/NodeWiseTriangleCount.jl b/examples/NodeWiseTriangleCount.jl new file mode 100644 index 00000000..bffd0f64 --- /dev/null +++ b/examples/NodeWiseTriangleCount.jl @@ -0,0 +1,20 @@ +#= +NodeWiseTriangleCount: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra + +#A is the input matrix. Output: triangles originated by each node +function nodewise_tc(A) + + #extracting lower matrix from input matrix + partial = mul(A, A, Semirings.PLUS_TIMES, mask=A) + t = reduce(Monoids.PLUS_MONOID[Float64], partial, dims=2) + return t/2 + +end \ No newline at end of file diff --git a/examples/Sandia.jl b/examples/Sandia.jl new file mode 100644 index 00000000..00a75971 --- /dev/null +++ b/examples/Sandia.jl @@ -0,0 +1,24 @@ +#= +Sandia: +- Julia version: 1.6.2 +- Author: samuel +- Date: 2021-09-10 +=# + +using SuiteSparseGraphBLAS +using SparseArrays +using LinearAlgebra + +#A is the input matrix, Output: Triangle Count +function sandia(A) + + #extracting lower matrix from input matrix + L = tril(A) + + + C = mul(L, L, Semirings.PLUS_TIMES, mask=L) + result = reduce(Monoids.PLUS_MONOID, C, dims=:) + + return result + +end \ No newline at end of file From 2792c18277135403c359ed49c141af59074ba845 Mon Sep 17 00:00:00 2001 From: Will Kimmerer Date: Sat, 30 Oct 2021 20:21:31 -0400 Subject: [PATCH 2/3] Some updates to more recent API. --- examples/Sandia.jl | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/examples/Sandia.jl b/examples/Sandia.jl index 00a75971..46d90b98 100644 --- a/examples/Sandia.jl +++ b/examples/Sandia.jl @@ -12,13 +12,8 @@ using LinearAlgebra #A is the input matrix, Output: Triangle Count function sandia(A) - #extracting lower matrix from input matrix L = tril(A) - - - C = mul(L, L, Semirings.PLUS_TIMES, mask=L) - result = reduce(Monoids.PLUS_MONOID, C, dims=:) - - return result + C = *(+, *; mask=L)(L, L) + return reduce(+, C, dims=:) end \ No newline at end of file From f3b39003512bc9182dd799c07a909c28bf4ff4a7 Mon Sep 17 00:00:00 2001 From: Will Kimmerer Date: Sat, 30 Oct 2021 20:24:59 -0400 Subject: [PATCH 3/3] Some more updates --- examples/BFSParentsMultiSource.jl | 8 +++----- examples/BasicPrim.jl | 2 +- examples/BellmanFord.jl | 4 ++-- examples/CDLP.jl | 4 +--- examples/CMU.jl | 27 ++++++++++----------------- examples/Cohen.jl | 18 +++--------------- examples/FloydWarshall.jl | 6 ++---- examples/KTruss.jl | 5 ++--- examples/NodeWiseTriangleCount.jl | 5 ++--- 9 files changed, 26 insertions(+), 53 deletions(-) diff --git a/examples/BFSParentsMultiSource.jl b/examples/BFSParentsMultiSource.jl index 2f4d1b81..f5bbdc18 100644 --- a/examples/BFSParentsMultiSource.jl +++ b/examples/BFSParentsMultiSource.jl @@ -12,7 +12,7 @@ using LinearAlgebra function insert(P, R, s, n) for i = 1:s for j = 1:n - if(P[i, j]!=nothing && R[i, j]==nothing) #* + if(P[i, j] !== nothing && R[i, j] === nothing) #* R[i, j] = P[i, j] end end @@ -51,10 +51,8 @@ function ms_bfsp(A, S, n, s) end end end - - - for i = 1:n-1 - F = mul(F, A, Semirings.MIN_FIRST, mask=P, desc=Descriptors.RC) + for _ ∈ 1:n-1 + F = mul(F, A, (min, first), mask=P, desc=Descriptors.RC) P = F[:, :, mask=F, desc=Descriptors.S] F = index[:, :, mask=F, desc=Descriptors.S] R = insert(P, R, s, n) diff --git a/examples/BasicPrim.jl b/examples/BasicPrim.jl index aba2ac2d..4214f5ea 100644 --- a/examples/BasicPrim.jl +++ b/examples/BasicPrim.jl @@ -36,7 +36,7 @@ function b_prim(A, n, m) u = argmin(m'+d) m[u[2]] = Inf weight = weight + d[u[2]] - d = emul(d, A[u[1],:], BinaryOps.MIN) + d = min.(d, A[u[1],:]) end return weight diff --git a/examples/BellmanFord.jl b/examples/BellmanFord.jl index 4bcc45b6..460995e6 100644 --- a/examples/BellmanFord.jl +++ b/examples/BellmanFord.jl @@ -18,8 +18,8 @@ function bellmanford(A, s, n) end d[s]=0.0 - for i = 1:n - d = mul(d, A, Semirings.MIN_PLUS, mask=d, desc=Descriptors.S) + for _ ∈ 1:n + d = mul(d, A, (min, +), mask=d, desc=Descriptors.S) end return d diff --git a/examples/CDLP.jl b/examples/CDLP.jl index b13bc3ff..e5ad3921 100644 --- a/examples/CDLP.jl +++ b/examples/CDLP.jl @@ -68,15 +68,13 @@ function cdlp(A, n, t) end for k = 1:t - F = mul(A, lab, Semirings.PLUS_TIMES) + F = A * lab for i = 1:n r = F[i,:] r = sort(r, dims=2) lab[i, i] = minMode(r) end - end - return lab end \ No newline at end of file diff --git a/examples/CMU.jl b/examples/CMU.jl index 7c56b4ac..1d6da176 100644 --- a/examples/CMU.jl +++ b/examples/CMU.jl @@ -11,23 +11,16 @@ using LinearAlgebra #A is the input matrix, n is the number of nodes in the original matrix, Output: Triangle Count function cmu(A, n) - - t = 0 - - for i = 2:n-1 - - #rpva - A20 = A[i+1:n,begin:i] - a10 = A[begin:i, i] - a12 = A[i, i+1:n] - - partial1 = mul(a10', A20', Semirings.PLUS_TIMES) - partial2 = mul(partial1, a12', Semirings.PLUS_TIMES) - - t = t + partial2[1] + t = 0 + for i ∈ 2:n-1 + #rpva + A20 = A[i+1:n,begin:i] + a10 = A[begin:i, i] + a12 = A[i, i+1:n] + + partial1 = a10' * A20' + partial2 = partial1 * a12' + t += partial2[1] end - - print(t) - return t end \ No newline at end of file diff --git a/examples/Cohen.jl b/examples/Cohen.jl index 50d48065..b8f112f2 100644 --- a/examples/Cohen.jl +++ b/examples/Cohen.jl @@ -11,19 +11,7 @@ using LinearAlgebra ##A is the input matrix, Output: Triangle Count function cohen(A) - - #extracting lower matrix from input matrix - L = tril(A) - - - #extracting upper matrix from input matrix - U = triu(A') - - B = mul(L, U, Semirings.PLUS_TIMES) - C = emul(B, A, BinaryOps.TIMES) - result = reduce(Monoids.PLUS_MONOID[Float64], C, dims=:) - result = result /2 - - return result - + U = select(TRIU, A) + L = select(TRIL, A) + return reduce(+, mul(L, U, (+, pair); mask=A)) ÷ 2 end \ No newline at end of file diff --git a/examples/FloydWarshall.jl b/examples/FloydWarshall.jl index fe084f52..fde73a78 100644 --- a/examples/FloydWarshall.jl +++ b/examples/FloydWarshall.jl @@ -15,13 +15,11 @@ function floydwarshall(A, n) D = A result = GBMatrix{Int64}(n, n) - for i = 1:n - partial = mul(D[:,i], D[i,:], Semirings.MIN_PLUS) - D = emul(D, partial, BinaryOps.MIN) + partial = mul(D[:,i], D[i,:], (min, +)) + D = emul(D, partial, min) result = partial end - return result end \ No newline at end of file diff --git a/examples/KTruss.jl b/examples/KTruss.jl index f705e20b..39bf5c27 100644 --- a/examples/KTruss.jl +++ b/examples/KTruss.jl @@ -13,12 +13,11 @@ using LinearAlgebra function ktruss(A, k, n) C = A - for i = 1:n-1 + for _ ∈ 1:n-1 C = mul(C, C, Semirings.PLUS_LAND, mask=C) - C = select(SelectOps.GE, C, k-2) + C = select(>=, C, k-2) print(C) end - return C end diff --git a/examples/NodeWiseTriangleCount.jl b/examples/NodeWiseTriangleCount.jl index bffd0f64..2aba3b8f 100644 --- a/examples/NodeWiseTriangleCount.jl +++ b/examples/NodeWiseTriangleCount.jl @@ -12,9 +12,8 @@ using LinearAlgebra #A is the input matrix. Output: triangles originated by each node function nodewise_tc(A) - #extracting lower matrix from input matrix - partial = mul(A, A, Semirings.PLUS_TIMES, mask=A) - t = reduce(Monoids.PLUS_MONOID[Float64], partial, dims=2) + partial = mul(A, A, (+, *), mask=A) + t = reduce(+, partial, dims=2) return t/2 end \ No newline at end of file