/
problem.jl
107 lines (83 loc) · 3.57 KB
/
problem.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
#
# Define a global problem and its constructors
#
# ---
@doc raw"""
AbstractManoptProblem{M<:AbstractManifold}
Describe a Riemannian optimization problem with all static (not-changing) properties.
The most prominent features that should always be stated here are
* the [`AbstractManifold`](@extref `ManifoldsBase.AbstractManifold`) ``\mathcal M``
* the cost function ``f: \mathcal M → ℝ``
Usually the cost should be within an [`AbstractManifoldObjective`](@ref).
"""
abstract type AbstractManoptProblem{M<:AbstractManifold} end
@doc raw"""
DefaultManoptProblem{TM <: AbstractManifold, Objective <: AbstractManifoldObjective}
Model a default manifold problem, that (just) consists of the domain of optimisation,
that is an `AbstractManifold` and an [`AbstractManifoldObjective`](@ref)
"""
struct DefaultManoptProblem{TM<:AbstractManifold,Objective<:AbstractManifoldObjective} <:
AbstractManoptProblem{TM}
manifold::TM
objective::Objective
end
"""
evaluation_type(mp::AbstractManoptProblem)
Get the [`AbstractEvaluationType`](@ref) of the objective in [`AbstractManoptProblem`](@ref)
`mp`.
"""
evaluation_type(amp::AbstractManoptProblem) = evaluation_type(get_objective(amp))
"""
evaluation_type(::AbstractManifoldObjective{Teval})
Get the [`AbstractEvaluationType`](@ref) of the objective.
"""
evaluation_type(::AbstractManifoldObjective{Teval}) where {Teval} = Teval
@doc raw"""
get_manifold(amp::AbstractManoptProblem)
return the manifold stored within an [`AbstractManoptProblem`](@ref)
"""
get_manifold(::AbstractManoptProblem)
get_manifold(amp::DefaultManoptProblem) = amp.manifold
@doc raw"""
get_objective(mp::AbstractManoptProblem, recursive=false)
return the objective [`AbstractManifoldObjective`](@ref) stored within an [`AbstractManoptProblem`](@ref).
If `recursive is set to true, it additionally unwraps all decorators of the objective`
"""
get_objective(::AbstractManoptProblem)
function get_objective(amp::DefaultManoptProblem, recursive=false)
return recursive ? get_objective(amp.objective, true) : amp.objective
end
@doc raw"""
get_cost(amp::AbstractManoptProblem, p)
evaluate the cost function `f` stored within the [`AbstractManifoldObjective`](@ref) of an
[`AbstractManoptProblem`](@ref) `amp` at the point `p`.
"""
function get_cost(amp::AbstractManoptProblem, p)
return get_cost(get_manifold(amp), get_objective(amp), p)
end
@doc raw"""
get_cost(M::AbstractManifold, obj::AbstractManifoldObjective, p)
evaluate the cost function `f` defined on `M` stored within the [`AbstractManifoldObjective`](@ref) at the point `p`.
"""
get_cost(::AbstractManifold, ::AbstractManifoldObjective, p)
"""
set_manopt_parameter!(ams::AbstractManoptProblem, element::Symbol, field::Symbol , value)
Set a certain field/element from the [`AbstractManoptProblem`](@ref) `ams` to `value`.
This function usually dispatches on `Val(element)`.
Instead of a single field, also a chain of elements can be provided, allowing to access
encapsulated parts of the problem.
Main values for `element` are `:Manifold` and `:Objective`.
"""
set_manopt_parameter!(amp::AbstractManoptProblem, e::Symbol, args...)
function set_manopt_parameter!(amp::AbstractManoptProblem, ::Val{:Manifold}, args...)
set_manopt_parameter!(get_manifold(amp), args...)
return amp
end
function set_manopt_parameter!(TpM::TangentSpace, ::Union{Val{:Basepoint},Val{:p}}, p)
copyto!(TpM.manifold, TpM.point, p)
return TpM
end
function set_manopt_parameter!(amp::AbstractManoptProblem, ::Val{:Objective}, args...)
set_manopt_parameter!(get_objective(amp), args...)
return amp
end