Skip to content

Add VertexDataGraph and EdgeDataGraph as concrete subtypes of AbstractVertexOrEdgeDataGraph#121

Open
jack-dunham wants to merge 28 commits into
mainfrom
jd/vertex-edge-datagraph
Open

Add VertexDataGraph and EdgeDataGraph as concrete subtypes of AbstractVertexOrEdgeDataGraph#121
jack-dunham wants to merge 28 commits into
mainfrom
jd/vertex-edge-datagraph

Conversation

@jack-dunham
Copy link
Copy Markdown
Contributor

@jack-dunham jack-dunham commented May 15, 2026

This point of this abstract interface is to allow the partial implementation of the Dictionaries.jl interface, on these graph types.

  1. Adds VertexDataGraph and EdgeDataGraph as concrete subtypes of AbstractVertexOrEdgeDataGraph
  2. Also adds AbstractVertexDataGraph and AbstractEdgeDataGraph interfaces.
  3. A new interface function insert_vertex_data that should be overloaded if a given AbstractVertexDataGraph graph isinsertable. See below as to why the analogous interface function doesn't exist for AbstractEdgeDataGraph.

A subtype of AbstractVertexOrEdgeDataGraph implements a stricter indexing interface, inline with the one used by Dictionaries.jl, that is setindex! strictly sets existing indices (doesn't add a vertex/edge that isn't already in the graph). One should use insert! to strictly add a new vertex/edge with data, and set! to perform an upsert (previous behavior of setindex!.

Eventually, this interface will be applied to AbstractDataGraph, but to avoid breaking changes this is deferred until a later date.

Subtleties

Difference in setindex! for vertex and edge data

The setindex! function on an AbstractEdgeDataGraph should add an edge if doesn't exist already. This is unlike setindex! for an AbstractVertexDataGraph, which errors if there vertex is not present. This is in analogy to SparseArrays:

In [36]: rn = sprand(4,4,0.25)
Out[36]: 4×4 SparseMatrixCSC{Float64, Int64} with 5 stored entries:
 0.859026  0.421836      0.719378
                         
          0.105066        
          0.181513        

In [37]: rn_dst = similar(rn, axes(rn))
Out[37]: 4×4 SparseMatrixCSC{Float64, Int64} with 0 stored entries:
               
               
               
               

In [38]: copyto!(rn_dst, rn)
Out[38]: 4×4 SparseMatrixCSC{Float64, Int64} with 5 stored entries:
 0.859026  0.421836      0.719378
                         
          0.105066        
          0.181513        

For an edge data graph, setindex! will only error if the vertices associated to an edge aren't present (irrespective of the existence of an edge).

Difference in insert! and delete! for vertex and edge data

For a vertex data graph, the function insert! inserts a vertex with data, erroring if it already exits. For an edge data graph, insert! also inserts the required vertices and then adds the edge with data, erroring if both vertices are already present. That is, insert! errors where setindex! would not error. The function delete! deletes the edge and data only, leaving the data untouched.

Interface differences

For a settable and insertable vertex data graph, one must define:

set_vertex_data!(graph, vertex, data) # set the vertex data (assuming the vertex exists)
insert_vertex_data!(graph, vertex, data) # insert the vertex data (assuming the vertex _does not_ exist)

An edge data graph only needs:

set_edge_data!(graph, edge, data) # set the edge data (assuming the required vertices exists)

As insert! is defined in terms of add_vertex! and set! (which can create edges).

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

❌ Patch coverage is 77.45098% with 69 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.02%. Comparing base (69a86af) to head (b91cd71).

Files with missing lines Patch % Lines
src/abstractedgeorvertexdatagraph.jl 73.79% 38 Missing ⚠️
src/abstractdatagraph.jl 60.52% 15 Missing ⚠️
src/vertexdatagraph.jl 83.92% 9 Missing ⚠️
src/edgedatagraph.jl 90.62% 6 Missing ⚠️
src/datagraph.jl 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #121      +/-   ##
==========================================
+ Coverage   59.89%   62.02%   +2.13%     
==========================================
  Files          10       12       +2     
  Lines         566      848     +282     
==========================================
+ Hits          339      526     +187     
- Misses        227      322      +95     
Flag Coverage Δ
docs 0.00% <0.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/edgedatagraph.jl Outdated
Comment thread src/vertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/edgedatagraph.jl Outdated
Comment thread src/abstractdatagraph.jl Outdated
Comment thread src/abstractedgeorvertexdatagraph.jl Outdated
Comment thread src/abstractdatagraph.jl Outdated
Comment thread src/edgedatagraph.jl Outdated
Comment thread src/vertexdatagraph.jl Outdated
Comment thread src/vertexdatagraph.jl Outdated
Comment thread src/abstractdatagraph.jl
@mtfishman
Copy link
Copy Markdown
Member

FYI something you can do to temporarily get the tests passing in this PR is to add a [sources] field to the Project.tomls that points to the branch of ITensor/NamedGraphs.jl#170 (I forget if you can just put it in Project.toml or also need it in test/Project.toml). I think that is a nice way to co-develop PRs that depend on each other.

@jack-dunham jack-dunham force-pushed the jd/vertex-edge-datagraph branch from 07854cc to 71fbb01 Compare May 27, 2026 20:10
@jack-dunham jack-dunham force-pushed the jd/vertex-edge-datagraph branch from d1089dd to b91cd71 Compare May 27, 2026 20:22
Comment on lines +26 to +41
function Base.copy(graph::AbstractVertexOrEdgeDataGraph)
graph_dst = similar_graph(graph)
# Allow copies of graphs with undefined data.
copyto!(graph_dst, graph, filter(key -> isassigned(graph, key), keys(graph)))
return graph_dst
end

function Base.copyto!(graph_dst::AbstractVertexOrEdgeDataGraph, src)
copyto!(graph_dst, src, keys(src))
return graph_dst
end

Base.iterate(graph::AbstractVertexOrEdgeDataGraph) = iterate(index_data(graph))
function Base.iterate(graph::AbstractVertexOrEdgeDataGraph, state)
return iterate(index_data(graph), state)
end
Copy link
Copy Markdown
Member

@mtfishman mtfishman May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These all become more subtle if we really embrace the idea that keys(::AbstractEdgeDataGraph) outputs all possible edges. I think it would be ok if we just had different implementations for AbstractEdgeDataGraph and AbstractVertexDataGraph, but it is something to think about. I don't think it is unreasonable to use edges(g) and iterate(EdgeDataView(g)) for iterating over just the edges/edge data. But overall I think we should either fully embrace the abstraction of an edge data graph as a sparse matrix, or treat it fully as a dictionary from edges to edge data, and not have the design be halfway in between those two abstractions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants