Skip to content

Commit 21caf90

Browse files
committed
some updates on spaces docs
1 parent 307b41d commit 21caf90

3 files changed

Lines changed: 117 additions & 108 deletions

File tree

docs/src/lib/spaces.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Vector spaces
1+
# [Vector spaces](@id s_libvectorspaces)
22

33
```@meta
44
CurrentModule = TensorKit
@@ -21,7 +21,7 @@ ProductSpace
2121
HomSpace
2222
```
2323

24-
together with the following specific types for encoding the inner product structure of
24+
together with the following specific type for encoding the inner product structure of
2525
a space:
2626

2727
```@docs

docs/src/man/spaces.md

Lines changed: 113 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ using TensorKit
66

77
From the [Introduction](@ref s_intro), it should be clear that an important aspect in the
88
definition 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
1111
abstract type VectorSpace end
1212
```
@@ -22,16 +22,16 @@ const IndexSpace = ElementarySpace
2222

2323
abstract 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
2626
associated 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
2929
of 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
3131
type `S`. Its properties are discussed in the section on [Composite spaces](@ref ss_compositespaces),
3232
together 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`
3535
associated with e.g. a composite space or a tensor. It works both on instances and in the
3636
type domain. Its use will be illustrated below.
3737

@@ -63,7 +63,7 @@ ComplexF64 ⊆ ℂ
6363
```
6464
and furthermore —probably more usefully— `ℝ^n` and `ℂ^n` create specific elementary vector
6565
spaces 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
6969
field
@@ -79,32 +79,21 @@ are objects of the same concrete type (i.e. with the same type parameters in cas
7979
parametric type). In particular, every `ElementarySpace` should implement the following
8080
methods
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

9789
For convenience, the dual of a space `V` can also be obtained as `V'`. Furthermore, it is
9890
sometimes necessary to test whether a space is a dual or conjugate space, for which the
9991
methods [`isdual(::ElementarySpace)`](@ref) and [`isconj(::ElementarySpace)`](@ref) should
10092
be 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
```
10998
to denote for a vector space `V` whether it has an inner product and thus a canonical
11099
mapping 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

181170
One 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)
185174
on 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
226277
or of `S<:ElementarySpace` itself returns the multiplicative identity for these objects.
227278
Similar to Julia Base, `one` also works in the type domain. The multiplicative identity for
228279
vector 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
235287
one(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,
248300
which 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

256307
Vector spaces of the same `spacetype` can be given a partial order, based on whether there
257308
exist 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

284335
There 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
341344
struct 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
352355
Note that `HomSpace` is not a subtype of `VectorSpace`, i.e. we restrict the latter to
353356
encode all spaces and generalizations thereof (i.e. objects in linear monoidal categories)
354357
that 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
362369
W = ℂ^2 ⊗ ℂ^3 → ℂ^3 ⊗ dual(ℂ^4)
363370
field(W)
@@ -383,11 +390,14 @@ insertrightunit(W, 2)
383390
removeunit(insertrightunit(W, 2), 3)
384391
TensorKit.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).

src/spaces/vectorspaces.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ Base.issubset(::ComplexNumbers, ::ComplexNumbers) = true
3636
abstract type VectorSpace end
3737
3838
Abstract type at the top of the type hierarchy for denoting vector spaces, or, more
39-
accurately, 𝕜-linear categories. All instances of subtypes of VectorSpace will
40-
represent objects in 𝕜-linear monoidal categories.
39+
generally, objects in linear monoidal categories.
4140
"""
4241
abstract type VectorSpace end
4342

@@ -46,7 +45,7 @@ abstract type VectorSpace end
4645
field(::Type{T}) -> Type{𝔽<:Field}
4746
4847
Return the type of field over which object `a` (e.g. a vector space or a tensor) is defined.
49-
Also works in type domain.
48+
This also works in type domain.
5049
"""
5150
field(x) = field(typeof(x))
5251
field(::Type{T}) where {T} = field(spacetype(T))

0 commit comments

Comments
 (0)