From ea770e522c73988a61bdb779995ceb0087fb6ee0 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Mon, 7 Sep 2026 17:40:55 +0200 Subject: [PATCH 1/4] stop revise from stopping from revising --- src/tensors/abstracttensor.jl | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/tensors/abstracttensor.jl b/src/tensors/abstracttensor.jl index f3b6fa18a..8be78c517 100644 --- a/src/tensors/abstracttensor.jl +++ b/src/tensors/abstracttensor.jl @@ -486,6 +486,17 @@ subblocktype(T::Type) = throw(MethodError(subblocktype, (T,))) @doc """ Base.getindex(t::AbstractTensorMap, sectors::Tuple{Vararg{Sector}}) t[sectors] + +$_doc_subblock + +!!! warning + Contrary to Julia's array types, the default behavior is to return a view into the tensor data. + As a result, modifying the view will modify the data in the tensor. + +See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). +""" Base.getindex(::AbstractTensorMap, ::Tuple{I, Vararg{I}}) where {I <: Sector} + +@doc """ Base.getindex(t::AbstractTensorMap, f₁::FusionTree, f₂::FusionTree) t[f₁, f₂] @@ -496,8 +507,7 @@ $_doc_subblock As a result, modifying the view will modify the data in the tensor. See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). -""" Base.getindex(::AbstractTensorMap, ::Tuple{I, Vararg{I}}) where {I <: Sector}, - Base.getindex(::AbstractTensorMap, ::FusionTree, ::FusionTree) +""" Base.getindex(::AbstractTensorMap, ::FusionTree, ::FusionTree) @inline Base.getindex(t::AbstractTensorMap, sectors::Tuple{I, Vararg{I}}) where {I <: Sector} = subblock(t, sectors) @@ -507,6 +517,14 @@ See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). @doc """ Base.setindex!(t::AbstractTensorMap, v, sectors::Tuple{Vararg{Sector}}) t[sectors] = v + +Copies `v` into the data slice of `t` corresponding to the splitting - fusion tree pair `(f₁, f₂)`. +By default, `v` can be any object that can be copied into the view associated with `t[f₁, f₂]`. + +See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). +""" Base.setindex!(::AbstractTensorMap, ::Any, ::Tuple{I, Vararg{I}}) where {I <: Sector} + +@doc """ Base.setindex!(t::AbstractTensorMap, v, f₁::FusionTree, f₂::FusionTree) t[f₁, f₂] = v @@ -514,8 +532,7 @@ Copies `v` into the data slice of `t` corresponding to the splitting - fusion tr By default, `v` can be any object that can be copied into the view associated with `t[f₁, f₂]`. See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). -""" Base.setindex!(::AbstractTensorMap, ::Any, ::Tuple{I, Vararg{I}}) where {I <: Sector}, - Base.setindex!(::AbstractTensorMap, ::Any, ::FusionTree, ::FusionTree) +""" Base.setindex!(::AbstractTensorMap, ::Any, ::FusionTree, ::FusionTree) @inline Base.setindex!(t::AbstractTensorMap, v, sectors::Tuple{I, Vararg{I}}) where {I <: Sector} = copy!(subblock(t, sectors), v) From a011c088324f364b1f9745b1d816c55a3be2ca3c Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Tue, 8 Sep 2026 09:17:55 +0200 Subject: [PATCH 2/4] don't duplicate docstrings [skip ci] --- src/tensors/abstracttensor.jl | 37 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/tensors/abstracttensor.jl b/src/tensors/abstracttensor.jl index 8be78c517..b2ef697b5 100644 --- a/src/tensors/abstracttensor.jl +++ b/src/tensors/abstracttensor.jl @@ -483,10 +483,7 @@ subblocktype(T::Type) = throw(MethodError(subblocktype, (T,))) # Indexing behavior # ----------------- # by default getindex returns views! -@doc """ - Base.getindex(t::AbstractTensorMap, sectors::Tuple{Vararg{Sector}}) - t[sectors] - +const _doc_getindex = """ $_doc_subblock !!! warning @@ -494,19 +491,20 @@ $_doc_subblock As a result, modifying the view will modify the data in the tensor. See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). +""" + +@doc """ + Base.getindex(t::AbstractTensorMap, sectors::Tuple{Vararg{Sector}}) + t[sectors] + +$_doc_getindex """ Base.getindex(::AbstractTensorMap, ::Tuple{I, Vararg{I}}) where {I <: Sector} @doc """ Base.getindex(t::AbstractTensorMap, f₁::FusionTree, f₂::FusionTree) t[f₁, f₂] -$_doc_subblock - -!!! warning - Contrary to Julia's array types, the default behavior is to return a view into the tensor data. - As a result, modifying the view will modify the data in the tensor. - -See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). +$_doc_getindex """ Base.getindex(::AbstractTensorMap, ::FusionTree, ::FusionTree) @inline Base.getindex(t::AbstractTensorMap, sectors::Tuple{I, Vararg{I}}) where {I <: Sector} = @@ -514,24 +512,25 @@ See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). @inline Base.getindex(t::AbstractTensorMap, f₁::FusionTree, f₂::FusionTree) = subblock(t, (f₁, f₂)) -@doc """ - Base.setindex!(t::AbstractTensorMap, v, sectors::Tuple{Vararg{Sector}}) - t[sectors] = v - +const _doc_setindex = """ Copies `v` into the data slice of `t` corresponding to the splitting - fusion tree pair `(f₁, f₂)`. By default, `v` can be any object that can be copied into the view associated with `t[f₁, f₂]`. See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). +""" + +@doc """ + Base.setindex!(t::AbstractTensorMap, v, sectors::Tuple{Vararg{Sector}}) + t[sectors] = v + +$_doc_setindex """ Base.setindex!(::AbstractTensorMap, ::Any, ::Tuple{I, Vararg{I}}) where {I <: Sector} @doc """ Base.setindex!(t::AbstractTensorMap, v, f₁::FusionTree, f₂::FusionTree) t[f₁, f₂] = v -Copies `v` into the data slice of `t` corresponding to the splitting - fusion tree pair `(f₁, f₂)`. -By default, `v` can be any object that can be copied into the view associated with `t[f₁, f₂]`. - -See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). +$_doc_setindex """ Base.setindex!(::AbstractTensorMap, ::Any, ::FusionTree, ::FusionTree) @inline Base.setindex!(t::AbstractTensorMap, v, sectors::Tuple{I, Vararg{I}}) where {I <: Sector} = From 1dcc9b054b807c20e299d2dab706560ccf236a87 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Wed, 9 Sep 2026 10:27:58 +0200 Subject: [PATCH 3/4] put all methods in one docstring --- src/tensors/abstracttensor.jl | 70 +++++++++++++---------------------- 1 file changed, 25 insertions(+), 45 deletions(-) diff --git a/src/tensors/abstracttensor.jl b/src/tensors/abstracttensor.jl index b2ef697b5..842cf1074 100644 --- a/src/tensors/abstracttensor.jl +++ b/src/tensors/abstracttensor.jl @@ -419,7 +419,7 @@ Return a view into the data of `t` corresponding to the splitting - fusion tree `(f₁, f₂)`. In particular, this is an `AbstractArray{T}` with `T = scalartype(t)`, of size `(dims(codomain(t), f₁.uncoupled)..., dims(codomain(t), f₂.uncoupled)...)`. -Whenever `FusionStyle(sectortype(t)) isa UniqueFusion` , it is also possible to provide only +Whenever `FusionStyle(sectortype(t)) isa UniqueFusion`, it is also possible to provide only the external `sectors`, in which case the fusion tree pair will be constructed automatically. """ @@ -483,7 +483,12 @@ subblocktype(T::Type) = throw(MethodError(subblocktype, (T,))) # Indexing behavior # ----------------- # by default getindex returns views! -const _doc_getindex = """ +@doc """ + Base.getindex(t::AbstractTensorMap, sectors::Tuple{Vararg{Sector}}) + t[sectors] + Base.getindex(t::AbstractTensorMap, f₁::FusionTree, f₂::FusionTree) + t[f₁, f₂] + $_doc_subblock !!! warning @@ -491,47 +496,40 @@ $_doc_subblock As a result, modifying the view will modify the data in the tensor. See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). -""" -@doc """ - Base.getindex(t::AbstractTensorMap, sectors::Tuple{Vararg{Sector}}) - t[sectors] + Base.getindex(t::AbstractTensorMap, indices::Vararg{Int}) + t[indices] -$_doc_getindex -""" Base.getindex(::AbstractTensorMap, ::Tuple{I, Vararg{I}}) where {I <: Sector} +Return a view into the data slice of `t` corresponding to `indices`, by slicing the +`StridedViews.StridedView` into the full data array. -@doc """ - Base.getindex(t::AbstractTensorMap, f₁::FusionTree, f₂::FusionTree) - t[f₁, f₂] + Base.getindex(t::AbstractTensorMap) + t[] -$_doc_getindex -""" Base.getindex(::AbstractTensorMap, ::FusionTree, ::FusionTree) +Return a view into the data of `t` as a `StridedViews.StridedView` of size `dims(t)`. +""" Base.getindex(::AbstractTensorMap, args...) @inline Base.getindex(t::AbstractTensorMap, sectors::Tuple{I, Vararg{I}}) where {I <: Sector} = subblock(t, sectors) @inline Base.getindex(t::AbstractTensorMap, f₁::FusionTree, f₂::FusionTree) = subblock(t, (f₁, f₂)) -const _doc_setindex = """ -Copies `v` into the data slice of `t` corresponding to the splitting - fusion tree pair `(f₁, f₂)`. -By default, `v` can be any object that can be copied into the view associated with `t[f₁, f₂]`. - -See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). -""" - @doc """ Base.setindex!(t::AbstractTensorMap, v, sectors::Tuple{Vararg{Sector}}) t[sectors] = v - -$_doc_setindex -""" Base.setindex!(::AbstractTensorMap, ::Any, ::Tuple{I, Vararg{I}}) where {I <: Sector} - -@doc """ Base.setindex!(t::AbstractTensorMap, v, f₁::FusionTree, f₂::FusionTree) t[f₁, f₂] = v -$_doc_setindex -""" Base.setindex!(::AbstractTensorMap, ::Any, ::FusionTree, ::FusionTree) +Copies `v` into the data slice of `t` corresponding to the splitting - fusion tree pair `(f₁, f₂)`. +By default, `v` can be any object that can be copied into the view associated with `t[f₁, f₂]`. + +See also [`subblock`](@ref), [`subblocks`](@ref) and [`fusiontrees`](@ref). + + Base.setindex!(t::AbstractTensorMap, v, indices::Vararg{Int}) + t[indices] = v + +Assigns `v` to the data slice of `t` corresponding to `indices`. +""" Base.setindex!(::AbstractTensorMap, args...) @inline Base.setindex!(t::AbstractTensorMap, v, sectors::Tuple{I, Vararg{I}}) where {I <: Sector} = copy!(subblock(t, sectors), v) @@ -546,25 +544,13 @@ using TensorKit.Strided: SliceIndex # TODO: should we allow range indices as well # TODO 2: should we enable this for (abelian) symmetric tensors with some CUDA like `allowscalar` flag? # TODO 3: should we then also allow at least `getindex` for nonabelian tensors -""" - Base.getindex(t::AbstractTensorMap, indices::Vararg{Int}) - t[indices] - -Return a view into the data slice of `t` corresponding to `indices`, by slicing the -`StridedViews.StridedView` into the full data array. -""" @inline function Base.getindex(t::AbstractTensorMap, indices::Vararg{SliceIndex}) data = t[trivial_fusiontree(t)...] @boundscheck checkbounds(data, indices...) @inbounds v = data[indices...] return v end -""" - Base.setindex!(t::AbstractTensorMap, v, indices::Vararg{Int}) - t[indices] = v -Assigns `v` to the data slice of `t` corresponding to `indices`. -""" @inline function Base.setindex!(t::AbstractTensorMap, v, indices::Vararg{SliceIndex}) data = t[trivial_fusiontree(t)...] @boundscheck checkbounds(data, indices...) @@ -574,12 +560,6 @@ end # TODO : probably deprecate the following # For a tensor with trivial symmetry, allow no argument indexing -""" - Base.getindex(t::AbstractTensorMap) - t[] - -Return a view into the data of `t` as a `StridedViews.StridedView` of size `dims(t)`. -""" @inline function Base.getindex(t::AbstractTensorMap) return t[trivial_fusiontree(t)...] end From f7e95e897cbcd8d5b0c2047ab21e3b598a5972c1 Mon Sep 17 00:00:00 2001 From: Boris De Vos Date: Wed, 9 Sep 2026 11:46:53 +0200 Subject: [PATCH 4/4] rephrasing in docs --- docs/src/lib/tensors.md | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/docs/src/lib/tensors.md b/docs/src/lib/tensors.md index 217c6640a..8594534f7 100644 --- a/docs/src/lib/tensors.md +++ b/docs/src/lib/tensors.md @@ -118,22 +118,11 @@ subblock subblocks ``` -To access the data associated with a specific fusion tree pair, you can use: +One can access the data of an `AbstractTensorMap` in multiple ways, its availability depending on the sector type of the tensor. +In particular, the data of a tensor `t` can be accessed by specifying the fusion tree pair, the outcoming sectors if `FusionStyle(sectortype(t)) isa UniqueFusion`, or by multidimensional array indexing if `sectortype(t) == Trivial`. ```@docs -Base.getindex(::AbstractTensorMap, ::FusionTree, ::FusionTree) -Base.setindex!(::AbstractTensorMap, ::Any, ::FusionTree, ::FusionTree) -``` - -For a tensor `t` with `FusionStyle(sectortype(t)) isa UniqueFusion`, fusion trees are completely determined by the outcoming sectors, and the data can be accessed in a more straightforward way: -```@docs -Base.getindex(::AbstractTensorMap, ::Tuple{I,Vararg{I}}) where {I<:Sector} -``` - -For tensor `t` with `sectortype(t) == Trivial`, the data can be accessed and manipulated directly as multidimensional arrays: -```@docs -Base.getindex(::AbstractTensorMap) -Base.getindex(::AbstractTensorMap, ::Vararg{SliceIndex}) -Base.setindex!(::AbstractTensorMap, ::Any, ::Vararg{SliceIndex}) +Base.getindex(::AbstractTensorMap, args...) +Base.setindex!(::AbstractTensorMap, args...) ``` The tensor data can also be filled with random numbers via