Skip to content

Commit

Permalink
add 🐬 functionality (#189)
Browse files Browse the repository at this point in the history
* add flipping functionality

* fix implementation and support fermions
  • Loading branch information
Jutho authored Dec 17, 2024
1 parent 48413d2 commit c041bfe
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/fusiontrees/manipulations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,26 @@ end
# -> B-move (bendleft, bendright) is simple in standard basis
# -> A-move (foldleft, foldright) is complicated, needs to be reexpressed in standard form

# flip a duality flag of a fusion tree
function flip(f₁::FusionTree{I,N₁}, f₂::FusionTree{I,N₂}, i::Int) where {I<:Sector,N₁,N₂}
@assert 0 < i N₁ + N₂
if i N₁
a = f₁.uncoupled[i]
fs = frobeniusschur(a) * twist(a)
factor = f₁.isdual[i] ? fs : one(fs)
isdual′ = TupleTools.setindex(f₁.isdual, !f₁.isdual[i], i)
f₁′ = FusionTree{I}(f₁.uncoupled, f₁.coupled, isdual′, f₁.innerlines, f₁.vertices)
return SingletonDict((f₁′, f₂) => factor)
else
i -= N₁
a = f₂.uncoupled[i]
factor = f₂.isdual[i] ? frobeniusschur(a) : twist(a)
isdual′ = TupleTools.setindex(f₂.isdual, !f₂.isdual[i], i)
f₂′ = FusionTree{I}(f₂.uncoupled, f₂.coupled, isdual′, f₂.innerlines, f₂.vertices)
return SingletonDict((f₁, f₂′) => factor)
end
end

# change to N₁ - 1, N₂ + 1
function bendright(f₁::FusionTree{I,N₁}, f₂::FusionTree{I,N₂}) where {I<:Sector,N₁,N₂}
# map final splitting vertex (a, b)<-c to fusion vertex a<-(c, dual(b))
Expand Down
16 changes: 16 additions & 0 deletions src/spaces/homspace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,22 @@ function select(W::HomSpace{S}, (p₁, p₂)::Index2Tuple{N₁,N₂}) where {S,N
return cod dom
end

"""
flip(W::HomSpace, I)
Return a new `HomSpace` object by applying `flip` to each of the spaces in the domain and
codomain of `W` for which the linear index `i` satisfies `i ∈ I`.
"""
function flip(W::HomSpace{S}, I) where {S}
cod′ = let cod = codomain(W)
ProductSpace{S}(ntuple(i -> i I ? flip(cod[i]) : cod[i], numout(W)))
end
dom′ = let dom = domain(W)
ProductSpace{S}(ntuple(i -> (i + numout(W)) I ? flip(dom[i]) : dom[i], numin(W)))
end
return cod′ dom′
end

"""
compose(W::HomSpace, V::HomSpace)
Expand Down
21 changes: 21 additions & 0 deletions src/tensors/indexmanipulations.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Index manipulations
#---------------------
"""
flip(t::AbstractTensorMap, I) -> t′::AbstractTensorMap
Return a new tensor that is isomorphic to `t` but where the arrows on the indices `i` that satisfy
`i ∈ I` are flipped, i.e. `space(t′, i) = flip(space(t, i))`.
"""
function flip(t::AbstractTensorMap, I)
P = flip(space(t), I)
t′ = similar(t, P)
for (f₁, f₂) in fusiontrees(t)
f₁′, f₂′ = f₁, f₂
factor = one(scalartype(t))
for i in I
(f₁′, f₂′), s = only(flip(f₁′, f₂′, i))
factor *= s
end
scale!(t′[f₁′, f₂′], t[f₁, f₂], factor)
end
return t′
end

"""
permute!(tdst::AbstractTensorMap, tsrc::AbstractTensorMap, (p₁, p₂)::Index2Tuple)
-> tdst
Expand Down
28 changes: 28 additions & 0 deletions test/tensors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,34 @@ for V in spacelist
@test HrA12array convert(Array, HrA12)
end
end
@timedtestset "Index flipping: test via explicit flip" begin
t = rand(ComplexF64, V1 V1' V1' V1)
F1 = unitary(flip(V1), V1)

@tensor tf[a, b; c, d] := F1[a, a'] * t[a', b; c, d]
@test flip(t, 1) tf
@tensor tf[a, b; c, d] := conj(F1[b, b']) * t[a, b'; c, d]
@test twist!(flip(t, 2), 2) tf
@tensor tf[a, b; c, d] := F1[c, c'] * t[a, b; c', d]
@test flip(t, 3) tf
@tensor tf[a, b; c, d] := conj(F1[d, d']) * t[a, b; c, d']
@test twist!(flip(t, 4), 4) tf
end
@timedtestset "Index flipping: test via contraction" begin
t1 = rand(ComplexF64, V1 V2 V3 V4)
t2 = rand(ComplexF64, V2' V5 V4' V1)
@tensor ta[a, b] := t1[x, y, a, z] * t2[y, b, z, x]
@tensor tb[a, b] := flip(t1, 1)[x, y, a, z] * flip(t2, 4)[y, b, z, x]
@test ta tb
@tensor tb[a, b] := flip(t1, (2, 4))[x, y, a, z] *
flip(t2, (1, 3))[y, b, z, x]
@test ta tb
@tensor tb[a, b] := flip(t1, (1, 2, 4))[x, y, a, z] *
flip(t2, (1, 3, 4))[y, b, z, x]
@tensor tb[a, b] := flip(t1, (1, 3))[x, y, a, z] *
flip(t2, (2, 4))[y, b, z, x]
@test flip(ta, (1, 2)) tb
end
@timedtestset "Multiplication of isometries: test properties" begin
W2 = V4 V5
W1 = W2 (oneunit(V1) oneunit(V1))
Expand Down

0 comments on commit c041bfe

Please sign in to comment.