[BREAKING] Drop unused methods and reshape basic ITensorNetwork constructor surface#354
Merged
Conversation
…ructor surface
Continuing the legacy ITensorNetworks.jl simplification ahead of the
ITensorNetworksNext.jl migration. Pure-deletion changes for methods
that aren't used by BP / `apply` / DMRG / TDVP, plus a constructor
reshape around two basic forms — `ITensorNetwork(tensors)` (collection
of tensors, edges inferred from shared indices) and
`ITensorNetwork(tensors, graph::NamedGraph)` (collection of tensors
placed at the vertices of a given graph, no edge inference).
## Deletions
- `_gate_vertices` and `_contract_gate` from `apply.jl` — zero callers.
- `neighbor_tensors`, `eachtensor(tn, vertices)` 2-arg form, and
`site_combiners` (which had a `# TODO: will be broken` marker) from
`abstractitensornetwork.jl`.
- `siteinds(tn, vertex)` is reimplemented natively via `setdiff` (matching
ITensorNetworksNext.jl) instead of as an alias for
`uniqueinds(tn, vertex)`. The underlying `uniqueinds(tn, vertex)`
method is removed; the two internal callers (`IndsNetwork(tn)` and
the 1-arg `siteinds(tn)`) switch to `siteinds(tn, v)`.
- `graphs.jl` (just `SimpleGraphs.SimpleGraph(::Vector{ITensor})`) and
`update_observer.jl` (`update_observer!` / `compose_observers` /
`ComposedObservers` / `ValuesObserver`) — both whole files, zero
callers across `src/`.
- Constructors: `ITensorNetwork(::ITensor)`, `ITensorNetwork(::Vector{ITensorNetwork})`
(Kronecker; users can call `reduce(⊗, itns)`), `ITensorNetwork{V}()` and
`ITensorNetwork()` (default empty), `ITensorNetwork(::AbstractVector{<:Pair})`,
`ITensorNetwork(vs, ts)`. The `(::Pair)` and `(vs, ts)` forms are
subsumed by `ITensorNetwork(Dict(...))` or `ITensorNetwork(Dictionary(...))`.
## Constructor reshape
The struct now has a single inner constructor — `ITensorNetwork{V}(tensors,
graph::NamedGraph)` — that places tensors at given vertices without edge
inference. The user-facing `ITensorNetwork(tensors)` form derives the
graph from `keys(tensors)` and runs edge inference (O(n²) until the
reverse-index map design lands). Both forms accept any
`AbstractVector{<:ITensor}` / `AbstractDict{<:Any, <:ITensor}` /
`AbstractDictionary{<:Any, <:ITensor}` (a private `_ITensorCollection`
Union, restricted to avoid a dispatch ambiguity with the function-callback
`ITensorNetwork(f, graph::AbstractNamedGraph)` Group-C form). The
`_ITensorNetwork` internal wrap is deleted; `copy`, `convert_vertextype`,
`similar_graph`, `rename_vertices`, and `union` all route through the
public `(tensors, graph)` inner.
## Doc sync
Removes the corresponding entries from `docs/src/deprecated_methods.md`
that #346 introduced. The Group-C constructor families
(`AbstractNamedGraph`, `AbstractSimpleGraph`, `IndsNetwork` shapes) and
the deferred BP `linkinds(::PartitionedGraph, ::QuotientEdge)` stay in
the deprecated doc — they wait for the reverse-index map design and a
BP refactor respectively.
## Version bump
`0.19.7 → 0.20.0` (breaking, since some of the deletions are public-API).
The `ITensorNetworks` pin in `test/`, `examples/`, and `docs/`
`Project.toml` is bumped from `"0.19"` to `"0.20"` to match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…vertex) Latent breakage from the previous commit: the else-branch of `simple_update_bp_full` (the full-update apply path) called `uniqueinds(ψ, v⃗[1])` and `uniqueinds(ψ, v⃗[2])`, but the underlying `uniqueinds(::AbstractITensorNetwork, vertex)` method was deleted. No test exercises this branch today, but it would error at runtime. Switching to `siteinds(ψ, v⃗[1])` / `siteinds(ψ, v⃗[2])` matches the other simple-update path's call sites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Follow-up cleanup surfaced by the dangling-functions audit on top of the prior commits: - Delete `flatten_linkinds(tn::AbstractITensorNetwork)` from `abstractitensornetwork.jl`. Only used in tests; no algorithm callers. Symmetric `flatten_siteinds` is kept (used by `formnetworks/bilinearformnetwork.jl`). Remove the corresponding test and import, and the `experimental_methods.md` entry. - Delete `indsnetwork(tn::AbstractITensorNetwork)` lowercase alias for `IndsNetwork(tn)`. Zero callers anywhere. - Rewrite the full-update `factorize` Q/R call in `apply.jl` to use `setdiff` directly on `inds(...)` and `siteinds(tn, vertex)` instead of nested `uniqueinds`. Same semantics, fewer wrapper hops. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #354 +/- ##
==========================================
+ Coverage 73.26% 74.36% +1.10%
==========================================
Files 66 64 -2
Lines 3183 3133 -50
==========================================
- Hits 2332 2330 -2
+ Misses 851 803 -48
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…sor}` in copy / conversion paths
Follow-up cleanup on top of the prior commits:
- Delete `flatten_siteinds(tn::AbstractITensorNetwork)` from
`abstractitensornetwork.jl`. The two `src/` call sites in
`formnetworks/bilinearformnetwork.jl` (an `@assert issetequal(...)`
check and an `isempty(...)` check inside the `BilinearFormNetwork`
ctor) inline trivially as
`mapreduce(v -> siteinds(tn, v), vcat, vertices(tn); init = Index[])`.
Update tests and `experimental_methods.md` accordingly.
- Type-annotate the `Dict(...)` literals built inside the parametric
`ITensorNetwork{V}(tensors)` ctor and the `copy` / `convert_vertextype` /
`similar_graph` / `rename_vertices` / `union` paths as
`Dict{V, ITensor}(...)`, locking the dict value type to `ITensor`
regardless of how the comprehension would otherwise infer.
- Add `Base.keys(tn::AbstractITensorNetwork) = vertices(tn)` alongside
the existing `Base.iterate` / `Base.eltype`. With this, an
`AbstractITensorNetwork` is a `keys`/`values`-shaped collection of
tensors keyed by vertex, useful in its own right and a prerequisite
for merging the `ITensorNetwork{V}(tn::ITensorNetwork)` specialization
into the generic `ITensorNetwork{V}(tensors)` once edge inference
becomes cheap (with the reverse index map).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nput vertex list
Two small simplifications + one bug fix on top of the prior commits:
- Delete `eachtensor(tn::AbstractITensorNetwork)` and the concrete
`eachtensor(ψ::ITensorNetwork)`; inline the three internal call sites
(`promote_indtypeof`, `scalartype`, the `visualize` method) as
`mapreduce(v -> ...(tn[v]), ..., vertices(tn))` /
`[tn[v] for v in vertices(tn)]`. Remove `eachtensor` from the
`test_belief_propagation.jl` import list (unused).
- Drop the redundant `Dict{V, ITensor}(...)` and `ITensorNetwork{V}(...)`
parametric annotations from `union`, `rename_vertices`, `Base.copy`,
`convert_vertextype`, `similar_graph`, and the parametric
`ITensorNetwork{V}(tensors)` form. The non-parametric delegate already
extracts `V` via `vertextype(graph)`, and the inner ctor builds
`DataGraph(g; vertex_data_type = ITensor, ...)` regardless of the
input Dict's value type, so the explicit annotations were doing no
work.
- Fix an empty-input bug surfaced by the above. `NamedGraph{V}(Int[])`
with `V = Tuple{Int64}` returns `NamedGraph{Int64}` (vertex type gets
inferred from the empty input element type, overriding the explicit
parametric). The parametric `ITensorNetwork{V}(tensors)` form now
builds the vertex list as `V[v for v in keys(tensors)]` so an empty
`tensors` (e.g. `ITensor[]`, used internally by the IndsNetwork
function-callback ctor when bootstrapping) doesn't drop the parametric
vertex type.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n docs
CI surfaced two issues:
1. Stack overflow in `test/solvers/test_applyexp.jl`. Root cause: when
the parametric `ITensorNetwork{V}(tensors)` form bootstraps an empty
`ITensorNetwork{Any}` (via the IndsNetwork function-callback ctor's
`tn = ITensorNetwork{vertextype(is)}(ITensor[])` for an
`IndsNetwork{Any, Index}`), Julia's type inference gives
`Dict{Any, Any}` for the empty default-tensor comprehension, not
`Dict{Any, ITensor}`. `Dict{Any, Any}` is outside the
`_ITensorCollection` Union, so the next dispatch (`ITensorNetwork(default, g)`)
misses the new `(tensors, graph::NamedGraph)` form and falls through
to the function-callback `ITensorNetwork(f, ::AbstractNamedGraph)`
Group C ctor, which routes back through the IndsNetwork
function-callback ctor — infinite recursion.
Fix: re-add the `Dict{V, ITensor}` annotation at every site where
we build a Dict from a comprehension that may be empty (parametric
`(tensors)` form, `convert_vertextype`, `Base.copy`, `similar_graph`,
`union`, `rename_vertices`). The annotation locks the value type so
the resulting Dict matches `_ITensorCollection` regardless of `V`.
2. Documentation build failed on the `@example` block in
`docs/src/itensor_networks.md:49–56` which used the dropped
`ITensorNetwork(["A", "B", "C"], [A, B, C])` and
`ITensorNetwork(["A" => A, "B" => B, "C" => C])` forms. Replaced
with `ITensorNetwork(Dict("A" => A, "B" => B, "C" => C))` and
`ITensorNetwork(Dictionary(...))` to match the new constructor surface.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The docs `Project.toml` doesn't include `Dictionaries.jl`, so the `using Dictionaries: Dictionary` line in the previous fix made the documentation build fail with "Package Dictionaries not found in current path." Just use `Dict` for the named-vertex example — the example only constructs the network, doesn't assert edge order, so `Dict`'s non-deterministic iteration order doesn't matter here. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 7, 2026
Merged
mtfishman
added a commit
that referenced
this pull request
May 8, 2026
## Summary - PR #354 removed `update_observer!` from ITensorNetworks but left the `ITensorNetworksObserversExt` weak-dependency extension still wired up. Since v0.20.0, any environment that loads ITensorNetworks alongside Observers fails to precompile with `UndefVarError: \`update_observer!\` not defined in \`ITensorNetworks\``. This blocks downstream packages that depend on Observers (e.g. Tennis.jl). - Drop the orphaned `ext/ITensorNetworksObserversExt/` directory, the `Observers` weakdep, the corresponding `[extensions]` entry, and the `Observers` compat bound. Also drop `Observers` from `test/Project.toml` (no test files reference it). - Bump version to `0.21.1` (patch — no public API change beyond the dead-code extension).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reshape the basic
ITensorNetworkconstructor surface around two forms:ITensorNetwork(tensors)— collection of tensors, edges inferred from shared indices.ITensorNetwork(tensors, graph::NamedGraph)— tensors placed at the vertices of a given graph, no edge inference.tensorsis any collection wherekeys(tensors)are vertex labels andvalues(tensors)are theITensors at those vertices (e.g. aDict, aDictionary, or aVector{ITensor}with linear-index vertex labels). The legacy single-ITensorwrap,Vector{ITensorNetwork}(Kronecker product), default-empty (ITensorNetwork{V}()/ITensorNetwork()), pair-vector, and two-vector forms are removed; construct viaDictorDictionaryinstead.Drop unused or trivially-replaceable helpers:
_gate_vertices,_contract_gate(whole helpers, zero callers).neighbor_tensors,eachtensor(tn, vertices)2-arg form,site_combiners(had a# TODO: will be brokenmarker),flatten_linkinds, the lowercaseindsnetworkalias.siteinds(tn, vertex)aliases — the method is kept but is now implemented natively viasetdiffover neighbors (matching ITensorNetworksNext.jl) rather than aliased touniqueinds. The underlyinguniqueinds(tn::AbstractITensorNetwork, vertex)method is removed.src/graphs.jl(justSimpleGraphs.SimpleGraph(::Vector{ITensor}), unused).src/update_observer.jl(update_observer!,compose_observers,ComposedObservers,ValuesObserver; no callers insrc/).Sync
docs/src/deprecated_methods.mdanddocs/src/experimental_methods.mdto reflect the deletions.The
IndsNetwork-,AbstractNamedGraph-, andAbstractSimpleGraph-based constructor families (ITensorNetwork(is::IndsNetwork),ITensorNetwork(::Function, is::IndsNetwork),ITensorNetwork(value, is::IndsNetwork),ITensorNetwork(eltype, undef, is::IndsNetwork), etc.) are not touched in this PR; their removal is being staged separately so it can be reviewed on its own. The same applies to the deprecated per-edge wrapperslinkinds(tn, edge)/commoninds(tn, edge)/uniqueinds(tn, edge), which are still used by internal call sites and are being deferred for replacement with explicit set-function calls (e.g.intersect(inds(tn[src(e)]), inds(tn[dst(e)]))).Release notes:
Breaking. Removed public methods include
ITensorNetwork(::ITensor),ITensorNetwork(::Vector{ITensorNetwork}),ITensorNetwork{V}()andITensorNetwork(),ITensorNetwork(::AbstractVector{<:Pair{<:Any, ITensor}}),ITensorNetwork(vs::AbstractVector, ts::AbstractVector{ITensor}),uniqueinds(tn::AbstractITensorNetwork, vertex),neighbor_tensors,eachtensor(tn, vertices)2-arg form,flatten_linkinds,indsnetwork(lowercase alias),site_combiners,SimpleGraphs.SimpleGraph(::Vector{ITensor}), and the contents ofupdate_observer.jl. Thesiteinds(tn, vertex)accessor is preserved with a re-implemented body. Construct anITensorNetworkfrom collections viaITensorNetwork(tensors)orITensorNetwork(tensors, graph::NamedGraph).