Add a general directsum built on a concatenation interface#210
Merged
Conversation
Move the generic concatenate machinery into TensorAlgebra as the single source of
truth, included flat (no Concatenate submodule): the lazy Concatenated{Style,Dims,Args},
concatenate/cat/cat!, the cat_axes/cat_axis/cat_style helpers, and the generic
copyto!(::Concatenated{Nothing}) block-placement fallback. Reuse TensorAlgebra's own
unval and zero!, and rename the internal dims/style accessors to concatenated_dims and
concatenated_style to avoid occupying those generic names at the top level.
Add directsum along given dims. Its FusionStyle is resolved by directsum_style, which
defaults to ReshapeFusion for every backend (a straight cat: a valid direct sum for a
dense or AbelianGradedArray backing, no basis rotation). A backend overloads
directsum_style to opt its arrays into a fusing or rotating variant such as SectorFusion,
or the style can be passed explicitly, like matricize(style, ...). directsum_style is
deliberately distinct from FusionStyle(a) (which matricize uses) and from cat_style
(the Concatenated broadcast style).
Downstream packages (SparseArraysBase, GradedArrays) will consolidate onto this copy.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 13, 2026
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #210 +/- ##
==========================================
+ Coverage 80.85% 81.33% +0.47%
==========================================
Files 24 26 +2
Lines 914 975 +61
==========================================
+ Hits 739 793 +54
- Misses 175 182 +7
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:
|
mtfishman
marked this pull request as draft
July 13, 2026 23:48
`directsum_style` now resolves the direct-sum style over several arguments by folding a per-argument `directsum_style(a)` with a binary `directsum_style(s1, s2)` combine, mirroring how `Base.Broadcast` folds `BroadcastStyle`. Two of the same style combine to that style and any mismatch falls back to `ReshapeFusion`, so heterogeneous inputs resolve to a well-defined combined style. This replaces the `directsum_style(as...) = ReshapeFusion()` vararg stub, which ignored its arguments and so was no better than plain vararg dispatch. The default is still `ReshapeFusion` for every backend, so behavior is unchanged. Its binary combine is kept independent of `FusionStyle`'s so the two traits can diverge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The concatenation interface no longer builds a lazy `Concatenated{Style,Dims,Args}` object. Concatenation does not fuse, so there was nothing for the wrapper to defer, and its only real jobs (choosing the destination and the placement per style, and computing the result axes) are expressed directly as functions. `cat`/`cat!`/`concatenate` now resolve the combined `cat_style`, allocate with `cat_similar(style, T, ax, args...)`, and place with `cat_copyto!(dest, style, dims, args...)`. Backends customize concatenation by overloading `cat_similar`/`cat_copyto!` on their style, replacing the previous overloads of `Base.similar`/`Base.copyto!` on `Concatenated{<:TheirStyle}`. The default `cat_copyto!` strips the style to `nothing`, which keeps the "specialize on the destination type without ambiguity against the style dispatch" property the `Concatenated{Nothing}` conversion used to provide. `Concatenated` and `concatenated` are dropped from the public interface.
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 14, 2026
Follows the TensorAlgebra change that replaces the lazy `Concatenated` wrapper with a function interface (ITensor/TensorAlgebra.jl#210). The abelian graded concatenation now overloads `TensorAlgebra.cat_similar(::AbelianGradedStyle, ...)` for the destination and `TensorAlgebra.cat_copyto!(dest, ::AbelianGradedStyle, ...)` for the block placement, in place of the previous `Base.similar`/`Base.copyto!` methods on `Concatenated{<:AbelianGradedStyle}`. Behavior is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
For now `directsum(as...; dims)` is just `cat(as...; dims)`. The `directsum_style` trait (per-argument style plus pairwise combine) had no user yet, since every backend resolved to `ReshapeFusion` and there is no fusing/rotating direct sum implemented, so it was speculative infrastructure. The style selector will come back the same way `matricize` takes a `FusionStyle` once a backend needs the canonicalizing (merge-and-sort) direct sum. `directsum_style` is dropped from the public interface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ments `cat_ndims`, `cat_axes`, and `dims2cat` now implement on their `Val` method and have the plain-value method forward with `Val(dims)`, matching the direction `concatenate` already normalizes. The forward can call `Val` directly rather than through a `to_val` helper, since dispatch guarantees the plain method never receives a `Val`. Also cut the comments down to the non-obvious rationale (the difference from `Base.cat`, the `Broadcasted` reuse, the style-to-`nothing` fallback, the Base attribution). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The keyword-dims entry point is Base.cat, routed to the concatenation interface through the Base._cat overloads that backends define. Keeping a separate TensorAlgebra.cat only shadowed Base.cat, so it is removed. The positional-dims TensorAlgebra names are now concatenate and concatenate!. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fold the separate placement hook into `concatenate!` by leading with the style: `concatenate!(::BroadcastStyle, dest, dims, args...)` is the generic placement, and `concatenate!(dest, args...; dims)` forwards to it after computing `cat_style`. A backend customizes placement by overloading `concatenate!` on its own style, alongside `cat_similar` for allocation. This drops the `cat_copyto!` name and its style-stripping fallback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
By placement time `cat_similar` has already used the combined `cat_style` to build the destination, so `concatenate!` can dispatch on the destination type and does not need the style. This drops the leading style argument and the keyword forwarding method, leaving `concatenate!(dest, dims, args...)` with `dims` positional, matching `concatenate(dims, args...)`. Allocation still dispatches on the style through `cat_similar`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`directsum(dims, as...)` matches `concatenate(dims, as...)` and the rest of the interface, and a positional signature composes better for later customization, whether a leading style argument or dispatch on the summed arrays. Also drops the empty `function directsum end` stub, since the fallback method already defines the function. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mtfishman
added a commit
to ITensor/ITensorBase.jl
that referenced
this pull request
Jul 14, 2026
Match the `directsum(dims, as...)` signature introduced in ITensor/TensorAlgebra.jl#210. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mtfishman
marked this pull request as ready for review
July 14, 2026 17:36
mtfishman
enabled auto-merge (squash)
July 14, 2026 17:36
mtfishman
added a commit
to ITensor/SparseArraysBase.jl
that referenced
this pull request
Jul 14, 2026
## Summary Drops the vendored `Concatenate` interface now that it lives in TensorAlgebra (ITensor/TensorAlgebra.jl#210), and extends that interface for sparse storage there instead. `zero!` is routed through TensorAlgebra the same way: the sparse array types extend `TensorAlgebra.zero!` to empty their storage in place rather than filling it with zeros. --------- 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 14, 2026
## Summary Adds `Base.cat` and `directsum` for abelian graded arrays by hooking into the concatenation interface in TensorAlgebra (ITensor/TensorAlgebra.jl#210). `cat_axis` on graded ranges block-appends in concat-order, keeping the argument sectors in order rather than merging or sorting them, and materialization places each argument's blocks into the destination's diagonal hyper-block. `AbelianBlocks` becomes an `AbstractSparseArray` exposing the stored (symmetry-allowed) blocks, so the placement visits only those blocks and never touches a forbidden position. The default `directsum` is plain concatenation, so it shares this path. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mtfishman
added a commit
to ITensor/ITensorBase.jl
that referenced
this pull request
Jul 14, 2026
## Summary Adds a name-aware `directsum` for tensors, building on the general `directsum` in TensorAlgebra (ITensor/TensorAlgebra.jl#210). It aligns the arguments by index name, sums them over a chosen set of indices, and returns a single tensor with the summed indices trailing. Two forms are provided, one taking the output indices explicitly and one minting fresh indices for the summed dimensions. --------- 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
directsumfor summing arrays over a chosen set of axes, together with the concatenation interface it builds on. Moving that interface here from SparseArraysBase gives the sparse and graded array packages a single owner to extend for their own storage, and letsdirectsumbuild on it generically.directsumis currently plain concatenation, a valid direct sum for dense and graded backings alike. A fusing variant can be added later when a backend needs it.The SparseArraysBase and GradedArrays changes that route through this interface, and the name-aware
directsumfor ITensorBase, land in follow-up PRs.