Repository navigation
Add ITensorNetworkOperator and QuadraticFormNetwork data structures - #195
Open
jack-dunham wants to merge 28 commits into
Open
jack-dunham wants to merge 28 commits into
jack-dunham wants to merge 28 commits into
Conversation
Member
|
Your PR no longer requires formatting changes. Thank you for your contribution! |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #195 +/- ##
==========================================
+ Coverage 88.81% 89.40% +0.59%
==========================================
Files 17 19 +2
Lines 724 840 +116
==========================================
+ Hits 643 751 +108
- Misses 81 89 +8
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
jack-dunham
commented
Sep 16, 2026
jack-dunham
commented
Sep 16, 2026
jack-dunham
force-pushed
the
jd/quadraticform
branch
3 times, most recently
from
September 29, 2026 14:48
3457ed5 to
2903a18
Compare
`QuadraticFormNetwork` represents `⟨tn|op|tn⟩` lazily, with an operator layer between the bra and ket layers. A ket index name is renamed in the bra layer when it is a link name or appears in the operator's `inputnames`, so a ket index the operator does not act on still contracts straight onto the bra. `operatortensor` renames each operator output name to the bra name of the input name it is paired with, leaving the input names to meet the ket. The constructor throws unless `vertices(operator)` and `vertices(ket)` are set-equal. `AbstractBilinearFormNetwork` is the new supertype of `NormNetwork` and `QuadraticFormNetwork`. A subtype implements `braname`, `kettensor` and, where it has an operator layer, `operatortensor`; `bratensor`, `conj_bratensor` and `indmap` are defined once in terms of those, so the two concrete files now share them instead of each carrying a copy. `AbstractBilinearFormNetworkView` does the same for `KetView`, `BraView` and the new `OperatorView`: each implements `Base.parent` and `get_vertex_data`, and takes its graph structure, assignment and mutability from the parent network. `test/test_quadraticformnetwork.jl` covers the name map, the three views, and three contractions: an identity operator layer reproduces `contract_network(NormNetwork(tn))`, a random on-site product operator matches a dense `⟨ψ|O|ψ⟩` reference, and a `2I` layer on three vertices scales the norm by 8. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The five files are byte-identical at their new paths; only the `include` paths in `src/ITensorNetworksNext.jl` change. `src/normnetworkview.jl` becomes `bilinearformnetworkview.jl`, since it now holds the views of both `NormNetwork` and `QuadraticFormNetwork`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`OperatorView` now accepts any `AbstractBilinearFormNetwork` rather than only a `QuadraticFormNetwork`, and a second constructor throws an `ArgumentError` for a `NormNetwork`, which reports the reason rather than surfacing a `MethodError`. A `NormNetwork` maps every site index name to itself in its bra layer, so an identity operator between the layers would need its output name to equal its input name, and `ITensor` rejects that: "Dimension names must be distinct". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`encoded_vertex`, `decoded_vertex` and `encoded_graph` move from a `for View in (:KetView, :BraView)` loop in `bilinearformnetworkview.jl` to `AbstractBilinearFormNetworkView` in `abstractbilinearformnetworkview.jl`, replacing the `vertex_positions`/`ordered_vertices`/`position_graph` methods that NamedGraphs 0.13 removed. `OperatorView` is now covered as well, as it was by the methods being replaced. The loop also `@eval`ed against `BraView` above that type's own definition, so including the file threw `UndefVarError: BraView`. `QuadraticFormNetwork` gets the same rename; it still defined the three removed names, so the package did not load. `test_quadraticformnetwork.jl` takes `incident_edges`, `named_grid` and `named_path_graph` from `NamedGraphs` itself, since the `GraphsExtensions` and `NamedGraphGenerators` submodules are gone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`ITensorNetworkOperator` is the network equivalent of `ITensorBase.ITensorOperator`:
a tensor network together with a positional pairing of its dangling index names,
`outputnames[i]` with `inputnames[i]`. The constructor, reached through
`ITensorBase.operator(tn, out, in)`, throws an `ArgumentError` when the two name
lists differ in length and when a named index is not dangling, since
`dimnamevertices` must return exactly one vertex for an operator leg.
A pair may straddle two vertices, as it does for a swap or a translation, so
`getindex` wraps each vertex tensor as an `ITensorOperator` carrying only the pairs
whose two halves both sit on that vertex; the remaining legs are dangling on the
wrapper, which `NamedTensorOperator` permits for names in neither list. The wrapper
is built even when no pair is local, so `eltype` is `NamedTensorOperator{I, T}` for
every vertex.
`QuadraticFormNetwork` takes one as its operator layer. Its `acted` set is now
`Set{I}(inputnames(operator))` rather than a loop over per-vertex input names, and
`operatortensor` reads the network-level pairing: reading `qf.operator[vertex]`
would skip a crossing pair's output leg, which is dangling on that wrapper, and the
bra layer would not meet it. `operatortensor` therefore returns a plain tensor and
`get_vertex_data` drops its `state` call.
`supportof` gains a method for the new type. Its body moves to
`supportof_dimnames(tn, opnames)` in `abstracttensornetwork.jl` so both methods
share it; a `Union` signature is not possible there because
`ITensorNetworkOperator` is not yet defined at that point in the include order.
`replacedimnames` is not implemented for the new type: `ITensorNetwork` has no
`replacedimnames` method to delegate to.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…etwork` `ketnetwork` and `operatornetwork` return the stored ket network and `ITensorNetworkOperator`. `branetwork` defaults to a `BraView`, since a bilinear-form network does not store its bra layer. The belief propagation code for `NormNetwork` now reads its link names through these accessors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ds on `BraView` `BraView` was the only remaining subtype, so it now subtypes `AbstractITensorNetwork` directly and carries the graph, encoding, assignment and mutability forwarding itself. The include order places `bilinearformnetworkview.jl` first, since the forwarding methods now name `BraView`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pure move: the contents of `bilinearformnetworkview.jl` and `abstractbilinearformnetworkview.jl` are appended verbatim, and their `using` lines are merged into the existing imports. `src/bilinearforms/` now holds the interface, `NormNetwork` and `QuadraticFormNetwork`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… `operatortensor` `ITensorNetworkOperator` now throws when a pair's output and input sit on different vertices, so each vertex operator carries its full pairing, and `operatortensor` reads it from `qf.operator[vertex]` rather than from the network-wide name vectors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The output and input name vectors are replaced by one map from each output name to its input name, so `getindex` looks up a vertex's pairs by name instead of scanning every pair. A repeated output name now throws an `ArgumentError`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…map` Graph forwarding, the ket part of `is_vertex_assigned`, `braname` and `kettensor` are defined once on `AbstractBilinearFormNetwork` through `ketnetwork` and a new `branamemap` accessor, and both constructors build the name map with `select_branames`. The unused `indmap` is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`AbstractBilinearFormNetwork{T, V, I}` carries the index name type `I`; `nametype` returns it,
as it does for `ITensorNetwork`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…et layer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… error A `QuadraticFormNetwork`'s factor at a vertex is its ket, operator and bra layers as separate operands. Indexing and `eltype` now throw, as they do for `NormNetwork`, since the lazy triple-layer product they returned cannot be contracted by `prod_tensors`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jack-dunham
force-pushed
the
jd/quadraticform
branch
from
October 8, 2026 15:26
794d49b to
ee408ab
Compare
jack-dunham
marked this pull request as ready for review
October 8, 2026 15:32
`inds(tn, v)` and `names(tn, v)` give the indices and names of the tensor at vertex `v`, defaulting to `inds(tn[v])`. The generic link and site functions, `dimnamevertices`, `has_dimname` and `insertlink!` read vertex metadata through them instead of indexing the vertex. Indexing a `BraView` builds the bra tensor through `bratensor`, whose `conj` broadcast allocates a conjugated copy of the ket tensor; `BraView` now overloads `inds(tn, v)` with the conjugated indices of `conj_bratensor`, which only renames. This removes the tensor-sized copies from `similar_message_environment` and from the bra names read after every bilinear-form message update. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The generic method returned a `Vector` in vertex order, while the `ITensorNetwork` method
returned the network's stored `Set` itself, so a caller mutating the result changed
`tn.dimname_vertices`. Both now return a new `Set{vertextype(tn)}`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Defining them on Graphs' `AbstractGraph` added methods of an ITensorBase function to a type neither package owns, which Aqua's piracy check rejects. Every caller passes an `AbstractITensorNetwork`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`select_branames` both chose the names that get a separate bra name and restricted `map` to them. `linknames(tn)` now gives the link names of a whole network, with a fast method for `ITensorNetwork`, and the constructors restrict `map` with Dictionaries' `getindices`: `NormNetwork` to the link names, and `QuadraticFormNetwork` to the link names and the operator's input names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`NormNetwork` and `QuadraticFormNetwork` kept bra names only for the links, so on a network that is part of a larger one, a bond to a vertex outside it kept its ket name in the bra layer. Message updates then left that bond's legs uncontracted. Any index name of the ket layer in the map now gets its own bra name; the one-argument constructors map only the links (and operator inputs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add `derivedname(name, key)`, which replaces the UUID of an `IndexName` with `uuid5(uuid(name), string(key))`, so every process derives the same bra name from the same ket name. `NormNetwork([f], tn, [linknames])` and `QuadraticFormNetwork([f], ket, op, [linknames])` map each link name (and, for the quadratic form, each operator input name) to `f(name)`, with `f` defaulting to `name -> derivedname(name, "bra")`. The inner constructors store the given `Dictionary` as is and `check_input` throws if two bra names coincide or a bra name is already an index name of the ket or operator layer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`derivedname(name, key)` now adds `key` as a bare-label tag, so a default bra name carries a `bra` tag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f a literal `\\` Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Network` `efe6d1d` stored the name map as given, so a map without a link was accepted and `braname` returned the ket name for it. `check_input` now throws if a link name, or for a quadratic form an operator input name, is not a key of the map; other keys are allowed. The checks shared by the two constructors move into `check_branamemap`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`map(f, ::Indices)` keeps the inferred return type of `f`, so a non-inferable `f` gave a
`Dictionary{I, Any}` and no inner constructor method matched. `narrow_map` collects the
values with a comprehension, which takes the type of the values returned.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Add
QuadraticFormNetworkandITensorNetworkOperatorThis adds
QuadraticFormNetwork, a lazy three-layer network (ket, operator, bra) for computing ⟨ψ|O|ψ⟩, and a sharedAbstractBilinearFormNetworksupertype that it andNormNetworkboth use.ITensorNetworkOperator: the network version ofITensorOperator. It's a tensor network plus an output→input pairing of its dangling indices, built withoperator(tn, outputnames, inputnames). Each pair has to sit on one vertex, andop[v]returns that vertex's tensor as anITensorOperator.QuadraticFormNetwork(ψ, O)/quadraticformnetwork(ψ, O): wraps a state and an operator. The operator's inputs connect to the ket, and its outputs are renamed so they connect to the bra. LikeNormNetwork, indexing it throws an error.factor_tensorshands its three layers to BP andprod_tensorsas separate operands.AbstractBilinearFormNetwork: graph forwarding,braname,kettensor,bratensorandnametypeare now defined once here. A subtype only needsketnetworkandbranamemap.NormNetworkis now a subtype.KetViewis replaced byketnetwork(bn), andBraViewis now created withbranetwork(bn), and works for any bilinear-form network.indmapis removed (it was unused).NormNetworkmoved tosrc/bilinearforms/along with the new files.