@@ -573,37 +573,39 @@ CacheStyle(::typeof(fstranspose), k::FSBTransposeKey{I}) where {I} =
573573# -> composite manipulations that depend on the duality (rigidity) and pivotal structure
574574# -> planar manipulations that do not require braiding, everything is in Fsymbol (A/Bsymbol)
575575
576- function planar_trace (
577- (f₁, f₂):: FusionTreePair{I} , (p1, p2):: Index2Tuple{N₁, N₂} , (q1, q2):: Index2Tuple{N₃, N₃}
578- ) where {I, N₁, N₂, N₃}
579- N = N₁ + N₂ + 2 N₃
580- @assert length (f₁) + length (f₂) == N
581- if N₃ == 0
582- return transpose ((f₁, f₂), (p1, p2))
576+ function planar_trace ((f₁, f₂):: FusionTreePair , (p₁, p₂):: Index2Tuple , (q₁, q₂):: Index2Tuple )
577+ length (q₁) == length (q₂) ||
578+ throw (ArgumentError (lazy " trace index tuples q₁ and q₂ must have equal length, got $(length(q₁)) and $(length(q₂))" ))
579+ I = sectortype (f₁)
580+ N = length (p₁) + length (p₂) + 2 * length (q₁)
581+ length (f₁) + length (f₂) == N ||
582+ throw (ArgumentError (lazy " fusion tree pair has $(length(f₁) + length(f₂)) indices, but permutation expects $N = $(length(p₁)) + $(length(p₂)) + 2×$(length(q₁))" ))
583+ if isempty (q₁)
584+ return transpose ((f₁, f₂), (p₁, p₂))
583585 end
584586
585587 linearindex = (
586588 ntuple (identity, Val (length (f₁)))... ,
587589 reverse (length (f₁) .+ ntuple (identity, Val (length (f₂))))... ,
588590 )
589591
590- q1 ′ = TupleTools. getindices (linearindex, q1 )
591- q2 ′ = TupleTools. getindices (linearindex, q2 )
592- p1 ′, p2 ′ = let q′ = (q1 ′... , q2 ′... )
592+ q₁ ′ = TupleTools. getindices (linearindex, q₁ )
593+ q₂ ′ = TupleTools. getindices (linearindex, q₂ )
594+ p₁ ′, p₂ ′ = let q′ = (q₁ ′... , q₂ ′... )
593595 (
594- map (l -> l - count (l .> q′), TupleTools. getindices (linearindex, p1 )),
595- map (l -> l - count (l .> q′), TupleTools. getindices (linearindex, p2 )),
596+ map (l -> l - count (l .> q′), TupleTools. getindices (linearindex, p₁ )),
597+ map (l -> l - count (l .> q′), TupleTools. getindices (linearindex, p₂ )),
596598 )
597599 end
598600
599601 T = fusionscalartype (I)
600- F₁ = fusiontreetype (I, N₁ )
601- F₂ = fusiontreetype (I, N₂ )
602+ F₁ = fusiontreetype (I, length (p₁) )
603+ F₂ = fusiontreetype (I, length (p₂) )
602604 newtrees = FusionTreeDict {Tuple{F₁, F₂}, T} ()
603605 if FusionStyle (I) isa UniqueFusion
604606 (f₁′, f₂′), coeff′ = repartition ((f₁, f₂), N)
605- for (f₁′′, coeff′′) in planar_trace (f₁′, (q1 ′, q2 ′))
606- (f12′′′, coeff′′′) = transpose ((f₁′′, f₂′), (p1 ′, p2 ′))
607+ for (f₁′′, coeff′′) in planar_trace (f₁′, (q₁ ′, q₂ ′))
608+ (f12′′′, coeff′′′) = transpose ((f₁′′, f₂′), (p₁ ′, p₂ ′))
607609 coeff = coeff′ * coeff′′ * coeff′′′
608610 iszero (coeff) || (newtrees[f12′′′] = get (newtrees, f12′′′, zero (coeff)) + coeff)
609611 end
@@ -612,9 +614,9 @@ function planar_trace(
612614 src = FusionTreeBlock ([(f₁, f₂)])
613615 dst, U = repartition (src, N)
614616 for ((f₁′, f₂′), coeff′) in zip (fusiontrees (dst), U)
615- for (f₁′′, coeff′′) in planar_trace (f₁′, (q1 ′, q2 ′))
617+ for (f₁′′, coeff′′) in planar_trace (f₁′, (q₁ ′, q₂ ′))
616618 src′ = FusionTreeBlock ([(f₁′′, f₂′)])
617- dst′, U′ = transpose (src′, (p1 ′, p2 ′))
619+ dst′, U′ = transpose (src′, (p₁ ′, p₂ ′))
618620 for (f12′′′, coeff′′′) in zip (fusiontrees (dst′), U′)
619621 coeff = coeff′ * coeff′′ * coeff′′′
620622 iszero (coeff) || (newtrees[f12′′′] = get (newtrees, f12′′′, zero (coeff)) + coeff)
@@ -626,20 +628,23 @@ function planar_trace(
626628end
627629
628630"""
629- planar_trace(f::FusionTree{I,N}, (q1, q2 )::Index2Tuple{N₃,N₃}) where {I,N,N₃}
630- -> <:AbstractDict{FusionTree{I,N-2*N₃} , <:Number}
631+ planar_trace(f::FusionTree, (q₁, q₂ )::Index2Tuple)
632+ -> <:AbstractDict{<: FusionTree, <:Number}
631633
632- Perform a planar trace of the uncoupled indices of the fusion tree `f` at `q1 ` with those at
633- `q2`, where `q1 [i]` is connected to `q2 [i]` for all `i`. The result is returned as a dictionary
634- of output trees and corresponding coefficients.
634+ Perform a planar trace of the uncoupled indices of the fusion tree `f` at `q₁ ` with those at `q₂`,
635+ where `q₁ [i]` is connected to `q₂ [i]` for all `i`. The result is returned as a dictionary of output
636+ trees and corresponding coefficients.
635637"""
636- function planar_trace (f:: FusionTree{I, N} , (q1, q2):: Index2Tuple{N₃, N₃} ) where {I, N, N₃}
638+ function planar_trace (f:: FusionTree , (q₁, q₂):: Index2Tuple )
639+ length (q₁) == length (q₂) ||
640+ throw (ArgumentError (lazy " trace index tuples q₁ and q₂ must have equal length, got $(length(q₁)) and $(length(q₂))" ))
641+ I = sectortype (f)
637642 T = fusionscalartype (I)
638- F = fusiontreetype (I, N - 2 * N₃ )
643+ F = fusiontreetype (I, length (f) - 2 * length (q₁) )
639644 newtrees = FusionTreeDict {F, T} ()
640- N₃ === 0 && return push! (newtrees, f => one (T))
645+ isempty (q₁) && return push! (newtrees, f => one (T))
641646
642- for (i, j) in zip (q1, q2 )
647+ for (i, j) in zip (q₁, q₂ )
643648 (f. uncoupled[i] == dual (f. uncoupled[j]) && f. isdual[i] != f. isdual[j]) ||
644649 return newtrees
645650 end
@@ -649,29 +654,30 @@ function planar_trace(f::FusionTree{I, N}, (q1, q2)::Index2Tuple{N₃, N₃}) wh
649654 # tracing away neighbouring pairs.
650655 k = 1
651656 local i, j
652- while k <= N₃
653- if mod1 (q1 [k] + 1 , N) == q2 [k]
654- i = q1 [k]
655- j = q2 [k]
657+ while k <= length (q₁)
658+ if mod1 (q₁ [k] + 1 , length (f)) == q₂ [k]
659+ i = q₁ [k]
660+ j = q₂ [k]
656661 break
657- elseif mod1 (q2 [k] + 1 , N) == q1 [k]
658- i = q2 [k]
659- j = q1 [k]
662+ elseif mod1 (q₂ [k] + 1 , length (f)) == q₁ [k]
663+ i = q₂ [k]
664+ j = q₁ [k]
660665 break
661666 else
662667 k += 1
663668 end
664669 end
665- k > N₃ && throw (ArgumentError (" Not a planar trace" ))
670+ k > length (q₁) &&
671+ throw (ArgumentError (lazy " indices $q₁ and $q₂ do not form a valid planar trace on a fusion tree with $(length(f)) legs: no neighboring pair found among the remaining trace indices" ))
666672
667- q1 ′ = let i = i, j = j
668- map (l -> (l - (l > i) - (l > j)), TupleTools. deleteat (q1 , k))
673+ q₁ ′ = let i = i, j = j
674+ map (l -> (l - (l > i) - (l > j)), TupleTools. deleteat (q₁ , k))
669675 end
670- q2 ′ = let i = i, j = j
671- map (l -> (l - (l > i) - (l > j)), TupleTools. deleteat (q2 , k))
676+ q₂ ′ = let i = i, j = j
677+ map (l -> (l - (l > i) - (l > j)), TupleTools. deleteat (q₂ , k))
672678 end
673679 for (f′, coeff′) in elementary_trace (f, i)
674- for (f′′, coeff′′) in planar_trace (f′, (q1 ′, q2 ′))
680+ for (f′′, coeff′′) in planar_trace (f′, (q₁ ′, q₂ ′))
675681 coeff = coeff′ * coeff′′
676682 if ! iszero (coeff)
677683 newtrees[f′′] = get (newtrees, f′′, zero (coeff)) + coeff
0 commit comments