Skip to content

Commit

Permalink
Adapt to ManifoldsBase 1.0 (#781)
Browse files Browse the repository at this point in the history
* Adapt new function names and naming scheme.
* Already remove two fallbacks on hat, that cause ambiguities on Groups.
* mostly convert to retraction_fused
* Adapt to removal of the _along methods.
* more retraction fixes
* fix ODE retraction
* nicer compat.
* rename exp_t -> exp_fused
* Fix most fused cases.
* fix a test.
* Fix two tests in SE(n) for hat/hat! where we checked they would not work but now they actually do work
* Fix sasaki.
* Fix connection.
* Don't export the fused variants.
* Fix two further tests.
* Add deprecation bindings, test and document them.
* Fix a typo.
* Fix compat entries in docs and tutorials.
* bump ambiguities.
* this method is not needed
* Towards code cov.
* add a few tests towards code coverage.
* Add references.
* Remove old code, that is no longer necessary, since we are on 1.10 at least & code cov.

---------

Co-authored-by: Mateusz Baran <mateuszbaran89@gmail.com>
  • Loading branch information
kellertuer and mateuszbaran authored Feb 10, 2025
1 parent 0c2a7b7 commit 6d0b94b
Show file tree
Hide file tree
Showing 90 changed files with 1,164 additions and 805 deletions.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ The allocating variant only needs to defined if a more efficient version
than the default is available.

Note that since the first argument is _always_ the [`AbstractManifold`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/types.html#ManifoldsBase.AbstractManifold), the mutated argument is always the second one in the signature.
In the example there are `exp(M, p, X, t)` for the exponential map that allocates
its result `q`, and `exp!(M, q, p, X, t)` for the in-place one, which computes and returns the `q`.
In the example there are `exp(M, p, X)` for the exponential map that allocates
its result `q`, and `exp!(M, q, p, X)` for the in-place one, which computes and returns the `q`.

Since a user probably looks for the documentation on the allocating variant,
we recommend to attach the documentation string to this variant, mentioning all
Expand All @@ -78,7 +78,7 @@ struct MyManifold <: AbstractManifold end
Describe the function, its input and output as well as a mathematical formula.
"""
exp(::MyManifold, ::Any...)
exp(::MyManifold, ::Any, ::Any)
```

You can also save the string to a variable, for example `_doc_myM_exp` and attach it to both functions
Expand Down
17 changes: 17 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.10.13] - 2025-02-10

## Changed

* Bumped dependency of ManifoldsBase.jl to 1.0, split `exp` into `exp` (without optional argument `t`) and `exp_fused` (with argument `t`) and similarly `retract` to `retract` and `retract_fused`.
* ManifoldsBase.jl 1.0 also moved from `TVector` to `TangentVector`s in type names.
The following names are adapted
* Renamed `HyperboloidTVector` (now deprecated) to `HyperboloidTangentVector`
* Renamed `OrthogonalTVector` (now deprecated) to `OrthogonalTangentVector`
* Renamed `PoincareBallTVector` (now deprecated) to `PoincareBallTangentVector`
* Renamed `PoincareHalfSpaceTVector` (now deprecated) to `PoincareHalfSpaceTangentVector`
* Renamed `ProjectorTVector` (now deprecated) to `ProjectorTangentVector`
* Renamed `StiefelTVector` (now deprecated) to `StiefelTangentVector`
* Renamed `TuckerTVector` (now deprecated) to `TuckerTangentVector`
* Renamed `UMVTVector` (now deprecated) to `UMVTangentVector`
* The internal access `array_value` is now called `internal_value`, compare to its renaming in `ManifoldsBase`

## [0.10.12] - 2025-01-10

### Added
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Manifolds"
uuid = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e"
authors = ["Seth Axen <seth.axen@gmail.com>", "Mateusz Baran <mateuszbaran89@gmail.com>", "Ronny Bergmann <manopt@ronnybergmann.net>", "Antoine Levitt <antoine.levitt@gmail.com>"]
version = "0.10.12"
version = "0.10.13"

[deps]
Einsum = "b7d42ee7-0b51-5a75-98ca-779d3107e4c0"
Expand Down Expand Up @@ -54,7 +54,7 @@ HybridArrays = "0.4"
Kronecker = "0.4, 0.5"
LinearAlgebra = "1.6"
ManifoldDiff = "0.4.0"
ManifoldsBase = "0.15.18"
ManifoldsBase = "1"
Markdown = "1.6"
MatrixEquations = "2.2"
NLsolve = "4"
Expand Down
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ FiniteDifferences = "0.12"
Graphs = "1.4"
HybridArrays = "0.4"
IJulia = "1"
ManifoldsBase = "0.15.0"
ManifoldsBase = "1"
OrdinaryDiffEq = "6"
Plots = "1"
PythonPlot = "1"
Expand Down
2 changes: 1 addition & 1 deletion docs/src/manifolds/rotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Tangent spaces at different points are different vector spaces.
Let ``L_R: \mathrm{SO}(n) → \mathrm{SO}(n)`` where ``R ∈ \mathrm{SO}(n)`` be the left-multiplication by ``R``, that is ``L_R(S) = RS``.
The tangent space at rotation ``R``, ``T_R \mathrm{SO}(n)``, is related to the tangent space at the identity rotation ``I_n`` by the differential of ``L_R`` at identity, ``(\mathrm{d}L_R)_{I_n} : T_{I_n} \mathrm{SO}(n) → T_R \mathrm{SO}(n)``.
To convert the tangent vector representation at the identity rotation ``X ∈ T_{I_n} \mathrm{SO}(n)`` (i.e., the default) to the matrix representation of the corresponding tangent vector ``Y`` at a rotation ``R`` use the [`embed`](@ref embed(::Manifolds.Rotations, :Any...)) which implements the following multiplication: ``Y = RX ∈ T_R \mathrm{SO}(n)``.
You can compare the functions [`log`](@ref log(::Manifolds.Rotations, :Any...)) and [`exp`](@ref exp(::Manifolds.Rotations, ::Any...)) to see how it works in practice.
You can compare the functions [`log`](@ref log(::Manifolds.Rotations, :Any...)) and [`exp`](@ref exp(::Manifolds.Rotations, ::Any, ::Any)) to see how it works in practice.

Several common functions are also implemented together with [orthogonal and unitary matrices](@ref generalunitarymatrices).

Expand Down
24 changes: 21 additions & 3 deletions docs/src/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,25 @@ @article{BergmannGousenbourger:2018
VOLUME = {4},
YEAR = {2018}
}
@article{BergmannPerschSteidl:2015:1,
AUTHOR = {Bergmann, Ronny and Persch, Johannes and Steidl, Gabriele},
EPRINT = {1512.02814},
EPRINTTYPE = {arXiv},
JOURNAL = {arXiv Preprint},
TITLE = {A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds},
URL = {https://arxiv.org/abs/2011.151202814},
YEAR = {2015}
}
@article{BergmannPerschSteidl:2016:1,
AUTHOR = {Bergmann, Ronny and Persch, Johannes and Steidl, Gabriele},
DOI = {10.1137/15M1052858},
JOURNAL = {SIAM Journal on Imaging Sciences},
NUMBER = {4},
PAGES = {901--937},
TITLE = {A parallel Douglas Rachford algorithm for minimizing ROF-like functionals on images with values in symmetric Hadamard manifolds},
VOLUME = {9},
YEAR = {2016}
}
@book{BinzPods:2008,
AUTHOR = {Biny, E and Pods, S},
PUBLISHER = {American Mathematical Society},
Expand All @@ -179,7 +198,6 @@ @article{BoyaSudarshanTilma:2003
TITLE = {Volumes of compact manifolds},
JOURNAL = {Reports on Mathematical Physics}
}

@book{Boumal:2023,
TITLE = {An Introduction to Optimization on Smooth Manifolds},
AUTHOR = {Boumal, Nicolas},
Expand Down Expand Up @@ -479,13 +497,13 @@ @article{HueperMarkinaSilvaLeite:2021
# J
# ----------------------------------------------------------------------------------------
@misc{JacobssonSwijsenVandervekenVannieuwenhoven:2024,
title={Warped geometries of Segre-Veronese manifolds},
title={Warped geometries of Segre-Veronese manifolds},
author={Simon Jacobsson and Lars Swijsen and Joeri Van der Veken and Nick Vannieuwenhoven},
year={2024},
eprint={2410.00664},
archivePrefix={arXiv},
primaryClass={math.NA},
url={https://arxiv.org/abs/2410.00664},
url={https://arxiv.org/abs/2410.00664},
}

@article{JourneeBachAbsilSepulchre:2010,
Expand Down
4 changes: 2 additions & 2 deletions ext/ManifoldsOrdinaryDiffEqExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ using ManifoldsBase
using ManifoldsBase: TraitList

using Manifolds
import Manifolds: exp!, solve_exp_ode
import Manifolds: exp!, exp_fused!, solve_exp_ode
using Manifolds: @einsum

using ManifoldDiff: default_differential_backend
Expand Down Expand Up @@ -49,7 +49,7 @@ function solve_exp_ode(
return q
end
# also define exp! for metric manifold anew in this case
function exp!(
function exp_fused!(
::TraitList{IsMetricManifold},
M::AbstractDecoratorManifold,
q,
Expand Down
4 changes: 2 additions & 2 deletions ext/ManifoldsRecipesBaseExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ SURFACE_RESOLUTION_DEFAULT = 32
circle_points=CIRCLE_DEFAULT_PLOT_POINTS,
geodesic_interpolation=-1,
hyperbolic_border_color=RGBA(0.0, 0.0, 0.0, 1.0),
) where {P<:PoincareBallPoint,T<:PoincareBallTVector}
) where {P<:PoincareBallPoint,T<:PoincareBallTangentVector}
@series begin
φr = range(0, stop=2 * π, length=circle_points)
x = [cos(φ) for φ in φr]
Expand Down Expand Up @@ -83,7 +83,7 @@ end
pts::AbstractVector{P},
vecs::Union{AbstractVector{T},Nothing}=nothing;
geodesic_interpolation=-1,
) where {P<:PoincareHalfSpacePoint,T<:PoincareHalfSpaceTVector}
) where {P<:PoincareHalfSpacePoint,T<:PoincareHalfSpaceTangentVector}
aspect_ratio --> :equal
framestyle --> :origin
x = []
Expand Down
43 changes: 27 additions & 16 deletions ext/ManifoldsTestExt/tests_general.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ function test_manifold(
test_mutating_rand=false,
parallel_transport=false,
parallel_transport_to=parallel_transport,
parallel_transport_along=parallel_transport,
parallel_transport_direction=parallel_transport,
test_inner=true,
test_norm=true,
Expand Down Expand Up @@ -207,13 +206,25 @@ function test_manifold(
X1 = log(M, pts[1], pts[2])
X2 = log(M, pts[2], pts[1])
Test.@test isapprox(M, pts[2], exp(M, pts[1], X1); atol=atolp1p2, rtol=rtolp1p2)
Test.@test isapprox(M, pts[1], exp(M, pts[1], X1, 0); atol=atolp1p2, rtol=rtolp1p2)
Test.@test isapprox(M, pts[2], exp(M, pts[1], X1, 1); atol=atolp1p2, rtol=rtolp1p2)
Test.@test isapprox(
M,
pts[1],
Manifolds.exp_fused(M, pts[1], X1, 0);
atol=atolp1p2,
rtol=rtolp1p2,
)
Test.@test isapprox(
M,
pts[2],
Manifolds.exp_fused(M, pts[1], X1, 1);
atol=atolp1p2,
rtol=rtolp1p2,
)
if is_mutating
q2 = allocate(pts[1])
exp!(M, q2, pts[1], X1)
Test.@test isapprox(M, pts[2], q2; atol=atolp1p2, rtol=rtolp1p2)
exp!(M, q2, pts[1], X1, 0)
Manifolds.exp_fused!(M, q2, pts[1], X1, 0)
Test.@test isapprox(M, pts[1], q2; atol=atolp1p2, rtol=rtolp1p2)
end
if VERSION >= v"1.5" && isa(M, Union{Grassmann,GeneralizedStiefel})
Expand All @@ -230,7 +241,13 @@ function test_manifold(
Test.@test isapprox(M, pts[1], exp(M, pts[2], X2); atol=atolp1p2, rtol=rtolp1p2)
end
Test.@test is_point(M, exp(M, pts[1], X1); atol=atolp1p2, rtol=rtolp1p2)
Test.@test isapprox(M, pts[1], exp(M, pts[1], X1, 0); atol=atolp1p2, rtol=rtolp1p2)
Test.@test isapprox(
M,
pts[1],
Manifolds.exp_fused(M, pts[1], X1, 0);
atol=atolp1p2,
rtol=rtolp1p2,
)
for p in pts
epsx = find_eps(p)
Test.@test isapprox(
Expand Down Expand Up @@ -265,8 +282,8 @@ function test_manifold(
X1 = log(M, pts[1], pts[2])
end

Test.@test isapprox(M, exp(M, pts[1], X1, 1), pts[2]; atol=atolp1)
Test.@test isapprox(M, exp(M, pts[1], X1, 0), pts[1]; atol=atolp1)
Test.@test isapprox(M, Manifolds.exp_fused(M, pts[1], X1, 1), pts[2]; atol=atolp1)
Test.@test isapprox(M, Manifolds.exp_fused(M, pts[1], X1, 0), pts[1]; atol=atolp1)

if test_norm
Test.@test distance(M, pts[1], pts[2]) norm(M, pts[1], X1)
Expand Down Expand Up @@ -297,7 +314,6 @@ function test_manifold(
parallel_transport && test_parallel_transport(
M,
pts;
along=parallel_transport_along,
to=parallel_transport_to,
direction=parallel_transport_direction,
mutating=is_mutating,
Expand All @@ -312,7 +328,7 @@ function test_manifold(
Test.@test isapprox(
M,
p,
retract(M, p, X, 0, retr_method);
Manifolds.retract_fused(M, p, X, 0, retr_method);
atol=epsx * retraction_atol_multiplier,
rtol=retraction_atol_multiplier == 0 ?
sqrt(epsx) * retraction_rtol_multiplier : 0,
Expand Down Expand Up @@ -842,15 +858,12 @@ function test_manifold(
end

"""
test_parallel_transport(M,P; along=false, to=true, direction=true)
test_parallel_transport(M,P; to=true, direction=true)
Generic tests for parallel transport on `M`given at least two pointsin `P`.
The single functions to transport `along` (a curve), `to` (a point) or (towards a) `direction`
The single functions to transport `to` (a point) or (in a) `direction`
are sub-tests that can be activated by the keywords arguments
!!! Note
Since the interface to specify curves is not yet provided, the along keyword does not have an effect yet
"""
function test_parallel_transport(
M::AbstractManifold,
Expand All @@ -861,15 +874,13 @@ function test_parallel_transport(
P[2:end],
Ref(default_inverse_retraction_method(M)),
);
along=false,
to=true,
direction=true,
mutating=true,
)
length(P) < 2 &&
error("The Parallel Transport test set requires at least 2 points in P")
Test.@testset "Test Parallel Transport" begin # COV_EXCL_LINE
along && @warn "parallel transport along test not yet implemented"
Test.@testset "To (a point)" begin # COV_EXCL_LINE
# even with to =false this displays no tests
if to
Expand Down
Loading

2 comments on commit 6d0b94b

@kellertuer
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register

Release notes:

Changed

  • Bumped dependency of ManifoldsBase.jl to 1.0, split exp into exp (without optional argument t) and exp_fused (with argument t) and similarly retract to retract and retract_fused.
  • ManifoldsBase.jl 1.0 also moved from TVector to TangentVectors in type names.
    The following names are adapted
    • Renamed HyperboloidTVector (now deprecated) to HyperboloidTangentVector
    • Renamed OrthogonalTVector (now deprecated) to OrthogonalTangentVector
    • Renamed PoincareBallTVector (now deprecated) to PoincareBallTangentVector
    • Renamed PoincareHalfSpaceTVector (now deprecated) to PoincareHalfSpaceTangentVector
    • Renamed ProjectorTVector (now deprecated) to ProjectorTangentVector
    • Renamed StiefelTVector (now deprecated) to StiefelTangentVector
    • Renamed TuckerTVector (now deprecated) to TuckerTangentVector
    • Renamed UMVTVector (now deprecated) to UMVTangentVector
  • The internal access array_value is now called internal_value, compare to its renaming in ManifoldsBase

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/124684

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.10.13 -m "<description of version>" 6d0b94b81f9d0907c8e73594dc6dc832d215e211
git push origin v0.10.13

Please sign in to comment.