@@ -17,7 +17,7 @@ struct BraidingTensor{T, S, A} <: AbstractTensorMap{T, S, 2, 2}
1717 V1:: S
1818 V2:: S
1919 adjoint:: Bool
20- function BraidingTensor {T, S} (V1:: S , V2:: S , :: Type{A} , adjoint:: Bool = false ) where {T, S <: IndexSpace , A <: DenseVector{T} }
20+ function BraidingTensor {T, S, A } (V1:: S , V2:: S , :: Type{A} , adjoint:: Bool = false ) where {T, S <: IndexSpace , A <: DenseVector{T} }
2121 for a in sectors (V1), b in sectors (V2), c in (a ⊗ b)
2222 Nsymbol (a, b, c) == Nsymbol (b, a, c) ||
2323 throw (ArgumentError (" Cannot define a braiding between $a and $b " ))
@@ -26,6 +26,9 @@ struct BraidingTensor{T, S, A} <: AbstractTensorMap{T, S, 2, 2}
2626 # partial construction: only construct rowr and colr when needed
2727 end
2828end
29+ function BraidingTensor {T, S} (V1:: S , V2:: S , :: Type{A} , adjoint:: Bool = false ) where {T, S <: IndexSpace , A}
30+ return BraidingTensor {T, S, A} (V1, V2, A, adjoint)
31+ end
2932function BraidingTensor {T} (V1:: S , V2:: S , A, adjoint:: Bool = false ) where {T, S <: IndexSpace }
3033 return BraidingTensor {T, S} (V1, V2, A, adjoint)
3134end
@@ -72,23 +75,16 @@ function BraidingTensor{T}(V::HomSpace, adjoint::Bool = false) where {T}
7275 return BraidingTensor {T} (V[2 ], V[1 ], adjoint)
7376end
7477function Base. adjoint (b:: BraidingTensor{T, S, A} ) where {T, S, A}
75- return BraidingTensor {T, S, A} (b. V1, b. V2, ! b. adjoint)
78+ return BraidingTensor {T, S, A} (b. V1, b. V2, A, ! b. adjoint)
7679end
7780
78- storagetype (b :: BraidingTensor{T, S, A} ) where {T, S, A} = A
81+ storagetype (:: Type{ BraidingTensor{T, S, A} } ) where {T, S, A} = A
7982space (b:: BraidingTensor ) = b. adjoint ? b. V1 ⊗ b. V2 ← b. V2 ⊗ b. V1 : b. V2 ⊗ b. V1 ← b. V1 ⊗ b. V2
8083
81- # specializations to ignore the storagetype of BraidingTensor
82- promote_storagetype (:: Type{A} , :: Type{B} ) where {A <: BraidingTensor , B <: AbstractTensorMap } = storagetype (B)
83- promote_storagetype (:: Type{A} , :: Type{B} ) where {A <: AbstractTensorMap , B <: BraidingTensor } = storagetype (A)
84- promote_storagetype (:: Type{A} , :: Type{B} ) where {A <: BraidingTensor , B <: BraidingTensor } = storagetype (A)
85-
86- promote_storagetype (:: Type{T} , :: Type{A} , :: Type{B} ) where {T <: Number , A <: BraidingTensor , B <: AbstractTensorMap } =
87- similarstoragetype (B, T)
88- promote_storagetype (:: Type{T} , :: Type{A} , :: Type{B} ) where {T <: Number , A <: AbstractTensorMap , B <: BraidingTensor } =
89- similarstoragetype (A, T)
90- promote_storagetype (:: Type{T} , :: Type{A} , :: Type{B} ) where {T <: Number , A <: BraidingTensor , B <: BraidingTensor } =
91- similarstoragetype (A, T)
84+ promote_storagetype (:: Type{B} , :: Type{T} ) where {B <: BraidingTensor , T <: AbstractTensorMap } =
85+ promote_storagetype (storagetype (B), storagetype (T))
86+ promote_storagetype (:: Type{T} , :: Type{B} ) where {B <: BraidingTensor , T <: AbstractTensorMap } =
87+ promote_storagetype (storagetype (B), storagetype (T))
9288
9389function Base. getindex (b:: BraidingTensor )
9490 sectortype (b) === Trivial || throw (SectorMismatch ())
@@ -120,6 +116,14 @@ function _braiding_factor(f₁, f₂, inv::Bool = false)
120116 return r
121117end
122118
119+ function _set_subblock! (data, val)
120+ @inbounds for i in axes (data, 1 ), j in axes (data, 2 )
121+ data[i, j, j, i] = val
122+ end
123+ return data
124+ end
125+
126+
123127@inline function subblock (
124128 b:: BraidingTensor , (f₁, f₂):: Tuple{FusionTree{I, 2}, FusionTree{I, 2}}
125129 ) where {I <: Sector }
141145 fill! (data, zero (eltype (b)))
142146
143147 r = _braiding_factor (f₁, f₂, b. adjoint)
144- if ! isnothing (r)
145- @inbounds for i in axes (data, 1 ), j in axes (data, 2 )
146- data[i, j, j, i] = r
147- end
148- end
148+ ! isnothing (r) && _set_subblock! (data, r)
149149 return data
150150end
151151
@@ -157,9 +157,30 @@ Base.convert(::Type{TensorMap}, b::BraidingTensor) = TensorMap(b)
157157
158158Base. complex (b:: BraidingTensor{<:Complex} ) = b
159159function Base. complex (b:: BraidingTensor{T, S, A} ) where {T, S, A}
160- Tc = complex (T)
161- Ac = similarstoragetype (Tc, A)
162- return BraidingTensor {Tc, S, Ac} (space (b), b. adjoint)
160+ Ac = similarstoragetype (A, complex (T))
161+ return BraidingTensor (space (b), Ac, b. adjoint)
162+ end
163+
164+ function _trivial_subblock! (data, b:: BraidingTensor )
165+ V1, V2 = codomain (b)
166+ d1, d2 = dim (V1), dim (V2)
167+ subblock = sreshape (StridedView (data), (d1, d2, d2, d1))
168+ _set_subblock! (subblock, one (eltype (b)))
169+ return data
170+ end
171+
172+ function _nontrivial_subblock! (data, b:: BraidingTensor , s:: Sector )
173+ base_offset = first (blockstructure (b)[s][2 ]) - 1
174+
175+ for ((f₁, f₂), (sz, str, off)) in pairs (subblockstructure (space (b)))
176+ (f₁. coupled == f₂. coupled == s) || continue
177+ r = _braiding_factor (f₁, f₂, b. adjoint)
178+ isnothing (r) && continue
179+ # change offset to account for single block
180+ subblock = StridedView (data, sz, str, off - base_offset)
181+ _set_subblock! (subblock, r)
182+ end
183+ return data
163184end
164185
165186function block (b:: BraidingTensor , s:: Sector )
@@ -169,36 +190,17 @@ function block(b::BraidingTensor, s::Sector)
169190 # TODO : probably always square?
170191 m = blockdim (codomain (b), s)
171192 n = blockdim (domain (b), s)
172- data = similarmatrixtype (storagetype (b))(undef, (m, n))
173193
174- length (data) == 0 && return data # s ∉ blocksectors(b)
194+ m * n == 0 && return similarmatrixtype ( storagetype (b))(undef, (m, n)) # s ∉ blocksectors(b)
175195
196+ data = similarmatrixtype (storagetype (b))(undef, (m, n))
176197 data = fill! (data, zero (eltype (b)))
177198
178- V1, V2 = codomain (b)
179199 if sectortype (b) === Trivial
180- d1, d2 = dim (V1), dim (V2)
181- subblock = sreshape (StridedView (data), (d1, d2, d2, d1))
182- @inbounds for i in axes (subblock, 1 ), j in axes (subblock, 2 )
183- subblock[i, j, j, i] = one (eltype (b))
184- end
185- return data
186- end
187-
188- base_offset = first (blockstructure (b)[s][2 ]) - 1
189-
190- for ((f₁, f₂), (sz, str, off)) in pairs (subblockstructure (space (b)))
191- (f₁. coupled == f₂. coupled == s) || continue
192- r = _braiding_factor (f₁, f₂, b. adjoint)
193- isnothing (r) && continue
194- # change offset to account for single block
195- subblock = StridedView (data, sz, str, off - base_offset)
196- @inbounds for i in axes (subblock, 1 ), j in axes (subblock, 2 )
197- subblock[i, j, j, i] = r
198- end
200+ return _trivial_subblock! (data, b)
201+ else
202+ return _nontrivial_subblock! (data, b, s)
199203 end
200-
201- return data
202204end
203205
204206# Index manipulations
0 commit comments