diff --git a/src/manifolds/Sphere.jl b/src/manifolds/Sphere.jl index 9d6f6ba2e1..703b8cd924 100644 --- a/src/manifolds/Sphere.jl +++ b/src/manifolds/Sphere.jl @@ -534,7 +534,7 @@ The formula is due to [AbsilMahonyTrumpf:2013](@cite) given by Weingarten(::Sphere, p, X, V) function Weingarten!(::Sphere, Y, p, X, V) - Y .= -X * p'V + Y .= -X * (p'V) return Y end diff --git a/src/manifolds/StiefelCanonicalMetric.jl b/src/manifolds/StiefelCanonicalMetric.jl index b7a18f64c7..8c1d2da219 100644 --- a/src/manifolds/StiefelCanonicalMetric.jl +++ b/src/manifolds/StiefelCanonicalMetric.jl @@ -188,14 +188,14 @@ function inverse_retract!( end @doc raw""" - Y = riemannian_Hessian(M::MetricManifold{ℝ, Stiefel{n,k,ℝ}, CanonicalMetric}, p, G, H, X) - riemannian_Hessian!(M::MetricManifold{ℝ, Stiefel{n,k,ℝ}, CanonicalMetric}, Y, p, G, H, X) + Y = riemannian_Hessian(M::MetricManifold{ℝ, Stiefel{n,k}, CanonicalMetric}, p, G, H, X) + riemannian_Hessian!(M::MetricManifold{ℝ, Stiefel{n,k}, CanonicalMetric}, Y, p, G, H, X) Compute the Riemannian Hessian ``\operatorname{Hess} f(p)[X]`` given the Euclidean gradient ``∇ f(\tilde p)`` in `G` and the Euclidean Hessian ``∇^2 f(\tilde p)[\tilde X]`` in `H`, where ``\tilde p, \tilde X`` are the representations of ``p,X`` in the embedding,. -Here, we adopt Eq. (5.6) [Nguyen:2023](@cite), for the [`CanonicalMetric`](https://juliamanifolds.github.io/ManifoldsBase.jl/stable/manifolds.html#ManifoldsBase.EuclideanMetric) +Here, we adopt Eq. (5.6) [Nguyen:2023](@cite), for the [`CanonicalMetric`](@ref) ``α_0=1, α_1=\frac{1}{2}`` in their formula. The formula reads ```math @@ -211,21 +211,21 @@ where ``P = I-pp^{\mathrm{H}}``. Compared to Eq. (5.6) we have ``α_0 = 1`` and ``α_1 = \frac{1}{2}``. """ riemannian_Hessian( - M::MetricManifold{ℝ,Stiefel{n,k,ℝ},CanonicalMetric}, + M::MetricManifold{𝔽,Stiefel{n,k,𝔽},CanonicalMetric}, p, G, H, X, -) where {n,k} +) where {n,k,𝔽} function riemannian_Hessian!( - ::MetricManifold{ℝ,Stiefel{n,k,ℝ},CanonicalMetric}, + M::MetricManifold{𝔽,Stiefel{n,k,𝔽},CanonicalMetric}, Y, p, G, H, X, -) where {n,k} +) where {n,k,𝔽} project!( M, Y, diff --git a/test/manifolds/sphere.jl b/test/manifolds/sphere.jl index 41fac3e55d..f217fe4901 100644 --- a/test/manifolds/sphere.jl +++ b/test/manifolds/sphere.jl @@ -264,4 +264,12 @@ using ManifoldsBase: TFVector @test dpX[2][1] == 1.0 @test dpX[2][2].X == normalize(X) end + @testset "Weingarten" begin + M = Sphere(2) + p = [1.0, 0.0, 0.0] + X = [0.0, 2.0, 0.0] + V = [0.3, 0.0, 0.0] + Y = -X * (p'V) + @test Weingarten(M, p, X, V) == Y + end end diff --git a/test/manifolds/stiefel.jl b/test/manifolds/stiefel.jl index edd765dc5e..aed954efa0 100644 --- a/test/manifolds/stiefel.jl +++ b/test/manifolds/stiefel.jl @@ -331,6 +331,8 @@ include("../utils.jl") @test inner(M3, p, X, Y) == 0 @test inner(M3, p, X, 2 * X + 3 * Y) == 2 * inner(M3, p, X, X) @test norm(M3, p, X) ≈ distance(M3, p, q) + Z = [0.0 0.0; 0.0 0.0; -1.0 -1.0] + @test riemannian_Hessian(M3, p, Y, Z, X) == [0.0 0.5; -0.5 0.0; -1.0 -1.0] # check on a higher dimensional manifold, that the iterations are actually used M4 = MetricManifold(Stiefel(10, 2), CanonicalMetric()) p = Matrix{Float64}(I, 10, 2) diff --git a/test/manifolds/vector_bundle.jl b/test/manifolds/vector_bundle.jl index b8d8018fd2..61265c4a70 100644 --- a/test/manifolds/vector_bundle.jl +++ b/test/manifolds/vector_bundle.jl @@ -271,4 +271,13 @@ struct TestVectorSpaceType <: VectorSpaceType end @test is_flat(M) @test injectivity_radius(M) == Inf end + + @testset "Weingarten Map" begin + p0 = [1.0, 0.0, 0.0] + M = TangentSpaceAtPoint(Sphere(2), p0) + p = [0.0, 1.0, 1.0] + X = [0.0, 1.0, 0.0] + N = [1.0, 0.0, 0.0] + @test Weingarten(M, p, X, V) == zero_vector(M, p) + end end