diff --git a/NEWS.md b/NEWS.md index cf148c70..ddf7922b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,11 @@ 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.15.10] unreleased + +* introduce a `base_point(TpM)` to access the base point of a tangent space +* introduce `TpM[i]` to access tangent spaces of factors from an `AbstractPowerManifold` or a `ProductManifold`. + ## [0.15.9] 02/05/2024 ### Added diff --git a/Project.toml b/Project.toml index 1c1fe3ca..a2f5afa3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ManifoldsBase" uuid = "3362f125-f0bb-47a3-aa74-596ffd7ef2fb" authors = ["Seth Axen ", "Mateusz Baran ", "Ronny Bergmann ", "Antoine Levitt "] -version = "0.15.9" +version = "0.15.10" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" diff --git a/src/ManifoldsBase.jl b/src/ManifoldsBase.jl index 09054298..af7877cf 100644 --- a/src/ManifoldsBase.jl +++ b/src/ManifoldsBase.jl @@ -1219,6 +1219,7 @@ export ×, allocate, angle, base_manifold, + base_point, change_basis, change_basis!, change_metric, diff --git a/src/PowerManifold.jl b/src/PowerManifold.jl index 78daf96b..39c96518 100644 --- a/src/PowerManifold.jl +++ b/src/PowerManifold.jl @@ -778,6 +778,23 @@ Base.@propagate_inbounds function Base.getindex( return get_component(M, p, I...) end +""" + getindex(M::TangentSpace{𝔽, AbstractPowerManifold}, i...) + TpM[i...] + +access the `i`th manifold component from a [`AbstractPowerManifold`](@ref)s tangent space `TpM`. +""" +function Base.getindex( + TpM::TangentSpace{𝔽,<:AbstractPowerManifold}, + I::Union{Integer,Colon,AbstractVector}..., +) where {𝔽} + M = base_manifold(TpM).manifold + p = base_point(TpM)[base_manifold(TpM), I] + return TangentSpace(M, p) +end + + + @doc raw""" injectivity_radius(M::AbstractPowerManifold[, p]) diff --git a/src/ProductManifold.jl b/src/ProductManifold.jl index f5b4b80c..4fbe3719 100644 --- a/src/ProductManifold.jl +++ b/src/ProductManifold.jl @@ -28,6 +28,17 @@ access the `i`th manifold component from the [`ProductManifold`](@ref) `M`. """ @inline Base.getindex(M::ProductManifold, i::Integer) = M.manifolds[i] +""" + getindex(M::TangentSpace{𝔽, ProductManifold}, i) + TpM[i] + +access the `i`th manifold component from a [`ProductManifold`](@ref)s tangent space `TpM`. +""" +function Base.getindex(TpM::TangentSpace{𝔽,<:ProductManifold}, i::Integer) where {𝔽} + M = base_manifold(TpM) + return TangentSpace(M[i], base_point(TpM)[M, i]) +end + ProductManifold() = throw(MethodError("No method matching ProductManifold().")) const PRODUCT_BASIS_LIST = [ diff --git a/src/TangentSpace.jl b/src/TangentSpace.jl index 8ba795ef..2b20d33d 100644 --- a/src/TangentSpace.jl +++ b/src/TangentSpace.jl @@ -40,6 +40,13 @@ function allocate_result(M::TangentSpace, ::typeof(rand)) return zero_vector(M.manifold, M.point) end +@doc raw""" + bae_point(TpM::TangentSpace) + +Return the base point of the [`TangentSpace`](@ref). +""" +base_point(TpM::TangentSpace) = TpM.point + # forward both point checks to tangent vector checks function check_point(TpM::TangentSpace, p; kwargs...) return check_vector(TpM.manifold, TpM.point, p; kwargs...) diff --git a/test/power.jl b/test/power.jl index aed5c441..b0e06bff 100644 --- a/test/power.jl +++ b/test/power.jl @@ -388,4 +388,13 @@ struct TestArrayRepresentation <: AbstractPowerRepresentation end p = rand(N) @test zero_vector(N, p) == 0 .* p end + + @testset "TangentSpace" begin + M = ManifoldsBase.DefaultManifold(3) + N = PowerManifold(M, NestedPowerRepresentation(), 2) + p = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]] + TpN = TangentSpace(N, p) + Tp1M = TangentSpace(M, p[N, 1]) + @test base_point(Tp1M) === p[1] + end end diff --git a/test/product_manifold.jl b/test/product_manifold.jl index fb516c8d..67c84266 100644 --- a/test/product_manifold.jl +++ b/test/product_manifold.jl @@ -1,6 +1,6 @@ using Test using ManifoldsBase -using ManifoldsBase: submanifold_component, submanifold_components +using ManifoldsBase: DefaultManifold, submanifold_component, submanifold_components using ManifoldsBase: AbstractNumbers, ℝ, ℂ, NestedReplacingPowerRepresentation, ProductBasisData using LinearAlgebra @@ -606,4 +606,10 @@ using ManifoldsBaseTestUtils @test ts1 × ts1 == ProductVectorTransport(tr1, tr2, tr1, tr2) end + @testset "TangentSpace" begin + TpM = TangentSpace(M, p1) + Tp1M1 = TpM[1] + @test base_point(Tp1M1) === p1[M, 1] + @test base_manifold(Tp1M1) === M[1] + end end