Skip to content

Commit

Permalink
Add removeunit functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
lkdvos committed Dec 12, 2024
1 parent 44d9dad commit 5da3632
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/TensorKit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export TruncationScheme
export SpaceMismatch, SectorMismatch, IndexError # error types

# general vector space methods
export space, field, dual, dim, reduceddim, dims, fuse, flip, isdual, insertunit, oplus
export space, field, dual, dim, reduceddim, dims, fuse, flip, isdual, insertunit,
removeunit, oplus

# partial order for vector spaces
export infimum, supremum, isisomorphic, ismonomorphic, isepimorphic
Expand Down
18 changes: 18 additions & 0 deletions src/spaces/homspace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,24 @@ Base.@constprop :aggressive function insertunit(W::HomSpace, i::Int=numind(W) +
end
end

"""
removeunit(P::HomSpace, i::Int)
This removes a trivial tensor product factor at position `1 ≤ i ≤ N`.
For this to work, that factor has to be isomorphic to the field of scalars.
This operation undoes the work of [`insertunit`](@ref).
"""
function removeunit(P::HomSpace, i::Int)
if i in 1:numout(P)
return removeunit(codomain(P), i) domain(P)
elseif i in (numout(P) + 1):numind(P)
return codomain(P) removeunit(P, i - numout(P))
else
throw(BoundsError(P, i))
end
end

# Block and fusion tree ranges: structure information for building tensors
#--------------------------------------------------------------------------
struct FusionBlockStructure{I,N,F₁,F₂}
Expand Down
17 changes: 17 additions & 0 deletions src/spaces/productspace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ For `P::ProductSpace{S,N}`, this adds an extra tensor product factor at position
underlying field of scalars, i.e. `oneunit(S)`. With the keyword arguments, one can choose
to insert the conjugated or dual space instead, which are all isomorphic to the field of
scalars.
This operation can be undone by [`removeunit`](@ref).
"""
function insertunit(P::ProductSpace, i::Int=length(P) + 1; dual=false, conj=false)
u = oneunit(spacetype(P))
Expand All @@ -265,6 +267,21 @@ function insertunit(P::ProductSpace, i::Int=length(P) + 1; dual=false, conj=fals
return ProductSpace(TupleTools.insertafter(P.spaces, i - 1, (u,)))
end

"""
removeunit(P::ProductSpace, i::Int)
This removes a trivial tensor product factor at position `1 ≤ i ≤ N`.
For this to work, that factor has to be isomorphic to the field of scalars.
This operation undoes the work of [`insertunit`](@ref).
"""
function removeunit(P::ProductSpace, i::Int)
1 i length(P) || throw(BoundsError(P, i))
isisomorphic(P[i], oneunit(P[i])) ||
throw(ArgumentError("Attempting to remove a non-trivial space"))
return ProductSpace{spacetype(P)}(TupleTools.deleteat(P.spaces, i))
end

# Functionality for extracting and iterating over spaces
#--------------------------------------------------------
Base.length(P::ProductSpace) = length(P.spaces)
Expand Down
23 changes: 23 additions & 0 deletions src/tensors/indexmanipulations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,29 @@ function insertunit(t::AbstractTensorMap, i::Int=numind(t) + 1;
return tdst
end

"""
removeunit(tsrc::AbstractTensorMap, i::Int; copy=false) -> tdst
This removes a trivial tensor product factor at position `1 ≤ i ≤ N`.
For this to work, that factor has to be isomorphic to the field of scalars.
If `copy=false`, `tdst` might share data with `tsrc` whenever possible. Otherwise, a copy is always made.
This operation undoes the work of [`insertunit`](@ref).
"""
function removeunit(t::TensorMap, i::Int; copy::Bool=false)
W = removeunit(space(t), i)
return TensorMap{scalartype(t)}(copy ? Base.copy(t.data) : t.data, W)
end
function removeunit(t::AbstractTensorMap, i::Int=numind(t) + 1; copy::Bool=true)
W = removeunit(space(t), i)
tdst = similar(t, W)
for (c, b) in blocks(t)
copy!(block(tdst, c), b)
end
return tdst
end

# Fusing and splitting
# TODO: add functionality for easy fusing and splitting of tensor indices

Expand Down

0 comments on commit 5da3632

Please sign in to comment.