Skip to content

Commit c0cb454

Browse files
committed
Rewrite in terms of insertleftunit and insertrightunit
1 parent 3de6dbb commit c0cb454

File tree

7 files changed

+123
-55
lines changed

7 files changed

+123
-55
lines changed

src/TensorKit.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ export TruncationScheme
3131
export SpaceMismatch, SectorMismatch, IndexError # error types
3232

3333
# general vector space methods
34-
export space, field, dual, dim, reduceddim, dims, fuse, flip, isdual, insertunit,
35-
removeunit, oplus
34+
export space, field, dual, dim, reduceddim, dims, fuse, flip, isdual, oplus,
35+
insertleftunit, insertrightunit, removeunit
3636

3737
# partial order for vector spaces
3838
export infimum, supremum, isisomorphic, ismonomorphic, isepimorphic

src/auxiliary/deprecate.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,6 @@ end
5656

5757
Base.@deprecate EuclideanProduct() EuclideanInnerProduct()
5858

59+
Base.@deprecate insertunit(P::ProductSpace, args...; kwargs...) insertleftunit(args...; kwargs...)
60+
5961
#! format: on

src/spaces/homspace.jl

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,25 +159,36 @@ function compose(W::HomSpace{S}, V::HomSpace{S}) where {S}
159159
end
160160

161161
"""
162-
insertunit(W::HomSpace, i::Int=ndims(W) + 1; conj=false, dual=false, preferdomain=false)
162+
insertleftunit(W::HomSpace, i::Int=numind(W) + 1; conj=false, dual=false)
163163
164164
Insert a trivial vector space, isomorphic to the underlying field, at position `i`.
165-
Whenever `i == numout(W)`, the ambiguity to determine whether this space is added in the domain or
166-
codomain is controlled by `preferdomain`.
165+
More specifically, adds a left monoidal unit or its dual.
166+
167+
See also [`insertrightunit`](@ref), [`removeunit`](@ref).
167168
"""
168-
Base.@constprop :aggressive function insertunit(W::HomSpace, i::Int=numind(W) + 1;
169-
conj::Bool=false, dual::Bool=false,
170-
preferdomain::Bool=false)
169+
function insertleftunit(W::HomSpace, i::Int=numind(W) + 1;
170+
conj::Bool=false, dual::Bool=false)
171171
if i numout(W)
172-
return insertunit(codomain(W), i; conj, dual) domain(W)
173-
elseif i == numout(W) + 1
174-
if preferdomain
175-
return codomain(W) insertunit(domain(W), 1; conj, dual)
176-
else
177-
return insertunit(codomain(W); conj, dual) domain(W)
178-
end
172+
return insertleftunit(codomain(W), i; conj, dual) domain(W)
173+
else
174+
return codomain(W) insertleftunit(domain(W), i - numout(W); conj, dual)
175+
end
176+
end
177+
178+
"""
179+
insertrightunit(W::HomSpace, i::Int=numind(W); conj=false, dual=false)
180+
181+
Insert a trivial vector space, isomorphic to the underlying field, after position `i`.
182+
More specifically, adds a right monoidal unit or its dual.
183+
184+
See also [`insertleftunit`](@ref), [`removeunit`](@ref).
185+
"""
186+
function insertrightunit(W::HomSpace, i::Int=numind(W);
187+
conj::Bool=false, dual::Bool=false)
188+
if i numout(W)
189+
return insertrightunit(codomain(W), i; conj, dual) domain(W)
179190
else
180-
return codomain(W) insertunit(domain(W), i - numout(W); conj, dual)
191+
return codomain(W) insertrightunit(domain(W), i - numout(W); conj, dual)
181192
end
182193
end
183194

@@ -187,7 +198,7 @@ end
187198
This removes a trivial tensor product factor at position `1 ≤ i ≤ N`.
188199
For this to work, that factor has to be isomorphic to the field of scalars.
189200
190-
This operation undoes the work of [`insertunit`](@ref).
201+
This operation undoes the work of [`insertleftunit`](@ref) or [`insertrightunit`](@ref).
191202
"""
192203
function removeunit(P::HomSpace, i::Int)
193204
if i in 1:numout(P)

src/spaces/productspace.jl

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -246,17 +246,14 @@ fuse(P::ProductSpace{S,0}) where {S<:ElementarySpace} = oneunit(S)
246246
fuse(P::ProductSpace{S}) where {S<:ElementarySpace} = fuse(P.spaces...)
247247

248248
"""
249-
insertunit(P::ProductSpace, i::Int = length(P)+1; dual = false, conj = false)
249+
insertleftunit(P::ProductSpace, i::Int=length(P) + 1; conj=false, dual=false)
250250
251-
For `P::ProductSpace{S,N}`, this adds an extra tensor product factor at position
252-
`1 <= i <= N+1` (last position by default) which is just the `S`-equivalent of the
253-
underlying field of scalars, i.e. `oneunit(S)`. With the keyword arguments, one can choose
254-
to insert the conjugated or dual space instead, which are all isomorphic to the field of
255-
scalars.
251+
Insert a trivial vector space, isomorphic to the underlying field, at position `i`.
252+
More specifically, adds a left monoidal unit or its dual.
256253
257-
This operation can be undone by [`removeunit`](@ref).
254+
See also [`insertrightunit`](@ref), [`removeunit`](@ref).
258255
"""
259-
function insertunit(P::ProductSpace, i::Int=length(P) + 1; dual=false, conj=false)
256+
function insertleftunit(P::ProductSpace, i::Int=length(P) + 1; kwargs...)
260257
u = oneunit(spacetype(P))
261258
if dual
262259
u = TensorKit.dual(u)
@@ -267,6 +264,25 @@ function insertunit(P::ProductSpace, i::Int=length(P) + 1; dual=false, conj=fals
267264
return ProductSpace(TupleTools.insertafter(P.spaces, i - 1, (u,)))
268265
end
269266

267+
"""
268+
insertrightunit(P::ProductSpace, i::Int=lenght(P); conj=false, dual=false)
269+
270+
Insert a trivial vector space, isomorphic to the underlying field, after position `i`.
271+
More specifically, adds a right monoidal unit or its dual.
272+
273+
See also [`insertleftunit`](@ref), [`removeunit`](@ref).
274+
"""
275+
function insertrightunit(P::ProductSpace, i::Int=length(P); kwargs...)
276+
u = oneunit(spacetype(P))
277+
if dual
278+
u = TensorKit.dual(u)
279+
end
280+
if conj
281+
u = TensorKit.conj(u)
282+
end
283+
return ProductSpace(TupleTools.insertafter(P.spaces, i, (u,)))
284+
end
285+
270286
"""
271287
removeunit(P::ProductSpace, i::Int)
272288

src/tensors/indexmanipulations.jl

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -272,31 +272,58 @@ See [`twist!`](@ref) for storing the result in place.
272272
twist(t::AbstractTensorMap, i; inv::Bool=false) = twist!(copy(t), i; inv)
273273

274274
"""
275-
insertunit(tsrc::AbstractTensorMap, i::Int=numind(t) + 1;
276-
conj=false, dual=false, preferdomain=false, copy=false) -> tdst
275+
insertleftunit(tsrc::AbstractTensorMap, i::Int=numind(t) + 1;
276+
conj=false, dual=false, copy=false) -> tdst
277277
278278
Insert a trivial vector space, isomorphic to the underlying field, at position `i`.
279-
Whenever `i == numout(W)`, the ambiguity to determine whether this space is added in the domain or
280-
codomain is controlled by `preferdomain`.
279+
More specifically, adds a left monoidal unit or its dual.
281280
282281
If `copy=false`, `tdst` might share data with `tsrc` whenever possible. Otherwise, a copy is always made.
282+
283+
See also [`insertrightunit`](@ref) and [`removeunit`](@ref).
283284
"""
284-
function insertunit(t::TensorMap, i::Int=numind(t) + 1;
285-
conj::Bool=false, dual::Bool=false, preferdomain::Bool=false,
286-
copy::Bool=false)
287-
W = insertunit(space(t), i; conj, dual, preferdomain)
285+
Base.@constprop :aggressive function insertleftunit(t::AbstractTensorMap,
286+
i::Int=numind(t) + 1; copy::Bool=true,
287+
conj::Bool=false, dual::Bool=false)
288+
W = insertleftunit(space(t), i; conj, dual)
289+
tdst = similar(t, W)
290+
for (c, b) in blocks(t)
291+
copy!(block(tdst, c), b)
292+
end
293+
return tdst
294+
end
295+
Base.@constprop :aggressive function insertleftunit(t::TensorMap, i::Int=numind(t) + 1;
296+
copy::Bool=false,
297+
conj::Bool=false, dual::Bool=false)
298+
W = insertleftunit(space(t), i; conj, dual)
288299
return TensorMap{scalartype(t)}(copy ? Base.copy(t.data) : t.data, W)
289300
end
290-
function insertunit(t::AbstractTensorMap, i::Int=numind(t) + 1;
291-
conj::Bool=false, dual::Bool=false, preferdomain::Bool=false,
292-
copy::Bool=true)
293-
W = insertunit(space(t), i; conj, dual, preferdomain)
301+
302+
"""
303+
insertrightunit(tsrc::AbstractTensorMap, i::Int=numind(t);
304+
conj=false, dual=false, copy=false) -> tdst
305+
306+
Insert a trivial vector space, isomorphic to the underlying field, after position `i`.
307+
More specifically, adds a right monoidal unit or its dual.
308+
309+
If `copy=false`, `tdst` might share data with `tsrc` whenever possible. Otherwise, a copy is always made.
310+
311+
See also [`insertleftunit`](@ref) and [`removeunit`](@ref).
312+
"""
313+
Base.@constprop :aggressive function insertrightunit(t::AbstractTensorMap, i::Int=numind(t);
314+
copy::Bool=true, kwargs...)
315+
W = insertrightunit(space(t), i; kwargs...)
294316
tdst = similar(t, W)
295317
for (c, b) in blocks(t)
296318
copy!(block(tdst, c), b)
297319
end
298320
return tdst
299321
end
322+
Base.@constprop :aggressive function insertrightunit(t::TensorMap, i::Int=numind(t);
323+
copy::Bool=false, kwargs...)
324+
W = insertrightunit(space(t), i; kwargs...)
325+
return TensorMap{scalartype(t)}(copy ? Base.copy(t.data) : t.data, W)
326+
end
300327

301328
"""
302329
removeunit(tsrc::AbstractTensorMap, i::Int; copy=false) -> tdst

test/spaces.jl

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ println("------------------------------------")
278278
@test @constinferred((V1 V2, V3 V4)) == P
279279
@test @constinferred((V1, V2, V3 V4)) == P
280280
@test @constinferred((V1, V2 V3, V4)) == P
281-
@test @constinferred(insertunit(P, 3)) == V1 * V2 * oneunit(V1) * V3 * V4
281+
@test V1 * V2 * oneunit(V1) * V3 * V4 ==
282+
@constinferred(insertleftunit(P, 3)) ==
283+
@constinferred(insertrightunit(P, 2))
282284
@test @constinferred(removeunit(V1 * V2 * oneunit(V1)' * V3 * V4, 3)) == P
283285
@test fuse(V1, V2', V3) V1 V2' V3
284286
@test fuse(V1, V2', V3) V1 V2' V3
@@ -339,8 +341,10 @@ println("------------------------------------")
339341
@test @constinferred(*(V1, V2, V3)) == P
340342
@test @constinferred((V1, V2, V3)) == P
341343
@test @constinferred(adjoint(P)) == dual(P) == V3' V2' V1'
342-
@test @constinferred(insertunit(P, 3; conj=true)) == V1 * V2 * oneunit(V1)' * V3
343-
@test P == @constinferred(removeunit(insertunit(P, 3), 3))
344+
@test V1 * V2 * oneunit(V1)' * V3 ==
345+
@constinferred(insertleftunit(P, 3; conj=true)) ==
346+
@constinferred(insertrightunit(P, 2; conj=true))
347+
@test P == @constinferred(removeunit(insertleftunit(P, 3), 3))
344348
@test fuse(V1, V2', V3) V1 V2' V3
345349
@test fuse(V1, V2', V3) V1 V2' V3 fuse(V1 V2' V3)
346350
@test fuse(V1, V2') V3 V1 V2' V3
@@ -421,15 +425,21 @@ println("------------------------------------")
421425
@test W == @constinferred permute(W, ((1, 2), (3, 4, 5)))
422426
@test permute(W, ((2, 4, 5), (3, 1))) == (V2 V4' V5' V3 V1')
423427
@test (V1 V2 V1 V2) == @constinferred TensorKit.compose(W, W')
424-
@test @constinferred(insertunit(W)) == (V1 V2 V3 V4 V5 oneunit(V5))
425-
@test @constinferred(removeunit(insertunit(W), $(numind(W) + 1))) == W
426-
@test @constinferred(insertunit(W; conj=true)) == (V1 V2
427-
V3 V4 V5 oneunit(V5)')
428-
@test @constinferred(insertunit(W, 1)) == (oneunit(V1) V1 V2 V3 V4 V5)
429-
@test @constinferred(insertunit(W, 3)) == (V1 V2 oneunit(V1) V3 V4 V5)
430-
@test @constinferred(removeunit(insertunit(W, 3), 3)) == W
431-
@test @constinferred(insertunit(W, 3; preferdomain=true)) ==
432-
(V1 V2 oneunit(V1) V3 V4 V5)
433-
@test @constinferred(removeunit(insertunit(W, 3; preferdomain=true), 3)) == W
428+
@test (V1 V2 V3 V4 V5 oneunit(V5)) ==
429+
@constinferred(insertleftunit(W)) ==
430+
@constinferred(insertrightunit(W))
431+
@test @constinferred(removeunit(insertleftunit(W), $(numind(W) + 1))) == W
432+
@test (V1 V2 V3 V4 V5 oneunit(V5)') ==
433+
@constinferred(insertleftunit(W; conj=true)) ==
434+
@constinferred(insertrightunit(W; conj=true))
435+
@test (oneunit(V1) V1 V2 V3 V4 V5) ==
436+
@constinferred(insertleftunit(W, 1)) ==
437+
@constinferred(insertrightunit(W, 0))
438+
@test (V1 V2 oneunit(V1) V3 V4 V5) ==
439+
@constinferred(insertrightunit(W, 2))
440+
@test (V1 V2 oneunit(V1) V3 V4 V5) == @constinferred(insertleftunit(W, 3))
441+
@test @constinferred(removeunit(insertleftunit(W, 3), 3)) == W
442+
@test @constinferred(insertrightunit(one(V1) V1, 0)) == (oneunit(V1) V1)
443+
@test_throws BoundsError insertleftunit(one(V1) V1, 0)
434444
end
435445
end

test/tensors.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,25 +177,27 @@ for V in spacelist
177177
W = V1 V2 V3 V4 V5
178178
for T in (Float32, ComplexF64)
179179
t = @constinferred rand(T, W)
180-
t2 = @constinferred insertunit(t)
180+
t2 = @constinferred insertleftunit(t)
181+
@test t2 == @constinferred insertrightunit(t)
181182
@test numind(t2) == numind(t) + 1
182-
@test space(t2) == insertunit(space(t))
183+
@test space(t2) == insertleftunit(space(t))
183184
@test scalartype(t2) === T
184185
@test t.data === t2.data
185186
@test @constinferred(removeunit(t2, $(numind(t2)))) == t
186-
t3 = @constinferred insertunit(t; copy=true)
187+
t3 = @constinferred insertleftunit(t; copy=true)
188+
@test t3 == @constinferred insertrightunit(t; copy=true)
187189
@test t.data !== t3.data
188190
for (c, b) in blocks(t)
189191
@test b == block(t3, c)
190192
end
191193
@test @constinferred(removeunit(t3, $(numind(t3)))) == t
192-
t4 = @constinferred insertunit(t, 4; dual=true)
194+
t4 = @constinferred insertrightunit(t, 3; dual=true)
193195
@test numin(t4) == numin(t) && numout(t4) == numout(t) + 1
194196
for (c, b) in blocks(t)
195197
@test b == block(t4, c)
196198
end
197199
@test @constinferred(removeunit(t4, 4)) == t
198-
t5 = @constinferred insertunit(t, 4; dual=true, preferdomain=true)
200+
t5 = @constinferred insertleftunit(t, 4; dual=true)
199201
@test numin(t5) == numin(t) + 1 && numout(t5) == numout(t)
200202
for (c, b) in blocks(t)
201203
@test b == block(t5, c)

0 commit comments

Comments
 (0)