-
Notifications
You must be signed in to change notification settings - Fork 9
/
exp_log_geo.jl
233 lines (184 loc) · 8.5 KB
/
exp_log_geo.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
@doc raw"""
exp(M::AbstractManifold, p, X)
exp(M::AbstractManifold, p, X, t::Number = 1)
Compute the exponential map of tangent vector `X`, optionally scaled by `t`, at point `p`
from the manifold [`AbstractManifold`](@ref) `M`, i.e.
```math
\exp_p X = γ_{p,X}(1),
```
where ``γ_{p,X}`` is the unique geodesic starting in ``γ(0)=p`` such that ``\dot γ(0) = X``.
See also [`shortest_geodesic`](@ref), [`retract`](@ref).
"""
function exp(M::AbstractManifold, p, X)
q = allocate_result(M, exp, p, X)
exp!(M, q, p, X)
return q
end
function exp(M::AbstractManifold, p, X, t::Number)
q = allocate_result(M, exp, p, X, t)
exp!(M, q, p, X, t)
return q
end
"""
exp!(M::AbstractManifold, q, p, X)
exp!(M::AbstractManifold, q, p, X, t::Number = 1)
Compute the exponential map of tangent vector `X`, optionally scaled by `t`, at point `p`
from the manifold [`AbstractManifold`](@ref) `M`.
The result is saved to `q`.
If you want to implement exponential map for your manifold, you should implement the
method with `t`, that is `exp!(M::MyManifold, q, p, X, t::Number)`.
See also [`exp`](@ref).
"""
exp!(M::AbstractManifold, q, p, X)
exp!(M::AbstractManifold, q, p, X, t::Number) = exp!(M, q, p, t * X)
@doc raw"""
geodesic(M::AbstractManifold, p, X) -> Function
Get the geodesic with initial point `p` and velocity `X` on the [`AbstractManifold`](@ref) `M`.
A geodesic is a curve of zero acceleration. That is for the curve ``γ_{p,X}: I → \mathcal M``,
with ``γ_{p,X}(0) = p`` and ``\dot γ_{p,X}(0) = X`` a geodesic further fulfills
```math
∇_{\dot γ_{p,X}(t)} \dot γ_{p,X}(t) = 0,
```
i.e. the curve is acceleration free with respect to the Riemannian metric.
This yields, that the curve has constant velocity that is locally distance-minimizing.
This function returns a function of (time) `t`.
"""
geodesic(M::AbstractManifold, p, X) = t -> exp(M, p, X, t)
@doc raw"""
geodesic(M::AbstractManifold, p, X, t::Real)
Evaluate the geodesic ``γ_{p,X}: I → \mathcal M``,
with ``γ_{p,X}(0) = p`` and ``\dot γ_{p,X}(0) = X`` a geodesic further fulfills
```math
∇_{\dot γ_{p,X}(t)} \dot γ_{p,X}(t) = 0,
```
at time `t`.
"""
geodesic(M::AbstractManifold, p, X, t::Real) = exp(M, p, X, t)
@doc raw"""
geodesic(M::AbstractManifold, p, X, T::AbstractVector) -> AbstractVector
Evaluate the geodesic ``γ_{p,X}: I → \mathcal M``,
with ``γ_{p,X}(0) = p`` and ``\dot γ_{p,X}(0) = X`` a geodesic further fulfills
```math
∇_{\dot γ_{p,X}(t)} \dot γ_{p,X}(t) = 0,
```
at time points `t` from `T`.
"""
geodesic(M::AbstractManifold, p, X, T::AbstractVector) = map(t -> exp(M, p, X, t), T)
@doc raw"""
geodesic!(M::AbstractManifold, p, X) -> Function
Get the geodesic with initial point `p` and velocity `X` on the [`AbstractManifold`](@ref) `M`.
A geodesic is a curve of zero acceleration. That is for the curve ``γ_{p,X}: I → \mathcal M``,
with ``γ_{p,X}(0) = p`` and ``\dot γ_{p,X}(0) = X`` a geodesic further fulfills
```math
∇_{\dot γ_{p,X}(t)} \dot γ_{p,X}(t) = 0,
```
i.e. the curve is acceleration free with respect to the Riemannian metric.
This yields that the curve has constant velocity and is locally distance-minimizing.
This function returns a function `(q,t)` of (time) `t` that mutates `q``.
"""
geodesic!(M::AbstractManifold, p, X) = (q, t) -> exp!(M, q, p, X, t)
@doc raw"""
geodesic!(M::AbstractManifold, q, p, X, t::Real)
Get the geodesic with initial point `p` and velocity `X` on the [`AbstractManifold`](@ref) `M`.
A geodesic is a curve of zero acceleration. That is for the curve ``γ_{p,X}: I → \mathcal M``,
with ``γ_{p,X}(0) = p`` and ``\dot γ_{p,X}(0) = X`` a geodesic further fulfills
```math
∇_{\dot γ_{p,X}(t)} \dot γ_{p,X}(t) = 0,
```
i.e. the curve is acceleration free with respect to the Riemannian metric.
This function evaluates the geodeic at `t` in place of `q`.
"""
geodesic!(M::AbstractManifold, q, p, X, t::Real) = exp!(M, q, p, X, t)
@doc raw"""
geodesic!(M::AbstractManifold, Q, p, X, T::AbstractVector) -> AbstractVector
Get the geodesic with initial point `p` and velocity `X` on the [`AbstractManifold`](@ref) `M`.
A geodesic is a curve of zero acceleration. That is for the curve ``γ_{p,X}: I → \mathcal M``,
with ``γ_{p,X}(0) = p`` and ``\dot γ_{p,X}(0) = X`` a geodesic further fulfills
```math
∇_{\dot γ_{p,X}(t)} \dot γ_{p,X}(t) = 0,
```
i.e. the curve is acceleration free with respect to the Riemannian metric.
This function evaluates the geodeic at time points `t` fom `T` in place of `Q`.
"""
function geodesic!(M::AbstractManifold, Q, p, X, T::AbstractVector)
for (q, t) in zip(Q, T)
exp!(M, q, p, X, t)
end
return Q
end
"""
log(M::AbstractManifold, p, q)
Compute the logarithmic map of point `q` at base point `p` on the [`AbstractManifold`](@ref) `M`.
The logarithmic map is the inverse of the [`exp`](@ref)onential map.
Note that the logarithmic map might not be globally defined.
See also [`inverse_retract`](@ref).
"""
function log(M::AbstractManifold, p, q)
X = allocate_result(M, log, p, q)
log!(M, X, p, q)
return X
end
"""
log!(M::AbstractManifold, X, p, q)
Compute the logarithmic map of point `q` at base point `p` on the [`AbstractManifold`](@ref) `M`.
The result is saved to `X`.
The logarithmic map is the inverse of the [`exp!`](@ref)onential map.
Note that the logarithmic map might not be globally defined.
see also [`log`](@ref) and [`inverse_retract!`](@ref),
"""
log!(M::AbstractManifold, X, p, q)
@doc raw"""
shortest_geodesic(M::AbstractManifold, p, q) -> Function
Get a [`geodesic`](@ref) $γ_{p,q}(t)$ whose length is the shortest path between the
points `p`and `q`, where $γ_{p,q}(0)=p$ and $γ_{p,q}(1)=q$.
When there are multiple shortest geodesics, a deterministic choice will be returned.
This function returns a function of time, which may be a `Real` or an `AbstractVector`.
"""
shortest_geodesic(M::AbstractManifold, p, q) = geodesic(M, p, log(M, p, q))
@doc raw"""
shortest_geodesic(M::AabstractManifold, p, q, t::Real)
Evaluate a [`geodesic`](@ref) $γ_{p,q}(t)$ whose length is the shortest path between the
points `p`and `q`, where $γ_{p,q}(0)=p$ and $γ_{p,q}(1)=q$ at time `t`.
When there are multiple shortest geodesics, a deterministic choice will be returned.
"""
shortest_geodesic(M::AbstractManifold, p, q, t::Real) = geodesic(M, p, log(M, p, q), t)
@doc raw"""
shortest_geodesic(M::AbstractManifold, p, q, T::AbstractVector) -> AbstractVector
Evaluate a [`geodesic`](@ref) $γ_{p,q}(t)$ whose length is the shortest path between the
points `p`and `q`, where $γ_{p,q}(0)=p$ and $γ_{p,q}(1)=q$ at time points `T`.
When there are multiple shortest geodesics, a deterministic choice will be returned.
"""
function shortest_geodesic(M::AbstractManifold, p, q, T::AbstractVector)
return geodesic(M, p, log(M, p, q), T)
end
@doc raw"""
shortest_geodesic!(M::AbstractManifold, p, q) -> Function
Get a [`geodesic`](@ref) $γ_{p,q}(t)$ whose length is the shortest path between the
points `p`and `q`, where $γ_{p,q}(0)=p$ and $γ_{p,q}(1)=q$. When there are
multiple shortest geodesics, a deterministic choice will be returned.
This function returns a function `(r,t) -> ... ` of time `t` which works in place of `r`.
Further variants
shortest_geodesic!(M::AabstractManifold, r, p, q, t::Real)
shortest_geodesic!(M::AbstractManifold, R, p, q, T::AbstractVector) -> AbstractVector
mutate (and return) the point `r` and the vector of points `R`, respectively,
returning the point at time `t` or points at times `t` in `T` along the shortest [`geodesic`](@ref).
"""
shortest_geodesic!(M::AbstractManifold, p, q) = geodesic!(M, p, log(M, p, q))
@doc raw"""
shortest_geodesic!(M::AabstractManifold, r, p, q, t::Real)
Evaluate a [`geodesic`](@ref) $γ_{p,q}(t)$ whose length is the shortest path between the
points `p`and `q`, where $γ_{p,q}(0)=p$ and $γ_{p,q}(1)=q$ at `t` in place of `r`.
When there are multiple shortest geodesics, a deterministic choice will be taken.
"""
function shortest_geodesic!(M::AbstractManifold, r, p, q, t::Real)
return geodesic!(M, r, p, log(M, p, q), t)
end
@doc raw"""
shortest_geodesic!(M::AbstractManifold, R, p, q, T::AbstractVector) -> AbstractVector
Evaluate a [`geodesic`](@ref) $γ_{p,q}(t)$ whose length is the shortest path between the
points `p`and `q`, where $γ_{p,q}(0)=p$ and $γ_{p,q}(1)=q$ at all `t` from `T` in place of `R`.
When there are multiple shortest geodesics, a deterministic choice will be taken.
"""
function shortest_geodesic!(M::AbstractManifold, R, p, q, T::AbstractVector)
return geodesic!(M, R, p, log(M, p, q), T)
end