-
Notifications
You must be signed in to change notification settings - Fork 71
Adjust injectivity radii for (inverse) retractions on the Sphere (#900) #915
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 11 commits
dcfdab3
68af73f
610082e
8369cbd
f8bd474
f3016ac
5470f33
6e57ba6
becf285
ecf8f64
cce40b4
048e253
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -308,6 +308,7 @@ using ManifoldsBase: | |
| SoftmaxRetraction, | ||
| SoftmaxInverseRetraction, | ||
| StabilizedRetraction, | ||
| StabilizedInverseRetraction, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not defined in ManifoldsBase? How can you import it from there then? |
||
| StopForwardingType, | ||
| TangentSpace, | ||
| TangentSpaceType, | ||
|
|
@@ -756,7 +757,10 @@ export AbstractInverseRetractionMethod, | |
| PolarLightInverseRetraction, | ||
| ProjectionInverseRetraction, | ||
| ShootingInverseRetraction, | ||
| SoftmaxInverseRetraction | ||
| SoftmaxInverseRetraction, | ||
| StabilizedInverseRetraction | ||
| # Bijectivity radii are exported here to be tested, but this should be removed if bijectivity radii get moved to ManifoldsBase. | ||
| export bijectivity_radius | ||
| # Estimation methods for median and mean | ||
| export AbstractApproximationMethod, | ||
| GradientDescentEstimation, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -286,7 +286,7 @@ function get_vector_orthonormal!(M::AbstractSphere{ℝ}, Y, p, c, ::RealNumbers) | |
| end | ||
|
|
||
| _doc_injectivity_radius_sphere = raw""" | ||
| injectivity_radius(M::AbstractSphere[, p, ::ExponentialRetraction]) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. We can not do this. You can for sure add a copy that does this for the stabilised one but I would even argue the stablized one just has a numerical check around so it could even just call infectivity radius on its inner retraction. |
||
| injectivity_radius(M::AbstractSphere[, p, ::StabilizedRetraction]) | ||
|
|
||
| Return the injectivity radius for the [`AbstractSphere`](@ref) `M`, which is globally ``π``. | ||
| """ | ||
|
|
@@ -301,12 +301,11 @@ _doc_injectivity_radius_sphere_projection = raw""" | |
| injectivity_radius(M::Sphere, p, ::ProjectionRetraction) | ||
|
|
||
| Return the injectivity radius for the [`ProjectionRetraction`](@extref `ManifoldsBase.ProjectionRetraction`) on the | ||
| [`AbstractSphere`](@ref), which is globally ``\frac{π}{2}``. | ||
| [`AbstractSphere`](@ref), which is globally ``\infty``. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we are here we should document this much more precise, what is injective here, we had a long discussion so lets also be precise here. |
||
| """ | ||
|
|
||
| @doc "$(_doc_injectivity_radius_sphere_projection)" | ||
| injectivity_radius(::AbstractSphere, ::ProjectionRetraction) | ||
|
|
||
| @doc "$(_doc_injectivity_radius_sphere_projection)" | ||
| injectivity_radius(::AbstractSphere, p, ::ProjectionRetraction) | ||
|
|
||
|
|
@@ -317,8 +316,8 @@ end | |
| function injectivity_radius(M::AbstractSphere, p, m::AbstractRetractionMethod) | ||
| return _injectivity_radius(M, p, m) | ||
| end | ||
| _injectivity_radius(::AbstractSphere, ::ExponentialRetraction) = π | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removing this definition here is what is actually breaking. Let's not do that, but as mentioned define the stabilised one to return the one of the retraction it stabilises .
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does make much more sense. I will keep it
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is our usual path. We introduce new features here in Manifolds.jl and once we notice they are good – well-designed and tested “in the real world”, we move them to ManifoldsBase |
||
| _injectivity_radius(::AbstractSphere, ::ProjectionRetraction) = π / 2 | ||
| _injectivity_radius(::AbstractSphere, ::StabilizedRetraction) = π | ||
| _injectivity_radius(::AbstractSphere, ::ProjectionRetraction) = Inf | ||
|
|
||
| @doc raw""" | ||
| inverse_retract(M::AbstractSphere, p, q, ::ProjectionInverseRetraction) | ||
|
|
@@ -337,6 +336,62 @@ function inverse_retract_project!(::AbstractSphere, X, p, q) | |
| return (X .= q ./ real(dot(p, q)) .- p) | ||
| end | ||
|
|
||
| _doc_injectivity_radius_sphere_inverse_projection = raw""" | ||
| injectivity_radius(M::AbstractSphere, p, ::ProjectionInverseRetraction) | ||
|
|
||
| Return the injectivity radius for the [`ProjectionInverseRetraction`](@extref `ManifoldsBase.ProjectionInverseRetraction`) on the [`AbstractSphere`](@ref), which is the largest geodesic distance ``ξ`` such that the inverse projection retraction from `p` is invertible whenever ``d_{𝕊^{d-1}}(p,q) ≤ ξ``. This is globally ``\frac{\pi}{2}``. | ||
| """ | ||
|
|
||
| @doc "$(_doc_injectivity_radius_sphere_inverse_projection)" | ||
| injectivity_radius(::AbstractSphere, ::ProjectionInverseRetraction) | ||
|
|
||
| @doc "$(_doc_injectivity_radius_sphere_inverse_projection)" | ||
| injectivity_radius(::AbstractSphere, p, ::ProjectionInverseRetraction) | ||
|
|
||
| function injectivity_radius(M::AbstractSphere, m::AbstractInverseRetractionMethod) | ||
| return _injectivity_radius(M, m) | ||
| end | ||
| function injectivity_radius(M::AbstractSphere, p, m::AbstractInverseRetractionMethod) | ||
| return _injectivity_radius(M, p, m) | ||
| end | ||
|
|
||
| function _injectivity_radius(M::AbstractSphere, m::LogarithmicInverseRetraction) | ||
| return injectivity_radius(M, StabilizedRetraction()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (c) I thought this was the right way to implement your suggestion in this message: the injectivity radius for log calls the one for exp. But I agree this is misleading, I will change that. |
||
| end | ||
| function _injectivity_radius(M::AbstractSphere, p, m::LogarithmicInverseRetraction) | ||
| return injectivity_radius(M, p, StabilizedRetraction()) | ||
| end | ||
| _injectivity_radius(::AbstractSphere, ::ProjectionInverseRetraction) = π / 2 | ||
| function _injectivity_radius(M::AbstractSphere, p, m::ProjectionInverseRetraction) | ||
| return _injectivity_radius(M, m) | ||
| end | ||
|
|
||
| _doc_bijectivity_radius_sphere = raw""" | ||
| bijectivity_radius(M::AbstractSphere[, p, m::Union{AbstractRetractionMethod, AbstractInverseRetractionMethod}]) | ||
|
|
||
| Return the bijectivity radius for the abstract sphere `M` endowed with (inverse) retraction method `m`, which is the smallest radius applicable to both the tangent spaces and the Riemannian metric for which the (inverse) retraction `m` has a well-defined inverse. This radius is computed as the minimum between the injectivity radius of `M` endowed with (inverse) retraction method `m` (at `p`), and the injectivity radius of the inverse of `m` (at `p`). | ||
| """ | ||
|
|
||
| @doc "$(_doc_bijectivity_radius_sphere)" | ||
| bijectivity_radius(::AbstractSphere, ::Union{AbstractRetractionMethod, AbstractInverseRetractionMethod}) | ||
| @doc"$(_doc_bijectivity_radius_sphere)" | ||
| bijectivity_radius(::AbstractSphere, p, ::Union{AbstractRetractionMethod, AbstractInverseRetractionMethod}) | ||
|
|
||
| function bijectivity_radius(M::AbstractSphere, m::Union{AbstractRetractionMethod, AbstractInverseRetractionMethod}) | ||
| if m ∈ (StabilizedRetraction(), StabilizedInverseRetraction()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks very strange and will often not yield what you want |
||
| return injectivity_radius(M) | ||
| elseif m ∈ (ProjectionRetraction(), ProjectionInverseRetraction()) | ||
| return injectivity_radius(M, ProjectionInverseRetraction()) | ||
| end | ||
| end | ||
| function bijectivity_radius(M::AbstractSphere, p, m::Union{AbstractRetractionMethod, AbstractInverseRetractionMethod}) | ||
| if m ∈ (StabilizedRetraction(), StabilizedInverseRetraction()) | ||
| return injectivity_radius(M, p) | ||
| elseif m ∈ (ProjectionRetraction(), ProjectionInverseRetraction()) | ||
| return injectivity_radius(M, p, ProjectionInverseRetraction()) | ||
| end | ||
| end | ||
|
|
||
| """ | ||
| is_flat(M::AbstractSphere) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,7 +33,7 @@ using ManifoldDiff | |
| :InvalidVectors => [p], | ||
| :NormalVectors => [V], | ||
| :Covectors => [ξ], | ||
| :RetractionMethods => [ExponentialRetraction(), ProjectionRetraction()], | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sane as before – no. The sphere should absolutely be tested on the ExponentialRetraction. Stabilisation is something extra – and exp is still the default. If you want to test it, add it at the end. |
||
| :RetractionMethods => [StabilizedRetraction(), ProjectionRetraction()], | ||
| :VectorTransportMethods => [ParallelTransport(), SchildsLadderTransport(), PoleLadderTransport()] | ||
| ), | ||
| # Expectations | ||
|
|
@@ -48,7 +48,9 @@ using ManifoldDiff | |
| (get_vectors, DefaultOrthonormalBasis()) => :Orthonormal, | ||
| (get_vectors, DefaultOrthogonalBasis()) => :Orthogonal, | ||
| injectivity_radius => π, | ||
| (injectivity_radius, ProjectionRetraction()) => π / 2, | ||
| (injectivity_radius, ProjectionRetraction()) => Inf, | ||
| (injectivity_radius, LogarithmicInverseRetraction()) => π, | ||
| (injectivity_radius, ProjectionInverseRetraction()) => π / 2, | ||
| is_default_metric => EuclideanMetric(), | ||
| log => X, norm => π / 4, | ||
| parallel_transport_to => parallel_transport_to(M, p, X, q), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could also add tests for this?