@@ -64,7 +64,7 @@ function artin_braid(f::FusionTree{I, N}, i; inv::Bool = false) where {I, N}
6464 a = inner_extended[i - 1 ]
6565 c = inner_extended[i]
6666 e = inner_extended[i + 1 ]
67- c′ = first (a ⊗ d)
67+ c′ = only (a ⊗ d)
6868 coeff = oftype (
6969 oneT,
7070 if inv
@@ -122,6 +122,8 @@ function artin_braid(src::FusionTreeBlock{I, N, 0}, i; inv::Bool = false) where
122122 BraidingStyle (I) isa NoBraiding &&
123123 throw (SectorMismatch (lazy " Cannot braid sectors $a and $b" ))
124124
125+ T = typeof (oneT)
126+ localbraidcache = Dict {NTuple{6, I}, FusionStyle(I) isa MultiplicityFreeFusion ? T : Array{T, 4}} ()
125127 for (col, (f, f₂)) in enumerate (fusiontrees (src))
126128 inner = f. innerlines
127129 inner_extended = (uncoupled[1 ], inner... , coupled′)
@@ -156,10 +158,8 @@ function artin_braid(src::FusionTreeBlock{I, N, 0}, i; inv::Bool = false) where
156158 e = inner_extended[i + 1 ]
157159 if FusionStyle (I) isa MultiplicityFreeFusion
158160 for c′ in intersect (a ⊗ d, e ⊗ conj (b))
159- coeff = if inv
160- conj (Rsymbol (d, c, e) * Fsymbol (d, a, b, e, c′, c)) * Rsymbol (d, a, c′)
161- else
162- Rsymbol (c, d, e) * conj (Fsymbol (d, a, b, e, c′, c) * Rsymbol (a, d, c′))
161+ coeff = let k = (a, b, c, d, e, c′)
162+ get! (() -> _artin_braid_local (k, inv), localbraidcache, k)
163163 end
164164 iszero (coeff) && continue
165165 inner′ = TupleTools. setindex (inner, c′, i - 1 )
@@ -172,15 +172,14 @@ function artin_braid(src::FusionTreeBlock{I, N, 0}, i; inv::Bool = false) where
172172 Rmat1 = inv ? Rsymbol (d, c, e)' : Rsymbol (c, d, e)
173173 Rmat2 = inv ? Rsymbol (d, a, c′)' : Rsymbol (a, d, c′)
174174 Fmat = Fsymbol (d, a, b, e, c′, c)
175+ coeff_tensor = let k = (a, b, c, d, e, c′)
176+ get! (() -> _artin_braid_local (k, inv), localbraidcache, k)
177+ end
175178 μ = vertices[i - 1 ]
176179 ν = vertices[i]
177- for σ in 1 : Nsymbol (a, d, c′)
178- for λ in 1 : Nsymbol (c′, b, e)
179- coeff = zero (oneT)
180- for ρ in 1 : Nsymbol (d, c, e), κ in 1 : Nsymbol (d, a, c′)
181- coeff += Rmat1[ν, ρ] * conj (Fmat[κ, λ, μ, ρ]) *
182- conj (Rmat2[σ, κ])
183- end
180+ for λ in 1 : size (coeff_tensor, 2 )
181+ for σ in 1 : size (coeff_tensor, 1 )
182+ coeff = coeff_tensor[σ, λ, μ, ν]
184183 iszero (coeff) && continue
185184 vertices′ = TupleTools. setindex (vertices, σ, i - 1 )
186185 vertices′ = TupleTools. setindex (vertices′, λ, i)
@@ -193,10 +192,26 @@ function artin_braid(src::FusionTreeBlock{I, N, 0}, i; inv::Bool = false) where
193192 end
194193 end
195194 end
196-
197195 return dst => U
198196end
199197
198+ function _artin_braid_local ((a, b, c, d, e, c′):: NTuple{6, I} , inv:: Bool ) where {I}
199+ if FusionStyle (I) isa MultiplicityFreeFusion
200+ coeff = if inv
201+ conj (Rsymbol (d, c, e) * Fsymbol (d, a, b, e, c′, c)) * Rsymbol (d, a, c′)
202+ else
203+ Rsymbol (c, d, e) * conj (Fsymbol (d, a, b, e, c′, c) * Rsymbol (a, d, c′))
204+ end
205+ return coeff
206+ else
207+ Rmat1 = inv ? Rsymbol (d, c, e)' : Rsymbol (c, d, e)
208+ Rmat2 = inv ? Rsymbol (d, a, c′)' : Rsymbol (a, d, c′)
209+ Fmat = Fsymbol (d, a, b, e, c′, c)
210+ @tensor coeff[σ, λ, μ, ν] := Rmat1[ν, ρ] * conj (Fmat[κ, λ, μ, ρ]) * conj (Rmat2[σ, κ])
211+ return coeff
212+ end
213+ end
214+
200215# braid fusion tree
201216"""
202217 braid(f::FusionTree{<:Sector, N}, p::NTuple{N, Int}, levels::NTuple{N, Int})
@@ -223,7 +238,7 @@ function braid(f::FusionTree{I, N}, (p, _)::Index2Tuple{N, 0}, (levels, _)::Inde
223238 for j in 1 : (i - 1 )
224239 if p[j] > p[i]
225240 a, b = f. uncoupled[p[j]], f. uncoupled[p[i]]
226- coeff *= Rsymbol (a, b, first (a ⊗ b))
241+ coeff *= Rsymbol (a, b, only (a ⊗ b))
227242 end
228243 end
229244 end
@@ -308,19 +323,22 @@ end
308323 f′, coeff2 = braid (f, p, levels)
309324 (f₁′, f₂′), coeff3 = repartition ((f′, f0), N₁)
310325 return (f₁′, f₂′) => coeff1 * coeff2 * coeff3
311-
312326 else
313327 src, (p1, p2), (l1, l2) = key
314328
315329 p = linearizepermutation (p1, p2, numout (src), numin (src))
316330 levels = (l1... , reverse (l2)... )
317331
318- dst, U = repartition (src, numind (src))
332+ dst, U′ = repartition (src, numind (src))
333+ T = sectorscalartype (I)
334+ U = eltype (U′) == T ? U′ : T .(U′) # U′ has fusionscalartype(I) elements
335+ Uold = similar (U)
319336
320337 for s in permutation2swaps (p)
338+ U, Uold = Uold, U
321339 inv = levels[s] > levels[s + 1 ]
322340 dst, U_tmp = artin_braid (dst, s; inv)
323- U = U_tmp * U
341+ U = mul! (U, U_tmp, Uold)
324342 l = levels[s]
325343 levels = TupleTools. setindex (levels, levels[s + 1 ], s)
326344 levels = TupleTools. setindex (levels, l, s + 1 )
329347 if N₂ == 0
330348 return dst => U
331349 else
350+ U, Uold = Uold, U
332351 dst, U_tmp = repartition (dst, N₁)
333- U = U_tmp * U
352+ U = mul! (U, U_tmp, Uold)
334353 return dst => U
335354 end
336355 end
0 commit comments