Skip to content
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

Deprecate LinearAffineMetric, resolves #527 #619

Merged
merged 5 commits into from
May 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ benchmark/tune.json
benchmark/results*
docs/src/tutorials/*.md
.CondaPkg
coverage
*.cov
2 changes: 1 addition & 1 deletion 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.8.65"
version = "0.8.66"

[deps]
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Expand Down
2 changes: 1 addition & 1 deletion benchmark/benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ function add_manifold_benchmarks()
M_spd_1 = Manifolds.SymmetricPositiveDefinite(3)
M_spd_2 = MetricManifold(
Manifolds.SymmetricPositiveDefinite(3),
Manifolds.LinearAffineMetric(),
Manifolds.AffineInvariantMetric(),
)
M_spd_3 = MetricManifold(
Manifolds.SymmetricPositiveDefinite(3),
Expand Down
8 changes: 4 additions & 4 deletions docs/src/manifolds/symmetricpositivedefinite.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ Private=false
Filter = t -> t !== mean
```

## Default metric: the linear affine metric
## Default metric: the affine invariant metric

```@autodocs
Modules = [Manifolds]
Pages = ["manifolds/SymmetricPositiveDefiniteLinearAffine.jl"]
Pages = ["manifolds/SymmetricPositiveDefiniteAffineInvariant.jl"]
Order = [:type]
```

This metric is also the default metric, i.e. any call of the following functions with `P=SymmetricPositiveDefinite(3)` will result in `MetricManifold(P,LinearAffineMetric())`and hence yield the formulae described in this seciton.
This metric is also the default metric, i.e. any call of the following functions with `P=SymmetricPositiveDefinite(3)` will result in `MetricManifold(P,AffineInvariantMetric())`and hence yield the formulae described in this seciton.

```@autodocs
Modules = [Manifolds]
Pages = ["manifolds/SymmetricPositiveDefiniteLinearAffine.jl"]
Pages = ["manifolds/SymmetricPositiveDefiniteAffineInvariant.jl"]
Order = [:function]
```

Expand Down
6 changes: 4 additions & 2 deletions src/Manifolds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ include("manifolds/Symmetric.jl")
include("manifolds/SymmetricPositiveDefinite.jl")
include("manifolds/SymmetricPositiveDefiniteBuresWasserstein.jl")
include("manifolds/SymmetricPositiveDefiniteGeneralizedBuresWasserstein.jl")
include("manifolds/SymmetricPositiveDefiniteLinearAffine.jl")
include("manifolds/SymmetricPositiveDefiniteAffineInvariant.jl")
include("manifolds/SymmetricPositiveDefiniteLogCholesky.jl")
include("manifolds/SymmetricPositiveDefiniteLogEuclidean.jl")
include("manifolds/SymmetricPositiveSemidefiniteFixedRank.jl")
Expand Down Expand Up @@ -536,6 +536,8 @@ function __init__()
return nothing
end

include("deprecated.jl")

export test_manifold
export test_group, test_action

Expand Down Expand Up @@ -642,7 +644,7 @@ export AbstractMetric,
BuresWassersteinMetric,
EuclideanMetric,
GeneralizedBuresWassersteinMetric,
LinearAffineMetric,
AffineInvariantMetric,
LogCholeskyMetric,
LogEuclideanMetric,
MinkowskiMetric,
Expand Down
2 changes: 2 additions & 0 deletions src/deprecated.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Base.@deprecate_binding LinearAffineMetric AffineInvariantMetric
export LinearAffineMetric
6 changes: 3 additions & 3 deletions src/manifolds/SymmetricPositiveDefinite.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function Base.:(==)(p::SPDPoint, q::SPDPoint)
end

function active_traits(f, ::SymmetricPositiveDefinite, args...)
return merge_traits(IsEmbeddedManifold(), IsDefaultMetric(LinearAffineMetric()))
return merge_traits(IsEmbeddedManifold(), IsDefaultMetric(AffineInvariantMetric()))
end

function allocate(p::SPDPoint)
Expand Down Expand Up @@ -229,11 +229,11 @@ end

@doc raw"""
injectivity_radius(M::SymmetricPositiveDefinite[, p])
injectivity_radius(M::MetricManifold{SymmetricPositiveDefinite,LinearAffineMetric}[, p])
injectivity_radius(M::MetricManifold{SymmetricPositiveDefinite,AffineInvariantMetric}[, p])
injectivity_radius(M::MetricManifold{SymmetricPositiveDefinite,LogCholeskyMetric}[, p])

Return the injectivity radius of the [`SymmetricPositiveDefinite`](@ref).
Since `M` is a Hadamard manifold with respect to the [`LinearAffineMetric`](@ref) and the
Since `M` is a Hadamard manifold with respect to the [`AffineInvariantMetric`](@ref) and the
[`LogCholeskyMetric`](@ref), the injectivity radius is globally $∞$.
"""
injectivity_radius(::SymmetricPositiveDefinite) = Inf
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
@doc raw"""
LinearAffineMetric <: AbstractMetric
AffineInvariantMetric <: AbstractMetric

The linear affine metric is the metric for symmetric positive definite matrices, that employs
matrix logarithms and exponentials, which yields a linear and affine metric.
"""
struct LinearAffineMetric <: RiemannianMetric end
struct AffineInvariantMetric <: RiemannianMetric end

@doc raw"""
change_representer(M::SymmetricPositiveDefinite, E::EuclideanMetric, p, X)

Given a tangent vector ``X ∈ T_p\mathcal M`` representing a linear function on the tangent
space at `p` with respect to the [`EuclideanMetric`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.EuclideanMetric)
`g_E`, this is turned into the representer with respect to the (default) metric,
the [`LinearAffineMetric`](@ref) on the [`SymmetricPositiveDefinite`](@ref) `M`.
the [`AffineInvariantMetric`](@ref) on the [`SymmetricPositiveDefinite`](@ref) `M`.

To be precise we are looking for ``Z∈T_p\mathcal P(n)`` such that for all ``Y∈T_p\mathcal P(n)```
it holds
Expand All @@ -34,7 +34,7 @@ end
change_metric(M::SymmetricPositiveDefinite{n}, E::EuclideanMetric, p, X)

Given a tangent vector ``X ∈ T_p\mathcal P(n)`` with respect to the [`EuclideanMetric`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.EuclideanMetric)
`g_E`, this function changes into the [`LinearAffineMetric`](@ref) (default) metric on the
`g_E`, this function changes into the [`AffineInvariantMetric`](@ref) (default) metric on the
[`SymmetricPositiveDefinite`](@ref) `M`.

To be precise we are looking for ``c\colon T_p\mathcal P(n) \to T_p\mathcal P(n) ``
Expand All @@ -55,10 +55,10 @@ end

@doc raw"""
distance(M::SymmetricPositiveDefinite, p, q)
distance(M::MetricManifold{SymmetricPositiveDefinite,LinearAffineMetric}, p, q)
distance(M::MetricManifold{SymmetricPositiveDefinite,AffineInvariantMetric}, p, q)

Compute the distance on the [`SymmetricPositiveDefinite`](@ref) manifold between `p` and `q`,
as a [`MetricManifold`](@ref) with [`LinearAffineMetric`](@ref). The formula reads
as a [`MetricManifold`](@ref) with [`AffineInvariantMetric`](@ref). The formula reads

```math
d_{\mathcal P(n)}(p,q)
Expand All @@ -80,11 +80,11 @@ end

@doc raw"""
exp(M::SymmetricPositiveDefinite, p, X)
exp(M::MetricManifold{SymmetricPositiveDefinite{N},LinearAffineMetric}, p, X)
exp(M::MetricManifold{SymmetricPositiveDefinite{N},AffineInvariantMetric}, p, X)

Compute the exponential map from `p` with tangent vector `X` on the
[`SymmetricPositiveDefinite`](@ref) `M` with its default [`MetricManifold`](@ref) having the
[`LinearAffineMetric`](@ref). The formula reads
[`AffineInvariantMetric`](@ref). The formula reads

```math
\exp_p X = p^{\frac{1}{2}}\operatorname{Exp}(p^{-\frac{1}{2}} X p^{-\frac{1}{2}})p^{\frac{1}{2}},
Expand Down Expand Up @@ -146,12 +146,12 @@ end

@doc raw"""
[Ξ,κ] = get_basis_diagonalizing(M::SymmetricPositiveDefinite, p, B::DiagonalizingOrthonormalBasis)
[Ξ,κ] = get_basis_diagonalizing(M::MetricManifold{SymmetricPositiveDefinite{N},LinearAffineMetric}, p, B::DiagonalizingOrthonormalBasis)
[Ξ,κ] = get_basis_diagonalizing(M::MetricManifold{SymmetricPositiveDefinite{N},AffineInvariantMetric}, p, B::DiagonalizingOrthonormalBasis)

Return a orthonormal basis `Ξ` as a vector of tangent vectors (of length
[`manifold_dimension`](@ref) of `M`) in the tangent space of `p` on the
[`MetricManifold`](@ref) of [`SymmetricPositiveDefinite`](@ref) manifold `M` with
[`LinearAffineMetric`](@ref) that diagonalizes the curvature tensor $R(u,v)w$
[`AffineInvariantMetric`](@ref) that diagonalizes the curvature tensor $R(u,v)w$
with eigenvalues `κ` and where the direction `B.frame_direction` ``V`` has curvature `0`.

The construction is based on an ONB for the symmetric matrices similar to [`get_basis(::SymmetricPositiveDefinite, p, ::DefaultOrthonormalBasis`](@ref get_basis(M::SymmetricPositiveDefinite,p,B::DefaultOrthonormalBasis{<:Any,ManifoldsBase.TangentSpaceType}))
Expand All @@ -178,9 +178,9 @@ end

@doc raw"""
[Ξ,κ] = get_basis(M::SymmetricPositiveDefinite, p, B::DefaultOrthonormalBasis)
[Ξ,κ] = get_basis(M::MetricManifold{SymmetricPositiveDefinite{N},LinearAffineMetric}, p, B::DefaultOrthonormalBasis)
[Ξ,κ] = get_basis(M::MetricManifold{SymmetricPositiveDefinite{N},AffineInvariantMetric}, p, B::DefaultOrthonormalBasis)

Return a default ONB for the tangent space ``T_p\mathcal P(n)`` of the [`SymmetricPositiveDefinite`](@ref) with respect to the [`LinearAffineMetric`](@ref).
Return a default ONB for the tangent space ``T_p\mathcal P(n)`` of the [`SymmetricPositiveDefinite`](@ref) with respect to the [`AffineInvariantMetric`](@ref).

```math
g_p(X,Y) = \operatorname{tr}(p^{-1} X p^{-1} Y),
Expand Down Expand Up @@ -312,11 +312,11 @@ end

@doc raw"""
inner(M::SymmetricPositiveDefinite, p, X, Y)
inner(M::MetricManifold{SymmetricPositiveDefinite,LinearAffineMetric}, p, X, Y)
inner(M::MetricManifold{SymmetricPositiveDefinite,AffineInvariantMetric}, p, X, Y)

Compute the inner product of `X`, `Y` in the tangent space of `p` on
the [`SymmetricPositiveDefinite`](@ref) manifold `M`, as
a [`MetricManifold`](@ref) with [`LinearAffineMetric`](@ref). The formula reads
a [`MetricManifold`](@ref) with [`AffineInvariantMetric`](@ref). The formula reads

````math
g_p(X,Y) = \operatorname{tr}(p^{-1} X p^{-1} Y),
Expand All @@ -328,19 +328,19 @@ function inner(::SymmetricPositiveDefinite, p, X, Y)
end

"""
is_flat(::MetricManifold{ℝ,<:SymmetricPositiveDefinite,LinearAffineMetric})
is_flat(::MetricManifold{ℝ,<:SymmetricPositiveDefinite,AffineInvariantMetric})

Return false. [`SymmetricPositiveDefinite`](@ref) with [`LinearAffineMetric`](@ref)
Return false. [`SymmetricPositiveDefinite`](@ref) with [`AffineInvariantMetric`](@ref)
is not a flat manifold.
"""
is_flat(M::MetricManifold{ℝ,<:SymmetricPositiveDefinite,LinearAffineMetric}) = false
is_flat(M::MetricManifold{ℝ,<:SymmetricPositiveDefinite,AffineInvariantMetric}) = false

@doc raw"""
log(M::SymmetricPositiveDefinite, p, q)
log(M::MetricManifold{SymmetricPositiveDefinite,LinearAffineMetric}, p, q)
log(M::MetricManifold{SymmetricPositiveDefinite,AffineInvariantMetric}, p, q)

Compute the logarithmic map from `p` to `q` on the [`SymmetricPositiveDefinite`](@ref)
as a [`MetricManifold`](@ref) with [`LinearAffineMetric`](@ref). The formula reads
as a [`MetricManifold`](@ref) with [`AffineInvariantMetric`](@ref). The formula reads

```math
\log_p q =
Expand Down Expand Up @@ -370,11 +370,11 @@ end

@doc raw"""
parallel_transport_to(M::SymmetricPositiveDefinite, p, X, q)
parallel_transport_to(M::MetricManifold{SymmetricPositiveDefinite,LinearAffineMetric}, p, X, y)
parallel_transport_to(M::MetricManifold{SymmetricPositiveDefinite,AffineInvariantMetric}, p, X, y)

Compute the parallel transport of `X` from the tangent space at `p` to the
tangent space at `q` on the [`SymmetricPositiveDefinite`](@ref) as a
[`MetricManifold`](@ref) with the [`LinearAffineMetric`](@ref).
[`MetricManifold`](@ref) with the [`AffineInvariantMetric`](@ref).
The formula reads

```math
Expand All @@ -391,7 +391,7 @@ p^{\frac{1}{2}},

where $\operatorname{Exp}$ denotes the matrix exponential
and `log` the logarithmic map on [`SymmetricPositiveDefinite`](@ref)
(again with respect to the [`LinearAffineMetric`](@ref)).
(again with respect to the [`AffineInvariantMetric`](@ref)).
"""
parallel_transport_to(::SymmetricPositiveDefinite, ::Any, ::Any, ::Any)

Expand Down
2 changes: 1 addition & 1 deletion test/manifolds/sphere.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ using ManifoldsBase: TFVector
@test injectivity_radius(M, ProjectionRetraction()) == π / 2
@test base_manifold(M) === M
@test is_default_metric(M, EuclideanMetric())
@test !is_default_metric(M, LinearAffineMetric())
@test !is_default_metric(M, AffineInvariantMetric())
@test !is_point(M, [1.0, 0.0, 0.0, 0.0])
@test !is_vector(M, [1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0])
@test_throws DomainError is_point(M, [2.0, 0.0, 0.0], true)
Expand Down
4 changes: 2 additions & 2 deletions test/manifolds/symmetric_positive_definite.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include("../utils.jl")
@testset "Symmetric Positive Definite Matrices" begin
M1 = SymmetricPositiveDefinite(3)
@test repr(M1) == "SymmetricPositiveDefinite(3)"
M2 = MetricManifold(SymmetricPositiveDefinite(3), Manifolds.LinearAffineMetric())
M2 = MetricManifold(SymmetricPositiveDefinite(3), Manifolds.AffineInvariantMetric())
M3 = MetricManifold(SymmetricPositiveDefinite(3), Manifolds.LogCholeskyMetric())
M4 = MetricManifold(SymmetricPositiveDefinite(3), Manifolds.LogEuclideanMetric())
M5 = MetricManifold(SymmetricPositiveDefinite(3), Manifolds.BuresWassersteinMetric())
Expand Down Expand Up @@ -115,7 +115,7 @@ include("../utils.jl")
@test isapprox(distance(M4, p, q), sqrt(2) * log(2))
@test manifold_dimension(M4) == manifold_dimension(M1)
end
@testset "Test for tangent ONB on LinearAffineMetric" begin
@testset "Test for tangent ONB on AffineInvariantMetric" begin
v = log(M2, p, q)
donb = get_basis(base_manifold(M2), p, DiagonalizingOrthonormalBasis(v))
Xs = get_vectors(base_manifold(M2), p, donb)
Expand Down
3 changes: 1 addition & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ include("utils.jl")
@testset "Manifolds.jl" begin
if TEST_GROUP ∈ ["all", "test_manifolds"]
include_test("differentiation.jl")

include_test("ambiguities.jl")

include_test("test_deprecated.jl")
@testset "utils test" begin
Random.seed!(42)
@testset "usinc_from_cos" begin
Expand Down
2 changes: 1 addition & 1 deletion test/statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ end
@testset "SymmetricPositiveDefinite default" begin
rng = MersenneTwister(36)
P1 = SymmetricPositiveDefinite(3)
P2 = MetricManifold(P1, LinearAffineMetric())
P2 = MetricManifold(P1, AffineInvariantMetric())
@testset "$P" for P in [P1, P2]
p0 = collect(exp(Symmetric(randn(rng, 3, 3) * 0.1)))
x = [exp(P, p0, Symmetric(randn(rng, 3, 3) * 0.1)) for _ in 1:10]
Expand Down
6 changes: 6 additions & 0 deletions test/test_deprecated.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using Manifolds, ManifoldsBase, Test

@testset "Deprecation tests" begin
# Let's just test that for now it still works
@test LinearAffineMetric() === AffineInvariantMetric()
end
2 changes: 1 addition & 1 deletion tutorials/getstarted.jl
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ M₈ = SymmetricPositiveDefinite(3)
# ╔═╡ 82dca58f-52e6-491e-97ec-904bb5b0b36b
md"""
which is the manifold of ``3×3`` matrices that are [symmetric and positive definite](https://juliamanifolds.github.io/Manifolds.jl/latest/manifolds/symmetricpositivedefinite.html#Manifolds.SymmetricPositiveDefinite).
which has a default as well, the affine invariant [`LinearAffineMetric`](https://juliamanifolds.github.io/Manifolds.jl/latest/manifolds/symmetricpositivedefinite.html#Default-metric:-the-linear-affine-metric), but also has several different metrics.
which has a default as well, the affine invariant [`AffineInvariantMetric`](https://juliamanifolds.github.io/Manifolds.jl/latest/manifolds/symmetricpositivedefinite.html#Default-metric:-the-affine-invariant-metric), but also has several different metrics.

To switch the metric, we use the idea of a [📖 decorator pattern](https://en.wikipedia.org/wiki/Decorator_pattern)-like approach. Defining
"""
Expand Down