Name-based index-set algebra, whole-tensor index ops, and the id/uuid rename#213
Merged
Conversation
…runc ϵ, trivialrange for named ranges Bugfixes and additive index utilities. `ITensor(array, Index-tuple)` now throws with guidance toward `array[i, j]` and `ITensor(array, name.((i, j)))` instead of silently mis-constructing. `replacedimnames` accepts `Index` keys by stripping to the dimname. `svd_trunc` returns the truncation error `ϵ` as a fourth output. And `trivialrange(::NamedUnitRange)` mints a fresh trivial named range on the same backend.
…replaceinds, rank-0 similar/one Whole-tensor index manipulation on `AbstractNamedTensor`. `mapinds(f, t)` relabels every index name-only (leaving the space untouched), with `prime(t)`, `noprime(t)`, and `sim(t)` built on it. `replaceinds` becomes a name-only relabel, a synonym for `replacedimnames`, and `sim(i)` mints a fresh id preserving tags and prime level. `similar(a, ())` and `one(a)` give a rank-0 scalar tensor on `a`'s backend.
Adds `commoninds`, `uniqueinds`, `unioninds`, `noncommoninds`, and `hascommoninds` on `AbstractNamedTensor`, along with the singular `commonind`/`uniqueind` and their non-erroring `trycommonind`/`trynoncommonind` counterparts. Indices are compared by name, so a shared bond matches even when the two tensors carry it as an index on one and its dual on the other.
The function form of `replaceinds`/`mapinds` forwarded straight to `replacedimnames`, so its `f` received a dimension name rather than the index its docstring describes. Apply `f` to each index instead, relabeling name-only through the pair form, so `replaceinds`/`mapinds` are the index-level counterpart of the name-level `replacedimnames`/`mapdimnames`.
…ity constructor Rename the unique-identifier accessor `id` on `IndexName`/`Index` to `uuid` (along with the struct field, the constructor keyword, and the `setuuid` setter), freeing the `id` name for the identity-tensor constructor. Add `id(elt, codomain, domain)`, the from-scratch identity operator over the given codomain and domain indices, a sibling of `one(a, codomain, domain)` that needs only the indices and an element type rather than a prototype tensor. `id` is exported. Breaking: `ITensorBase.id` on an index or index name is now `ITensorBase.uuid`.
`name` already strips an index to its dimension name and passes a bare name through unchanged, so `to_dimname` duplicated it. Call `name` directly when normalizing relabel pairs, which handles either an index or a bare name on either side of the pair.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #213 +/- ##
==========================================
+ Coverage 74.40% 74.65% +0.24%
==========================================
Files 30 30
Lines 1567 1653 +86
==========================================
+ Hits 1166 1234 +68
- Misses 401 419 +18
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:
|
Adds `LinearAlgebra.tr(a, codomain, domain)` for an `AbstractNamedTensor`, plus a `NamedTensorOperator` method, the trace of a named tensor viewed as a map. It pairs each codomain index with the domain index in the same position and sums the diagonal. The contracting identity is built over the dual axes with `similar` and `one!`, so the trace follows the backend (dense, graded, or TensorMap). Adds a map-shaped `Base.similar(a, codomain, domain)` carrying a nontrivial domain, so a graded or TensorMap backend allocates the correct codomain-to-domain block structure. The existing single-axis-tuple forms are all-codomain. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rAlgebra.tr Equality, isequal, and hash on NamedUnitRange now key on the name plus the axis's ungraded extent (via TensorAlgebra.ungrade) rather than the full range. Conjugation preserves the name and the ungraded extent while flipping arrows and charge labels, so an index compares equal to its dual and stock Base set-ops, Dict, and Set treat the two as the same leg. isequal delegates to ==. tr on a named tensor now forwards to TensorAlgebra.tr on the unnamed data, which matricizes into the square matrix and takes the matrix trace, replacing the earlier identity contraction. The two agree for bosons and differ for fermions by the twist sign, and the matricized trace is the plain operator trace. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The map-shaped `similar(a, [elt,] codomain, domain)` now takes its axis lists as any iterable, so a vector or a tuple of named axes both work. The body is already generic over the collection (broadcast plus splat, and `TensorAlgebra.similar_map` accepts either), so the previous `Tuple{Vararg{NamedUnitRange}}` restriction only forced callers to pre-wrap their axes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a `datatype` method for `AbstractNamedTensor` that returns the underlying storage array type by delegating to `TensorAlgebra.datatype` through `unnamed`, so downstream code can get an ITensor's storage type through the shared `TensorAlgebra.datatype` interface rather than a bespoke accessor. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mtfishman
added a commit
to mtfishman/TensorNetworkQuantumSimulator.jl
that referenced
this pull request
Jul 9, 2026
…jl wrappers Continues shrinking `src/itensors.jl` by deleting thin compat wrappers and calling the upstream ITensorBase / TensorAlgebra functions at the call sites instead. Index relabeling uses ITensorBase's `replaceinds` directly (in place of the vendored `replaceind`/`replaceinds` shims, with collection relabels spelled `(from .=> to)...`), storage access uses `unnamed`/`Array` and a `datatype` that now delegates to `TensorAlgebra.datatype` (ITensor/ITensorBase.jl#213), and in-place scaling goes through ITensorBase's `rmul!` for `AbstractNamedTensor`. The list-contraction verb `contract` is renamed to `contract_network`, and tag construction passes a `key => value` pair now that the comma-string `settags` form is gone (`site_tag` returns the site-type tag). `hasqns` stays for contraction-optimizer selection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mtfishman
added a commit
to mtfishman/TensorNetworkQuantumSimulator.jl
that referenced
this pull request
Jul 9, 2026
`simple_update` and `full_update` now take the truncation error from `svd_trunc`'s `ϵ` (the 2-norm of the discarded singular values, exposed in ITensor/ITensorBase.jl#213) as `(ϵ / ‖M‖)^2`. This is the same relative squared error the code reported before, but computed directly instead of by the `1 - ‖S‖²/‖M‖²` subtraction, which lost all precision when little was discarded. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the `TensorAlgebra.datatype(a::AbstractNamedTensor)` method. The generic in TensorAlgebra now reaches the storage through `parent`, and `Base.parent(::NamedTensor)` already returns the unnamed backing, so named tensors resolve through it without a dedicated method. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give the name-based index-set functions, `replaceinds`, and `mapinds` runnable doctests, and simplify the `replaceinds`/`mapinds` docstrings to describe the relabel directly. Credit the TensorKit functions that `id` and `one` are modeled on, and simplify the `id`/`one`/`tr` examples to use `Index` and demonstrate the identity through `tr`. Fix the `tr` doctest so it brings `tr` into scope. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a positional `matricize` form that fuses the two dimension groups into a matrix and mints fresh unique names for the fused row and column dimensions, next to the pair form that takes explicit output names. Both forms now accept any iterable of dimensions per group, so a `Vector` works without wrapping in `Tuple`. Documents both forms with a shared docstring and doctest, and adds tests covering the positional form and vector groups. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
TensorAlgebra 0.17.1 is registered, so drop the branch `[sources]` pin and set the compat floor to 0.17.1, the version that provides the `data`/`datatype` and `matricize` additions this PR builds on. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mtfishman
marked this pull request as ready for review
July 9, 2026 22:40
mtfishman
enabled auto-merge (squash)
July 9, 2026 22:41
The dual-insensitive `NamedUnitRange` hash bypassed `hash_named`, dropping the `:NamedArray` typetag and reordering the fields, so a named range no longer hashed equal to a named array of the same values despite comparing `==` to it, breaking Julia's `a == b` implies `hash(a) == hash(b)` contract. Add `ungrade` on `NamedUnitRange` (strip the grading, keep the name) and hash through `hash_named(:NamedArray, ungrade(r), h)`, matching the named-array hash while keeping the dual-insensitivity. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mtfishman
added a commit
to mtfishman/TensorNetworkQuantumSimulator.jl
that referenced
this pull request
Jul 10, 2026
…upstream API (#2) ## Summary Removes the `ITensorsITensorBaseCompat` submodule and shrinks the remaining legacy shim onto the upstream `ITensorBase` / `TensorAlgebra` / `MatrixAlgebraKit` API. The operator and named-state system, which has no upstream equivalent, becomes a TNQS-owned `Ops` submodule (custom gates extend `Ops.op`, and `state` is called qualified as `Ops.state` so it does not collide with `ITensorBase.state`). The remaining legacy tensor helpers move into an `itensors.jl` shim that this PR then trims: - **Index and tensor ops** move to the upstream versions: `prime`/`noprime` (including the whole-tensor forms), `id`, `sim`, `scalartype`, and the name-based index-set algebra (`commoninds`/`uniqueinds`/`trycommonind`/`trynoncommonind`). `Index` equality is name-based (dual-insensitive), so plain `Base` set-ops work directly on index collections and the local `small`/`name` set helpers and the `commonind`/`noncommonind`/`similar_map` wrappers are gone. - **More index and storage helpers move to the upstream API too:** index relabeling uses ITensorBase's `replaceinds` directly (dropping the vendored `replaceind`/`replaceinds`/`swapind` wrappers, with collection relabels spelled `(from .=> to)...`), storage access uses `unnamed`/`Array` and a `datatype` that delegates to `TensorAlgebra.datatype` (ITensor/ITensorBase.jl#213), and in-place scaling uses ITensorBase's `rmul!`. The `matricize(a::ITensor)` helper is dropped for the upstream `matricize(a, codomain, domain)`, which generates the fused output names itself, so no fresh-name minting remains at the TNQS call sites. The list-contraction verb `contract` is renamed to `contract_network`, and tags are set through `key => value` pairs now that the comma-string `settags` form is gone (`settags` accepts any iterable of pairs). - **Factorizations** at the call sites go straight through MatrixAlgebraKit (`qr_compact`/`svd_compact`/`svd_trunc`/`left_orth`/`right_orth`), and the operator trace is `tr(a, operator_inds(a)...)`. The compat `factorize` and `eigen` wrappers are removed, keeping `itensor_trunc` for the `cutoff`/`maxdim` to `trunc` translation. A call that names the new bond inlines the relabel until tag support lands in the upstream factorizations. The apply routines report their truncation error from `svd_trunc`'s returned `ϵ` instead of a cancellation-prone norm subtraction. - Because `Index` equality is name-based, the contraction-sequence optimizers, the graph index-set operations, and `directsum` take `Index` objects directly, dropping the `name.(...)` labels and comparisons that only worked around dual-mismatched indices. `directsum` now aligns each tensor with `unname`, and gains a first test through the `+`/`add` path. - Legacy no-ops (`disable_warn_order`, `denseblocks`, `dense`) and the first-shrink shims (`random_itensor`, `itensor`, `algorithm_name`, `dim`, `dag`, filtered-`inds`) are dropped for `randn`, `TensorAlgebra.scalar`, `length`, `conj`, and inline `filter` at the call sites. Builds on the ITensorBase and TensorAlgebra API additions in ITensor/ITensorBase.jl#213 and ITensor/TensorAlgebra.jl#205. The `[compat]` floors are ITensorBase 0.11.2 and TensorAlgebra 0.17.2, since those releases additionally carry the `Array(::ITensor)` densification, `namedunitrange(::ElementarySpace)`, and `data` / `datatype` over TensorMap storage that the TensorKit-backed path relies on. --------- 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
A batch of next-generation index and identity utilities for
AbstractNamedTensor, plus one breaking rename. Builds on the TensorAlgebra additions in ITensor/TensorAlgebra.jl#205 (TensorAlgebra 0.17.1).commoninds/uniqueinds/unioninds/noncommoninds/hascommoninds, the singularcommonind/uniqueind, and the non-erroringtrycommonind/trynoncommonind. Indices match by name, andNamedUnitRangeequality is now dual-insensitive, so a shared bond matches even when one tensor carries its dual.prime,noprime, andsimrelabel every index of a tensor.id(elt, codomain, domain)builds the identity operator from indices and an element type alone, andtrtraces a named tensor viewed as a codomain/domain map. Both rest on a map-shapedsimilar(a, codomain, domain)that follows the tensor's backend and takes its axes as any iterable.matricize(a, codomain, domain)fuses two dimension groups into a matrix and generates fresh names for the fused dimensions, next to the pair form that takes explicit names. Both forms accept any iterable of dimensions per group.svd_truncnow returns the truncation error as a fourth output, matching the matrix-level primitive.replacedimnames, andtrivialrangefor aNamedUnitRange.Breaking: the unique-identifier accessor on an index or index name is renamed from
idtouuid, freeingidfor the identity constructor.