Skip to content

Commit c041bfe

Browse files
authored
add 🐬 functionality (#189)
* add flipping functionality * fix implementation and support fermions
1 parent 48413d2 commit c041bfe

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

src/fusiontrees/manipulations.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,26 @@ end
242242
# -> B-move (bendleft, bendright) is simple in standard basis
243243
# -> A-move (foldleft, foldright) is complicated, needs to be reexpressed in standard form
244244

245+
# flip a duality flag of a fusion tree
246+
function flip(f₁::FusionTree{I,N₁}, f₂::FusionTree{I,N₂}, i::Int) where {I<:Sector,N₁,N₂}
247+
@assert 0 < i N₁ + N₂
248+
if i N₁
249+
a = f₁.uncoupled[i]
250+
fs = frobeniusschur(a) * twist(a)
251+
factor = f₁.isdual[i] ? fs : one(fs)
252+
isdual′ = TupleTools.setindex(f₁.isdual, !f₁.isdual[i], i)
253+
f₁′ = FusionTree{I}(f₁.uncoupled, f₁.coupled, isdual′, f₁.innerlines, f₁.vertices)
254+
return SingletonDict((f₁′, f₂) => factor)
255+
else
256+
i -= N₁
257+
a = f₂.uncoupled[i]
258+
factor = f₂.isdual[i] ? frobeniusschur(a) : twist(a)
259+
isdual′ = TupleTools.setindex(f₂.isdual, !f₂.isdual[i], i)
260+
f₂′ = FusionTree{I}(f₂.uncoupled, f₂.coupled, isdual′, f₂.innerlines, f₂.vertices)
261+
return SingletonDict((f₁, f₂′) => factor)
262+
end
263+
end
264+
245265
# change to N₁ - 1, N₂ + 1
246266
function bendright(f₁::FusionTree{I,N₁}, f₂::FusionTree{I,N₂}) where {I<:Sector,N₁,N₂}
247267
# map final splitting vertex (a, b)<-c to fusion vertex a<-(c, dual(b))

src/spaces/homspace.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,22 @@ function select(W::HomSpace{S}, (p₁, p₂)::Index2Tuple{N₁,N₂}) where {S,N
147147
return cod dom
148148
end
149149

150+
"""
151+
flip(W::HomSpace, I)
152+
153+
Return a new `HomSpace` object by applying `flip` to each of the spaces in the domain and
154+
codomain of `W` for which the linear index `i` satisfies `i ∈ I`.
155+
"""
156+
function flip(W::HomSpace{S}, I) where {S}
157+
cod′ = let cod = codomain(W)
158+
ProductSpace{S}(ntuple(i -> i I ? flip(cod[i]) : cod[i], numout(W)))
159+
end
160+
dom′ = let dom = domain(W)
161+
ProductSpace{S}(ntuple(i -> (i + numout(W)) I ? flip(dom[i]) : dom[i], numin(W)))
162+
end
163+
return cod′ dom′
164+
end
165+
150166
"""
151167
compose(W::HomSpace, V::HomSpace)
152168

src/tensors/indexmanipulations.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Index manipulations
22
#---------------------
3+
"""
4+
flip(t::AbstractTensorMap, I) -> t′::AbstractTensorMap
5+
6+
Return a new tensor that is isomorphic to `t` but where the arrows on the indices `i` that satisfy
7+
`i ∈ I` are flipped, i.e. `space(t′, i) = flip(space(t, i))`.
8+
"""
9+
function flip(t::AbstractTensorMap, I)
10+
P = flip(space(t), I)
11+
t′ = similar(t, P)
12+
for (f₁, f₂) in fusiontrees(t)
13+
f₁′, f₂′ = f₁, f₂
14+
factor = one(scalartype(t))
15+
for i in I
16+
(f₁′, f₂′), s = only(flip(f₁′, f₂′, i))
17+
factor *= s
18+
end
19+
scale!(t′[f₁′, f₂′], t[f₁, f₂], factor)
20+
end
21+
return t′
22+
end
23+
324
"""
425
permute!(tdst::AbstractTensorMap, tsrc::AbstractTensorMap, (p₁, p₂)::Index2Tuple)
526
-> tdst

test/tensors.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,34 @@ for V in spacelist
326326
@test HrA12array convert(Array, HrA12)
327327
end
328328
end
329+
@timedtestset "Index flipping: test via explicit flip" begin
330+
t = rand(ComplexF64, V1 V1' V1' V1)
331+
F1 = unitary(flip(V1), V1)
332+
333+
@tensor tf[a, b; c, d] := F1[a, a'] * t[a', b; c, d]
334+
@test flip(t, 1) tf
335+
@tensor tf[a, b; c, d] := conj(F1[b, b']) * t[a, b'; c, d]
336+
@test twist!(flip(t, 2), 2) tf
337+
@tensor tf[a, b; c, d] := F1[c, c'] * t[a, b; c', d]
338+
@test flip(t, 3) tf
339+
@tensor tf[a, b; c, d] := conj(F1[d, d']) * t[a, b; c, d']
340+
@test twist!(flip(t, 4), 4) tf
341+
end
342+
@timedtestset "Index flipping: test via contraction" begin
343+
t1 = rand(ComplexF64, V1 V2 V3 V4)
344+
t2 = rand(ComplexF64, V2' V5 V4' V1)
345+
@tensor ta[a, b] := t1[x, y, a, z] * t2[y, b, z, x]
346+
@tensor tb[a, b] := flip(t1, 1)[x, y, a, z] * flip(t2, 4)[y, b, z, x]
347+
@test ta tb
348+
@tensor tb[a, b] := flip(t1, (2, 4))[x, y, a, z] *
349+
flip(t2, (1, 3))[y, b, z, x]
350+
@test ta tb
351+
@tensor tb[a, b] := flip(t1, (1, 2, 4))[x, y, a, z] *
352+
flip(t2, (1, 3, 4))[y, b, z, x]
353+
@tensor tb[a, b] := flip(t1, (1, 3))[x, y, a, z] *
354+
flip(t2, (2, 4))[y, b, z, x]
355+
@test flip(ta, (1, 2)) tb
356+
end
329357
@timedtestset "Multiplication of isometries: test properties" begin
330358
W2 = V4 V5
331359
W1 = W2 (oneunit(V1) oneunit(V1))

0 commit comments

Comments
 (0)