/
vector_spaces.jl
140 lines (108 loc) · 4.44 KB
/
vector_spaces.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"""
FVector(type::VectorSpaceType, data, basis::AbstractBasis)
Decorator indicating that the vector `data` contains coordinates of a vector from a fiber
of a vector bundle of type `type`. `basis` is an object describing the basis of that space
in which the coordinates are given.
Conversion between `FVector` representation and the default representation of an object
(for example a tangent vector) for a manifold should be done using [`get_coordinates`](@ref)
and [`get_vector`](@ref).
# Examples
```julia-repl
julia> using Manifolds
julia> M = Sphere(2)
Sphere(2, ℝ)
julia> p = [1.0, 0.0, 0.0]
3-element Vector{Float64}:
1.0
0.0
0.0
julia> X = [0.0, 2.0, -1.0]
3-element Vector{Float64}:
0.0
2.0
-1.0
julia> B = DefaultOrthonormalBasis()
DefaultOrthonormalBasis(ℝ)
julia> fX = TFVector(get_coordinates(M, p, X, B), B)
TFVector([2.0, -1.0], DefaultOrthonormalBasis(ℝ))
julia> X_back = get_vector(M, p, fX.data, fX.basis)
3-element Vector{Float64}:
-0.0
2.0
-1.0
```
"""
struct FVector{TType<:VectorSpaceType,TData,TBasis<:AbstractBasis}
type::TType
data::TData
basis::TBasis
end
const TFVector = FVector{TangentSpaceType}
const CoTFVector = FVector{CotangentSpaceType}
function TFVector(data, basis::AbstractBasis)
return TFVector{typeof(data),typeof(basis)}(TangentSpace, data, basis)
end
function CoTFVector(data, basis::AbstractBasis)
return CoTFVector{typeof(data),typeof(basis)}(CotangentSpace, data, basis)
end
function Base.show(io::IO, fX::TFVector)
return print(io, "TFVector(", fX.data, ", ", fX.basis, ")")
end
function Base.show(io::IO, fX::CoTFVector)
return print(io, "CoTFVector(", fX.data, ", ", fX.basis, ")")
end
"""
AbstractFibreVector{TType<:VectorSpaceType}
Type for a vector from a vector space (fibre of a vector bundle) of type `TType` of a manifold.
While a [`AbstractManifold`](@ref) does not necessarily require this type, for example when it is
implemented for `Vector`s or `Matrix` type elements, this type can be used for more
complicated representations, semantic verification, or even dispatch for different
representations of tangent vectors and their types on a manifold.
You may use macro [`@manifold_vector_forwards`](@ref) to introduce commonly used method
definitions for your subtype of `AbstractFibreVector`.
"""
abstract type AbstractFibreVector{TType<:VectorSpaceType} end
"""
TVector = AbstractFibreVector{TangentSpaceType}
Type for a tangent vector of a manifold. While a [`AbstractManifold`](@ref) does not necessarily
require this type, for example when it is implemented for `Vector`s or `Matrix` type
elements, this type can be used for more complicated representations, semantic verification,
or even dispatch for different representations of tangent vectors and their types on a
manifold.
"""
const TVector = AbstractFibreVector{TangentSpaceType}
"""
CoTVector = AbstractFibreVector{CotangentSpaceType}
Type for a cotangent vector of a manifold. While a [`AbstractManifold`](@ref) does not necessarily
require this type, for example when it is implemented for `Vector`s or `Matrix` type
elements, this type can be used for more complicated representations, semantic verification,
or even dispatch for different representations of cotangent vectors and their types on a
manifold.
"""
const CoTVector = AbstractFibreVector{CotangentSpaceType}
Base.:+(X::FVector, Y::FVector) = FVector(X.type, X.data + Y.data, X.basis)
Base.:-(X::FVector, Y::FVector) = FVector(X.type, X.data - Y.data, X.basis)
Base.:-(X::FVector) = FVector(X.type, -X.data, X.basis)
Base.:*(a::Number, X::FVector) = FVector(X.type, a * X.data, X.basis)
allocate(x::FVector) = FVector(x.type, allocate(x.data), x.basis)
allocate(x::FVector, ::Type{T}) where {T} = FVector(x.type, allocate(x.data, T), x.basis)
function Base.copyto!(X::FVector, Y::FVector)
copyto!(X.data, Y.data)
return X
end
function number_eltype(
::Type{FVector{TType,TData,TBasis}},
) where {TType<:VectorSpaceType,TData,TBasis}
return number_eltype(TData)
end
number_eltype(v::FVector) = number_eltype(v.data)
Base.show(io::IO, ::TangentSpaceType) = print(io, "TangentSpace")
Base.show(io::IO, ::CotangentSpaceType) = print(io, "CotangentSpace")
"""
vector_space_dimension(M::AbstractManifold, V::VectorSpaceType)
Dimension of the vector space of type `V` on manifold `M`.
"""
vector_space_dimension(::AbstractManifold, ::VectorSpaceType)
function vector_space_dimension(M::AbstractManifold, ::TCoTSpaceType)
return manifold_dimension(M)
end