11"""
22 struct GradedSpace{I<:Sector, D} <: ElementarySpace
3- dims::D
4- dual::Bool
5- end
3+ GradedSpace{I,D}(dims; dual::Bool = false) where {I<:Sector, D}
64
7- A complex Euclidean space with a direct sum structure corresponding to labels in a set `I`,
8- the objects of which have the structure of a monoid with respect to a monoidal product `⊗`.
9- In practice, we restrict the label set to be a set of superselection sectors of type
10- `I<:Sector`, e.g. the set of distinct irreps of a finite or compact group, or the
11- isomorphism classes of simple objects of a unitary and pivotal (pre-)fusion category.
5+ A complex Euclidean space with a grading, i.e. a direct sum structure corresponding
6+ to labels in a set `I`, the objects of which have the structure of a monoid with
7+ respect to a monoidal product `⊗`. In practice, we restrict the label set to be a set
8+ of superselection sectors of type `I<:Sector`, e.g. the set of distinct irreps of a
9+ finite or compact group, or the isomorphism classes of simple objects of a unitary
10+ and pivotal (pre-, multi-) fusion category.
1211
1312Here `dims` represents the degeneracy or multiplicity of every sector.
1413
15- The data structure `D` of `dims` will depend on the result `Base.IteratorSize(values(I))`;
16- if the result is of type `HasLength` or `HasShape`, `dims` will be stored in a
14+ The data structure `D` of `dims` will depend on the result `Base.IteratorSize(values(I))`.
15+ If the result is of type `HasLength` or `HasShape`, `dims` will be stored in a
1716`NTuple{N,Int}` with `N = length(values(I))`. This requires that a sector `s::I` can be
1817transformed into an index via `s == getindex(values(I), i)` and
1918`i == findindex(values(I), s)`. If `Base.IteratorElsize(values(I))` results `IsInfinite()`
8584GradedSpace (g:: Base.Generator ; dual:: Bool = false ) = GradedSpace (g... ; dual = dual)
8685GradedSpace (g:: AbstractDict ; dual:: Bool = false ) = GradedSpace (g... ; dual = dual)
8786
88- Base. hash (V:: GradedSpace , h:: UInt ) = hash (V. dual, hash (V. dims, h))
89-
9087# Corresponding methods:
91- # properties
88+ # ------------------------
9289field (:: Type{<:GradedSpace} ) = ℂ
9390InnerProductStyle (:: Type{<:GradedSpace} ) = EuclideanInnerProduct ()
91+
9492function dim (V:: GradedSpace )
9593 return reduce (
9694 + , dim (V, c) * dim (c) for c in sectors (V);
103101function dim (V:: GradedSpace{I, <:Tuple} , c:: I ) where {I <: Sector }
104102 return V. dims[findindex (values (I), isdual (V) ? dual (c) : c)]
105103end
106-
107- function sectors (V:: GradedSpace{I, <:AbstractDict} ) where {I <: Sector }
108- return SectorSet {I} (s -> isdual (V) ? dual (s) : s, keys (V. dims))
109- end
110- function sectors (V:: GradedSpace{I, NTuple{N, Int}} ) where {I <: Sector , N}
111- return SectorSet {I} (Iterators. filter (n -> V. dims[n] != 0 , 1 : N)) do n
112- return isdual (V) ? dual (values (I)[n]) : values (I)[n]
113- end
114- end
115-
116- hassector (V:: GradedSpace{I} , s:: I ) where {I <: Sector } = dim (V, s) != 0
117-
118- Base. conj (V:: GradedSpace ) = typeof (V)(V. dims, ! V. dual)
119- isdual (V:: GradedSpace ) = V. dual
120-
121- # equality / comparison
122- function Base.:(== )(V₁:: GradedSpace , V₂:: GradedSpace )
123- return sectortype (V₁) == sectortype (V₂) && (V₁. dims == V₂. dims) && V₁. dual == V₂. dual
124- end
125-
126- # axes
127104Base. axes (V:: GradedSpace ) = Base. OneTo (dim (V))
128105function Base. axes (V:: GradedSpace{I} , c:: I ) where {I <: Sector }
129106 offset = 0
@@ -134,9 +111,20 @@ function Base.axes(V::GradedSpace{I}, c::I) where {I <: Sector}
134111 return (offset + 1 ): (offset + dim (c) * dim (V, c))
135112end
136113
114+ dual (V:: GradedSpace ) = typeof (V)(V. dims, ! V. dual)
115+ Base. conj (V:: GradedSpace ) = dual (V)
116+ isdual (V:: GradedSpace ) = V. dual
117+ isconj (V:: GradedSpace ) = isdual (V)
118+ function flip (V:: GradedSpace{I} ) where {I <: Sector }
119+ return if isdual (V)
120+ typeof (V)(c => dim (V, c) for c in sectors (V))
121+ else
122+ typeof (V)(dual (c) => dim (V, c) for c in sectors (V))'
123+ end
124+ end
125+
137126unitspace (S:: Type{<:GradedSpace{I}} ) where {I <: Sector } = S (unit (I) => 1 )
138127zerospace (S:: Type{<:GradedSpace{I}} ) where {I <: Sector } = S (unit (I) => 0 )
139-
140128# TODO : the following methods can probably be implemented more efficiently for
141129# `FiniteGradedSpace`, but we don't expect them to be used often in hot loops, so
142130# these generic definitions (which are still quite efficient) are good for now.
@@ -151,22 +139,13 @@ function ⊕(V₁::GradedSpace{I}, V₂::GradedSpace{I}) where {I <: Sector}
151139 end
152140 return typeof (V₁)(dims; dual = dual1)
153141end
154-
155142function ⊖ (V:: GradedSpace{I} , W:: GradedSpace{I} ) where {I <: Sector }
156143 dual = isdual (V)
157144 V ≿ W && dual == isdual (W) ||
158145 throw (SpaceMismatch (" $(W) is not a subspace of $(V) " ))
159146 return typeof (V)(c => dim (V, c) - dim (W, c) for c in sectors (V); dual)
160147end
161148
162- function flip (V:: GradedSpace{I} ) where {I <: Sector }
163- return if isdual (V)
164- typeof (V)(c => dim (V, c) for c in sectors (V))
165- else
166- typeof (V)(dual (c) => dim (V, c) for c in sectors (V))'
167- end
168- end
169-
170149function fuse (V₁:: GradedSpace{I} , V₂:: GradedSpace{I} ) where {I <: Sector }
171150 dims = SectorDict {I, Int} ()
172151 for a in sectors (V₁), b in sectors (V₂)
@@ -186,7 +165,6 @@ function infimum(V₁::GradedSpace{I}, V₂::GradedSpace{I}) where {I <: Sector}
186165 for c in intersect (sectors (V₁), sectors (V₂)); dual = Visdual
187166 )
188167end
189-
190168function supremum (V₁:: GradedSpace{I} , V₂:: GradedSpace{I} ) where {I <: Sector }
191169 Visdual = isdual (V₁)
192170 Visdual == isdual (V₂) ||
@@ -197,6 +175,21 @@ function supremum(V₁::GradedSpace{I}, V₂::GradedSpace{I}) where {I <: Sector
197175 )
198176end
199177
178+ hassector (V:: GradedSpace{I} , s:: I ) where {I <: Sector } = dim (V, s) != 0
179+ function sectors (V:: GradedSpace{I, <:AbstractDict} ) where {I <: Sector }
180+ return SectorSet {I} (s -> isdual (V) ? dual (s) : s, keys (V. dims))
181+ end
182+ function sectors (V:: GradedSpace{I, NTuple{N, Int}} ) where {I <: Sector , N}
183+ return SectorSet {I} (Iterators. filter (n -> V. dims[n] != 0 , 1 : N)) do n
184+ return isdual (V) ? dual (values (I)[n]) : values (I)[n]
185+ end
186+ end
187+
188+ Base. hash (V:: GradedSpace , h:: UInt ) = hash (V. dual, hash (V. dims, h))
189+ function Base.:(== )(V₁:: GradedSpace , V₂:: GradedSpace )
190+ return sectortype (V₁) == sectortype (V₂) && (V₁. dims == V₂. dims) && V₁. dual == V₂. dual
191+ end
192+
200193function Base. show (io:: IO , V:: GradedSpace{I} ) where {I <: Sector }
201194 print (io, type_repr (typeof (V)), " (" )
202195 separator = " "
0 commit comments