[WIP] Rework NamedTensorOperator around output/input pairing#222
Draft
mtfishman wants to merge 3 commits into
Draft
[WIP] Rework NamedTensorOperator around output/input pairing#222mtfishman wants to merge 3 commits into
mtfishman wants to merge 3 commits into
Conversation
Rename the operator's dimension-name accessors from codomainnames/domainnames to outputnames/inputnames, and store the pairing as two equal-length name vectors over the wrapped tensor instead of a Bijection (linear findfirst is faster than hashing for the few paired legs an operator carries, and it drops the OrderedCollections dependency). Add outputname/inputname get-style wire lookups, express apply as a contraction followed by an output-to-input relabel, and define product as composition on matching sites, gated by check_product.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #222 +/- ##
==========================================
- Coverage 76.13% 73.67% -2.46%
==========================================
Files 29 28 -1
Lines 1697 1683 -14
==========================================
- Hits 1292 1240 -52
- Misses 405 443 +38
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:
|
Add two-argument `outputname(a, i)` / `inputname(a, i)` that return the paired name and throw a clear `ArgumentError` when `i` is unpaired, alongside the three-argument get-style forms that return a supplied default.
Rework `apply` so applying an operator to another operator returns an operator: `x`'s inputs land on `y`'s outputs, each consumed output of `x` is relabeled back to its input, and uncontracted structure passes through, with a disjoint part of `x` tensored in. Applying to a bare state still returns a state, and `check_apply` rejects landing an input of `x` on an input of `y`. Remove `apply_dag`, which was unused. The dagger application is `apply(adjoint(x), y)`.
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
Reworks
NamedTensorOperatorto describe an operator as a wrapped tensor plus a pairing of its dimension names into an output side and an input side, renaming thecodomainnames/domainnamesaccessors tooutputnames/inputnames. The rename freescodomain/domainfor the tensor's own structural split, which is separate from the operator's output/input pairing.The pairing is now stored as two equal-length name vectors over the wrapped tensor instead of a
Bijection. Lookups are a linearfindfirst, which is faster than hashing for the handful of paired legs an operator carries and drops theOrderedCollectionsdependency.outputname/inputnamelook up a wire's other end, with a three-argumentget-style form that returns a supplied default when a name is unpaired (so a caller can writeinputname(op, i, i)for "the other end of the wire, oriitself") and a two-argument form that throws instead.apply(x, y)appliesxtoy, landingx's inputs ony's outputs (or a plain state's legs) and relabeling each consumed output ofxback to its input, so the result sits onx's input space. Applying an operator to a state gives a state and applying it to another operator gives an operator, with a disjoint part ofxtensored in.check_applyrejects landing an input ofxon an input ofy.apply_dagis removed, since the dagger application isapply(adjoint(x), y).product(a, b)composes operators on matching sites: a name that is an input of both operands is welded through a fresh bond so the site composes, while dangling names such as batch and Kraus dimensions contract the way*contracts them. The rule that keeps a product well defined is factored intocheck_product: a wire ofaand a wire ofbmust either be the same wire, which welds, or share no name, which stays independent. Connecting two operators end to end through a shared bond is left to*, which already returns the composed operator.Priming is demoted from a pairing mechanism to a naming convenience. The pairing is explicit data, so
prime/noprimesurvive only as name generators for constructing operators, and any pair of distinct names describes a wire equally well.TODO
codomainnames/domainnamesaccessors.