Skip to content

Commit fe3cfd4

Browse files
committed
Refactor artin_braid to avoid extra dicts
1 parent 54b7abc commit fe3cfd4

File tree

1 file changed

+121
-4
lines changed

1 file changed

+121
-4
lines changed

src/fusiontrees/fusiontreeblocks.jl

Lines changed: 121 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ function treeindex_map(fs::FusionTreeBlock)
5959
return fusiontreedict(I)(f => ind for (ind, f) in enumerate(fusiontrees(fs)))
6060
end
6161

62-
6362
# Manipulations
6463
# -------------
6564
function transformation_matrix(transform, dst::FusionTreeBlock{I},
@@ -451,10 +450,128 @@ function artin_braid(src::FusionTreeBlock{I,N,0}, i; inv::Bool=false) where {I,N
451450
isdual′ = TupleTools.setindex(isdual′, isdual[i + 1], i)
452451
dst = FusionTreeBlock{I}((uncoupled′, ()), (isdual′, ()))
453452

454-
# TODO: do we want to rewrite `artin_braid` to take double trees instead?
455-
U = transformation_matrix(dst, src) do (f₁, f₂)
456-
return ((f₁′, f₂) => c for (f₁′, c) in artin_braid(f₁, i; inv))
453+
indexmap = treeindex_map(dst)
454+
U = zeros(sectorscalartype(I), length(dst), length(src))
455+
456+
for (col, (f, f₂)) in enumerate(fusiontrees(src))
457+
a, b = uncoupled[i], uncoupled[i + 1]
458+
uncoupled′ = TupleTools.setindex(uncoupled, b, i)
459+
uncoupled′ = TupleTools.setindex(uncoupled′, a, i + 1)
460+
coupled′ = f.coupled
461+
isdual′ = TupleTools.setindex(f.isdual, f.isdual[i], i + 1)
462+
isdual′ = TupleTools.setindex(isdual′, f.isdual[i + 1], i)
463+
inner = f.innerlines
464+
inner_extended = (uncoupled[1], inner..., coupled′)
465+
vertices = f.vertices
466+
oneT = one(sectorscalartype(I))
467+
468+
if isone(uncoupled[i]) || isone(uncoupled[i + 1])
469+
# braiding with trivial sector: simple and always possible
470+
inner′ = inner
471+
vertices′ = vertices
472+
if i > 1 # we also need to alter innerlines and vertices
473+
inner′ = TupleTools.setindex(inner,
474+
inner_extended[isone(a) ? (i + 1) : (i - 1)],
475+
i - 1)
476+
vertices′ = TupleTools.setindex(vertices′, vertices[i], i - 1)
477+
vertices′ = TupleTools.setindex(vertices′, vertices[i - 1], i)
478+
end
479+
f′ = FusionTree{I}(uncoupled′, coupled′, isdual′, inner′, vertices′)
480+
row = indexmap[(f′, f₂)]
481+
@inbounds U[row, col] = oneT
482+
continue
483+
end
484+
485+
BraidingStyle(I) isa NoBraiding &&
486+
throw(SectorMismatch("Cannot braid sectors $(uncoupled[i]) and $(uncoupled[i + 1])"))
487+
488+
if i == 1
489+
c = N > 2 ? inner[1] : coupled′
490+
if FusionStyle(I) isa MultiplicityFreeFusion
491+
R = oftype(oneT, (inv ? conj(Rsymbol(b, a, c)) : Rsymbol(a, b, c)))
492+
f′ = FusionTree{I}(uncoupled′, coupled′, isdual′, inner, vertices)
493+
row = indexmap[(f′, f₂)]
494+
@inbounds U[row, col] = R
495+
else # GenericFusion
496+
μ = vertices[1]
497+
Rmat = inv ? Rsymbol(b, a, c)' : Rsymbol(a, b, c)
498+
local newtrees
499+
for ν in axes(Rmat, 2)
500+
R = oftype(oneT, Rmat[μ, ν])
501+
iszero(R) && continue
502+
vertices′ = TupleTools.setindex(vertices, ν, 1)
503+
f′ = FusionTree{I}(uncoupled′, coupled′, isdual′, inner, vertices′)
504+
row = indexmap[(f′, f₂)]
505+
@inbounds U[row, col] = R
506+
end
507+
end
508+
continue
509+
end
510+
# case i > 1: other naming convention
511+
b = uncoupled[i]
512+
d = uncoupled[i + 1]
513+
a = inner_extended[i - 1]
514+
c = inner_extended[i]
515+
e = inner_extended[i + 1]
516+
if FusionStyle(I) isa UniqueFusion
517+
c′ = first(a d)
518+
coeff = oftype(oneT,
519+
if inv
520+
conj(Rsymbol(d, c, e) * Fsymbol(d, a, b, e, c′, c)) *
521+
Rsymbol(d, a, c′)
522+
else
523+
Rsymbol(c, d, e) *
524+
conj(Fsymbol(d, a, b, e, c′, c) * Rsymbol(a, d, c′))
525+
end)
526+
inner′ = TupleTools.setindex(inner, c′, i - 1)
527+
f′ = FusionTree{I}(uncoupled′, coupled′, isdual′, inner′)
528+
row = indexmap[(f′, f₂)]
529+
@inbounds U[row, col] = coeff
530+
elseif FusionStyle(I) isa SimpleFusion
531+
cs = collect(I, intersect(a d, e conj(b)))
532+
for c′ in cs
533+
coeff = oftype(oneT,
534+
if inv
535+
conj(Rsymbol(d, c, e) * Fsymbol(d, a, b, e, c′, c)) *
536+
Rsymbol(d, a, c′)
537+
else
538+
Rsymbol(c, d, e) *
539+
conj(Fsymbol(d, a, b, e, c′, c) * Rsymbol(a, d, c′))
540+
end)
541+
iszero(coeff) && continue
542+
inner′ = TupleTools.setindex(inner, c′, i - 1)
543+
f′ = FusionTree{I}(uncoupled′, coupled′, isdual′, inner′)
544+
row = indexmap[(f′, f₂)]
545+
@inbounds U[row, col] = coeff
546+
end
547+
else # GenericFusion
548+
cs = collect(I, intersect(a d, e conj(b)))
549+
for c′ in cs
550+
Rmat1 = inv ? Rsymbol(d, c, e)' : Rsymbol(c, d, e)
551+
Rmat2 = inv ? Rsymbol(d, a, c′)' : Rsymbol(a, d, c′)
552+
Fmat = Fsymbol(d, a, b, e, c′, c)
553+
μ = vertices[i - 1]
554+
ν = vertices[i]
555+
for σ in 1:Nsymbol(a, d, c′)
556+
for λ in 1:Nsymbol(c′, b, e)
557+
coeff = zero(oneT)
558+
for ρ in 1:Nsymbol(d, c, e), κ in 1:Nsymbol(d, a, c′)
559+
coeff += Rmat1[ν, ρ] * conj(Fmat[κ, λ, μ, ρ]) *
560+
conj(Rmat2[σ, κ])
561+
end
562+
iszero(coeff) && continue
563+
vertices′ = TupleTools.setindex(vertices, σ, i - 1)
564+
vertices′ = TupleTools.setindex(vertices′, λ, i)
565+
inner′ = TupleTools.setindex(inner, c′, i - 1)
566+
f′ = FusionTree{I}(uncoupled′, coupled′, isdual′, inner′, vertices′)
567+
row = indexmap[(f′, f₂)]
568+
@inbounds U[row, col] = coeff
569+
end
570+
end
571+
end
572+
end
457573
end
574+
458575
return dst, U
459576
end
460577

0 commit comments

Comments
 (0)