From 47598e32a7de96264c1e1db9b6e062cf18df2132 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 7 Nov 2024 16:08:38 -0500 Subject: [PATCH 01/30] Fix ambiguity on steiner_tree --- src/steiner_tree.jl | 14 +++++++++++++- test/test_namedgraph.jl | 10 ++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/steiner_tree.jl b/src/steiner_tree.jl index c01207f9..1672955f 100644 --- a/src/steiner_tree.jl +++ b/src/steiner_tree.jl @@ -1,7 +1,7 @@ using Graphs: Graphs, IsDirected, nv, steiner_tree using SimpleTraits: SimpleTraits, Not, @traitfn -@traitfn function Graphs.steiner_tree( +@traitfn function namedgraph_steiner_tree( g::AbstractNamedGraph::(!IsDirected), term_vert, distmx=weights(g) ) position_tree = steiner_tree( @@ -11,3 +11,15 @@ using SimpleTraits: SimpleTraits, Not, @traitfn ) return typeof(g)(position_tree, map(v -> ordered_vertices(g)[v], vertices(position_tree))) end + +@traitfn function Graphs.steiner_tree( + g::AbstractNamedGraph::(!IsDirected), term_vert, args... +) + return namedgraph_steiner_tree(g, term_vert, args...) +end + +@traitfn function Graphs.steiner_tree( + g::AbstractNamedGraph::(!IsDirected), term_vert::Vector{<:Integer}, args... +) + return namedgraph_steiner_tree(g, term_vert, args...) +end diff --git a/test/test_namedgraph.jl b/test/test_namedgraph.jl index 2d9e6c05..f28f96cc 100644 --- a/test/test_namedgraph.jl +++ b/test/test_namedgraph.jl @@ -679,6 +679,16 @@ end for e in es @test has_edge(st, e) end + + g = named_path_graph(4) + terminal_vertices = [1, 3] + st = steiner_tree(g, terminal_vertices) + es = [1 => 2, 2 => 3] + @test ne(st) == 2 + @test nv(st) == 3 + for e in es + @test has_edge(st, e) + end end @testset "topological_sort_by_dfs" begin g = NamedDiGraph(["A", "B", "C", "D", "E", "F", "G"]) From 6d09f22772f2936564ae85532f28b7473cb374c5 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 27 Mar 2025 14:58:03 -0400 Subject: [PATCH 02/30] Cycle functionality --- Project.toml | 6 +- src/NamedGraphs.jl | 1 + src/lib/GraphsExtensions/src/abstractgraph.jl | 7 +++ src/simplecycles.jl | 57 +++++++++++++++++++ test/test_cycles.jl | 43 ++++++++++++++ 5 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 src/simplecycles.jl create mode 100644 test/test_cycles.jl diff --git a/Project.toml b/Project.toml index 669542c2..f4704395 100644 --- a/Project.toml +++ b/Project.toml @@ -1,10 +1,11 @@ name = "NamedGraphs" uuid = "678767b0-92e7-4007-89e4-4527a8725b19" -authors = ["Matthew Fishman and contributors"] -version = "0.6.4" +authors = ["Matthew Fishman , Joseph Tindall and contributors"] +version = "0.6.5" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -29,6 +30,7 @@ NamedGraphsSymRCMExt = "SymRCM" [compat] AbstractTrees = "0.3, 0.4" +Combinatorics = "1.0.2" Dictionaries = "0.4" Graphs = "1.8" GraphsFlows = "0.1.1" diff --git a/src/NamedGraphs.jl b/src/NamedGraphs.jl index 2c99f054..584ec967 100644 --- a/src/NamedGraphs.jl +++ b/src/NamedGraphs.jl @@ -10,6 +10,7 @@ include("abstractnamededge.jl") include("namededge.jl") include("abstractnamedgraph.jl") include("decorate.jl") +include("simplecycles.jl") include("shortestpaths.jl") include("distance.jl") include("distances_and_capacities.jl") diff --git a/src/lib/GraphsExtensions/src/abstractgraph.jl b/src/lib/GraphsExtensions/src/abstractgraph.jl index 9090b4e9..4636b29b 100644 --- a/src/lib/GraphsExtensions/src/abstractgraph.jl +++ b/src/lib/GraphsExtensions/src/abstractgraph.jl @@ -134,6 +134,13 @@ function subgraph(f::Function, graph::AbstractGraph) return subgraph(graph, filter(f, vertices(graph))) end +function edge_subgraph(graph::AbstractGraph, es::Vector{<:AbstractEdge}) + vs = unique(vcat(src.(es), dst.(es))) + g = subgraph(graph, vs) + g = rem_edges(g, edges(g)) + return add_edges(g, es) +end + function degrees(graph::AbstractGraph, vertices=vertices(graph)) return map(vertex -> degree(graph, vertex), vertices) end diff --git a/src/simplecycles.jl b/src/simplecycles.jl new file mode 100644 index 00000000..46e82c3b --- /dev/null +++ b/src/simplecycles.jl @@ -0,0 +1,57 @@ +using Combinatorics: powerset +using Graphs: Graphs, is_tree, simplecycles_limited_length +using NamedGraphs.GraphsExtensions: add_edges, disjoint_union, edge_subgraph +using SplitApplyCombine: group + +function Graphs.simplecycles_limited_length(g::AbstractNamedGraph, max_cycle_size::Int64) + vs = collect(vertices(g)) + cycles = simplecycles_limited_length(position_graph(g), max_cycle_size) + cycles = [[vs[i] for i in cycle] for cycle in cycles] + return cycles +end + +function unique_simplecycles_limited_length(g::AbstractNamedGraph, max_cycle_size) + cycles = simplecycles_limited_length(g, max_cycle_size) + + #Filter out length 2 cycles and non-unique cycles + cycles = filter(cycle -> length(cycle) > 2, cycles) + cycles = group(cycle -> Set(cycle), cycles) + cycles = first.(collect(values(cycles))) + + return cycles +end + +function cycle_to_path(g::AbstractNamedGraph, cycle::Vector) + es = [NamedEdge(cycle[i] => cycle[i + 1]) for i in 1:(length(cycle) - 1)] + final_edge = NamedEdge(first(cycle) => last(cycle)) + return vcat(es, final_edge) +end + +function unique_cyclesubgraphs_limited_length(g::AbstractNamedGraph, max_cycle_size::Int64) + cycles = unique_simplecycles_limited_length(g, max_cycle_size) + paths = cycle_to_path.((g,), cycles) + return edge_subgraph.((g,), paths) +end + +""" +Enumerate all unqiue, connected edgesubgraphs without any leaf vertices (degree 1) and with Nedges < max_number_of_edges +""" +function edge_subgraphs_no_leaf_vertices(g::AbstractGraph, max_number_of_edges::Int64) + edge_subgraphs = unique_cyclesubgraphs_limited_length(g, max_number_of_edges) + isempty(edge_subgraphs) && return [] + + #Take powerset, but don't exceed max_number of edges and remove disconnected components + min_loop_size = minimum(length.(edges.(edge_subgraphs))) + max_genus = round(Int64, ceil(max_number_of_edges / min_loop_size)) + subgraph_components = collect(powerset(edge_subgraphs, 1, max_genus)) + + edge_subgraphs = [] + for sc in subgraph_components + g = reduce(union, sc) + if is_connected(g) && ne(g) <= max_number_of_edges && g ∉ edge_subgraphs + push!(edge_subgraphs, g) + end + end + + return edge_subgraphs +end diff --git a/test/test_cycles.jl b/test/test_cycles.jl new file mode 100644 index 00000000..4c2db4ab --- /dev/null +++ b/test/test_cycles.jl @@ -0,0 +1,43 @@ +@eval module $(gensym()) +using Graphs: edges, ne, vertices +using NamedGraphs: edge_subgraphs_no_leaf_vertices, unique_simplecycles_limited_length +using NamedGraphs.GraphsExtensions: degree, edge_subgraph, is_connected, rem_vertex +using NamedGraphs.NamedGraphGenerators: + named_comb_tree, named_grid, named_hexagonal_lattice_graph +using Test: @test, @testset + +@testset "SimpleCycles" begin + g = named_comb_tree((4, 3)) + @test isempty(unique_simplecycles_limited_length(g, ne(g))) + + g = named_grid((3, 3)) + cycles = unique_simplecycles_limited_length(g, 4) + @test length(cycles) == 4 + @test Set([(1, 1), (1, 2), (2, 2), (2, 1)]) ∈ Set.(cycles) + + g = rem_vertex(g, (2, 2)) + all_cycles = unique_simplecycles_limited_length(g, ne(g)) + @test length(all_cycles) == 1 + @test Set(vertices(g)) == Set(only(all_cycles)) +end + +@testset "EdgeSubgraphs_NoLeaves" begin + g = named_comb_tree((3, 3)) + edge_subgraphs = edge_subgraphs_no_leaf_vertices(g, ne(g)) + @test isempty(edge_subgraphs) + + g = named_hexagonal_lattice_graph(3, 3) + + edge_subgraphs = edge_subgraphs_no_leaf_vertices(g, 3) + @test isempty(edge_subgraphs) + + edge_subgraphs = edge_subgraphs_no_leaf_vertices(g, 6) + @test all(x -> x == 6, ne.(edge_subgraphs)) + + edge_subgraphs = edge_subgraphs_no_leaf_vertices(g, 10) + @test all(x -> x == 6 || x == 10, ne.(edge_subgraphs)) + #All nodes have degree > 1 + @test all(g -> minimum(degree.((g,), collect(vertices(g)))) > 1, edge_subgraphs) + @test all(g -> is_connected(g), edge_subgraphs) +end +end From 1ef54b18208d32762bea7c85fdf3fea426f0cfa4 Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 27 Mar 2025 15:11:16 -0400 Subject: [PATCH 03/30] Function name --- src/simplecycles.jl | 4 ++-- test/test_cycles.jl | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/simplecycles.jl b/src/simplecycles.jl index 46e82c3b..cdcfdebe 100644 --- a/src/simplecycles.jl +++ b/src/simplecycles.jl @@ -34,9 +34,9 @@ function unique_cyclesubgraphs_limited_length(g::AbstractNamedGraph, max_cycle_s end """ -Enumerate all unqiue, connected edgesubgraphs without any leaf vertices (degree 1) and with Nedges < max_number_of_edges +Enumerate all unqiue, connected edgesubgraphs without any leaf vertices (degree 1) and with Nedges <= max_number_of_edges """ -function edge_subgraphs_no_leaf_vertices(g::AbstractGraph, max_number_of_edges::Int64) +function edgeinduced_subgraphs_no_leaves(g::AbstractNamedGraph, max_number_of_edges::Int64) edge_subgraphs = unique_cyclesubgraphs_limited_length(g, max_number_of_edges) isempty(edge_subgraphs) && return [] diff --git a/test/test_cycles.jl b/test/test_cycles.jl index 4c2db4ab..5fdaaa98 100644 --- a/test/test_cycles.jl +++ b/test/test_cycles.jl @@ -1,6 +1,6 @@ @eval module $(gensym()) using Graphs: edges, ne, vertices -using NamedGraphs: edge_subgraphs_no_leaf_vertices, unique_simplecycles_limited_length +using NamedGraphs: edgeinduced_subgraphs_no_leaves, unique_simplecycles_limited_length using NamedGraphs.GraphsExtensions: degree, edge_subgraph, is_connected, rem_vertex using NamedGraphs.NamedGraphGenerators: named_comb_tree, named_grid, named_hexagonal_lattice_graph @@ -21,20 +21,20 @@ using Test: @test, @testset @test Set(vertices(g)) == Set(only(all_cycles)) end -@testset "EdgeSubgraphs_NoLeaves" begin +@testset "EdgeInduced_Subgraphs_No_Leaves" begin g = named_comb_tree((3, 3)) - edge_subgraphs = edge_subgraphs_no_leaf_vertices(g, ne(g)) + edge_subgraphs = edgeinduced_subgraphs_no_leaves(g, ne(g)) @test isempty(edge_subgraphs) g = named_hexagonal_lattice_graph(3, 3) - edge_subgraphs = edge_subgraphs_no_leaf_vertices(g, 3) + edge_subgraphs = edgeinduced_subgraphs_no_leaves(g, 3) @test isempty(edge_subgraphs) - edge_subgraphs = edge_subgraphs_no_leaf_vertices(g, 6) + edge_subgraphs = edgeinduced_subgraphs_no_leaves(g, 6) @test all(x -> x == 6, ne.(edge_subgraphs)) - edge_subgraphs = edge_subgraphs_no_leaf_vertices(g, 10) + edge_subgraphs = edgeinduced_subgraphs_no_leaves(g, 10) @test all(x -> x == 6 || x == 10, ne.(edge_subgraphs)) #All nodes have degree > 1 @test all(g -> minimum(degree.((g,), collect(vertices(g)))) > 1, edge_subgraphs) From e752b67ce9f53b1259ad719e666c49b0541710f6 Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:40:14 -0400 Subject: [PATCH 04/30] Update src/simplecycles.jl Co-authored-by: Matt Fishman --- src/simplecycles.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simplecycles.jl b/src/simplecycles.jl index cdcfdebe..2aedd7fb 100644 --- a/src/simplecycles.jl +++ b/src/simplecycles.jl @@ -45,7 +45,7 @@ function edgeinduced_subgraphs_no_leaves(g::AbstractNamedGraph, max_number_of_ed max_genus = round(Int64, ceil(max_number_of_edges / min_loop_size)) subgraph_components = collect(powerset(edge_subgraphs, 1, max_genus)) - edge_subgraphs = [] + edge_subgraphs = typeof(g)[] for sc in subgraph_components g = reduce(union, sc) if is_connected(g) && ne(g) <= max_number_of_edges && g ∉ edge_subgraphs From ea33311931216ed14382d6505883e405d22e150e Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:40:20 -0400 Subject: [PATCH 05/30] Update src/simplecycles.jl Co-authored-by: Matt Fishman --- src/simplecycles.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simplecycles.jl b/src/simplecycles.jl index 2aedd7fb..dbb85eda 100644 --- a/src/simplecycles.jl +++ b/src/simplecycles.jl @@ -6,7 +6,7 @@ using SplitApplyCombine: group function Graphs.simplecycles_limited_length(g::AbstractNamedGraph, max_cycle_size::Int64) vs = collect(vertices(g)) cycles = simplecycles_limited_length(position_graph(g), max_cycle_size) - cycles = [[vs[i] for i in cycle] for cycle in cycles] + cycles = map(cycle -> map(i -> vs[i], cycle), cycles) return cycles end From 29e6f12e1482cebf7fc46452c659fe2018cf8772 Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:40:27 -0400 Subject: [PATCH 06/30] Update src/simplecycles.jl Co-authored-by: Matt Fishman --- src/simplecycles.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/simplecycles.jl b/src/simplecycles.jl index dbb85eda..91471910 100644 --- a/src/simplecycles.jl +++ b/src/simplecycles.jl @@ -34,7 +34,9 @@ function unique_cyclesubgraphs_limited_length(g::AbstractNamedGraph, max_cycle_s end """ -Enumerate all unqiue, connected edgesubgraphs without any leaf vertices (degree 1) and with Nedges <= max_number_of_edges + edgeinduced_subgraphs_no_leaves(g::AbstractNamedGraph, max_number_of_edges::Int64) + +Enumerate all unique, connected edgesubgraphs without any leaf vertices (degree 1) and with Nedges <= max_number_of_edges """ function edgeinduced_subgraphs_no_leaves(g::AbstractNamedGraph, max_number_of_edges::Int64) edge_subgraphs = unique_cyclesubgraphs_limited_length(g, max_number_of_edges) From 4f5e29f93d63fc13a6a6c95288cc457f621d06f7 Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:41:02 -0400 Subject: [PATCH 07/30] Update src/simplecycles.jl Co-authored-by: Matt Fishman --- src/simplecycles.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simplecycles.jl b/src/simplecycles.jl index 91471910..b803bd9b 100644 --- a/src/simplecycles.jl +++ b/src/simplecycles.jl @@ -40,7 +40,7 @@ Enumerate all unique, connected edgesubgraphs without any leaf vertices (degree """ function edgeinduced_subgraphs_no_leaves(g::AbstractNamedGraph, max_number_of_edges::Int64) edge_subgraphs = unique_cyclesubgraphs_limited_length(g, max_number_of_edges) - isempty(edge_subgraphs) && return [] + isempty(edge_subgraphs) && return typeof(g)[] #Take powerset, but don't exceed max_number of edges and remove disconnected components min_loop_size = minimum(length.(edges.(edge_subgraphs))) From a52380033ff48bbe68b94b4ce44431e7c2856b0c Mon Sep 17 00:00:00 2001 From: Joey Date: Mon, 31 Mar 2025 09:42:39 -0400 Subject: [PATCH 08/30] Remove redundant arg --- src/simplecycles.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simplecycles.jl b/src/simplecycles.jl index b803bd9b..9ebf99fa 100644 --- a/src/simplecycles.jl +++ b/src/simplecycles.jl @@ -21,7 +21,7 @@ function unique_simplecycles_limited_length(g::AbstractNamedGraph, max_cycle_siz return cycles end -function cycle_to_path(g::AbstractNamedGraph, cycle::Vector) +function cycle_to_path(cycle::Vector) es = [NamedEdge(cycle[i] => cycle[i + 1]) for i in 1:(length(cycle) - 1)] final_edge = NamedEdge(first(cycle) => last(cycle)) return vcat(es, final_edge) @@ -29,7 +29,7 @@ end function unique_cyclesubgraphs_limited_length(g::AbstractNamedGraph, max_cycle_size::Int64) cycles = unique_simplecycles_limited_length(g, max_cycle_size) - paths = cycle_to_path.((g,), cycles) + paths = cycle_to_path.(cycles) return edge_subgraph.((g,), paths) end From 03f4de9c102b13900696e0d4ef57f1df4b0e08e6 Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 24 Sep 2025 17:04:19 -0400 Subject: [PATCH 09/30] PartitionedGraphView --- .../src/PartitionedGraphs.jl | 1 + .../src/partitionedgraphview.jl | 36 +++++++++++++++++++ test/test_partitionedgraph.jl | 6 ++++ 3 files changed, 43 insertions(+) create mode 100644 src/lib/PartitionedGraphs/src/partitionedgraphview.jl diff --git a/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl b/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl index 57a6b71d..d7464c90 100644 --- a/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl +++ b/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl @@ -5,4 +5,5 @@ include("abstractpartitionedgraph.jl") include("partitionvertex.jl") include("partitionedge.jl") include("partitionedgraph.jl") +include("partitionedgraphview.jl") end diff --git a/src/lib/PartitionedGraphs/src/partitionedgraphview.jl b/src/lib/PartitionedGraphs/src/partitionedgraphview.jl new file mode 100644 index 00000000..4d012f02 --- /dev/null +++ b/src/lib/PartitionedGraphs/src/partitionedgraphview.jl @@ -0,0 +1,36 @@ +struct PartitionedGraphView{PG} + value::PG +end + +value(pgv::PartitionedGraphView) = pgv.value +Base.copy(pgv::PartitionedGraphView) = PartitionedGraphView(copy(value(pgv))) +PartitionedGraph(pgv::PartitionedGraphView) = value(pgv) + +#Functionality that behaves differently +for f in [ + :(Graphs.vertices), + :(Graphs.edges), + :(Graphs.induced_subgraph), + :(Graphs.neighbors), + :(Graphs.degree), + :(Graphs.is_tree), + :(Graphs.is_connected), + :(Graphs.connected_components), + :(Graphs.is_cyclic), + :(NamedGraphs.GraphsExtensions.boundary_edges), +] + @eval begin + function $f(pgv::PartitionedGraphView, args...; kwargs...) + return $f(partitioned_graph(PartitionedGraph(pgv)), args...; kwargs...) + end + end +end + +#Functionality that behaves the same +for f in [:unpartitioned_graph] + @eval begin + function $f(pgv::PartitionedGraphView, args...; kwargs...) + return $f(PartitionedGraph(pgv), args...; kwargs...) + end + end +end diff --git a/test/test_partitionedgraph.jl b/test/test_partitionedgraph.jl index 6d3e034b..459f14b0 100644 --- a/test/test_partitionedgraph.jl +++ b/test/test_partitionedgraph.jl @@ -32,6 +32,7 @@ using NamedGraphs.OrderedDictionaries: OrderedDictionary using NamedGraphs.PartitionedGraphs: PartitionEdge, PartitionedGraph, + PartitionedGraphView, PartitionVertex, boundary_partitionedges, partitioned_graph, @@ -61,6 +62,11 @@ using Test: @test, @testset pg_c = copy(pg) @test pg_c == pg + #PartionedGraphView test + pgv = PartitionedGraphView(pg) + @test vertices(pgv) == parent.(partitionvertices(pg)) + @test edges(pgv) == parent.(partitionedges(pg)) + #Same partitioning but with a dictionary constructor partition_dict = Dictionary([first(partition) for partition in partitions], partitions) pg = PartitionedGraph(g, partition_dict) From 51c71f9f9ebbf8cdb291c4898926550ad80d3ada Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 24 Sep 2025 17:07:20 -0400 Subject: [PATCH 10/30] Version bump --- Project.toml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index b640b78d..05717b04 100644 --- a/Project.toml +++ b/Project.toml @@ -1,14 +1,17 @@ name = "NamedGraphs" uuid = "678767b0-92e7-4007-89e4-4527a8725b19" authors = ["Matthew Fishman , Joseph Tindall and contributors"] -version = "0.6.9" +version = "0.6.10" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" +JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899" +KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b" PackageExtensionCompat = "65ce6f38-6b18-4e1d-a461-8949797d7930" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SimpleGraphAlgorithms = "41400c72-0c58-5c16-8579-4ecbce768449" @@ -20,8 +23,6 @@ Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" [weakdeps] GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" -KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880" -Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b" SymRCM = "286e6d88-80af-4590-acc9-0001b223b9bd" [extensions] @@ -37,6 +38,7 @@ Combinatorics = "1.0.2" Dictionaries = "0.4" Graphs = "1.8" GraphsFlows = "0.1.1" +JuliaFormatter = "2.1.6" KaHyPar = "0.3.1" LinearAlgebra = "1.7" Metis = "1.4" From 2386b4472ab4f1647ebd2e273d7503b3129dd127 Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 24 Sep 2025 19:51:33 -0400 Subject: [PATCH 11/30] Abstruct subtype. Fix toml --- Project.toml | 6 ------ src/lib/PartitionedGraphs/src/partitionedgraphview.jl | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Project.toml b/Project.toml index 05717b04..e316c017 100644 --- a/Project.toml +++ b/Project.toml @@ -8,10 +8,7 @@ AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" -JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899" -KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b" PackageExtensionCompat = "65ce6f38-6b18-4e1d-a461-8949797d7930" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SimpleGraphAlgorithms = "41400c72-0c58-5c16-8579-4ecbce768449" @@ -38,10 +35,7 @@ Combinatorics = "1.0.2" Dictionaries = "0.4" Graphs = "1.8" GraphsFlows = "0.1.1" -JuliaFormatter = "2.1.6" -KaHyPar = "0.3.1" LinearAlgebra = "1.7" -Metis = "1.4" PackageExtensionCompat = "1" SimpleGraphAlgorithms = "0.6.0" SimpleGraphConverter = "0.1.0" diff --git a/src/lib/PartitionedGraphs/src/partitionedgraphview.jl b/src/lib/PartitionedGraphs/src/partitionedgraphview.jl index 4d012f02..d4ad4026 100644 --- a/src/lib/PartitionedGraphs/src/partitionedgraphview.jl +++ b/src/lib/PartitionedGraphs/src/partitionedgraphview.jl @@ -1,4 +1,4 @@ -struct PartitionedGraphView{PG} +struct PartitionedGraphView{V,PG<:AbstractGraph{V}} <: AbstractGraph{V} value::PG end From 668e6dcc051a5e480e6ceb79448612bb5b57a047 Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 24 Sep 2025 19:52:58 -0400 Subject: [PATCH 12/30] Fix toml again --- Project.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Project.toml b/Project.toml index e316c017..3cbef5ca 100644 --- a/Project.toml +++ b/Project.toml @@ -20,6 +20,8 @@ Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" [weakdeps] GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" +KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880" +Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b" SymRCM = "286e6d88-80af-4590-acc9-0001b223b9bd" [extensions] From b7e71aa4ad98eb91592927c4748d33cda0df382e Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 24 Sep 2025 19:53:56 -0400 Subject: [PATCH 13/30] Fix toml again --- Project.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Project.toml b/Project.toml index 3cbef5ca..2fbcace3 100644 --- a/Project.toml +++ b/Project.toml @@ -37,7 +37,9 @@ Combinatorics = "1.0.2" Dictionaries = "0.4" Graphs = "1.8" GraphsFlows = "0.1.1" +KaHyPar = "0.3.1" LinearAlgebra = "1.7" +Metis = "1.4" PackageExtensionCompat = "1" SimpleGraphAlgorithms = "0.6.0" SimpleGraphConverter = "0.1.0" From 4d37a3c9ae20155c720f6d92b0ebf08c5b146988 Mon Sep 17 00:00:00 2001 From: Joseph Tindall <51231103+JoeyT1994@users.noreply.github.com> Date: Fri, 26 Sep 2025 09:49:09 -0400 Subject: [PATCH 14/30] Update src/lib/PartitionedGraphs/src/partitionedgraphview.jl Co-authored-by: Matt Fishman --- src/lib/PartitionedGraphs/src/partitionedgraphview.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lib/PartitionedGraphs/src/partitionedgraphview.jl b/src/lib/PartitionedGraphs/src/partitionedgraphview.jl index d4ad4026..9a3b72f6 100644 --- a/src/lib/PartitionedGraphs/src/partitionedgraphview.jl +++ b/src/lib/PartitionedGraphs/src/partitionedgraphview.jl @@ -1,10 +1,9 @@ struct PartitionedGraphView{V,PG<:AbstractGraph{V}} <: AbstractGraph{V} - value::PG + partitioned_graph::PG end -value(pgv::PartitionedGraphView) = pgv.value -Base.copy(pgv::PartitionedGraphView) = PartitionedGraphView(copy(value(pgv))) -PartitionedGraph(pgv::PartitionedGraphView) = value(pgv) +PartitionedGraph(pgv::PartitionedGraphView) = pgv.partitioned_graph +Base.copy(pgv::PartitionedGraphView) = PartitionedGraphView(copy(PartitionedGraph(pgv))) #Functionality that behaves differently for f in [ From 7083dcb1df2af4caa38b616c6d1f22b0198bd5a5 Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 26 Sep 2025 12:46:06 -0400 Subject: [PATCH 15/30] Refactor --- .../src/PartitionedGraphs.jl | 2 +- .../src/abstractpartitionedgraph.jl | 18 +++--- .../PartitionedGraphs/src/partitionedgraph.jl | 14 ++--- .../src/partitionedgraphview.jl | 35 ------------ .../src/partitionsgraphview.jl | 30 ++++++++++ test/test_partitionedgraph.jl | 56 ++++++++++--------- 6 files changed, 78 insertions(+), 77 deletions(-) delete mode 100644 src/lib/PartitionedGraphs/src/partitionedgraphview.jl create mode 100644 src/lib/PartitionedGraphs/src/partitionsgraphview.jl diff --git a/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl b/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl index d7464c90..a14d5efb 100644 --- a/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl +++ b/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl @@ -5,5 +5,5 @@ include("abstractpartitionedgraph.jl") include("partitionvertex.jl") include("partitionedge.jl") include("partitionedgraph.jl") -include("partitionedgraphview.jl") +include("partitionsgraphview.jl") end diff --git a/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl b/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl index 246dfe38..3e9143dd 100644 --- a/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl +++ b/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl @@ -16,7 +16,7 @@ using ..NamedGraphs.GraphsExtensions: abstract type AbstractPartitionedGraph{V,PV} <: AbstractNamedGraph{V} end #Needed for interface -partitioned_graph(pg::AbstractPartitionedGraph) = not_implemented() +partitions_graph(pg::AbstractPartitionedGraph) = not_implemented() unpartitioned_graph(pg::AbstractPartitionedGraph) = not_implemented() function unpartitioned_graph_type(pg::Type{<:AbstractPartitionedGraph}) return not_implemented() @@ -75,11 +75,11 @@ end function Graphs.has_vertex( pg::AbstractPartitionedGraph, partitionvertex::AbstractPartitionVertex ) - return has_vertex(partitioned_graph(pg), parent(partitionvertex)) + return has_vertex(partitions_graph(pg), parent(partitionvertex)) end function Graphs.has_edge(pg::AbstractPartitionedGraph, partitionedge::AbstractPartitionEdge) - return has_edge(partitioned_graph(pg), parent(partitionedge)) + return has_edge(partitions_graph(pg), parent(partitionedge)) end function is_boundary_edge(pg::AbstractPartitionedGraph, edge::AbstractEdge) @@ -91,17 +91,17 @@ function Graphs.add_edge!(pg::AbstractPartitionedGraph, edge::AbstractEdge) add_edge!(unpartitioned_graph(pg), edge) pg_edge = parent(partitionedge(pg, edge)) if src(pg_edge) != dst(pg_edge) - add_edge!(partitioned_graph(pg), pg_edge) + add_edge!(partitions_graph(pg), pg_edge) end return pg end function Graphs.rem_edge!(pg::AbstractPartitionedGraph, edge::AbstractEdge) pg_edge = partitionedge(pg, edge) - if has_edge(partitioned_graph(pg), pg_edge) + if has_edge(partitions_graph(pg), pg_edge) g_edges = edges(pg, pg_edge) if length(g_edges) == 1 - rem_edge!(partitioned_graph(pg), pg_edge) + rem_edge!(partitions_graph(pg), pg_edge) end end return rem_edge!(unpartitioned_graph(pg), edge) @@ -118,7 +118,7 @@ function Graphs.add_vertex!( pg::AbstractPartitionedGraph, vertex, partitionvertex::AbstractPartitionVertex ) add_vertex!(unpartitioned_graph(pg), vertex) - add_vertex!(partitioned_graph(pg), parent(partitionvertex)) + add_vertex!(partitions_graph(pg), parent(partitionvertex)) insert_to_vertex_map!(pg, vertex, partitionvertex) return pg end @@ -148,7 +148,7 @@ function Graphs.rem_vertex!(pg::AbstractPartitionedGraph, vertex) delete_from_vertex_map!(pg, pv, vertex) rem_vertex!(unpartitioned_graph(pg), vertex) if !haskey(partitioned_vertices(pg), parent(pv)) - rem_vertex!(partitioned_graph(pg), parent(pv)) + rem_vertex!(partitions_graph(pg), parent(pv)) end return pg end @@ -174,7 +174,7 @@ end function Base.:(==)(pg1::AbstractPartitionedGraph, pg2::AbstractPartitionedGraph) if unpartitioned_graph(pg1) != unpartitioned_graph(pg2) || - partitioned_graph(pg1) != partitioned_graph(pg2) + partitions_graph(pg1) != partitions_graph(pg2) return false end for v in vertices(pg1) diff --git a/src/lib/PartitionedGraphs/src/partitionedgraph.jl b/src/lib/PartitionedGraphs/src/partitionedgraph.jl index 5fa1ade2..47adc4cb 100644 --- a/src/lib/PartitionedGraphs/src/partitionedgraph.jl +++ b/src/lib/PartitionedGraphs/src/partitionedgraph.jl @@ -10,7 +10,7 @@ using ..NamedGraphs: NamedEdge, NamedGraph struct PartitionedGraph{V,PV,G<:AbstractGraph{V},PG<:AbstractGraph{PV}} <: AbstractPartitionedGraph{V,PV} graph::G - partitioned_graph::PG + partitions_graph::PG partitioned_vertices::Dictionary which_partition::Dictionary end @@ -46,7 +46,7 @@ function PartitionedGraph(g::AbstractGraph; kwargs...) end #Needed for interface -partitioned_graph(pg::PartitionedGraph) = getfield(pg, :partitioned_graph) +partitions_graph(pg::PartitionedGraph) = getfield(pg, :partitions_graph) unpartitioned_graph(pg::PartitionedGraph) = getfield(pg, :graph) function unpartitioned_graph_type(graph_type::Type{<:PartitionedGraph}) return fieldtype(graph_type, :graph) @@ -70,7 +70,7 @@ function partitionvertices(pg::PartitionedGraph, verts) end function partitionvertices(pg::PartitionedGraph) - return PartitionVertex.(vertices(partitioned_graph(pg))) + return PartitionVertex.(vertices(partitions_graph(pg))) end function partitionedge(pg::PartitionedGraph, edge::AbstractEdge) @@ -86,7 +86,7 @@ function partitionedges(pg::PartitionedGraph, edges::Vector) end function partitionedges(pg::PartitionedGraph) - return PartitionEdge.(edges(partitioned_graph(pg))) + return PartitionEdge.(edges(partitions_graph(pg))) end function Graphs.edges(pg::PartitionedGraph, partitionedge::PartitionEdge) @@ -105,7 +105,7 @@ end function boundary_partitionedges(pg::PartitionedGraph, partitionvertices; kwargs...) return PartitionEdge.( - boundary_edges(partitioned_graph(pg), parent.(partitionvertices); kwargs...) + boundary_edges(partitions_graph(pg), parent.(partitionvertices); kwargs...) ) end @@ -118,7 +118,7 @@ end function Base.copy(pg::PartitionedGraph) return PartitionedGraph( copy(unpartitioned_graph(pg)), - copy(partitioned_graph(pg)), + copy(partitions_graph(pg)), copy(partitioned_vertices(pg)), copy(which_partition(pg)), ) @@ -160,7 +160,7 @@ end function partitionedgraph_induced_subgraph(pg::PartitionedGraph, vertices::Vector) sub_pg_graph, _ = induced_subgraph(unpartitioned_graph(pg), vertices) sub_partitioned_vertices = copy(partitioned_vertices(pg)) - for pv in NamedGraphs.vertices(partitioned_graph(pg)) + for pv in NamedGraphs.vertices(partitions_graph(pg)) vs = intersect(vertices, sub_partitioned_vertices[pv]) if !isempty(vs) sub_partitioned_vertices[pv] = vs diff --git a/src/lib/PartitionedGraphs/src/partitionedgraphview.jl b/src/lib/PartitionedGraphs/src/partitionedgraphview.jl deleted file mode 100644 index 9a3b72f6..00000000 --- a/src/lib/PartitionedGraphs/src/partitionedgraphview.jl +++ /dev/null @@ -1,35 +0,0 @@ -struct PartitionedGraphView{V,PG<:AbstractGraph{V}} <: AbstractGraph{V} - partitioned_graph::PG -end - -PartitionedGraph(pgv::PartitionedGraphView) = pgv.partitioned_graph -Base.copy(pgv::PartitionedGraphView) = PartitionedGraphView(copy(PartitionedGraph(pgv))) - -#Functionality that behaves differently -for f in [ - :(Graphs.vertices), - :(Graphs.edges), - :(Graphs.induced_subgraph), - :(Graphs.neighbors), - :(Graphs.degree), - :(Graphs.is_tree), - :(Graphs.is_connected), - :(Graphs.connected_components), - :(Graphs.is_cyclic), - :(NamedGraphs.GraphsExtensions.boundary_edges), -] - @eval begin - function $f(pgv::PartitionedGraphView, args...; kwargs...) - return $f(partitioned_graph(PartitionedGraph(pgv)), args...; kwargs...) - end - end -end - -#Functionality that behaves the same -for f in [:unpartitioned_graph] - @eval begin - function $f(pgv::PartitionedGraphView, args...; kwargs...) - return $f(PartitionedGraph(pgv), args...; kwargs...) - end - end -end diff --git a/src/lib/PartitionedGraphs/src/partitionsgraphview.jl b/src/lib/PartitionedGraphs/src/partitionsgraphview.jl new file mode 100644 index 00000000..1229d6f5 --- /dev/null +++ b/src/lib/PartitionedGraphs/src/partitionsgraphview.jl @@ -0,0 +1,30 @@ +struct PartitionsGraphView{V,PG<:AbstractGraph{V}} <: AbstractNamedGraph{V} + partitioned_graph::PG +end + +Base.copy(pgv::PartitionsGraphView) = PartitionsGraphView(copy(pgv.partitioned_graph)) +partitions_graph(pgv::PartitionsGraphView) = partitions_graph(pgv.partitioned_graph) + +# AbstractNamedGraph required interface. +function NamedGraphs.position_graph_type(type::Type{<:PartitionsGraphView}) + return fieldtype( + fieldtype(fieldtype(type, :partitioned_graph), :partitions_graph), :position_graph + ) +end + +#Functionality needed to overload most graphs functions onto the partitioned_graph +for f in [ + :(Graphs.vertices), + :(Graphs.edges), + :(NamedGraphs.position_graph), + :(NamedGraphs.vertex_positions), + :(NamedGraphs.ordered_vertices), + :(NamedGraphs.edgetype), + :(NamedGraphs.vertextype), +] + @eval begin + function $f(pgv::PartitionsGraphView, args...; kwargs...) + return $f(partitions_graph(pgv), args...; kwargs...) + end + end +end diff --git a/test/test_partitionedgraph.jl b/test/test_partitionedgraph.jl index 459f14b0..5dc5376a 100644 --- a/test/test_partitionedgraph.jl +++ b/test/test_partitionedgraph.jl @@ -1,19 +1,23 @@ @eval module $(gensym()) using Graphs: + a_star, center, + connected_components, diameter, edges, has_vertex, is_connected, + is_directed, is_tree, ne, + neighbors, nv, radius, random_regular_graph, rem_vertex!, vertices using Metis: Metis -using NamedGraphs: NamedEdge, NamedGraph +using NamedGraphs: NamedEdge, NamedGraph, NamedGraphs using NamedGraphs.GraphsExtensions: add_edges!, add_vertices!, @@ -32,10 +36,10 @@ using NamedGraphs.OrderedDictionaries: OrderedDictionary using NamedGraphs.PartitionedGraphs: PartitionEdge, PartitionedGraph, - PartitionedGraphView, + PartitionsGraphView, PartitionVertex, boundary_partitionedges, - partitioned_graph, + partitions_graph, partitionedge, partitionedges, partitionvertex, @@ -52,25 +56,27 @@ using Test: @test, @testset #Partition it column-wise (into a 1D chain) partitions = [[(i, j) for j in 1:ny] for i in 1:nx] pg = PartitionedGraph(g, partitions) - @test vertextype(partitioned_graph(pg)) == Int64 + @test vertextype(partitions_graph(pg)) == Int64 @test vertextype(unpartitioned_graph(pg)) == vertextype(g) @test isa(partitionvertices(pg), OrderedDictionary{Int64,PartitionVertex{Int64}}) @test isa(partitionedges(pg), Vector{PartitionEdge{Int64,NamedEdge{Int64}}}) - @test is_tree(partitioned_graph(pg)) + @test is_tree(partitions_graph(pg)) @test nv(pg) == nx * ny - @test nv(partitioned_graph(pg)) == nx + @test nv(partitions_graph(pg)) == nx pg_c = copy(pg) @test pg_c == pg #PartionedGraphView test - pgv = PartitionedGraphView(pg) + pgv = PartitionsGraphView(pg) @test vertices(pgv) == parent.(partitionvertices(pg)) @test edges(pgv) == parent.(partitionedges(pg)) + @test is_tree(pgv) == true + @test neighbors(pgv, 1) == [2] #Same partitioning but with a dictionary constructor partition_dict = Dictionary([first(partition) for partition in partitions], partitions) pg = PartitionedGraph(g, partition_dict) - @test vertextype(partitioned_graph(pg)) == vertextype(g) + @test vertextype(partitions_graph(pg)) == vertextype(g) @test vertextype(unpartitioned_graph(pg)) == vertextype(g) @test isa( partitionvertices(pg), @@ -80,19 +86,19 @@ using Test: @test, @testset partitionedges(pg), Vector{PartitionEdge{Tuple{Int64,Int64},NamedEdge{Tuple{Int64,Int64}}}}, ) - @test is_tree(partitioned_graph(pg)) + @test is_tree(partitions_graph(pg)) @test nv(pg) == nx * ny - @test nv(partitioned_graph(pg)) == nx + @test nv(partitions_graph(pg)) == nx pg_c = copy(pg) @test pg_c == pg #Partition the whole thing into just 1 vertex pg = PartitionedGraph([i for i in 1:nx]) - @test unpartitioned_graph(pg) == partitioned_graph(pg) + @test unpartitioned_graph(pg) == partitions_graph(pg) @test nv(pg) == nx - @test nv(partitioned_graph(pg)) == nx + @test nv(partitions_graph(pg)) == nx @test ne(pg) == 0 - @test ne(partitioned_graph(pg)) == 0 + @test ne(partitions_graph(pg)) == 0 pg_c = copy(pg) @test pg_c == pg end @@ -138,22 +144,22 @@ end #Strip the middle column from pg via the partitioned graph vertex, and make a new pg rem_vertex!(pg, pv) - @test !is_connected(unpartitioned_graph(pg)) && !is_connected(partitioned_graph(pg)) - @test parent(pv) ∉ vertices(partitioned_graph(pg)) + @test !is_connected(unpartitioned_graph(pg)) && !is_connected(partitions_graph(pg)) + @test parent(pv) ∉ vertices(partitions_graph(pg)) @test !has_vertex(pg, pv) @test nv(pg) == (nx - 1) * ny - @test nv(partitioned_graph(pg)) == nx - 1 - @test !is_tree(partitioned_graph(pg)) + @test nv(partitions_graph(pg)) == nx - 1 + @test !is_tree(partitions_graph(pg)) #Add the column back to the in place graph add_vertices!(pg, v_set, pv) add_edges!(pg, edges_involving_v_set) - @test is_connected(pg.graph) && is_path_graph(partitioned_graph(pg)) - @test parent(pv) ∈ vertices(partitioned_graph(pg)) + @test is_connected(pg.graph) && is_path_graph(partitions_graph(pg)) + @test parent(pv) ∈ vertices(partitions_graph(pg)) @test has_vertex(pg, pv) - @test is_tree(partitioned_graph(pg)) + @test is_tree(partitions_graph(pg)) @test nv(pg) == nx * ny - @test nv(partitioned_graph(pg)) == nx + @test nv(partitions_graph(pg)) == nx end @testset "Test Partitioned Graph Subgraph Functionality" begin @@ -173,7 +179,7 @@ end pg_2 = subgraph(pg, subgraph_vertices) @test pg_1 == pg_2 @test nv(pg_1) == length(subgraph_vertices) - @test nv(partitioned_graph(pg_1)) == length(subgraph_partitioned_vertices) + @test nv(partitions_graph(pg_1)) == length(subgraph_partitioned_vertices) subgraph_partitioned_vertex = 3 subgraph_vertices = partitions[subgraph_partitioned_vertex] @@ -196,9 +202,9 @@ end pg = PartitionedGraph(g, [vertices(g)]) @test f(pg) == f(unpartitioned_graph(pg)) @test nv(pg) == nv(g) - @test nv(partitioned_graph(pg)) == 1 + @test nv(partitions_graph(pg)) == 1 @test ne(pg) == ne(g) - @test ne(partitioned_graph(pg)) == 0 + @test ne(partitions_graph(pg)) == 0 end end end @@ -215,7 +221,7 @@ end for backend in backends pg = PartitionedGraph(g; npartitions, backend="metis") @test pg isa PartitionedGraph - @test nv(partitioned_graph(pg)) == npartitions + @test nv(partitions_graph(pg)) == npartitions end end end From 500e919074fe10f28cee9dc6e818965360f09ab4 Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 26 Sep 2025 12:52:08 -0400 Subject: [PATCH 16/30] Define partitions_graph(g::AbstractGraph) --- src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl b/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl index 3e9143dd..be97513e 100644 --- a/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl +++ b/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl @@ -1,4 +1,5 @@ using Graphs: + AbstractGraph, Graphs, AbstractEdge, add_vertex!, @@ -15,6 +16,8 @@ using ..NamedGraphs.GraphsExtensions: abstract type AbstractPartitionedGraph{V,PV} <: AbstractNamedGraph{V} end +partitions_graph(g::AbstractGraph) = typeof(g)(1) + #Needed for interface partitions_graph(pg::AbstractPartitionedGraph) = not_implemented() unpartitioned_graph(pg::AbstractPartitionedGraph) = not_implemented() From def431dfcd83430230097f2130f0437658bfd8d2 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Fri, 26 Sep 2025 14:28:11 -0400 Subject: [PATCH 17/30] PartitionsGraphView --- Project.toml | 2 +- .../src/PartitionedGraphs.jl | 1 + .../src/abstractpartitionedgraph.jl | 18 +++--- .../PartitionedGraphs/src/partitionedgraph.jl | 14 ++--- .../src/partitionsgraphview.jl | 31 +++++++++++ test/test_partitionedgraph.jl | 55 +++++++++++-------- 6 files changed, 81 insertions(+), 40 deletions(-) create mode 100644 src/lib/PartitionedGraphs/src/partitionsgraphview.jl diff --git a/Project.toml b/Project.toml index b640b78d..2fbcace3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "NamedGraphs" uuid = "678767b0-92e7-4007-89e4-4527a8725b19" authors = ["Matthew Fishman , Joseph Tindall and contributors"] -version = "0.6.9" +version = "0.6.10" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl b/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl index 57a6b71d..a14d5efb 100644 --- a/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl +++ b/src/lib/PartitionedGraphs/src/PartitionedGraphs.jl @@ -5,4 +5,5 @@ include("abstractpartitionedgraph.jl") include("partitionvertex.jl") include("partitionedge.jl") include("partitionedgraph.jl") +include("partitionsgraphview.jl") end diff --git a/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl b/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl index 246dfe38..3e9143dd 100644 --- a/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl +++ b/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl @@ -16,7 +16,7 @@ using ..NamedGraphs.GraphsExtensions: abstract type AbstractPartitionedGraph{V,PV} <: AbstractNamedGraph{V} end #Needed for interface -partitioned_graph(pg::AbstractPartitionedGraph) = not_implemented() +partitions_graph(pg::AbstractPartitionedGraph) = not_implemented() unpartitioned_graph(pg::AbstractPartitionedGraph) = not_implemented() function unpartitioned_graph_type(pg::Type{<:AbstractPartitionedGraph}) return not_implemented() @@ -75,11 +75,11 @@ end function Graphs.has_vertex( pg::AbstractPartitionedGraph, partitionvertex::AbstractPartitionVertex ) - return has_vertex(partitioned_graph(pg), parent(partitionvertex)) + return has_vertex(partitions_graph(pg), parent(partitionvertex)) end function Graphs.has_edge(pg::AbstractPartitionedGraph, partitionedge::AbstractPartitionEdge) - return has_edge(partitioned_graph(pg), parent(partitionedge)) + return has_edge(partitions_graph(pg), parent(partitionedge)) end function is_boundary_edge(pg::AbstractPartitionedGraph, edge::AbstractEdge) @@ -91,17 +91,17 @@ function Graphs.add_edge!(pg::AbstractPartitionedGraph, edge::AbstractEdge) add_edge!(unpartitioned_graph(pg), edge) pg_edge = parent(partitionedge(pg, edge)) if src(pg_edge) != dst(pg_edge) - add_edge!(partitioned_graph(pg), pg_edge) + add_edge!(partitions_graph(pg), pg_edge) end return pg end function Graphs.rem_edge!(pg::AbstractPartitionedGraph, edge::AbstractEdge) pg_edge = partitionedge(pg, edge) - if has_edge(partitioned_graph(pg), pg_edge) + if has_edge(partitions_graph(pg), pg_edge) g_edges = edges(pg, pg_edge) if length(g_edges) == 1 - rem_edge!(partitioned_graph(pg), pg_edge) + rem_edge!(partitions_graph(pg), pg_edge) end end return rem_edge!(unpartitioned_graph(pg), edge) @@ -118,7 +118,7 @@ function Graphs.add_vertex!( pg::AbstractPartitionedGraph, vertex, partitionvertex::AbstractPartitionVertex ) add_vertex!(unpartitioned_graph(pg), vertex) - add_vertex!(partitioned_graph(pg), parent(partitionvertex)) + add_vertex!(partitions_graph(pg), parent(partitionvertex)) insert_to_vertex_map!(pg, vertex, partitionvertex) return pg end @@ -148,7 +148,7 @@ function Graphs.rem_vertex!(pg::AbstractPartitionedGraph, vertex) delete_from_vertex_map!(pg, pv, vertex) rem_vertex!(unpartitioned_graph(pg), vertex) if !haskey(partitioned_vertices(pg), parent(pv)) - rem_vertex!(partitioned_graph(pg), parent(pv)) + rem_vertex!(partitions_graph(pg), parent(pv)) end return pg end @@ -174,7 +174,7 @@ end function Base.:(==)(pg1::AbstractPartitionedGraph, pg2::AbstractPartitionedGraph) if unpartitioned_graph(pg1) != unpartitioned_graph(pg2) || - partitioned_graph(pg1) != partitioned_graph(pg2) + partitions_graph(pg1) != partitions_graph(pg2) return false end for v in vertices(pg1) diff --git a/src/lib/PartitionedGraphs/src/partitionedgraph.jl b/src/lib/PartitionedGraphs/src/partitionedgraph.jl index 5fa1ade2..4ac0a515 100644 --- a/src/lib/PartitionedGraphs/src/partitionedgraph.jl +++ b/src/lib/PartitionedGraphs/src/partitionedgraph.jl @@ -10,7 +10,7 @@ using ..NamedGraphs: NamedEdge, NamedGraph struct PartitionedGraph{V,PV,G<:AbstractGraph{V},PG<:AbstractGraph{PV}} <: AbstractPartitionedGraph{V,PV} graph::G - partitioned_graph::PG + partitions_graph::PG partitioned_vertices::Dictionary which_partition::Dictionary end @@ -46,7 +46,7 @@ function PartitionedGraph(g::AbstractGraph; kwargs...) end #Needed for interface -partitioned_graph(pg::PartitionedGraph) = getfield(pg, :partitioned_graph) +partitions_graph(pg::PartitionedGraph) = PartitionsGraphView(pg) unpartitioned_graph(pg::PartitionedGraph) = getfield(pg, :graph) function unpartitioned_graph_type(graph_type::Type{<:PartitionedGraph}) return fieldtype(graph_type, :graph) @@ -70,7 +70,7 @@ function partitionvertices(pg::PartitionedGraph, verts) end function partitionvertices(pg::PartitionedGraph) - return PartitionVertex.(vertices(partitioned_graph(pg))) + return PartitionVertex.(vertices(pg.partitions_graph)) end function partitionedge(pg::PartitionedGraph, edge::AbstractEdge) @@ -86,7 +86,7 @@ function partitionedges(pg::PartitionedGraph, edges::Vector) end function partitionedges(pg::PartitionedGraph) - return PartitionEdge.(edges(partitioned_graph(pg))) + return PartitionEdge.(edges(pg.partitions_graph)) end function Graphs.edges(pg::PartitionedGraph, partitionedge::PartitionEdge) @@ -105,7 +105,7 @@ end function boundary_partitionedges(pg::PartitionedGraph, partitionvertices; kwargs...) return PartitionEdge.( - boundary_edges(partitioned_graph(pg), parent.(partitionvertices); kwargs...) + boundary_edges(pg.partitions_graph, parent.(partitionvertices); kwargs...) ) end @@ -118,7 +118,7 @@ end function Base.copy(pg::PartitionedGraph) return PartitionedGraph( copy(unpartitioned_graph(pg)), - copy(partitioned_graph(pg)), + copy(pg.partitions_graph), copy(partitioned_vertices(pg)), copy(which_partition(pg)), ) @@ -160,7 +160,7 @@ end function partitionedgraph_induced_subgraph(pg::PartitionedGraph, vertices::Vector) sub_pg_graph, _ = induced_subgraph(unpartitioned_graph(pg), vertices) sub_partitioned_vertices = copy(partitioned_vertices(pg)) - for pv in NamedGraphs.vertices(partitioned_graph(pg)) + for pv in NamedGraphs.vertices(pg.partitions_graph) vs = intersect(vertices, sub_partitioned_vertices[pv]) if !isempty(vs) sub_partitioned_vertices[pv] = vs diff --git a/src/lib/PartitionedGraphs/src/partitionsgraphview.jl b/src/lib/PartitionedGraphs/src/partitionsgraphview.jl new file mode 100644 index 00000000..332e2fd3 --- /dev/null +++ b/src/lib/PartitionedGraphs/src/partitionsgraphview.jl @@ -0,0 +1,31 @@ +struct PartitionsGraphView{V,G<:AbstractGraph{V}} <: AbstractNamedGraph{V} + graph::G +end + +Base.copy(g::PartitionsGraphView) = PartitionsGraphView(copy(g.graph)) + +using Graphs: AbstractGraph +partitions_graph(g::AbstractGraph) = PartitionsGraphView(PartitionedGraph(g, [vertices(g)])) + +# Graphs.jl and NamedGraphs.jl interface overloads for `PartitionsGraphView` wrapping +# a `PartitionedGraph`. +function NamedGraphs.position_graph_type(type::Type{<:PartitionsGraphView{V,G}}) where {V,G<:PartitionedGraph{V}} + return fieldtype(fieldtype(fieldtype(type, :graph), :partitions_graph), :position_graph) +end +for f in [ + :(Graphs.add_vertex!), + :(Graphs.edges), + :(Graphs.vertices), + :(Graphs.rem_vertex!), + :(NamedGraphs.position_graph), + :(NamedGraphs.vertex_positions), + :(NamedGraphs.ordered_vertices), + :(NamedGraphs.edgetype), + :(NamedGraphs.vertextype), +] + @eval begin + function $f(g::PartitionsGraphView{V,G}, args...; kwargs...) where {V,G<:PartitionedGraph{V}} + return $f(g.graph.partitions_graph, args...; kwargs...) + end + end +end diff --git a/test/test_partitionedgraph.jl b/test/test_partitionedgraph.jl index 6d3e034b..677e7706 100644 --- a/test/test_partitionedgraph.jl +++ b/test/test_partitionedgraph.jl @@ -7,6 +7,7 @@ using Graphs: is_connected, is_tree, ne, + neighbors, nv, radius, random_regular_graph, @@ -31,10 +32,11 @@ using NamedGraphs.NamedGraphGenerators: using NamedGraphs.OrderedDictionaries: OrderedDictionary using NamedGraphs.PartitionedGraphs: PartitionEdge, - PartitionedGraph, PartitionVertex, + PartitionedGraph, + PartitionsGraphView, boundary_partitionedges, - partitioned_graph, + partitions_graph, partitionedge, partitionedges, partitionvertex, @@ -51,20 +53,27 @@ using Test: @test, @testset #Partition it column-wise (into a 1D chain) partitions = [[(i, j) for j in 1:ny] for i in 1:nx] pg = PartitionedGraph(g, partitions) - @test vertextype(partitioned_graph(pg)) == Int64 + @test vertextype(partitions_graph(pg)) == Int64 @test vertextype(unpartitioned_graph(pg)) == vertextype(g) @test isa(partitionvertices(pg), OrderedDictionary{Int64,PartitionVertex{Int64}}) @test isa(partitionedges(pg), Vector{PartitionEdge{Int64,NamedEdge{Int64}}}) - @test is_tree(partitioned_graph(pg)) + @test is_tree(partitions_graph(pg)) @test nv(pg) == nx * ny - @test nv(partitioned_graph(pg)) == nx + @test nv(partitions_graph(pg)) == nx pg_c = copy(pg) @test pg_c == pg + #PartionsGraphView test + pgv = PartitionsGraphView(pg) + @test vertices(pgv) == parent.(partitionvertices(pg)) + @test edges(pgv) == parent.(partitionedges(pg)) + @test is_tree(pgv) == true + @test neighbors(pgv, 1) == [2] + #Same partitioning but with a dictionary constructor partition_dict = Dictionary([first(partition) for partition in partitions], partitions) pg = PartitionedGraph(g, partition_dict) - @test vertextype(partitioned_graph(pg)) == vertextype(g) + @test vertextype(partitions_graph(pg)) == vertextype(g) @test vertextype(unpartitioned_graph(pg)) == vertextype(g) @test isa( partitionvertices(pg), @@ -74,19 +83,19 @@ using Test: @test, @testset partitionedges(pg), Vector{PartitionEdge{Tuple{Int64,Int64},NamedEdge{Tuple{Int64,Int64}}}}, ) - @test is_tree(partitioned_graph(pg)) + @test is_tree(partitions_graph(pg)) @test nv(pg) == nx * ny - @test nv(partitioned_graph(pg)) == nx + @test nv(partitions_graph(pg)) == nx pg_c = copy(pg) @test pg_c == pg #Partition the whole thing into just 1 vertex pg = PartitionedGraph([i for i in 1:nx]) - @test unpartitioned_graph(pg) == partitioned_graph(pg) + @test unpartitioned_graph(pg) == partitions_graph(pg) @test nv(pg) == nx - @test nv(partitioned_graph(pg)) == nx + @test nv(partitions_graph(pg)) == nx @test ne(pg) == 0 - @test ne(partitioned_graph(pg)) == 0 + @test ne(partitions_graph(pg)) == 0 pg_c = copy(pg) @test pg_c == pg end @@ -132,22 +141,22 @@ end #Strip the middle column from pg via the partitioned graph vertex, and make a new pg rem_vertex!(pg, pv) - @test !is_connected(unpartitioned_graph(pg)) && !is_connected(partitioned_graph(pg)) - @test parent(pv) ∉ vertices(partitioned_graph(pg)) + @test !is_connected(unpartitioned_graph(pg)) && !is_connected(partitions_graph(pg)) + @test parent(pv) ∉ vertices(partitions_graph(pg)) @test !has_vertex(pg, pv) @test nv(pg) == (nx - 1) * ny - @test nv(partitioned_graph(pg)) == nx - 1 - @test !is_tree(partitioned_graph(pg)) + @test nv(partitions_graph(pg)) == nx - 1 + @test !is_tree(partitions_graph(pg)) #Add the column back to the in place graph add_vertices!(pg, v_set, pv) add_edges!(pg, edges_involving_v_set) - @test is_connected(pg.graph) && is_path_graph(partitioned_graph(pg)) - @test parent(pv) ∈ vertices(partitioned_graph(pg)) + @test is_connected(pg.graph) && is_path_graph(partitions_graph(pg)) + @test parent(pv) ∈ vertices(partitions_graph(pg)) @test has_vertex(pg, pv) - @test is_tree(partitioned_graph(pg)) + @test is_tree(partitions_graph(pg)) @test nv(pg) == nx * ny - @test nv(partitioned_graph(pg)) == nx + @test nv(partitions_graph(pg)) == nx end @testset "Test Partitioned Graph Subgraph Functionality" begin @@ -167,7 +176,7 @@ end pg_2 = subgraph(pg, subgraph_vertices) @test pg_1 == pg_2 @test nv(pg_1) == length(subgraph_vertices) - @test nv(partitioned_graph(pg_1)) == length(subgraph_partitioned_vertices) + @test nv(partitions_graph(pg_1)) == length(subgraph_partitioned_vertices) subgraph_partitioned_vertex = 3 subgraph_vertices = partitions[subgraph_partitioned_vertex] @@ -190,9 +199,9 @@ end pg = PartitionedGraph(g, [vertices(g)]) @test f(pg) == f(unpartitioned_graph(pg)) @test nv(pg) == nv(g) - @test nv(partitioned_graph(pg)) == 1 + @test nv(partitions_graph(pg)) == 1 @test ne(pg) == ne(g) - @test ne(partitioned_graph(pg)) == 0 + @test ne(partitions_graph(pg)) == 0 end end end @@ -209,7 +218,7 @@ end for backend in backends pg = PartitionedGraph(g; npartitions, backend="metis") @test pg isa PartitionedGraph - @test nv(partitioned_graph(pg)) == npartitions + @test nv(partitions_graph(pg)) == npartitions end end end From 9b805b0e80d926704bce501aae854943f39d3f3e Mon Sep 17 00:00:00 2001 From: mtfishman Date: Fri, 26 Sep 2025 14:55:21 -0400 Subject: [PATCH 18/30] Create conflict --- src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl b/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl index 3e9143dd..fa849dde 100644 --- a/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl +++ b/src/lib/PartitionedGraphs/src/abstractpartitionedgraph.jl @@ -1,4 +1,5 @@ using Graphs: + Graphs, AbstractEdge, add_vertex!, @@ -15,6 +16,7 @@ using ..NamedGraphs.GraphsExtensions: abstract type AbstractPartitionedGraph{V,PV} <: AbstractNamedGraph{V} end + #Needed for interface partitions_graph(pg::AbstractPartitionedGraph) = not_implemented() unpartitioned_graph(pg::AbstractPartitionedGraph) = not_implemented() From 3aeffc3c78f63e71acdcac59f69d914973e7d678 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Fri, 26 Sep 2025 15:05:54 -0400 Subject: [PATCH 19/30] Mark as breaking --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 2fbcace3..c839c81b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "NamedGraphs" uuid = "678767b0-92e7-4007-89e4-4527a8725b19" authors = ["Matthew Fishman , Joseph Tindall and contributors"] -version = "0.6.10" +version = "0.7.0" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" From 28dc06f4aa63bfe8b2394d928aaaf0532e4edd89 Mon Sep 17 00:00:00 2001 From: Matt Fishman Date: Fri, 26 Sep 2025 15:28:56 -0400 Subject: [PATCH 20/30] Bump subdir versions --- docs/Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Project.toml b/docs/Project.toml index b91d65d2..16ff40a9 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -4,6 +4,6 @@ Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" [compat] -Documenter = "1.10.0" +Documenter = "1.10" Literate = "2.20.1" -NamedGraphs = "0.6.5" +NamedGraphs = "0.7" From ee14afef8f1ea8e974b6a3850c4db004855a6f44 Mon Sep 17 00:00:00 2001 From: Matt Fishman Date: Fri, 26 Sep 2025 15:29:20 -0400 Subject: [PATCH 21/30] Bump subdir versions --- examples/Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Project.toml b/examples/Project.toml index a7bf512f..ecaf29cf 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -3,5 +3,5 @@ Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" [compat] -Graphs = "1.12.0" -NamedGraphs = "0.6.6" +Graphs = "1.12" +NamedGraphs = "0.7" From 5ab5ff2c9cc43022cb9d0319268c71630772ef01 Mon Sep 17 00:00:00 2001 From: Matt Fishman Date: Fri, 26 Sep 2025 15:30:23 -0400 Subject: [PATCH 22/30] Bump subdir versions --- test/Project.toml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/Project.toml b/test/Project.toml index 2bb21dcc..8ed4731f 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -20,16 +20,16 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" AbstractTrees = "0.4.5" Aqua = "0.8.11" Dictionaries = "0.4.4" -Graphs = "1.12.0" +Graphs = "1.12" GraphsFlows = "0.1.1" KaHyPar = "0.3.1" -Metis = "1.5.0" -NamedGraphs = "0.6.6" -SafeTestsets = "0.1.0" -SimpleGraphAlgorithms = "0.6.0" -SimpleGraphConverter = "0.1.0" +Metis = "1.5" +NamedGraphs = "0.7" +SafeTestsets = "0.1" +SimpleGraphAlgorithms = "0.6" +SimpleGraphConverter = "0.1" Suppressor = "0.2.8" SymRCM = "0.2.2" -Pkg = "1.10.0" -Random = "1.10.0" -Test = "1.10.0" +Pkg = "1.10" +Random = "1.10" +Test = "1.10" From 986acb628037a8fc21b1750e4ab06f320d9674b5 Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 26 Sep 2025 15:32:41 -0400 Subject: [PATCH 23/30] Merge --- examples/Project.toml | 4 ++-- src/lib/PartitionedGraphs/src/partitionsgraphview.jl | 10 +++++++--- test/Project.toml | 10 +++++----- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/examples/Project.toml b/examples/Project.toml index ecaf29cf..123e6c31 100644 --- a/examples/Project.toml +++ b/examples/Project.toml @@ -3,5 +3,5 @@ Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" NamedGraphs = "678767b0-92e7-4007-89e4-4527a8725b19" [compat] -Graphs = "1.12" -NamedGraphs = "0.7" +Graphs = "1.12.0" +NamedGraphs = "0.7.0" diff --git a/src/lib/PartitionedGraphs/src/partitionsgraphview.jl b/src/lib/PartitionedGraphs/src/partitionsgraphview.jl index 332e2fd3..20d294b4 100644 --- a/src/lib/PartitionedGraphs/src/partitionsgraphview.jl +++ b/src/lib/PartitionedGraphs/src/partitionsgraphview.jl @@ -9,8 +9,10 @@ partitions_graph(g::AbstractGraph) = PartitionsGraphView(PartitionedGraph(g, [ve # Graphs.jl and NamedGraphs.jl interface overloads for `PartitionsGraphView` wrapping # a `PartitionedGraph`. -function NamedGraphs.position_graph_type(type::Type{<:PartitionsGraphView{V,G}}) where {V,G<:PartitionedGraph{V}} - return fieldtype(fieldtype(fieldtype(type, :graph), :partitions_graph), :position_graph) +function NamedGraphs.position_graph_type( + type::Type{<:PartitionsGraphView{V,G}} +) where {V,G<:PartitionedGraph{V}} + return fieldtype(fieldtype(fieldtype(type, :graph), :partitions_graph), :position_graph) end for f in [ :(Graphs.add_vertex!), @@ -24,7 +26,9 @@ for f in [ :(NamedGraphs.vertextype), ] @eval begin - function $f(g::PartitionsGraphView{V,G}, args...; kwargs...) where {V,G<:PartitionedGraph{V}} + function $f( + g::PartitionsGraphView{V,G}, args...; kwargs... + ) where {V,G<:PartitionedGraph{V}} return $f(g.graph.partitions_graph, args...; kwargs...) end end diff --git a/test/Project.toml b/test/Project.toml index 8ed4731f..e75deaf5 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -23,11 +23,11 @@ Dictionaries = "0.4.4" Graphs = "1.12" GraphsFlows = "0.1.1" KaHyPar = "0.3.1" -Metis = "1.5" -NamedGraphs = "0.7" -SafeTestsets = "0.1" -SimpleGraphAlgorithms = "0.6" -SimpleGraphConverter = "0.1" +Metis = "1.5.0" +NamedGraphs = "0.7.0" +SafeTestsets = "0.1.0" +SimpleGraphAlgorithms = "0.6.0" +SimpleGraphConverter = "0.1.0" Suppressor = "0.2.8" SymRCM = "0.2.2" Pkg = "1.10" From 43e4ba0d5200c169f6b342e159cf77c7573f0f67 Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 8 Jul 2026 09:55:12 +0200 Subject: [PATCH 24/30] Fix edge subgraph --- Project.toml | 6 +----- src/abstractnamedgraph.jl | 7 ------- src/namedgraph.jl | 18 ++++++++++++++++++ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Project.toml b/Project.toml index 0c91d1f6..df748b75 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "NamedGraphs" uuid = "678767b0-92e7-4007-89e4-4527a8725b19" -version = "0.12.1" +version = "0.12.2" authors = ["Matthew Fishman , Joseph Tindall and contributors"] [workspace] @@ -21,12 +21,10 @@ SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" [weakdeps] -GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" ITensorVisualizationBase = "cd2553d2-8bef-4d93-8a38-c62f17d5ad23" KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880" Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b" SimpleGraphAlgorithms = "41400c72-0c58-5c16-8579-4ecbce768449" -SymRCM = "286e6d88-80af-4590-acc9-0001b223b9bd" [extensions] NamedGraphsGraphsFlowsExt = "GraphsFlows" @@ -41,7 +39,6 @@ AbstractTrees = "0.3, 0.4" Combinatorics = "1.0.2" Dictionaries = "0.4" Graphs = "1.8" -GraphsFlows = "0.1.1" ITensorVisualizationBase = "0.1" KaHyPar = "0.3.1" LinearAlgebra = "1.10" @@ -53,5 +50,4 @@ SimpleTraits = "0.9" SparseArrays = "1.10" SplitApplyCombine = "1.2.2" Suppressor = "0.2" -SymRCM = "0.2.1" julia = "1.10" diff --git a/src/abstractnamedgraph.jl b/src/abstractnamedgraph.jl index 6d99927b..8a230d29 100644 --- a/src/abstractnamedgraph.jl +++ b/src/abstractnamedgraph.jl @@ -569,10 +569,3 @@ function GraphsExtensions.edge_subgraph( ) return edge_subgraph_namedgraph(graph, to_edges(graph, edges)) end - -function edge_subgraph_namedgraph(graph, edgelist) - vs = unique(vcat(src.(edgelist), dst.(edgelist))) - g = subgraph(graph, vs) - g = rem_edges!(g, setdiff(edges(g), edgelist)) - return g -end diff --git a/src/namedgraph.jl b/src/namedgraph.jl index 66e96463..b93f8fda 100644 --- a/src/namedgraph.jl +++ b/src/namedgraph.jl @@ -225,3 +225,21 @@ end function GraphsExtensions.similar_graph(T::Type{<:GenericNamedGraph}, vertices) return T(vertices) end + +function edge_subgraph_namedgraph(graph::NamedDiGraph, edgelist) + vs = unique(vcat(src.(edgelist), dst.(edgelist))) + g = subgraph(graph, vs) + g = rem_edges!(g, setdiff(edges(g), edgelist)) + return g +end + +function edge_subgraph_namedgraph(graph::NamedGraph, edgelist) + vs = unique(vcat(src.(edgelist), dst.(edgelist))) + g = subgraph(graph, vs) + for e in edges(g) + if !(e ∈ edgelist || reverse(e) ∈ edgelist) + rem_edge!(g, e) + end + end + return g +end From 035046cb43c9139dc72b0deb286b5153b7844fa8 Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 8 Jul 2026 09:58:47 +0200 Subject: [PATCH 25/30] Update tests --- test/test_namedgraph.jl | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/test/test_namedgraph.jl b/test/test_namedgraph.jl index 18d21b0a..2d735b2a 100644 --- a/test/test_namedgraph.jl +++ b/test/test_namedgraph.jl @@ -14,10 +14,10 @@ using Graphs: Edge, a_star, add_edge!, add_vertex!, adjacency_matrix, using GraphsFlows: GraphsFlows using NamedGraphs.GraphsExtensions: GraphsExtensions, boundary_edges, boundary_vertices, convert_vertextype, degrees, dijkstra_mst, dijkstra_parents, dijkstra_tree, - eccentricities, has_vertices, incident_edges, indegrees, inner_boundary_vertices, + eccentricities, edge_subgraph, has_vertices, incident_edges, indegrees, inner_boundary_vertices, mincut_partitions, outdegrees, outer_boundary_vertices, permute_vertices, rename_vertices, subgraph, symrcm_perm, symrcm_permute, vertextype, ⊔ -using NamedGraphs.NamedGraphGenerators: named_binary_tree, named_grid, named_path_graph +using NamedGraphs.NamedGraphGenerators: named_binary_tree, named_grid, named_path_graph, named_hexagonal_lattice_graph using NamedGraphs: AbstractNamedEdge, NamedDiGraph, NamedEdge, NamedGraph, Vertices using SymRCM: SymRCM using Test: @test, @test_broken, @testset @@ -118,6 +118,21 @@ end # Test Graphs.jl `getindex` syntax. @test g_sub == g[Vertices(["A", "B"])] + g_sub = edge_subgraph(g, NamedEdge.(["A" => "B"])) + @test has_vertex(g_sub, "A") + @test has_vertex(g_sub, "B") + @test !has_vertex(g_sub, "C") + @test !has_vertex(g_sub, "D") + @test has_edge(g_sub, "A" => "B") + # Test Graphs.jl `getindex` syntax. + @test g_sub == g[Vertices(["A", "B"])] + + g = named_hexagonal_lattice_graph(3, 3) + es = NamedEdge.([(1, 1) => (2, 1), (2, 1) => (3, 1), (3, 1) => (3, 2), (2, 2) => (3, 2), (1, 2) => (2, 2), (1, 1) => (1, 2)]) + @test all([e ∈ edges(g) for e in es]) + eg = edge_subgraph(g,es) + @test length(edges(eg)) == length(es) + g = NamedGraph(["A", "B", "C", "D", "E"]) add_edge!(g, "A" => "B") add_edge!(g, "B" => "C") From 1e9c330a80a042dd956722e890c3bd67bf99cc68 Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 8 Jul 2026 09:59:20 +0200 Subject: [PATCH 26/30] Fix Project file --- Project.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index df748b75..13a73d08 100644 --- a/Project.toml +++ b/Project.toml @@ -21,10 +21,12 @@ SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66" Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb" [weakdeps] +GraphsFlows = "06909019-6f44-4949-96fc-b9d9aaa02889" ITensorVisualizationBase = "cd2553d2-8bef-4d93-8a38-c62f17d5ad23" KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880" Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b" SimpleGraphAlgorithms = "41400c72-0c58-5c16-8579-4ecbce768449" +SymRCM = "286e6d88-80af-4590-acc9-0001b223b9bd" [extensions] NamedGraphsGraphsFlowsExt = "GraphsFlows" @@ -39,6 +41,7 @@ AbstractTrees = "0.3, 0.4" Combinatorics = "1.0.2" Dictionaries = "0.4" Graphs = "1.8" +GraphsFlows = "0.1.1" ITensorVisualizationBase = "0.1" KaHyPar = "0.3.1" LinearAlgebra = "1.10" @@ -50,4 +53,5 @@ SimpleTraits = "0.9" SparseArrays = "1.10" SplitApplyCombine = "1.2.2" Suppressor = "0.2" -julia = "1.10" +SymRCM = "0.2.1" +julia = "1.10" \ No newline at end of file From 7b632f32fefa82968d06103cd36a8e7d1a7104d4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:00:22 +0000 Subject: [PATCH 27/30] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 13a73d08..c76bb5fd 100644 --- a/Project.toml +++ b/Project.toml @@ -54,4 +54,4 @@ SparseArrays = "1.10" SplitApplyCombine = "1.2.2" Suppressor = "0.2" SymRCM = "0.2.1" -julia = "1.10" \ No newline at end of file +julia = "1.10" From 70db0ed1fe6b496d1280ab27740c0260f0ec4c0a Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 8 Jul 2026 10:40:20 +0200 Subject: [PATCH 28/30] Format --- Project.toml | 2 +- test/test_namedgraph.jl | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Project.toml b/Project.toml index 13a73d08..c76bb5fd 100644 --- a/Project.toml +++ b/Project.toml @@ -54,4 +54,4 @@ SparseArrays = "1.10" SplitApplyCombine = "1.2.2" Suppressor = "0.2" SymRCM = "0.2.1" -julia = "1.10" \ No newline at end of file +julia = "1.10" diff --git a/test/test_namedgraph.jl b/test/test_namedgraph.jl index 2d735b2a..061813ca 100644 --- a/test/test_namedgraph.jl +++ b/test/test_namedgraph.jl @@ -14,10 +14,11 @@ using Graphs: Edge, a_star, add_edge!, add_vertex!, adjacency_matrix, using GraphsFlows: GraphsFlows using NamedGraphs.GraphsExtensions: GraphsExtensions, boundary_edges, boundary_vertices, convert_vertextype, degrees, dijkstra_mst, dijkstra_parents, dijkstra_tree, - eccentricities, edge_subgraph, has_vertices, incident_edges, indegrees, inner_boundary_vertices, - mincut_partitions, outdegrees, outer_boundary_vertices, permute_vertices, - rename_vertices, subgraph, symrcm_perm, symrcm_permute, vertextype, ⊔ -using NamedGraphs.NamedGraphGenerators: named_binary_tree, named_grid, named_path_graph, named_hexagonal_lattice_graph + eccentricities, edge_subgraph, has_vertices, incident_edges, indegrees, + inner_boundary_vertices, mincut_partitions, outdegrees, outer_boundary_vertices, + permute_vertices, rename_vertices, subgraph, symrcm_perm, symrcm_permute, vertextype, ⊔ +using NamedGraphs.NamedGraphGenerators: + named_binary_tree, named_grid, named_hexagonal_lattice_graph, named_path_graph using NamedGraphs: AbstractNamedEdge, NamedDiGraph, NamedEdge, NamedGraph, Vertices using SymRCM: SymRCM using Test: @test, @test_broken, @testset @@ -128,9 +129,18 @@ end @test g_sub == g[Vertices(["A", "B"])] g = named_hexagonal_lattice_graph(3, 3) - es = NamedEdge.([(1, 1) => (2, 1), (2, 1) => (3, 1), (3, 1) => (3, 2), (2, 2) => (3, 2), (1, 2) => (2, 2), (1, 1) => (1, 2)]) - @test all([e ∈ edges(g) for e in es]) - eg = edge_subgraph(g,es) + es = NamedEdge.( + [ + (1, 1) => (2, 1), + (2, 1) => (3, 1), + (3, 1) => (3, 2), + (2, 2) => (3, 2), + (1, 2) => (2, 2), + (1, 1) => (1, 2), + ] + ) + @test all([e in edges(g) for e in es]) + eg = edge_subgraph(g, es) @test length(edges(eg)) == length(es) g = NamedGraph(["A", "B", "C", "D", "E"]) From 5c2b291be636f65c8431e7a3568e58ecf12dd6eb Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 8 Jul 2026 11:12:32 +0200 Subject: [PATCH 29/30] Make abstract --- src/abstractnamedgraph.jl | 11 +++++++++++ src/namedgraph.jl | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/abstractnamedgraph.jl b/src/abstractnamedgraph.jl index 8a230d29..8beee184 100644 --- a/src/abstractnamedgraph.jl +++ b/src/abstractnamedgraph.jl @@ -569,3 +569,14 @@ function GraphsExtensions.edge_subgraph( ) return edge_subgraph_namedgraph(graph, to_edges(graph, edges)) end + +function edge_subgraph_namedgraph(graph, edgelist) + vs = unique(vcat(src.(edgelist), dst.(edgelist))) + g = subgraph(graph, vs) + for e in edges(g) + if !(e ∈ edgelist || reverse(e) ∈ edgelist) + rem_edge!(g, e) + end + end + return g +end diff --git a/src/namedgraph.jl b/src/namedgraph.jl index b93f8fda..63f15adc 100644 --- a/src/namedgraph.jl +++ b/src/namedgraph.jl @@ -232,14 +232,3 @@ function edge_subgraph_namedgraph(graph::NamedDiGraph, edgelist) g = rem_edges!(g, setdiff(edges(g), edgelist)) return g end - -function edge_subgraph_namedgraph(graph::NamedGraph, edgelist) - vs = unique(vcat(src.(edgelist), dst.(edgelist))) - g = subgraph(graph, vs) - for e in edges(g) - if !(e ∈ edgelist || reverse(e) ∈ edgelist) - rem_edge!(g, e) - end - end - return g -end From cbb071e80ae6c65e1e9e4f02671d9f80d2a165dd Mon Sep 17 00:00:00 2001 From: Joey Date: Wed, 8 Jul 2026 16:36:31 +0200 Subject: [PATCH 30/30] Use Set(edgeset) --- src/abstractnamedgraph.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/abstractnamedgraph.jl b/src/abstractnamedgraph.jl index 8beee184..b766e093 100644 --- a/src/abstractnamedgraph.jl +++ b/src/abstractnamedgraph.jl @@ -573,8 +573,9 @@ end function edge_subgraph_namedgraph(graph, edgelist) vs = unique(vcat(src.(edgelist), dst.(edgelist))) g = subgraph(graph, vs) + edgeset = Set(edgelist) for e in edges(g) - if !(e ∈ edgelist || reverse(e) ∈ edgelist) + if !(e ∈ edgeset || reverse(e) ∈ edgeset) rem_edge!(g, e) end end