@@ -6,7 +6,7 @@ using TensorKit
66
77From the [ Introduction] (@ref s_intro), it should be clear that an important aspect in the
88definition of a tensor (map) is specifying the vector spaces and their structure in the
9- domain and codomain of the map. The starting point is an abstract type ` VectorSpace `
9+ domain and codomain of the map. The starting point is an abstract type [ ` VectorSpace ` ] ( @ref )
1010``` julia
1111abstract type VectorSpace end
1212```
@@ -22,16 +22,16 @@ const IndexSpace = ElementarySpace
2222
2323abstract type CompositeSpace{S<: ElementarySpace } <: VectorSpace end
2424```
25- Here, ` ElementarySpace ` is a super type for all vector spaces (objects) that can be
25+ Here, [ ` ElementarySpace ` ] ( @ref ) is a super type for all vector spaces (objects) that can be
2626associated with the individual indices of a tensor, as hinted to by its alias ` IndexSpace ` .
2727
28- On the other hand, subtypes of ` CompositeSpace{S} ` where ` S<:ElementarySpace ` are composed
28+ On the other hand, subtypes of [ ` CompositeSpace{S} ` ] ( @ref ) where ` S<:ElementarySpace ` are composed
2929of a number of elementary spaces of type ` S ` . So far, there is a single concrete type
30- ` ProductSpace{S,N} ` that represents the tensor product of ` N ` vector spaces of a homogeneous
30+ [ ` ProductSpace{S,N} ` ] ( @ref ) that represents the tensor product of ` N ` vector spaces of a homogeneous
3131type ` S ` . Its properties are discussed in the section on [ Composite spaces] (@ref ss_compositespaces),
3232together with possible extensions for the future.
3333
34- Throughout TensorKit.jl, the function ` spacetype ` returns the type of ` ElementarySpace `
34+ Throughout TensorKit.jl, the function [ ` spacetype ` ] ( @ref ) returns the type of ` ElementarySpace `
3535associated with e.g. a composite space or a tensor. It works both on instances and in the
3636type domain. Its use will be illustrated below.
3737
@@ -63,7 +63,7 @@ ComplexF64 ⊆ ℂ
6363```
6464and furthermore —probably more usefully— ` ℝ^n ` and ` ℂ^n ` create specific elementary vector
6565spaces as described in the next section. The underlying field of a vector space or tensor
66- ` a ` can be obtained with ` field(a) ` :
66+ ` a ` can be obtained with [ ` field(a) ` ] ( @ref ) :
6767
6868``` @docs; canonical=false
6969field
@@ -79,32 +79,21 @@ are objects of the same concrete type (i.e. with the same type parameters in cas
7979parametric type). In particular, every ` ElementarySpace ` should implement the following
8080methods
8181
82- * ` dim(::ElementarySpace) ` returns the dimension of the space
83-
84- * ` field(::ElementarySpace) ` returns the field ` 𝔽 ` over which the vector space is defined
85-
86- * ` dual(::S) where {S<:ElementarySpace} -> ::S ` returns the
87- [ dual space] ( http://en.wikipedia.org/wiki/Dual_space ) ` dual(V) ` , using an instance of
88- the same concrete type (i.e. not via type parameters); this should satisfy
89- ` dual(dual(V)) == V `
90-
91- * ` conj(::S) where {S<:ElementarySpace} -> ::S ` returns the
92- [ complex conjugate space] ( http://en.wikipedia.org/wiki/Complex_conjugate_vector_space )
93- ` conj(V) ` , using an instance of the same concrete type (i.e. not via type parameters);
94- this should satisfy ` conj(conj(V)) == V ` and we automatically have
95- ` conj(V::ElementarySpace{ℝ}) = V ` .
82+ ``` @docs; canonical=false
83+ dim(::ElementarySpace)
84+ field(::ElementarySpace)
85+ dual(::S) where {S<:ElementarySpace}
86+ conj(::S) where {S<:ElementarySpace}
87+ ```
9688
9789For convenience, the dual of a space ` V ` can also be obtained as ` V' ` . Furthermore, it is
9890sometimes necessary to test whether a space is a dual or conjugate space, for which the
9991methods [ ` isdual(::ElementarySpace) ` ] ( @ref ) and [ ` isconj(::ElementarySpace) ` ] ( @ref ) should
10092be implemented.
10193
102- We furthermore define the trait types
103- ``` julia
104- abstract type InnerProductStyle end
105- struct NoInnerProduct <: InnerProductStyle end
106- abstract type HasInnerProduct <: InnerProductStyle end
107- struct EuclideanInnerProduct <: HasInnerProduct end
94+ We furthermore define a trait type
95+ ``` @docs; canonical=false
96+ InnerProductStyle
10897```
10998to denote for a vector space ` V ` whether it has an inner product and thus a canonical
11099mapping from ` dual(V) ` to ` V ` (for real fields ` 𝔽 ⊆ ℝ ` ) or from ` dual(V) ` to ` conj(V) `
@@ -179,15 +168,77 @@ InnerProductStyle(ℂ^5)
179168 to work nonetheless.
180169
181170One more important concrete implementation of ` ElementarySpace ` with a ` EuclideanInnerProduct() `
182- is the ` GradedSpace ` , which is used to represent a graded complex vector space, where the grading
183- is provided by the irreducible representations of a group, or more generally, the simple
184- objects of a unitary fusion category. We refer to the subsection on [ graded spaces] (@ref ss_rep)
171+ is the [ ` GradedSpace ` ] ( @ref ) type , which is used to represent a graded complex vector space,
172+ where the grading is provided by the irreducible representations of a group, or more generally,
173+ the simple objects of a unitary fusion category. We refer to the subsection on [ graded spaces] (@ref ss_rep)
185174on the [ next page] (@ref s_sectorsrepfusion) for further information about ` GradedSpace ` .
186175
187176## Operations with elementary spaces
188177
189- Instances of ` ElementarySpace ` support a number of useful operations.
178+ Instances of ` ElementarySpace ` support a number of useful operations. Firstly, we define the direct
179+ sum of two vector spaces ` V1 ` and ` V2 ` of the same ` spacetype ` (and with the same value of ` isdual ` )
180+ as [ ` V1 ⊕ V2 ` ] ( @ref ) , where ` ⊕ ` is obtained by typing ` \oplus ` +TAB. [ ` zerospace(V) ` ] ( @ref ) corresponds
181+ to the identity or zero element with respect to this direct sum operation, i.e. it corresponds to
182+ a zero-dimensional space. Furthermore, [ ` unitspace(V) ` ] (@ref ) applied to an elementary space returns a
183+ one-dimensional space, that is isomorphic to the scalar field underlying the space itself. Finally,
184+ we have also introduced the non-standard convention ` V1 ⊖ V2 ` (obtained by typing ` \ominus ` +TAB.)
185+ in order to obtain a space that is isomorphic to the quotient space of ` V1 ` by ` V2 ` , or thus,
186+ a particular choice of complement of ` V2 ` in ` V1 ` such that ` V1 == V2 ⊕ (V1 ⊖ V2) ` is satisfied.
187+
188+ Some examples illustrate this better.
189+ ``` @repl tensorkit
190+ ℝ^5 ⊕ ℝ^3
191+ ℂ^5 ⊕ ℂ^3
192+ ℂ^5 ⊕ (ℂ^3)'
193+ zerospace(ℂ^3)
194+ unitspace(ℝ^3)
195+ ℂ^5 ⊕ unitspace(ComplexSpace)
196+ unitspace((ℂ^3)')
197+ (ℂ^5) ⊕ unitspace((ℂ^5))
198+ (ℂ^5)' ⊕ unitspace((ℂ^5)')
199+ (ℝ^5) ⊖ (ℝ^3)
200+ (ℂ^5) ⊖ (ℂ^3)
201+ (ℂ^5)' ⊖ (ℂ^3)'
202+ ℂ^5 == ((ℂ^5) ⊖ (ℂ^3)) ⊕ (ℂ^3) == (ℂ^3) ⊕ ((ℂ^5) ⊖ (ℂ^3))
203+ ```
204+
205+ Note, finally, that we have defined ` oplus ` and ` ominus ` as ASCII alternatives for ` ⊕ ` and ` ⊖ ` respectively.
206+
207+ A second type of operation with elementary spaces is the function [ ` flip(V::ElementarySpace) ` ] ( @ref ) ,
208+ which returns a space that is isomorphic to ` V ` but has ` isdual(flip(V)) == isdual(V') ` , i.e., if ` V `
209+ is a normal space, then ` flip(V) ` is a dual space. ` flip(V) ` is different from ` dual(V) ` in the case
210+ of [ ` GradedSpace ` ] ( @ref ) . It is useful to flip a tensor index from a ket to a bra (or vice versa),
211+ by contracting that index with a unitary map from ` V1 ` to ` flip(V1) ` .
212+
213+ While we provide some trivial examples here, we refer to the section on [ graded spaces] (@ref ss_rep)
214+ for examples where ` flip ` acts non-trivially and produces results that are different than ` dual ` .
215+ ``` @repl tensorkit
216+ flip(ℂ^4)
217+ flip(ℂ^4) ≅ ℂ^4
218+ flip(ℂ^4) == ℂ^4
219+ ```
220+
221+ Finally, we provide two methods [ ` infimum(V1, V2) ` ] ( @ref ) and [ ` supremum(V1, V2) ` ] ( @ref ) for
222+ elementary spaces ` V1 ` and ` V2 ` with the same ` spacetype ` and value of ` isdual ` . The former
223+ returns the "largest" elementary space ` V::ElementarySpace ` with the same value of ` isdual `
224+ such that we can construct surjective morphisms from both ` V1 ` and ` V2 ` to ` V ` . Similarly,
225+ the latter returns the "smallest" elementary space ` W::ElementarySpace ` with the same value
226+ of ` isdual ` such that we can construct injective morphisms from both ` V1 ` and ` V2 ` to ` W ` .
227+ For ` CartesianSpace ` and ` ComplexSpace ` , this simply amounts to the space with minimal or maximal
228+ dimension, but it is again more interesting in the case of [ ` GradedSpace ` ] ( @ref ) , as discussed
229+ on the [ next page] (@ref ss_ ). It is that case where ` infimum(V1, V2) ` might be different from either
230+ ` V1 ` or ` V2 ` , and similar for ` supremum(V1, V2) ` , which justifies the choice of these names
231+ over simply ` min ` and ` max ` . Also note that these methods are a direct consequence of the
232+ partial order that we can define between vector spaces of the same ` spacetype ` more generally,
233+ as discussed below in the subsection [ "More operations with vector spaces"] (@ref ss_spaceops).
190234
235+ Some examples:
236+ ``` @repl tensorkit
237+ infimum(ℝ^5, ℝ^3)
238+ supremum(ℂ^5, ℂ^3)
239+ supremum(ℂ^5, (ℂ^3)')
240+ supremum((ℂ^5)', (ℂ^3)')
241+ ```
191242
192243## [ Composite spaces] (@id ss_compositespaces)
193244
@@ -226,10 +277,11 @@ Following Julia's Base library, the function `one` applied to an instance of `Pr
226277or of ` S<:ElementarySpace ` itself returns the multiplicative identity for these objects.
227278Similar to Julia Base, ` one ` also works in the type domain. The multiplicative identity for
228279vector spaces corresponds to the (monoidal) unit, which is represented as ` ProductSpace{S,0}(()) `
229- and simply printed as ` one(S) ` for the specific type ` S ` . Note, however, that for ` V::S ` ,
230- ` V ⊗ one(V) ` will yield ` ProductSpace{S,1}(V) ` and not ` V ` itself. However, even though
231- ` V ⊗ one(V) ` is not strictly equal to ` V ` , the object ` ProductSpace(V) ` , which can also be
232- created as ` ⊗(V) ` , does mathematically encapsulate the same vector space as ` V ` .
280+ and simply printed as ` one(S) ` for the specific type ` S ` . Note, however, that ` one(S) ` is
281+ strictly speaking only the multiplicative identity when multiplied with ` ProductSpace{S,N} `
282+ instances. For elementary spaces ` V::S ` , ` V ⊗ one(V) ` will yield ` ProductSpace{S,1}(V) ` and not
283+ ` V ` itself. However, even though ` V ⊗ one(V) ` is not strictly equal to ` V ` , the object ` ProductSpace(V) ` ,
284+ which can also be created as ` ⊗(V) ` , does mathematically encapsulate the same vector space as ` V ` .
233285
234286``` @repl tensorkit
235287one(V1)
@@ -247,11 +299,10 @@ of an `N`-particle quantum system in first quantization would require the introd
247299` SymmetricSpace{S,N} ` or a ` AntiSymmetricSpace{S,N} ` for bosons or fermions respectively,
248300which correspond to the symmetric (permutation invariant) or antisymmetric subspace of
249301` V^N ` , where ` V::S ` represents the Hilbert space of the single particle system. Other
250- domains , like general relativity, might also benefit from tensors living in a subspace with
251- certain symmetries under specific index permutations.
302+ scientific fields , like general relativity, might also benefit from tensors living in
303+ subspace with certain symmetries under specific index permutations.
252304
253-
254- ## Operations on and relations between vector spaces
305+ ## [ More operations with vector spaces] (@id ss_spaceops)
255306
256307Vector spaces of the same ` spacetype ` can be given a partial order, based on whether there
257308exist injective morphisms (a.k.a * monomorphisms* ) or surjective morphisms (a.k.a.
@@ -283,60 +334,12 @@ corresponding spaces, but in general none of those will be canonical.
283334
284335There are also a number of convenience functions to create isomorphic spaces. The function
285336` fuse(V1, V2, ...) ` or ` fuse(V1 ⊗ V2 ⊗ ...) ` returns an elementary space that is isomorphic
286- to ` V1 ⊗ V2 ⊗ ... ` . The function ` flip(V::ElementarySpace) ` returns a space that is
287- isomorphic to ` V ` but has ` isdual(flip(V)) == isdual(V') ` , i.e., if ` V ` is a normal space,
288- then ` flip(V) ` is a dual space. ` flip(V) ` is different from ` dual(V) ` in the case of
289- [ ` GradedSpace ` ] ( @ref ) . It is useful to flip a tensor index from a ket to a bra (or
290- vice versa), by contracting that index with a unitary map from ` V1 ` to ` flip(V1) ` . We refer
291- to the reference on [ vector space methods] (@ref s_spacemethods) for further information.
292- Some examples:
293- ``` @repl tensorkit
294- ℝ^3 ≾ ℝ^5
295- ℂ^3 ≾ (ℂ^5)'
296- (ℂ^5) ≅ (ℂ^5)'
297- fuse(ℝ^5, ℝ^3)
298- fuse(ℂ^3, (ℂ^5)' ⊗ ℂ^2)
299- fuse(ℂ^3, (ℂ^5)') ⊗ ℂ^2 ≅ fuse(ℂ^3, (ℂ^5)', ℂ^2) ≅ ℂ^3 ⊗ (ℂ^5)' ⊗ ℂ^2
300- flip(ℂ^4)
301- flip(ℂ^4) ≅ ℂ^4
302- flip(ℂ^4) == ℂ^4
303- ```
304-
305- We also define the direct sum ` V1 ` and ` V2 ` as ` V1 ⊕ V2 ` , where ` ⊕ ` is obtained by typing
306- ` \oplus ` +TAB. This is possible only if ` isdual(V1) == isdual(V2) ` . ` unitspace ` applied to an elementary space
307- (in the value or type domain) returns the one-dimensional space, which is isomorphic to the
308- scalar field of the space itself. Some examples illustrate this better.
309- ``` @repl tensorkit
310- ℝ^5 ⊕ ℝ^3
311- ℂ^5 ⊕ ℂ^3
312- ℂ^5 ⊕ (ℂ^3)'
313- unitspace(ℝ^3)
314- ℂ^5 ⊕ unitspace(ComplexSpace)
315- unitspace((ℂ^3)')
316- (ℂ^5) ⊕ unitspace((ℂ^5))
317- (ℂ^5)' ⊕ unitspace((ℂ^5)')
318- ```
319-
320- Finally, while spaces have a partial order, there is no unique infimum or supremum of a two
321- or more spaces. However, if ` V1 ` and ` V2 ` are two ` ElementarySpace ` instances with
322- ` isdual(V1) == isdual(V2) ` , then we can define a unique infimum ` V::ElementarySpace ` with
323- the same value of ` isdual ` that satisfies ` V ≾ V1 ` and ` V ≾ V2 ` , as well as a unique
324- supremum ` W::ElementarySpace ` with the same value of ` isdual ` that satisfies ` W ≿ V1 `
325- and ` W ≿ V2 ` . For ` CartesianSpace ` and ` ComplexSpace ` , this simply amounts to the
326- space with minimal or maximal dimension, i.e.
327- ``` @repl tensorkit
328- infimum(ℝ^5, ℝ^3)
329- supremum(ℂ^5, ℂ^3)
330- supremum(ℂ^5, (ℂ^3)')
331- ```
332- The names ` infimum ` and ` supremum ` are especially suited in the case of
333- [ ` GradedSpace ` ] ( @ref ) , as the infimum of two spaces might be different from either
334- of those two spaces, and similar for the supremum.
337+ to ` V1 ⊗ V2 ⊗ ... ` .
335338
336339## [ Space of morphisms] (@id ss_homspaces)
337- As mentioned in the introduction, we will define tensor maps as linear maps from
338- a ` ProductSpace ` domain to a ` ProductSpace ` codomain. All tensor maps with a fixed
339- domain and codomain form a vector space, which we represent with the ` HomSpace ` type.
340+ As mentioned in the introduction, we define tensor maps as linear maps from
341+ a ` ProductSpace ` domain to a ` ProductSpace ` codomain. The set of all tensor maps with a fixed
342+ domain and codomain constitutes a vector space, which we represent with the ` HomSpace ` type.
340343``` julia
341344struct HomSpace{S<: ElementarySpace , P1<: CompositeSpace{S} , P2<: CompositeSpace{S} }
342345 codomain:: P1
@@ -352,12 +355,16 @@ reason for first listing the codomain and than the domain will become clear in t
352355Note that ` HomSpace ` is not a subtype of ` VectorSpace ` , i.e. we restrict the latter to
353356encode all spaces and generalizations thereof (i.e. objects in linear monoidal categories)
354357that are associated with the indices and the domain and codomain of a tensor map. Even when
355- these genearalizations are no longer strictly vector spaces and have unconventional properties
358+ these generalizations are no longer strictly vector spaces and have unconventional properties
356359(such as non-integer dimensions), the space of tensor maps (homomorphisms) between a given
357- domain and codomain is always a vector space in the strict mathematical sense. Furthermore,
358- on these ` HomSpace ` instances, we define a number of useful methods that are a predecessor
359- to the corresponidng methods that we will define to manipulate the actual tensors, as we
360- illustrate in the following example:
360+ domain and codomain, represented by a ` HomSpace ` instance, is always a vector space in the
361+ strict mathematical sense (with in particular an integer dimension). Because ` HomSpace ` and
362+ the different subtypes of ` VectorSpace ` represent very different mathematical concepts that do
363+ not directly interact, we have chosen to keep them separate in the type hierarchy.
364+
365+ Furthermore, on these ` HomSpace ` instances, we define a number of useful methods that are a
366+ precursor to the corresponding methods that we will define to manipulate the actual tensors,
367+ as illustrated in the following example:
361368``` @repl tensorkit
362369W = ℂ^2 ⊗ ℂ^3 → ℂ^3 ⊗ dual(ℂ^4)
363370field(W)
@@ -383,11 +390,14 @@ insertrightunit(W, 2)
383390removeunit(insertrightunit(W, 2), 3)
384391TensorKit.compose(W, adjoint(W))
385392```
386- Note that indexing ` W ` yields first the spaces in the codomain, followed by the dual of the
387- spaces in the domain. This particular convention is useful in combination with the
388- instances of type [ ` TensorMap ` ] ( @ref ) , which represent morphisms living in such a
389- ` HomSpace ` . Also note that ` dim(W) ` is here given by the product of the dimensions of the
390- individual spaces, but that this is no longer true once symmetries are involved. At any
391- time will ` dim(::HomSpace) ` represent the number of linearly independent morphisms in this
392- space, or thus, the number of independent components that a corresponding ` TensorMap `
393- object will have.
393+ Note that indexing ` W ` follows an order that first targets the spaces in the codomain,
394+ followed by the dual of the spaces in the domain. This particular convention is useful
395+ in combination with the instances of type [ ` TensorMap ` ] ( @ref ) , which represent the actual
396+ morphisms living in such a ` HomSpace ` . Also note that ` dim(W) ` is here given by the product
397+ of the dimensions of the individual spaces, but that this is no longer true once symmetries
398+ are involved. At any time will ` dim(::HomSpace) ` represent the number of linearly independent
399+ morphisms in this space, or thus, the number of independent components that a corresponding
400+ ` TensorMap ` object will have.
401+
402+ A complete list of methods defined on ` HomSpace ` instances together with the corresponding
403+ documentation is provided in the [ library section on Vector spaces] (@ref s_libvectorspaces).
0 commit comments