Add unproject to invert project given the codomain/domain split#211
Merged
Conversation
Adds `unproject(a, ndims_codomain::Val)`, the inverse of `project`: it recovers the dense array `project` maps to `a`, taking the codomain/domain split as a `Val`. The default is `convert(Array, a)`. A backend that changes basis during `project` (for example a graded array that bends its domain legs into the codomain to carry a fermion sign) overloads it to undo that change. `project` and `tryproject` now verify their result through a split-aware `is_projected(dest, src, ndims_codomain::Val)` that compares against `unproject` rather than `convert(Array, dest)`, so such a backend passes its own round-trip check. Behavior is unchanged for backends that store the projection in the plain dense layout such as a dense array or a `TensorMap`, for which `unproject` is `convert(Array, ·)`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #211 +/- ##
==========================================
- Coverage 81.53% 81.48% -0.06%
==========================================
Files 26 26
Lines 975 983 +8
==========================================
+ Hits 795 801 +6
- Misses 180 182 +2
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:
|
The two-argument `is_projected` now forwards to the split-aware form using the destination's own codomain rank, given by a new `ndims_codomain` accessor (`ndims` by default, `numout` for a `TensorMap`). This removes the duplicated method body and makes the two-argument form the split-aware check at the destination's own split. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mtfishman
added a commit
to ITensor/GradedArrays.jl
that referenced
this pull request
Jul 21, 2026
## Summary `project(A, codomain, domain)` for a fermionic operator now bends its domain (bra) legs, multiplying each stored block by the `±1` fermion sign of moving them past the codomain, so the operator contracts like the corresponding `TensorMap`. Previously the three-argument operator projection collapsed to the naive dual form and dropped that sign, so an operator with a both-odd domain block (for example a hopping gate's doubly-occupied diagonal) contracted with the wrong sign. `unproject(a, Val(K))` inverts the bend given the codomain/domain split, and `project` runs its self-check through it so the round trip holds. This builds on the `unproject` verb from ITensor/TensorAlgebra.jl#211. This also fixes the fermion permutation and bend signs in `matricizeopperm`, `unmatricizeperm!`, and `bipermutedimsopadd!`, so fermionic contraction no longer depends on contraction order. Breaking (`0.14.0`) because it changes the results of fermionic operator contraction. --------- Co-authored-by: Claude Opus 4.8 (1M context) <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.
Summary
Adds
unproject(a, ndims_codomain::Val), the inverse ofproject. It recovers the dense array thatprojectmapsafrom, given the codomain/domain split as aVal. The default isconvert(Array, a). A backend that changes basis duringprojectoverloadsunprojectto undo that change, so thatunproject(project(raw, codomain_axes, domain_axes), Val(length(codomain_axes)))recoversraw.projectandtryprojectnow run theiris_projectedself-check throughunprojectwith the split they were handed, instead of comparing againstconvert(Array, dest). A backend that stores the projection in the plain dense layout is unaffected. A backend that changes basis inprojectis now checked in the frame the input was given in, so its self-check passes. The two-argumentis_projectedforwards to this split-aware form using the destination's own codomain rank, a newndims_codomainaccessor that aTensorMapoverloads withnumout.The TensorKit extension defines
unprojectforAbstractTensorMapasconvert(Array, ·), which already undoes the domain braiding, guarded by a check that the passed split matches the map's codomain rank.