Vector spaces
Type hierarchy
The following types are defined to characterise vector spaces and their properties:
TensorKit.Field — Typeabstract type Field endAbstract type at the top of the type hierarchy for denoting fields over which vector spaces (or more generally, linear categories) can be defined. Two common fields are ℝ and ℂ, representing the field of real or complex numbers respectively.
TensorKit.VectorSpace — Typeabstract type VectorSpace endAbstract type at the top of the type hierarchy for denoting vector spaces, or, more generally, objects in linear monoidal categories.
TensorKit.ElementarySpace — Typeabstract type ElementarySpace <: VectorSpaceElementary finite-dimensional vector space over a field that can be used as the index space corresponding to the indices of a tensor. ElementarySpace is a supertype for all vector spaces (objects) that can be associated with the individual indices of a tensor, as hinted to by its alias IndexSpace`.
Every elementary vector space should respond to the methods conj and dual, returning the complex conjugate space and the dual space respectively. The complex conjugate of the dual space is obtained as dual(conj(V)) === conj(dual(V)). These different spaces should be of the same type, so that a tensor can be defined as an element of a homogeneous tensor product of these spaces.
TensorKit.GeneralSpace — Typestruct GeneralSpace{𝔽} <: ElementarySpace
GeneralSpace{𝔽}(d::Integer = 0; dual::Bool = false, conj::Bool = false)A finite-dimensional space over an arbitrary field 𝔽 without additional structure. It is thus characterized by its dimension, and whether or not it is the dual and/or conjugate space. For a real field 𝔽, the space and its conjugate are the same.
TensorKit.CartesianSpace — Typestruct CartesianSpace <: ElementarySpace
CartesianSpace(d::Integer = 0; dual = false)
ℝ^dA real Euclidean space $ℝ^d$. CartesianSpace has no additonal structure and is completely characterised by its dimension d. A dual keyword argument is accepted for compatibility with other space constructors, but is ignored since the dual of a Cartesian space is isomorphic to itself. This is the vector space that is implicitly assumed in most of matrix algebra.
TensorKit.ComplexSpace — Typestruct ComplexSpace <: ElementarySpace
ComplexSpace(d::Integer = 0; dual = false)
ℂ^dA standard complex vector space $ℂ^d$ with Euclidean inner product and no additional structure. It is completely characterised by its dimension and whether its the normal space or its dual (which is canonically isomorphic to the conjugate space).
TensorKit.GradedSpace — Typestruct GradedSpace{I<:Sector, D} <: ElementarySpace
GradedSpace{I,D}(dims; dual::Bool = false) where {I<:Sector, D}A complex Euclidean space with a grading, i.e. a direct sum structure corresponding to labels in a set I, the objects of which have the structure of a monoid with respect to a monoidal product ⊗. In practice, we restrict the label set to be a set of superselection sectors of type I<:Sector, e.g. the set of distinct irreps of a finite or compact group, or the isomorphism classes of simple objects of a unitary and pivotal (pre-, multi-) fusion category.
Here dims represents the degeneracy or multiplicity of every sector.
The data structure D of dims will depend on the result Base.IteratorSize(values(I)). If the result is of type HasLength or HasShape, dims will be stored in a NTuple{N,Int} with N = length(values(I)). This requires that a sector s::I can be transformed into an index via s == getindex(values(I), i) and i == findindex(values(I), s). If Base.IteratorElsize(values(I)) results IsInfinite() or SizeUnknown(), a SectorDict{I,Int} is used to store the non-zero degeneracy dimensions with the corresponding sector as key. The parameter D is hidden from the user and should typically be of no concern.
The concrete type GradedSpace{I,D} with correct D can be obtained as Vect[I], or if I == Irrep[G] for some G<:Group, as Rep[G].
TensorKit.CompositeSpace — Typeabstract type CompositeSpace{S<:ElementarySpace} <: VectorSpace endAbstract type for composite spaces that are defined in terms of a number of elementary vector spaces of a homogeneous type S<:ElementarySpace.
TensorKit.ProductSpace — Typestruct ProductSpace{S<:ElementarySpace, N} <: CompositeSpace{S}
ProductSpace(spaces::NTuple{N, S}) where {S<:ElementarySpace, N}A ProductSpace is a tensor product space of N vector spaces of type S<:ElementarySpace. Only tensor products between ElementarySpace objects of the same type are allowed.
TensorKit.HomSpace — Typestruct HomSpace{S<:ElementarySpace, P1<:CompositeSpace{S}, P2<:CompositeSpace{S}}
HomSpace(codomain::CompositeSpace{S}, domain::CompositeSpace{S}) where {S<:ElementarySpace}Represents the linear space of morphisms with codomain of type P1 and domain of type P2. Note that HomSpaceis not a subtype of [VectorSpace](@ref), i.e. we restrict the latter to denote categories and their objects, and keepHomSpace` distinct.
together with the following specific type for encoding the inner product structure of a space:
TensorKit.InnerProductStyle — TypeInnerProductStyle(V::VectorSpace) -> ::InnerProductStyle
InnerProductStyle(S::Type{<:VectorSpace}) -> ::InnerProductStyleReturn the type of inner product for vector spaces, which can be either
NoInnerProduct(): no mapping fromdual(V)toconj(V), i.e. no metric- subtype of
HasInnerProduct: a metric exists, but no further support is implemented. EuclideanInnerProduct(): the metric is the identity, such that dual and conjugate spaces are isomorphic.
Useful constants
The following constants are defined to easily create the concrete type of GradedSpace associated with a given type of sector.
TensorKit.Vect — Constantconst VectA constant of a singleton type used as Vect[I] with I<:Sector a type of sector, to construct or obtain the concrete type GradedSpace{I,D} instances without having to specify D.
TensorKit.Rep — Constantconst RepA constant of a singleton type used as Rep[G] with G<:Group a type of group, to construct or obtain the concrete type GradedSpace{Irrep[G],D} instances without having to specify D. Note that Rep[G] == Vect[Irrep[G]].
In this respect, there are also a number of type aliases for the GradedSpace types associated with the most common sectors, namely
const ZNSpace{N} = Vect[ZNIrrep{N}]
const Z2Space = ZNSpace{2}
const Z3Space = ZNSpace{3}
const Z4Space = ZNSpace{4}
const U1Space = Rep[U₁]
const CU1Space = Rep[CU₁]
const SU2Space = Rep[SU₂]
# Unicode alternatives
const ℤ₂Space = Z2Space
const ℤ₃Space = Z3Space
const ℤ₄Space = Z4Space
const U₁Space = U1Space
const CU₁Space = CU1Space
const SU₂Space = SU2SpaceMethods
Methods often apply similar to e.g. spaces and corresponding tensors or tensor maps, e.g.:
TensorKit.field — Functionfield(a) -> Type{𝔽<:Field}
field(::Type{T}) -> Type{𝔽<:Field}Return the type of field over which object a (e.g. a vector space or a tensor) is defined. This also works in type domain.
TensorKit.sectortype — Functionsectortype(a) -> Type{<:Sector}
sectortype(::Type) -> Type{<:Sector}Return the type of sector over which object a (e.g. a representation space or a tensor) is defined. Also works in type domain.
TensorKit.sectors — Functionsectors(V::ElementarySpace)Return an iterator over the different sectors of V.
TensorKit.hassector — Functionhassector(V::VectorSpace, a::Sector) -> BoolReturn whether a vector space V has a subspace corresponding to sector a with non-zero dimension, i.e. dim(V, a) > 0.
TensorKitSectors.dim — Methoddim(V::VectorSpace) -> IntReturn the total dimension of the vector space V as an Int.
TensorKitSectors.dim — Methoddim(V::ElementarySpace, s::Sector) -> IntReturn the degeneracy dimension corresponding to the sector s of the vector space V.
TensorKit.reduceddim — Functionreduceddim(V::ElementarySpace) -> IntReturn the sum of all degeneracy dimensions of the vector space V.
TensorKitSectors.dim — Methoddim(P::ProductSpace{S, N}, s::NTuple{N, sectortype(S)}) where {S<:ElementarySpace}
-> IntReturn the total degeneracy dimension corresponding to a tuple of sectors for each of the spaces in the tensor product, obtained as prod(dims(P, s))`.
TensorKitSectors.dim — Methoddim(W::HomSpace)Return the total dimension of a HomSpace, i.e. the number of linearly independent morphisms that can be constructed within this space.
TensorKit.dims — Functiondims(::ProductSpace{S, N}) -> Dims{N} = NTuple{N, Int}Return the dimensions of the spaces in the tensor product space as a tuple of integers.
dims(P::ProductSpace{S, N}, s::NTuple{N, sectortype(S)}) where {S<:ElementarySpace}
-> Dims{N} = NTuple{N, Int}Return the degeneracy dimensions corresponding to a tuple of sectors s for each of the spaces in the tensor product P.
TensorKit.blocksectors — Methodblocksectors(P::ProductSpace)Return an iterator over the different unique coupled sector labels, i.e. the different fusion outputs that can be obtained by fusing the sectors present in the different spaces that make up the ProductSpace instance.
TensorKit.blocksectors — Methodblocksectors(W::HomSpace)Return an iterator over the different unique coupled sector labels, i.e. the intersection of the different fusion outputs that can be obtained by fusing the sectors present in the domain, as well as from the codomain.
See also hasblock.
TensorKit.hasblock — Functionhasblock(P::ProductSpace, c::Sector)Query whether a coupled sector c appears with nonzero dimension in P, i.e. whether blockdim(P, c) > 0.
See also blockdim and blocksectors.
hasblock(W::HomSpace, c::Sector)Query whether a coupled sector c appears in both the codomain and domain of W.
See also blocksectors.
hasblock(t::AbstractTensorMap, c::Sector) -> BoolVerify whether a tensor has a block corresponding to a coupled sector c.
TensorKit.blockdim — Functionblockdim(P::ProductSpace, c::Sector)Return the total dimension of a coupled sector c in the product space, by summing over all dim(P, s) for all tuples of sectors s::NTuple{N, <:Sector} that can fuse to c, counted with the correct multiplicity (i.e. number of ways in which s can fuse to c).
See also hasblock and blocksectors.
TensorKit.fusiontrees — Methodfusiontrees(P::ProductSpace, blocksector::Sector)Return an iterator over all fusion trees that can be formed by fusing the sectors present in the different spaces that make up the ProductSpace instance into the coupled sector blocksector.
TensorKit.space — Functionspace(a) -> VectorSpaceReturn the vector space associated to object a.
The following methods act specifically on ElementarySpace spaces:
TensorKitSectors.dual — Methoddual(V::VectorSpace) -> VectorSpaceReturn the dual space of V; also obtained via V'. This should satisfy dual(dual(V)) == V. It is assumed that typeof(V) == typeof(V').
Base.conj — Functionconj(V::VectorSpace) -> VectorSpaceReturn the conjugate space of V. This should satisfy conj(conj(V)) == V. For vector spaces over the real numbers, it must hold that conj(V) == V. For vector spaces with a Euclidean inner product, it must hold that conj(V) == dual(V).
conj(V::S) where {S<:ElementarySpace} -> SReturn the conjugate space of V. This should satisfy conj(conj(V)) == V.
For field(V)==ℝ, conj(V) == V. It is assumed that typeof(V) == typeof(conj(V)).
TensorKit.isconj — Functionisconj(V::ElementarySpace) -> BoolReturn whether an ElementarySpace V is normal or rather the conjugated space. Always returns false for spaces where V == conj(V), i.e. vector spaces over ℝ.
TensorKit.isdual — Functionisdual(V::ElementarySpace) -> BoolReturn whether an ElementarySpace V is normal or rather a dual space. Always returns false for spaces where V == dual(V).
TensorKit.flip — Functionflip(V::S) where {S<:ElementarySpace} -> SReturn a single vector space of type S that has the same value of isdual as dual(V), but yet is isomorphic to V rather than to dual(V). The spaces flip(V) and dual(V) only differ in the case of GradedSpace{I}.
TensorKit.zerospace — Functionzerospace(V::S) where {S<:ElementarySpace} -> SReturn the corresponding vector space of type S that represents the zero-dimensional or empty space. This is the zero element of the direct sum of vector spaces. Base.zero falls back to zerospace.
TensorKit.unitspace — Functionunitspace(V::S) where {S<:ElementarySpace} -> SReturn the corresponding vector space of type S that represents the trivial one-dimensional space, i.e. the space that is isomorphic to the corresponding field.
unitspace(V)is different from one(V). The latter returns the empty product space ProductSpace{S,0}(()). Base.oneunit falls back to unitspace.
TensorKit.:⊕ — Function⊕(V₁::S, V₂::S, V₃::S...) where {S<:ElementarySpace} -> S
oplus(V₁::S, V₂::S, V₃::S...) where {S<:ElementarySpace} -> SReturn the corresponding vector space of type S that represents the direct sum sum of the spaces V₁, V₂, ... Note that all the individual spaces should have the same value for isdual, as otherwise the direct sum is not defined.
TensorKit.:⊖ — Function⊖(V::ElementarySpace, W::ElementarySpace) -> X::ElementarySpace
ominus(V::ElementarySpace, W::ElementarySpace) -> X::ElementarySpaceReturn a space that is equivalent to the orthogonal complement of W in V, i.e. an instance X::ElementarySpace such that V = W ⊕ X.
TensorKit.supremum — Functionsupremum(V₁::ElementarySpace, V₂::ElementarySpace, V₃::ElementarySpace...)Return the supremum of a number of elementary spaces, i.e. an instance V::ElementarySpace such that V ≿ V₁, V ≿ V₂, ... and no other W ≺ V has this property. This requires that all arguments have the same value of isdual( ), and also the return value V will have the same value.
TensorKit.infimum — Functioninfimum(V₁::ElementarySpace, V₂::ElementarySpace, V₃::ElementarySpace...)Return the infimum of a number of elementary spaces, i.e. an instance V::ElementarySpace such that V ≾ V₁, V ≾ V₂, ... and no other W ≻ V has this property. This requires that all arguments have the same value of isdual( ), and also the return value V will have the same value.
while the following also work on both ElementarySpace and ProductSpace
TensorKit.fuse — Functionfuse(V₁::S, V₂::S, V₃::S...) where {S<:ElementarySpace} -> S
fuse(P::ProductSpace{S}) where {S<:ElementarySpace} -> SReturn a single vector space of type S that is isomorphic to the fusion product of the individual spaces V₁, V₂, ..., or the spaces contained in P.
Base.one — Methodone(::S) where {S<:ElementarySpace} -> ProductSpace{S, 0}
one(::ProductSpace{S}) where {S<:ElementarySpace} -> ProductSpace{S, 0}Return a tensor product of zero spaces of type S, i.e. this is the unit object under the tensor product operation, such that V ⊗ one(V) == V.
TensorKitSectors.:⊗ — Method⊗(V₁::S, V₂::S, V₃::S...) where {S<:ElementarySpace} -> SCreate a ProductSpace{S}(V₁, V₂, V₃...) representing the tensor product of several elementary vector spaces. For convience, Julia's regular multiplication operator * applied to vector spaces has the same effect.
The tensor product structure is preserved, see fuse for returning a single elementary space of type S that is isomorphic to this tensor product.
TensorKitSectors.:⊠ — Method⊠(V₁::VectorSpace, V₂::VectorSpace)Given two vector spaces V₁ and V₂ (ElementarySpace or ProductSpace), or thus, objects of corresponding fusion categories $C₁$ and $C₂$, $V₁ ⊠ V₂$ constructs the Deligne tensor product, an object in $C₁ ⊠ C₂$ which is the natural tensor product of those categories. In particular, the corresponding type of sectors (simple objects) is given by sectortype(V₁ ⊠ V₂) == sectortype(V₁) ⊠ sectortype(V₂) and can be thought of as a tuple of the individual sectors.
The Deligne tensor product also works in the type domain and for sectors and tensors. For group representations, we have Rep[G₁] ⊠ Rep[G₂] == Rep[G₁ × G₂], i.e. these are the natural representation spaces of the direct product of two groups.
TensorKit.ismonomorphic — Functionismonomorphic(V₁::VectorSpace, V₂::VectorSpace)
V₁ ≾ V₂Return whether there exist monomorphisms from V₁ to V₂, i.e. 'injective' morphisms with left inverses.
TensorKit.isepimorphic — Functionisepimorphic(V₁::VectorSpace, V₂::VectorSpace)
V₁ ≿ V₂Return whether there exist epimorphisms from V₁ to V₂, i.e. 'surjective' morphisms with right inverses.
TensorKit.isisomorphic — Functionisisomorphic(V₁::VectorSpace, V₂::VectorSpace)
V₁ ≅ V₂Return if V₁ and V₂ are isomorphic, meaning that there exists isomorphisms from V₁ to V₂, i.e. morphisms with left and right inverses.
Inserting trivial space factors or removing such factors for ProductSpace instances can be done with the following methods.
TensorKit.insertleftunit — Methodinsertleftunit(P::ProductSpace, i::Int=length(P) + 1; conj=false, dual=false)Insert a trivial vector space, isomorphic to the underlying field, at position i, which can be specified as an Int or as Val(i) for improved type stability. More specifically, adds a left monoidal unit or its dual.
See also insertrightunit, removeunit.
TensorKit.insertrightunit — Methodinsertrightunit(P::ProductSpace, i=lenght(P); conj=false, dual=false)Insert a trivial vector space, isomorphic to the underlying field, after position i, which can be specified as an Int or as Val(i) for improved type stability. More specifically, adds a right monoidal unit or its dual.
See also insertleftunit, removeunit.
TensorKit.removeunit — Methodremoveunit(P::ProductSpace, i::Int)This removes a trivial tensor product factor at position 1 ≤ i ≤ N, where i can be specified as an Int or as Val(i) for improved type stability. For this to work, that factor has to be isomorphic to the field of scalars.
This operation undoes the work of insertleftunit and insertrightunit.
There are also specific methods for HomSpace instances, that are used in determining the resuling HomSpace after applying certain tensor operations.
TensorKit.flip — Methodflip(W::HomSpace, I)Return a new HomSpace object by applying flip to each of the spaces in the domain and codomain of W for which the linear index i satisfies i ∈ I.
TensorKit.permute — Methodpermute(W::HomSpace, (p₁, p₂)::Index2Tuple{N₁,N₂})Return the HomSpace obtained by permuting the indices of the domain and codomain of W according to the permutation p₁ and p₂ respectively.
TensorKit.select — Methodselect(W::HomSpace, (p₁, p₂)::Index2Tuple{N₁,N₂})Return the HomSpace obtained by a selection from the domain and codomain of W according to the indices in p₁ and p₂ respectively.
TensorKit.compose — Methodcompose(W::HomSpace, V::HomSpace)Obtain the HomSpace that is obtained from composing the morphisms in W and V. For this to be possible, the domain of W must match the codomain of V.
TensorKit.insertleftunit — Methodinsertleftunit(W::HomSpace, i=numind(W) + 1; conj=false, dual=false)Insert a trivial vector space, isomorphic to the underlying field, at position i, which can be specified as an Int or as Val(i) for improved type stability. More specifically, adds a left monoidal unit or its dual.
See also insertrightunit, removeunit.
TensorKit.insertrightunit — Methodinsertrightunit(W::HomSpace, i=numind(W); conj=false, dual=false)Insert a trivial vector space, isomorphic to the underlying field, after position i, which can be specified as an Int or as Val(i) for improved type stability. More specifically, adds a right monoidal unit or its dual.
See also insertleftunit, removeunit.
TensorKit.removeunit — Methodremoveunit(P::HomSpace, i)This removes a trivial tensor product factor at position 1 ≤ i ≤ N, where i can be specified as an Int or as Val(i) for improved type stability. For this to work, the space at position i has to be isomorphic to the field of scalars.
This operation undoes the work of insertleftunit and insertrightunit.