-
Notifications
You must be signed in to change notification settings - Fork 21
/
ManifoldSampling.jl
136 lines (114 loc) · 4.29 KB
/
ManifoldSampling.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
"""
$SIGNATURES
Return a random sample as a tangent vector from a belief represented by coordinates on a manifold at point p.
Notes
"""
function sampleTangent end
# Sampling MKD
function sampleTangent(M::AbstractDecoratorManifold, x::ManifoldKernelDensity, p = mean(x))
# get legacy matrix of coordinates and selected labels
#TODO make sure that when `sample` is replaced in MKD, coordinates is a vector
coords, lbls = sample(x.belief, 1)
X = hat(x.manifold, p, coords[:])
return X
end
function sampleTangent(x::ManifoldKernelDensity, p = mean(x))
return sampleTangent(x.manifold, x, p)
end
# Sampling Distributions
function sampleTangent(M::AbstractManifold, z::Distribution, p, basis::AbstractBasis)
return get_vector(M, p, rand(z), basis)
end
function sampleTangent(
M::AbstractDecoratorManifold,
z::Distribution,
p = getPointIdentity(M),
)
return hat(M, p, rand(z, 1)[:]) #TODO find something better than (z,1)[:]
end
"""
$SIGNATURES
Return a random sample point on a manifold from a belief represented by coordinates at point p.
Notes
"""
function samplePoint(
M::AbstractManifold,
sbelief,
p,
basis::AbstractBasis,
retraction_method::AbstractRetractionMethod = ExponentialRetraction(),
)
X = sampleTangent(M, sbelief, p, basis)
return retract(M, p, X, retraction_method)
end
function samplePoint(
M::AbstractDecoratorManifold,
sbelief,
p = getPointIdentity(M),
retraction_method::AbstractRetractionMethod = ExponentialRetraction(),
)
X = sampleTangent(M, sbelief, p)
return retract(M, p, X, retraction_method)
end
function samplePoint(
M::AbstractDecoratorManifold,
sbelief::ManifoldKernelDensity,
p = identity_element(M, mean(sbelief)),
retraction_method::AbstractRetractionMethod = ExponentialRetraction(),
)
X = sampleTangent(M, sbelief, p)
return retract(M, p, X, retraction_method)
end
function samplePoint(x::ManifoldKernelDensity, p = mean(x))
return samplePoint(x.manifold, x, p)
end
# FIXME: rather use manifolds
function samplePoint(distr::SamplableBelief)
Base.depwarn(
"samplePoint(distr::SamplableBelief) should be replaced by samplePoint(M<:AbstractManifold, distr::SamplableBelief, ...)",
:samplePoint,
)
return rand(distr, 1)
end
## default getSample
"""
$SIGNATURES
Sample the factor in `CalcFactor`. A default `getSample` method is provided that should cover most use cases,
if more advanced sampling is required, the `getSample` function should be extended.
The default behavior for `getSample` is as follows:
- The `SamplableBelief`` shall be in the field `Z` and that shall be enough to fully define the factor, i.e. `Z<:SamplableBelief` should be the only field.
- Sampling on `<:AbstractManifoldMinimize` factors defined on Group Manifolds:
- `getSample` normally returns a tangent vector at the identity element, however it should just match the custom factor definition.
- Sampling on prior (`<:AbstractPrior`) factors :
- `getSample` must return a point on the manifold that matches the point representation of the variable.
Notes
- Users should overload this method should their factor not only use field `Z` for the `SamplableBelief`.
- See the Custom Factors section in the Caesar.jl documentation for more examples and details.
- Also see issue https://github.com/JuliaRobotics/IncrementalInference.jl/issues/1441
See also: [`getMeasurementParametric`](@ref)
"""
function getSample end
function getSample(cf::CalcFactor{<:AbstractPrior})
M = cf.manifold # getManifold(cf.factor)
if hasfield(typeof(cf.factor), :Z)
X = samplePoint(M, cf.factor.Z)
else
error(
"""Factor $(typeof(cf.factor)) does not have a field `Z`, to use the default `getSample` method, use `Z` for the measurement.
Alternatively, provide a `getSample` method. See IIF issue #1441 and Custom Factors in the Caesar documentation.""",
)
end
return X
end
function getSample(cf::CalcFactor{<:AbstractRelative})
M = cf.manifold # getManifold(cf.factor)
if hasfield(typeof(cf.factor), :Z)
X = sampleTangent(M, cf.factor.Z)
else
error(
"""Factor $(typeof(cf.factor)) does not have a field `Z`, to use the default `getSample` method, use `Z` for the measurement.
Alternatively, provide a `getSample` method. See IIF issue #1441 and Custom Factors in the Caesar documentation.""",
)
end
return X
end