Skip to content

Commit 837fabb

Browse files
mtfishmanclaude
andcommitted
Loosen linkdim(::AbstractITensorNetwork, ::AbstractEdge) signature
The previous signature `linkdim(tn::AbstractITensorNetwork{V}, edge::AbstractEdge{V}) where V` required the network's vertex-type parameter and the edge's vertex-type parameter to match exactly. For graphs with abstract V (e.g. the `NamedGraph{Tuple}` produced by `named_binary_tree`, where vertices are tuples of varying arity), downstream operations can produce edges whose V parameter is a strict subtype — for example, `subgraph(g, vs)` where `vs` came from a Dict's keys and concretized to `Tuple{Int64, Vararg{Int64}}`. In that situation dispatch failed with `MethodError` even though `linkinds` itself accepts the edge fine. Drop the `{V}` constraint so `linkdim` accepts any `AbstractEdge` alongside any `AbstractITensorNetwork`. Behavior is unchanged for cases that previously dispatched; previously-failing cases now go through. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c0cb74d commit 837fabb

2 files changed

Lines changed: 32 additions & 3 deletions

File tree

src/abstractitensornetwork.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ function linkdim(tn::AbstractITensorNetwork, edge::Pair)
556556
return linkdim(tn, edgetype(tn)(edge))
557557
end
558558

559-
function linkdim(tn::AbstractITensorNetwork{V}, edge::AbstractEdge{V}) where {V}
559+
function linkdim(tn::AbstractITensorNetwork, edge::AbstractEdge)
560560
ls = linkinds(tn, edge)
561561
return prod([isnothing(l) ? 1 : dim(l) for l in ls])
562562
end

test/test_itensornetwork.jl

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ using ITensors.NDTensors: NDTensors, dim
99
using ITensors: ITensors, ITensor, Index, Op, commonind, commoninds, contract, dag, hasinds,
1010
inds, inner, itensor, onehot, order, prime, random_itensor, scalartype, sim
1111
using NDTensors: NDTensors, dim
12-
using NamedGraphs.GraphsExtensions: disjoint_union, incident_edges
13-
using NamedGraphs.NamedGraphGenerators: named_comb_tree, named_grid
12+
using NamedGraphs.GraphsExtensions: disjoint_union, incident_edges, subgraph
13+
using NamedGraphs.NamedGraphGenerators: named_binary_tree, named_comb_tree, named_grid
1414
using NamedGraphs: NamedEdge
1515
using Random: randn!
1616
using StableRNGs: StableRNG
@@ -250,4 +250,33 @@ const elts = (Float32, Float64, Complex{Float32}, Complex{Float64})
250250
tn = random_tensornetwork(rng, is; link_space = 3)
251251
@test_broken swapprime(tn, 0, 2)
252252
end
253+
254+
# `named_binary_tree` has vertices of varying tuple arity (`(1,)`, `(1,1)`,
255+
# …), so its V parameter is the abstract `Tuple`. Downstream graph
256+
# operations can produce edges with a more concrete vertex-type parameter —
257+
# for example `subgraph(g, collect(keys(dict)))` where the dict's key type
258+
# has concretized to `Tuple{Int64, Vararg{Int64}}`. Previously
259+
# `linkdim(::AbstractITensorNetwork{V}, ::AbstractEdge{V}) where V` required
260+
# both `V`s to match exactly and failed in that case; the loosened signature
261+
# accepts any compatible edge.
262+
@testset "linkdim accepts an AbstractEdge whose vertex type is a subtype" begin
263+
g = named_binary_tree(3)
264+
is = siteinds("S=1/2", g)
265+
rng = StableRNG(1234)
266+
tn = random_tensornetwork(rng, is; link_space = 3)
267+
@test tn isa ITensorNetwork{Tuple}
268+
269+
# The matching-V case still works.
270+
e = first(edges(g))
271+
@test e isa NamedEdge{Tuple}
272+
@test ITensorNetworks.linkdim(tn, e) == 3
273+
274+
# The concrete-V edge from a typed-key Dict-driven subgraph, which is
275+
# the path that was previously broken.
276+
site_inds = Dict(v => is[v] for v in vertices(g))
277+
g_sub = subgraph(g, collect(keys(site_inds)))
278+
e_concrete = first(edges(g_sub))
279+
@test e_concrete isa NamedEdge{Tuple{Int, Vararg{Int}}}
280+
@test ITensorNetworks.linkdim(tn, e_concrete) == 3
281+
end
253282
end

0 commit comments

Comments
 (0)