From f3959c64e38380903af08212ecbcaad9526f41f0 Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 9 Oct 2023 11:06:19 +0200 Subject: [PATCH 01/17] Add orthographic retraction and inverse retraction. --- src/manifolds/FixedRankMatrices.jl | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index 12f57674fb..5e949410ad 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -377,6 +377,18 @@ function inner(::FixedRankMatrices, x::SVDMPoint, v::UMVTVector, w::UMVTVector) return dot(v.U, w.U) + dot(v.M, w.M) + dot(v.Vt, w.Vt) end +function inverse_retract_orthographic!( + M::FixedRankMatrices{m,n,k}, + X::UMVTVector, + p::SVDMPoint, + q::SVDMPoint +) where {m,n,k} + + project!(M, X, p, embed(M,q) - embed(M,p)) + + return X +end + function _isapprox(::FixedRankMatrices, p::SVDMPoint, q::SVDMPoint; kwargs...) return isapprox(p.U * Diagonal(p.S) * p.Vt, q.U * Diagonal(q.S) * q.Vt; kwargs...) end @@ -496,6 +508,27 @@ the size of matrices on this manifold ``(m,n)``. """ @generated representation_size(::FixedRankMatrices{m,n}) where {m,n} = (m, n) +function retract_orthographic!( + ::FixedRankMatrices{m,n,k}, + q::SVDMPoint, + p::SVDMPoint, + X::UMVTVector, + t::Number, +) where {m,n,k} + + tX = t * X + QU, RU = qr(p.U*(diagm(p.S)+ tX.M) + tX.U) + QV, RV = qr(p.Vt'*(diagm(p.S) + tX.M') + tX.Vt') + + Uk, Sk, Vtk = svd(RU*inv(diagm(p.S) + tX.M)* RV') + + mul!(q.U, QU[:, 1:k], Uk) + q.S .= Sk[1:k] + mul!(q.Vt, Vtk, QV[:, 1:k]') + + return q +end + @doc raw""" retract(M, p, X, ::PolarRetraction) From 16c9f0463e63d18ba1220b0a0b963821fee36b14 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Mon, 9 Oct 2023 12:14:18 +0200 Subject: [PATCH 02/17] Add boilerplate code for orthographic retractions and their inverses and already 2 new references. --- docs/src/references.bib | 23 ++++- src/Manifolds.jl | 4 + src/manifolds/FixedRankMatrices.jl | 131 +++++++++++++++++++++++++++-- 3 files changed, 150 insertions(+), 8 deletions(-) diff --git a/docs/src/references.bib b/docs/src/references.bib index 46e3f3d19b..f313545904 100644 --- a/docs/src/references.bib +++ b/docs/src/references.bib @@ -25,7 +25,28 @@ @incollection{AbsilMahonyTrumpf:2013 PUBLISHER = {Springer Berlin Heidelberg}, PAGES = {361--368}, TITLE = {An Extrinsic Look at the Riemannian Hessian}, - BOOKTITLE = {Geometric Science of Information}, + BOOKTITLE = {Geometric Science of Information} +} +@article{AbsilMalick:2012, + AUTHOR = {Absil, P.-A. and Malick, Jérôme}, + TITLE = {Projection-like Retractions on Matrix Manifolds}, + JOURNAL = {SIAM Journal on Optimization}, + VOLUME = {22}, + NUMBER = {1}, + PAGES = {135-158}, + YEAR = {2012}, + DOI = {10.1137/100802529} +} +@article{AbsilOseledets:2014, + DOI = {10.1007/s10589-014-9714-4}, + YEAR = {2014}, + PUBLISHER = {Springer Science and Business Media LLC}, + VOLUME = {62}, + NUMBER = {1}, + PAGES = {5--29}, + AUTHOR = {P.-A. Absil and I. V. Oseledets}, + TITLE = {Low-rank retractions: a survey and new results}, + JOURNAL = {Computational Optimization and Applications} } @article{AfsariTronVidal:2013, DOI = {10.1137/12086282x}, diff --git a/src/Manifolds.jl b/src/Manifolds.jl index 259c4a7b17..6e8b81e54b 100644 --- a/src/Manifolds.jl +++ b/src/Manifolds.jl @@ -132,6 +132,8 @@ import ManifoldsBase: representation_size, retract, retract!, + _retract, + retract!, retract_cayley!, retract_exp_ode!, retract_pade!, @@ -704,6 +706,7 @@ export AbstractRetractionMethod, ProjectionRetraction, SoftmaxRetraction, ODEExponentialRetraction, + OrthographicRetraction, PadeRetraction, ProductRetraction, PowerRetraction, @@ -715,6 +718,7 @@ export AbstractInverseRetractionMethod, CayleyInverseRetraction, LogarithmicInverseRetraction, QRInverseRetraction, + OrthographicInverseRetraction, PolarInverseRetraction, ProjectionInverseRetraction, ShootingInverseRetraction, diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index 5e949410ad..92c2615f1a 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -108,6 +108,111 @@ Base.:-(v::UMVTVector) = UMVTVector(-v.U, -v.M, -v.Vt) Base.:+(v::UMVTVector) = UMVTVector(v.U, v.M, v.Vt) Base.:(==)(v::UMVTVector, w::UMVTVector) = (v.U == w.U) && (v.M == w.M) && (v.Vt == w.Vt) +# Move to Base when name is established – i.e. used in more than one manifold +# |/--- +""" + OrthographicRetraction <: AbstractRetractionMethod + +Retractions that are related to orthographic projections, which was first +used in [AbsilMalick:2012](@cite). + +!!! note "Technical Note" + Though you would call e.g. [`retract`](@ref)`(M, p, X, OrthographicRetractionRetractiontraction())`, + to implement a orthographic retraction, define [`retract_orthographic`](@ref)`(M, p, X, t)` + or [`retract_orthographic!`](@ref)`(M, q, p, X, t)` for your manifold `M`. +""" +struct OrthographicRetraction <: AbstractRetractionMethod end + +""" + OrthographicInverseRetraction <: AbstractInverseRetractionMethod + +Retractions that are related to orthographic projections, which was first +used in [AbsilMalick:2012](@cite). + +!!! note "Technical Note" + Though you would call e.g. [`inverse_retract`](@ref)`(M, p, q, OrthographicRetractionInverseRetraction())`, + to implement an inverse orthographic retraction, define [`inverse_retract_orthographic`](@ref)`(M, p, q)` + or [`inverse_retract_orthographic!`](@ref)`(M, X, p, q)` for your manifold `M`. +""" +struct OrthographicInverseRetraction <: AbstractInverseRetractionMethod end + +# Layer II +function _inverse_retract!( + M::AbstractManifold, + X, + p, + q, + ::OrthographicInverseRetraction; + kwargs..., +) + return inverse_retract_orthographic!(M, X, p, q; kwargs...) +end + +function _inverse_retract( + M::AbstractManifold, + p, + q, + ::OrthographicInverseRetraction; + kwargs..., +) + return inverse_retract_orthographic(M, p, q; kwargs...) +end + +""" + inverse_retract_orthographic(M::AbstractManifold, p, q) + +computes the allocating variant of the [`OrthographicInverseRetraction`](@ref), +which by default allocates and calls [`inverse_retract_orthographic!`](@ref ManifoldsBase.inverse_retract_polar!). +""" +function inverse_retract_orthographic(M::AbstractManifold, p, q; kwargs...) + X = allocate_result(M, inverse_retract, p, q) + return inverse_retract_orthographic!(M, X, p, q; kwargs...) +end + +# Layer III +""" + inverse_retract_polar!(M::AbstractManifold, X, p, q) + +Compute the in-place variant of the [`OrthographicInverseRetraction`](@ref). +""" +inverse_retract_orthographic!(M::AbstractManifold, X, p, q) + +## Layer II +function _retract!( + M::AbstractManifold, + q, + p, + X, + t::Number, + ::OrthographicRetraction; + kwargs..., +) + return retract_orthographic!(M, q, p, X, t; kwargs...) +end +function _retract(M::AbstractManifold, p, X, t::Number, ::OrthographicRetraction; kwargs...) + return retract_orthographic(M, p, X, t; kwargs...) +end + +## Layer III +""" + retract_orthographic!(M::AbstractManifold, q, p, X, t::Number) + +Compute the in-place variant of the [`OrthographicRetraction`](@ref). +""" +retract_orthographic!(M::AbstractManifold, q, p, X, t::Number) + +""" + retract_orthographic(M::AbstractManifold, p, X, t::Number) + +computes the allocating variant of the [`PolarRetraction`](@ref), +which by default allocates and calls [`retract_polar!`](@ref ManifoldsBase.retract_polar!). +""" +function retract_orthographic(M::AbstractManifold, p, X, t::Number; kwargs...) + q = allocate_result(M, retract, p, X) + return retract_orthographic!(M, q, p, X, t; kwargs...) +end +# \|--- + allocate(p::SVDMPoint) = SVDMPoint(allocate(p.U), allocate(p.S), allocate(p.Vt)) function allocate(p::SVDMPoint, ::Type{T}) where {T} return SVDMPoint(allocate(p.U, T), allocate(p.S, T), allocate(p.Vt, T)) @@ -377,14 +482,20 @@ function inner(::FixedRankMatrices, x::SVDMPoint, v::UMVTVector, w::UMVTVector) return dot(v.U, w.U) + dot(v.M, w.M) + dot(v.Vt, w.Vt) end +@doc raw""" + inverse_retract(M, p, X, ::OrthographicInverseRetraction) + +**(ToDo Docs, but we already have [AbsilOseledets:2014](@cite))** +""" +inverse_retract(::FixedRankMatrices, ::Any, ::Any, ::OrthographicInverseRetraction) + function inverse_retract_orthographic!( M::FixedRankMatrices{m,n,k}, X::UMVTVector, p::SVDMPoint, - q::SVDMPoint + q::SVDMPoint, ) where {m,n,k} - - project!(M, X, p, embed(M,q) - embed(M,p)) + project!(M, X, p, embed(M, q) - embed(M, p)) return X end @@ -508,6 +619,13 @@ the size of matrices on this manifold ``(m,n)``. """ @generated representation_size(::FixedRankMatrices{m,n}) where {m,n} = (m, n) +@doc raw""" + retract(M, p, X, ::OrthographicRetraction) + +**(ToDo Docs, but we already have [AbsilOseledets:2014](@cite))** +""" +retract(::FixedRankMatrices, ::Any, ::Any, ::OrthographicRetraction) + function retract_orthographic!( ::FixedRankMatrices{m,n,k}, q::SVDMPoint, @@ -515,12 +633,11 @@ function retract_orthographic!( X::UMVTVector, t::Number, ) where {m,n,k} - tX = t * X - QU, RU = qr(p.U*(diagm(p.S)+ tX.M) + tX.U) - QV, RV = qr(p.Vt'*(diagm(p.S) + tX.M') + tX.Vt') + QU, RU = qr(p.U * (diagm(p.S) + tX.M) + tX.U) + QV, RV = qr(p.Vt' * (diagm(p.S) + tX.M') + tX.Vt') - Uk, Sk, Vtk = svd(RU*inv(diagm(p.S) + tX.M)* RV') + Uk, Sk, Vtk = svd(RU * inv(diagm(p.S) + tX.M) * RV') mul!(q.U, QU[:, 1:k], Uk) q.S .= Sk[1:k] From 7bb6e971b27db3744cd2b9e922a97490db748a99 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Mon, 9 Oct 2023 15:53:55 +0200 Subject: [PATCH 03/17] Adds an allocation for the inverse retraction on Fixed Rank. --- src/manifolds/FixedRankMatrices.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index 92c2615f1a..5e349071ba 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -222,6 +222,14 @@ function allocate(X::UMVTVector, ::Type{T}) where {T} return UMVTVector(allocate(X.U, T), allocate(X.M, T), allocate(X.Vt, T)) end +function allocate_result( + ::FixedRankMatrices{m,n,k}, + ::typeof(inverse_retract), + p, + q, +) where {m,n,k} + return zero_vector(M, p) +end function allocate_result( ::FixedRankMatrices{m,n,k}, ::typeof(project), From bd485db75228e5437b242948865e7ff5cf43e5c0 Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 9 Oct 2023 15:56:13 +0200 Subject: [PATCH 04/17] typo fixed. --- src/manifolds/FixedRankMatrices.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index 92c2615f1a..c61ad44349 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -171,7 +171,7 @@ end # Layer III """ - inverse_retract_polar!(M::AbstractManifold, X, p, q) + inverse_retract_orthographic!(M::AbstractManifold, X, p, q) Compute the in-place variant of the [`OrthographicInverseRetraction`](@ref). """ From a0da6330c6a048ac90c290191a413419aac42a2c Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 9 Oct 2023 16:10:52 +0200 Subject: [PATCH 05/17] add test to new retraction method and fixes typo. --- src/manifolds/FixedRankMatrices.jl | 2 +- test/manifolds/fixed_rank.jl | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index 8a2109c14e..7f19ffe7aa 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -223,7 +223,7 @@ function allocate(X::UMVTVector, ::Type{T}) where {T} end function allocate_result( - ::FixedRankMatrices{m,n,k}, + M::FixedRankMatrices{m,n,k}, ::typeof(inverse_retract), p, q, diff --git a/test/manifolds/fixed_rank.jl b/test/manifolds/fixed_rank.jl index e381bb4da8..70009206a8 100644 --- a/test/manifolds/fixed_rank.jl +++ b/test/manifolds/fixed_rank.jl @@ -219,7 +219,8 @@ include("../utils.jl") test_vee_hat=false, test_tangent_vector_broadcasting=true, projection_atol_multiplier=15, - retraction_methods=[PolarRetraction()], + retraction_methods=[PolarRetraction(), OrthographicRetraction()], + inverse_retraction_methods = [OrthographicInverseRetraction()], vector_transport_methods=[ProjectionTransport()], vector_transport_retractions=[PolarRetraction()], vector_transport_inverse_retractions=[PolarInverseRetraction()], From ca22d6a7921706b777fe63967c1a5455f6d42416 Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 16 Oct 2023 11:57:11 +0200 Subject: [PATCH 06/17] add docs to retract_orthographic and inverse_retract_orthographic --- src/manifolds/FixedRankMatrices.jl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index 7f19ffe7aa..da73aa6bd0 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -491,8 +491,13 @@ function inner(::FixedRankMatrices, x::SVDMPoint, v::UMVTVector, w::UMVTVector) end @doc raw""" - inverse_retract(M, p, X, ::OrthographicInverseRetraction) + inverse_retract(M, p, q, ::OrthographicInverseRetraction) +Compute the OrthographicInverseRetraction [`FixedRankMatrices`](@ref) `M` by computing +''''math + X = P_{T_{p}M }(q - p) = qVt^{\top}Vt \ + \ UU^{\top}q - UU^{\top}qVt^{\top}Vt - p, +'''' +where ''p'' is a [`SVDMPoint'](@ref) `(U,S,Vt)` and ''P_{T_{p}M }'' is the projection [`project'](@ref) into the tangent space at ""p"". **(ToDo Docs, but we already have [AbsilOseledets:2014](@cite))** """ inverse_retract(::FixedRankMatrices, ::Any, ::Any, ::OrthographicInverseRetraction) @@ -629,7 +634,16 @@ the size of matrices on this manifold ``(m,n)``. @doc raw""" retract(M, p, X, ::OrthographicRetraction) - +Compute the OrthographicRetraction on the [`FixedRankMatrices`](@ref) `M` by finding the nearest point to ''p + X'' in +''''math + p + X + T^{\bot}_{p}M \cap M +''' +where ''T^{\bot}_{p}M '' is the Normal Space of ''T_{p}M ''. \\ +If ''X'' is sufficiently small, then the nearest is unique and can be expressed by +''''math + q = (U(S + M) + U_{p})(S + M)^{-1}((S + M)Vt + Vt_{p}), +'''' +where ''p'' is a [`SVDMPoint](@ref) `(U,S,Vt)` and X is an [`UMVTVector](@ref) `(U_{p},M,Vt_{p})`. **(ToDo Docs, but we already have [AbsilOseledets:2014](@cite))** """ retract(::FixedRankMatrices, ::Any, ::Any, ::OrthographicRetraction) From f76a86337a56a7a2b6cee60560cdfdc9f6116dfd Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Tue, 17 Oct 2023 09:49:13 +0200 Subject: [PATCH 07/17] Fix doc strings. Use the right math environment and disentangle markdown notation and LaTeX notation. --- src/manifolds/FixedRankMatrices.jl | 38 +++++++++++++++++++----------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index da73aa6bd0..3353669b7f 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -494,11 +494,14 @@ end inverse_retract(M, p, q, ::OrthographicInverseRetraction) Compute the OrthographicInverseRetraction [`FixedRankMatrices`](@ref) `M` by computing -''''math - X = P_{T_{p}M }(q - p) = qVt^{\top}Vt \ + \ UU^{\top}q - UU^{\top}qVt^{\top}Vt - p, -'''' -where ''p'' is a [`SVDMPoint'](@ref) `(U,S,Vt)` and ''P_{T_{p}M }'' is the projection [`project'](@ref) into the tangent space at ""p"". -**(ToDo Docs, but we already have [AbsilOseledets:2014](@cite))** + +```math + X = P_{T_{p}M}(q - p) = qVV^\mathrm{T} + UU^{\mathrm{T}}q - UU^{\mathrm{T}}qVV^{\mathrm{T}} - p, +``` +where ``p`` is a [`SVDMPoint`](@ref)`(U,S,Vt)` and ``P_{T_{p}M}`` is the [`project'](@ref)ion +onto the tangent space at ``p``. + +For more details, see [AbsilOseledets:2014](@cite). """ inverse_retract(::FixedRankMatrices, ::Any, ::Any, ::OrthographicInverseRetraction) @@ -634,17 +637,24 @@ the size of matrices on this manifold ``(m,n)``. @doc raw""" retract(M, p, X, ::OrthographicRetraction) -Compute the OrthographicRetraction on the [`FixedRankMatrices`](@ref) `M` by finding the nearest point to ''p + X'' in -''''math +Compute the OrthographicRetraction on the [`FixedRankMatrices`](@ref) `M` by finding +the nearest point to ``p + X`` in + +```math p + X + T^{\bot}_{p}M \cap M -''' -where ''T^{\bot}_{p}M '' is the Normal Space of ''T_{p}M ''. \\ -If ''X'' is sufficiently small, then the nearest is unique and can be expressed by -''''math +``' + +where ``T^{\bot}_{p}M `` is the Normal Space of ``T_{p}M ``. + +If ``X`` is sufficiently small, then the nearest is unique and can be expressed by + +```math q = (U(S + M) + U_{p})(S + M)^{-1}((S + M)Vt + Vt_{p}), -'''' -where ''p'' is a [`SVDMPoint](@ref) `(U,S,Vt)` and X is an [`UMVTVector](@ref) `(U_{p},M,Vt_{p})`. -**(ToDo Docs, but we already have [AbsilOseledets:2014](@cite))** +``` + +where ``p`` is a [`SVDMPoint`](@ref)`(U,S,Vt)` and X is an [`UMVTVector`](@ref)`(Up,M,Vtp)`. + +For more details, see [AbsilOseledets:2014](@cite). """ retract(::FixedRankMatrices, ::Any, ::Any, ::OrthographicRetraction) From 53a6f06ba23f19e4663d8377e11afe59c973dc0a Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Tue, 17 Oct 2023 09:55:46 +0200 Subject: [PATCH 08/17] Fix a few errors that appeared when rendering the docs. --- src/manifolds/FixedRankMatrices.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index 3353669b7f..c8c3672888 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -162,7 +162,7 @@ end inverse_retract_orthographic(M::AbstractManifold, p, q) computes the allocating variant of the [`OrthographicInverseRetraction`](@ref), -which by default allocates and calls [`inverse_retract_orthographic!`](@ref ManifoldsBase.inverse_retract_polar!). +which by default allocates and calls [`inverse_retract_orthographic!`](@ref inverse_retract_orthographic!). """ function inverse_retract_orthographic(M::AbstractManifold, p, q; kwargs...) X = allocate_result(M, inverse_retract, p, q) @@ -204,8 +204,8 @@ retract_orthographic!(M::AbstractManifold, q, p, X, t::Number) """ retract_orthographic(M::AbstractManifold, p, X, t::Number) -computes the allocating variant of the [`PolarRetraction`](@ref), -which by default allocates and calls [`retract_polar!`](@ref ManifoldsBase.retract_polar!). +computes the allocating variant of the [`OrthographicRetraction`](@ref), +which by default allocates and calls [`retract_polar!`](@ref ManifoldsBase.retract_orthographic!). """ function retract_orthographic(M::AbstractManifold, p, X, t::Number; kwargs...) q = allocate_result(M, retract, p, X) @@ -498,7 +498,7 @@ Compute the OrthographicInverseRetraction [`FixedRankMatrices`](@ref) `M` by com ```math X = P_{T_{p}M}(q - p) = qVV^\mathrm{T} + UU^{\mathrm{T}}q - UU^{\mathrm{T}}qVV^{\mathrm{T}} - p, ``` -where ``p`` is a [`SVDMPoint`](@ref)`(U,S,Vt)` and ``P_{T_{p}M}`` is the [`project'](@ref)ion +where ``p`` is a [`SVDMPoint`](@ref)`(U,S,Vt)` and ``P_{T_{p}M}`` is the [`project`](@ref)ion onto the tangent space at ``p``. For more details, see [AbsilOseledets:2014](@cite). From afeb767c6c2cf0f7ef4b04b0923119b0bf6e0128 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Tue, 17 Oct 2023 09:57:07 +0200 Subject: [PATCH 09/17] Fix another typo. --- src/manifolds/FixedRankMatrices.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index c8c3672888..fdc192204b 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -205,7 +205,7 @@ retract_orthographic!(M::AbstractManifold, q, p, X, t::Number) retract_orthographic(M::AbstractManifold, p, X, t::Number) computes the allocating variant of the [`OrthographicRetraction`](@ref), -which by default allocates and calls [`retract_polar!`](@ref ManifoldsBase.retract_orthographic!). +which by default allocates and calls [`retract_polar!`](@ref retract_orthographic!). """ function retract_orthographic(M::AbstractManifold, p, X, t::Number; kwargs...) q = allocate_result(M, retract, p, X) From 0cd634d9f8c2b0c85af140bf5426aa8c1c79ef9f Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Tue, 17 Oct 2023 14:35:37 +0200 Subject: [PATCH 10/17] Fix even more typos. --- src/manifolds/FixedRankMatrices.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index fdc192204b..b66319f9af 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -641,18 +641,18 @@ Compute the OrthographicRetraction on the [`FixedRankMatrices`](@ref) `M` by fin the nearest point to ``p + X`` in ```math - p + X + T^{\bot}_{p}M \cap M -``' + p + X + N_{p}\mathcal M \cap \mathcal M +``` -where ``T^{\bot}_{p}M `` is the Normal Space of ``T_{p}M ``. +where ``N_{p}\mathcal M `` is the Normal Space of ``T_{p}\mathcal M ``. -If ``X`` is sufficiently small, then the nearest is unique and can be expressed by +If ``X`` is sufficiently small, then the nearest such point is unique and can be expressed by ```math - q = (U(S + M) + U_{p})(S + M)^{-1}((S + M)Vt + Vt_{p}), + q = (U(S + M) + U_{p})(S + M)^{-1}((S + M)V^{\mathrm{T}} + V^{\mathrm{T}}_{p}), ``` -where ``p`` is a [`SVDMPoint`](@ref)`(U,S,Vt)` and X is an [`UMVTVector`](@ref)`(Up,M,Vtp)`. +where ``p`` is a [`SVDMPoint`](@ref)`(U,S,Vt)` and ``X`` is an [`UMVTVector`](@ref)`(Up,M,Vtp)`. For more details, see [AbsilOseledets:2014](@cite). """ From a01f37ee09a51e427a1f2aa25b21ff5f28eb2b35 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Fri, 20 Oct 2023 15:35:20 +0200 Subject: [PATCH 11/17] Fix one further typo. --- src/manifolds/FixedRankMatrices.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index b66319f9af..d47c171dbf 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -493,7 +493,7 @@ end @doc raw""" inverse_retract(M, p, q, ::OrthographicInverseRetraction) -Compute the OrthographicInverseRetraction [`FixedRankMatrices`](@ref) `M` by computing +Compute the orthographic inverse retraction [`FixedRankMatrices`](@ref) `M` by computing ```math X = P_{T_{p}M}(q - p) = qVV^\mathrm{T} + UU^{\mathrm{T}}q - UU^{\mathrm{T}}qVV^{\mathrm{T}} - p, From f462f3b128e1e20d516ba5b9b5bdac9f1b8c1af8 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Fri, 20 Oct 2023 15:42:33 +0200 Subject: [PATCH 12/17] Adds Lukas to Project members. --- .zenodo.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.zenodo.json b/.zenodo.json index d4a28f3ea3..4076fbb329 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -31,6 +31,11 @@ "name": "Weiß, Manuel", "type": "ProjectMember" }, + { + "affiliation": "Georg-August-University Göttingen", + "name": "Klingbiel, Lukas", + "type": "ProjectMember" + }, { "affiliation": "NTNU Trondheim", "name": "Kolstø, Johannes Voll", From 82c7a8c16d611acb75c8fb053922253863f81f2e Mon Sep 17 00:00:00 2001 From: Lukas Date: Fri, 20 Oct 2023 16:01:31 +0200 Subject: [PATCH 13/17] runs formatter --- test/manifolds/fixed_rank.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/manifolds/fixed_rank.jl b/test/manifolds/fixed_rank.jl index 70009206a8..7bd9a128a5 100644 --- a/test/manifolds/fixed_rank.jl +++ b/test/manifolds/fixed_rank.jl @@ -220,7 +220,7 @@ include("../utils.jl") test_tangent_vector_broadcasting=true, projection_atol_multiplier=15, retraction_methods=[PolarRetraction(), OrthographicRetraction()], - inverse_retraction_methods = [OrthographicInverseRetraction()], + inverse_retraction_methods=[OrthographicInverseRetraction()], vector_transport_methods=[ProjectionTransport()], vector_transport_retractions=[PolarRetraction()], vector_transport_inverse_retractions=[PolarInverseRetraction()], From e673e69f359b88c5c28a0aafca46e487a731b162 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Fri, 20 Oct 2023 18:58:08 +0200 Subject: [PATCH 14/17] extend tests to inplace inverse retractions. --- ext/ManifoldsTestExt/tests_general.jl | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/ext/ManifoldsTestExt/tests_general.jl b/ext/ManifoldsTestExt/tests_general.jl index 7e43010977..7cbe9d33d1 100644 --- a/ext/ManifoldsTestExt/tests_general.jl +++ b/ext/ManifoldsTestExt/tests_general.jl @@ -342,21 +342,27 @@ function test_manifold( Test.@test isapprox(M, p2, q; atol=point_atol) # This test is not reasonable for `inverse_retract!(M, X, p, q, m)`, # since X is of different type/concept than p,q + end end end for p in pts epsx = find_eps(p) for inv_retr_method in inverse_retraction_methods - Test.@test isapprox( - M, - p, - zero_vector(M, p), - inverse_retract(M, p, p, inv_retr_method); - atol=epsx * retraction_atol_multiplier, - rtol=retraction_atol_multiplier == 0 ? - sqrt(epsx) * retraction_rtol_multiplier : 0, - ) + X = inverse_retract(M, p, p, inv_retr_method) + Y = copy(M, p, X) + inverse_retract!(M, Y, p, p, inv_retr_method) + for Z in [X, Y] + Test.@test isapprox( + M, + p, + zero_vector(M, p), + Z; + atol=epsx * retraction_atol_multiplier, + rtol=retraction_atol_multiplier == 0 ? + sqrt(epsx) * retraction_rtol_multiplier : 0, + ) + end end end end From b9786067876b105fb8b622e73e71de4cee01979c Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Fri, 20 Oct 2023 19:05:19 +0200 Subject: [PATCH 15/17] make tests more safe. --- ext/ManifoldsTestExt/tests_general.jl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/ext/ManifoldsTestExt/tests_general.jl b/ext/ManifoldsTestExt/tests_general.jl index 7cbe9d33d1..741fd68148 100644 --- a/ext/ManifoldsTestExt/tests_general.jl +++ b/ext/ManifoldsTestExt/tests_general.jl @@ -350,14 +350,23 @@ function test_manifold( epsx = find_eps(p) for inv_retr_method in inverse_retraction_methods X = inverse_retract(M, p, p, inv_retr_method) - Y = copy(M, p, X) - inverse_retract!(M, Y, p, p, inv_retr_method) - for Z in [X, Y] + Test.@test isapprox( + M, + p, + zero_vector(M, p), + X; + atol=epsx * retraction_atol_multiplier, + rtol=retraction_atol_multiplier == 0 ? + sqrt(epsx) * retraction_rtol_multiplier : 0, + ) + if (test_inplace && is_mutating) + Y = copy(M, p, X) + inverse_retract!(M, Y, p, p, inv_retr_method) Test.@test isapprox( M, p, zero_vector(M, p), - Z; + Y; atol=epsx * retraction_atol_multiplier, rtol=retraction_atol_multiplier == 0 ? sqrt(epsx) * retraction_rtol_multiplier : 0, From b6b60167438b6a4e6fa9de57fe29bd2b3e8fa6c1 Mon Sep 17 00:00:00 2001 From: Mateusz Baran Date: Tue, 24 Oct 2023 21:48:10 +0200 Subject: [PATCH 16/17] Update src/manifolds/FixedRankMatrices.jl --- src/manifolds/FixedRankMatrices.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/manifolds/FixedRankMatrices.jl b/src/manifolds/FixedRankMatrices.jl index 2364002a00..97bc66fd18 100644 --- a/src/manifolds/FixedRankMatrices.jl +++ b/src/manifolds/FixedRankMatrices.jl @@ -613,7 +613,8 @@ function representation_size(M::FixedRankMatrices) end @doc raw""" - retract(M, p, X, ::OrthographicRetraction) + retract(M::FixedRankMatrices, p, X, ::OrthographicRetraction) + Compute the OrthographicRetraction on the [`FixedRankMatrices`](@ref) `M` by finding the nearest point to ``p + X`` in From 62dcf0e06247cc28a2a3a3c54f29482929859c15 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Wed, 25 Oct 2023 09:30:13 +0200 Subject: [PATCH 17/17] Bump version, adapt and fix News.md --- NEWS.md | 12 +++++++++--- Project.toml | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index eedd76e525..84ca00e2f7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,7 +5,13 @@ 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.9.0] - 2023-mm-dd +## [0.9.1] - 2023-10-25 + +### Added + +- a new retraction and its inverse for the fixed Rank Manifolds, the orthographic retraction. + +## [0.9.0] - 2023-10-24 ### Added @@ -57,7 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `SymplecticStiefel{n,k}`, - `TranslationGroup`, - `Tucker`. - + For example ```{julia} @@ -84,7 +90,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ``` for groups with size stored in field. Alternatively, you can use a single generic method like this: - + ```{julia} function Base.show(io::IO, M::CenteredMatrices{T}) where {T} m, n = get_parameter(M) diff --git a/Project.toml b/Project.toml index 8c5a5e0c7f..8f2d4c8e94 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Manifolds" uuid = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e" authors = ["Seth Axen ", "Mateusz Baran ", "Ronny Bergmann ", "Antoine Levitt "] -version = "0.9.0" +version = "0.9.1" [deps] Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"