From a35e472acdde3c48184758fa9bf03f0a1b2f8e9d Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Wed, 2 Oct 2024 14:20:35 +0200 Subject: [PATCH 01/35] add segre and warped segre manifold --- docs/src/references.bib | 12 +- src/Manifolds.jl | 4 + src/manifolds/Segre.jl | 609 +++++++++++++++++++++++++++++++++++ src/manifolds/SegreWarped.jl | 362 +++++++++++++++++++++ test/manifolds/segre.jl | 192 +++++++++++ 5 files changed, 1178 insertions(+), 1 deletion(-) create mode 100644 src/manifolds/Segre.jl create mode 100644 src/manifolds/SegreWarped.jl create mode 100644 test/manifolds/segre.jl diff --git a/docs/src/references.bib b/docs/src/references.bib index 9683061c59..4b43166ece 100644 --- a/docs/src/references.bib +++ b/docs/src/references.bib @@ -466,6 +466,16 @@ @article{HueperMarkinaSilvaLeite:2021 # # J # ---------------------------------------------------------------------------------------- +@misc{JacobssonSwijsenVandervekenVannieuwenhoven:2024, + 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}, +} + @article{JourneeBachAbsilSepulchre:2010, DOI = {10.1137/080731359}, EPRINT = {0807.4423}, @@ -939,4 +949,4 @@ @article{AastroemPetraSchmitzerSchnoerr:2017 AUTHOR = {Freddie Γ…strΓΆm and Stefania Petra and Bernhard Schmitzer and Christoph SchnΓΆrr}, TITLE = {Image Labeling by Assignment}, JOURNAL = {Journal of Mathematical Imaging and Vision} -} \ No newline at end of file +} diff --git a/src/Manifolds.jl b/src/Manifolds.jl index e693a5b882..b513c99b40 100644 --- a/src/Manifolds.jl +++ b/src/Manifolds.jl @@ -447,6 +447,8 @@ include("manifolds/MultinomialSymmetric.jl") include("manifolds/MultinomialSymmetricPositiveDefinite.jl") include("manifolds/PositiveNumbers.jl") include("manifolds/ProjectiveSpace.jl") +include("manifolds/Segre.jl") +include("manifolds/SegreWarped.jl") include("manifolds/SkewHermitian.jl") include("manifolds/Spectrahedron.jl") include("manifolds/Stiefel.jl") @@ -690,6 +692,7 @@ export Euclidean, ProbabilitySimplex, ProjectiveSpace, Rotations, + Segre, SkewHermitianMatrices, SkewSymmetricMatrices, Spectrahedron, @@ -768,6 +771,7 @@ export AbstractMetric, ProductMetric, RealSymplecticMetric, RiemannianMetric, + SegreWarpedMetric, StiefelSubmersionMetric export AbstractAtlas, RetractionAtlas # Vector transport types diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl new file mode 100644 index 0000000000..a7a8dd7a67 --- /dev/null +++ b/src/manifolds/Segre.jl @@ -0,0 +1,609 @@ +@doc raw""" + Seg(𝔽^n1 x ... x 𝔽^nd) +is the space of rank-one tensors in 𝔽^n1 βŠ— ... βŠ— 𝔽^nd. + +When 𝔽 = ℝ, + Seg(ℝ^n1 x ... x ℝ^nd) ~ ℝ^+ x S^(n1 - 1) x ... x S^(nd - 1) +is a local diffeomorphism. The geometry of this manifold is computed in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). +""" +abstract type AbstractSegre{𝔽} <: AbstractManifold{𝔽} end +struct Segre{V, 𝔽} <: AbstractSegre{𝔽} end + +""" +function Segre( + valence::NTuple{D, Int}; + field::AbstractNumbers=ℝ, + ) +""" +function Segre(#={{{=# + valence::NTuple{D, Int}; + field::AbstractNumbers=ℝ, + ) where {D} + + return Segre{valence, field}() +end#=}}}=# + +valence(::Segre{V, 𝔽}) where {V, 𝔽} = V +ndims(::Segre{V, 𝔽}) where {V, 𝔽} = length(V) +manifold_dimension(::Segre{V, 𝔽}) where {V, 𝔽} = (1 + sum(V .- 1)) + +""" + check_size(M::Segre{V, 𝔽}, p) + +Check whether `p` has the right size for `Segre` manifold `M`. +""" +function check_size(#={{{=# + M::Segre{V, 𝔽}, + p; + ) where {V, 𝔽} + + p_size = only.(size.(p)) + M_size = [1, V...] + + if p_size != M_size + return DomainError( + p_size, + "The point $(p) can not belong to the manifold $(M), since its size $(p_size) is not equal to the manifolds representation size ($(M_size)).", + ) + end + + return nothing +end#=}}}=# + +""" + check_size(M::Segre{V, 𝔽}, p, v) + +Check whether `p` and `v` have the right size for `Segre` manifold `M`. +""" +function check_size(#={{{=# + M::Segre{V, 𝔽}, + p, + v; + ) where {V, 𝔽} + + p_size = only.(size.(p)) + v_size = only.(size.(v)) + M_size = [1, V...] + + if p_size != M_size + return DomainError( + p_size, + "The point $(p) can not belong to the manifold $(M), since its size $(p_size) is not equal to the manifolds representation size ($(M_size)).", + ) + end + + if v_size != M_size + return DomainError( + v_size, + "The vector $(v) can not belong to the manifold $(M), since its size $(v_size) is not equal to the manifolds representation size ($(M_size)).", + ) + end + + return nothing +end#=}}}=# + +""" + check_point(M::Segre{V, 𝔽}, p; kwargs...) + +Check whether `p` is a valid point on `M`, i.e. `p[1]` is a singleton containing a positive number and `p[i + 1]` is a point on `Sphere(V[i])`. The tolerance can be set using the `kwargs...`. +""" +function check_point(#={{{=# + M::Segre{V, 𝔽}, + p; + kwargs... + ) where {V, 𝔽} + + if p[1][1] <= 0.0 + return DomainError( + p[1][1], + "$(p) has non-positive modulus." + ) + end + + for (x, n) in zip(p[2:end], V) + e = check_point(Sphere(n - 1)::AbstractSphere{𝔽}, x; rtol=1e-10, atol=1e-10, kwargs...) + if !isnothing(e); return e; end + end + + return nothing +end#=}}}=# + +""" + function check_vector( + M::Segre{V, 𝔽}, + p, + v, + kwargs... + ) + +Check whether `v` is a tangent vector to `p` on `M`, i.e. after `check_point(M, p)`, `v` has to be of same dimension as `p` and orthogonal to `p`. The tolerance can be set using the `kwargs...`. +""" +function check_vector(#={{{=# + M::Segre{V, 𝔽}, + p, + v, + kwargs... + ) where {V, 𝔽} + + e = check_point(M, p, kwargs...) + if !isnothing(e); return e; end + + for (x, xdot, n) in zip(p[2:end], v[2:end], V) + # check_vector(::AbstractSphere, ...) uses isapprox to compare the dot product to 0, which by default sets atol=0 + e = check_vector(Sphere(n - 1)::AbstractSphere{𝔽}, x, xdot; rtol=1e-10, atol=1e-10, kwargs...) + if !isnothing(e); return e; end + end + + return nothing +end#=}}}=# + +""" + function get_coordinates( + M::Segre{V, 𝔽}, + p, + v; + kwargs... + ) +""" +function get_coordinates(#={{{=# + M::Segre{V, 𝔽}, + p, + v; + kwargs... + ) where {V, 𝔽} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, v)) + + coords = [v[1], [get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end])]...] + + return vcat(coords...) +end#=}}}=# + +""" + function get_vector( + M::Segre{V, 𝔽}, + p, + X; + kwargs... + ) +""" +function get_vector(#={{{=# + M::Segre{V, 𝔽}, + p, + X; + kwargs... + ) where {V, 𝔽} + + @assert(is_point(M, p)) + + X_ = deepcopy(X) + v = eltype(p)[[] for _ in p] # Initialize + v[1] = [X_[1]] + X_ = drop(X_, 1) + for (i, n) in enumerate(V) + v[i + 1] = get_vector(Sphere(n - 1), p[i + 1], take(X_, n - 1), DefaultOrthonormalBasis(); kwargs...) + X_ = drop(X_, n - 1) + end + + @assert(length(X_) == 0) + check_vector(M, p, v) + + return v +end#=}}}=# + +""" + function inner( + M::Segre{V, ℝ}, + p, + u, + v, + ) + +Inner product between two tangent vectors `u` and `v` at `p`. This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric. +""" +function inner(#={{{=# + M::Segre{V, ℝ}, + p, + u, + v, + ) where {V} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, u)) + @assert(is_vector(M, p, v)) + + return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) +end#=}}}=# + +""" + function norm( + M::Segre{V, 𝔽}, + p, + v, + ) + +Norm of tangent vector `v` at `p`. +""" +function norm(#={{{=# + M::Segre{V, 𝔽}, + p, + v, + ) where {V, 𝔽} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, v)) + + return sqrt(inner(M, p, v, v)) +end#=}}}=# + +""" + function rand( + M::Segre{V, ℝ}; + vector_at=nothing, + ) +""" +function rand(#={{{=# + M::Segre{V, ℝ}; + vector_at=nothing, + ) where {V} + + if isnothing(vector_at) + lambda = abs.(rand(Euclidean(1))) + xs = [rand(Sphere(n - 1)) for n in V] + return [lambda, xs...] + else + @assert(is_point(M, vector_at)) + + lambdadot = rand(Euclidean(1); vector_at=vector_at[1]) + xdots = [rand(Sphere(n - 1); vector_at=vector_at[i + 1]) for (i, n) in enumerate(V)] + return [lambdadot, xdots...] + end +end#=}}}=# + +""" + function embed( + M::Segre{V, 𝔽}, + v, + ) + +Embed `p ∈ Segre((n1, ..., nd), 𝔽)` in `𝔽^{n1 x ... x nd}` +""" +function embed(#={{{=# + M::Segre{V, 𝔽}, + p, + ) where {V, 𝔽} + + @assert(is_point(M, p)) + + return kronecker(p...)[:] +end#=}}}=# + +""" + function embed_vector( + M::Segre{V, 𝔽}, + p, + v, + ) + +Embed `v ∈ T_p Segre((n1, ..., nd), 𝔽)` in `𝔽^{n1 x ... x nd}` +""" +function embed_vector(#={{{=# + M::Segre{V, 𝔽}, + p, + v, + ) where {V, 𝔽} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, v)) + + # Product rule + return sum([ + kronecker([ + i == j ? + xdot : + x + for (j, (x, xdot)) in enumerate(zip(p, v)) + ]...)[:] + for (i, _) in enumerate(p) + ]) +end#=}}}=# + + +""" + function exp( + M::Segre{V, ℝ}, + p, + v, + ) + +Exponential map on Segre manifold. Theorem 1.1 in Swijsen 2021. +""" +function exp(#={{{=# + M::Segre{V, ℝ}, + p, + v, + ) where {V} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, v)) + + q = zeros.(size.(p)) # Initialize + exp!(M, q, p, v) + + return q +end#=}}}=# + +""" + function exp!( + M::Segre{V, ℝ}, + q, + p, + v, + ) + +Exponential map on Segre manifold. Theorem 1.1 in Swijsen 2021. +""" +function exp!(#={{{=# + M::Segre{V, ℝ}, + q, + p, + v, + ) where {V} + + m = sqrt(sum([norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end])])) + if m == 0.0 + q .= deepcopy(p) # Initialize + q[1] .= q[1] .+ v[1] + return q + end + + t = norm(M, p, v) + P = v[1][1] / (p[1][1] * m) + f = atan(sqrt(P^2 + 1.0) * t / p[1][1] + P) - atan(P) + + q[1][1] = sqrt( + t^2 + + 2 * p[1][1] * P * t / sqrt(P^2 + 1.0) + + p[1][1]^2 # This factor is wrong in Swijsen21 on arxiv + ) + + for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) + if all(xdot .== 0.0) + y .= deepcopy(x) + else + a = norm(Sphere(n - 1), x, xdot) + y .= + x * cos(a * f / m) .+ + xdot * sin(a * f / m) / a + end + end + + return 0 +end#=}}}=# + +# Theorem 6.2.1 in thesisLarsSwijsen +""" + function log( + M::Segre{V, ℝ}, + p, + q, + ) + +Logarithmic map on Segre manifold. +""" +function log(#={{{=# + M::Segre{V, ℝ}, + p, + q, + ) where {V} + + @assert(is_point(M, p)) + @assert(is_point(M, q)) + + # Check for compatability + m(a, b) = sqrt(sum([ + distance(Sphere(n - 1), x, y)^2 + for (n, x, y) in zip(V, a[2:end], b[2:end]) + ])) + if m(p, q) < pi # Even if there are closer representations, we prioritize log being continuous + v = zeros.(size.(p)) # Initialize + log!(M, v, p, q) + else + # Find closest representation by flipping an even number of signs. + ds = [distance(Sphere(n - 1), x, y) for (n, x, y) in zip(V, p[2:end], q[2:end])] + flips = [false, (ds .> (pi / 2))...] + nbr_flips = sum(flips) + + # This code is pretty ugly. + if isodd(nbr_flips) + if nbr_flips == length(V) + flips[argmin(ds) + 1] = false + else + is = sortperm(ds; rev=true) + + flips1 = deepcopy(flips) + flips1[is[nbr_flips] + 1] = false + q1 = deepcopy(q) + q1[flips1] = -q1[flips1] + + flips2 = deepcopy(flips) + flips2[is[nbr_flips + 1] + 1] = true + q2 = deepcopy(q) + q2[flips2] = -q2[flips2] + + m(p, q1) < m(p, q2) ? flips = flips1 : flips = flips2 + end + end + + q_ = deepcopy(q) + q_[flips] = -q[flips] + @assert(iseven(sum(flips))) # Should not be necessary but you never know... + @assert(m(p, q_) < pi) + + v = zeros.(size.(p)) # Initialize + log!(M, v, p, q_) + end + + return v +end#=}}}=# + +""" + function log!( + M::Segre{V, ℝ}, + v, + p, + q + ) + +Logarithmic map on Segre manifold. +""" +function log!(#={{{=# + M::Segre{V, ℝ}, + v, + p, + q + ) where {V} + + for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + a = distance(Sphere(n - 1), x, y) + if a == 0.0 + xdot .= zeros(size(x)) + else + xdot .= a * (y - dot(x, y) * x) / sin(a) + end + end + + m = sqrt(sum([ + distance(Sphere(n - 1), x, y)^2 + for (n, x, y) in zip(V, p[2:end], q[2:end]) + ])) + if m == 0.0 + v[1][1] = q[1][1] - p[1][1] + else + v[1][1] = m * p[1][1] * (q[1][1] * cos(m) - p[1][1]) / (q[1][1] * sin(m)) + + t = distance(M, p, q) + v .= t * v / norm(M, p, v) + end + + return 0 +end#=}}}=# + +""" + function distance( + M::Segre{V, ℝ}, + p, + q + ) +Riemannian distance between two points `p` and `q` on the Segre manifold. +""" +function distance(#={{{=# + M::Segre{V, ℝ}, + p, + q + ) where {V} + + @assert(is_point(M, p)) + @assert(is_point(M, q)) + + m = sqrt(sum([ + distance(Sphere(n - 1), x, y)^2 + for (n, x, y) in zip(V, p[2:end], q[2:end]) + ])) + + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m / 2)^2) + # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(m)) but more stable for small m +end#=}}}=# + +""" + function second_fundamental_form( + M::Segre{V, ℝ}, + p, + u, + v, + ) + +Second fundamental form of the Segre manifold embedded in `ℝ^{n1 x ... x nd}`. +""" +function second_fundamental_form(#={{{=# + M::Segre{V, ℝ}, + p, + u, + v, + ) where {V} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, u)) + @assert(is_vector(M, p, v)) + + # TODO: Review this + h = 0 * embed(M, p) # Initialize + for i in 1:length(V) + for j in 1:length(V) + if i != j + p_ = 1 * p + p_[i + 1] = u[i + 1] + p_[j + 1] = v[j + 1] + h = h + kron(p_...)[:, 1] + end + end + end + + return h +end#=}}}=# + +""" + function riemann_tensor( + M::Segre{V, ℝ}, + p, + u, + v, + ) + +Riemann tensor of the Segre manifold at `p`. +""" +function riemann_tensor(#={{{=# + M::Segre{V, ℝ}, + p, + u, + v, + w, + ) where {V} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, u)) + @assert(is_vector(M, p, v)) + @assert(is_vector(M, p, w)) + + u_ = deepcopy(u); u_[1][1] = 0.0 + v_ = deepcopy(v); v_[1][1] = 0.0 + w_ = deepcopy(w); w_[1][1] = 0.0 + + # return [[0.0], [riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end])]...] - (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) + return [[0.0], [riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end])]...] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) +end#=}}}=# + +""" + function sectional_curvature( + M::Segre{V, ℝ}, + p, + u, + v + ) + +Sectional curvature of the Segre manifold in the plane spanned by tangent vectors `u` and `v` at `p`. +""" +function sectional_curvature(#={{{=# + M::Segre{V, ℝ}, + p, + u, + v + ) where {V} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, u)) + @assert(is_vector(M, p, v)) + + return inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) +end#=}}}=# diff --git a/src/manifolds/SegreWarped.jl b/src/manifolds/SegreWarped.jl new file mode 100644 index 0000000000..20ba1809c1 --- /dev/null +++ b/src/manifolds/SegreWarped.jl @@ -0,0 +1,362 @@ +@doc raw""" + SegreWarpedMetric{A} <: AbstractMetric + +Is the alpha-warped metric on the Segre manifold, namely if + + p = (lambda, x1, ..., xd) ∈ Seg(ℝ^n1 x ... x ℝ^nd) ~ ℝ^+ x S^(n1 - 1) x ... x S^(nd - 1) +and + + u = (a, u1, ..., ud), v = (b, v1, ..., vd) ∈ T_p Seg(ℝ^n1 x ... x ℝ^nd) +then + + ⟨u, v⟩ := a * b + (alpha * lambda)^2 * (dot(u1, v1) + ... + dot(ud, vd)). + +Example: + + MetricManifold(Segre((2, 2, 3)), SegreWarpedMetric{1.5}()) + + +The geometry of this manifold is computed in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). +""" +struct SegreWarpedMetric{A} <: AbstractMetric end + +valence(::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}) where {V, A, 𝔽} = V +ndims(::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}) where {V, A, 𝔽} = length(V) + +""" + function get_coordinates( + M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, + p, + v; + kwargs... + ) +""" +function get_coordinates(#={{{=# + M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, + p, + v; + kwargs... + ) where {V, A, 𝔽} + + return get_coordinates(M.manifold, p, v; kwargs...) +end#=}}}=# + +""" + function get_vector( + M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, + p, + X; + kwargs... + ) +""" +function get_vector(#={{{=# + M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, + p, + X; + kwargs... + ) where {V, A, 𝔽} + + return get_vector(M.manifold, p, X; kwargs...) +end#=}}}=# + +""" + function inner( + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + u, + v, + ) + +Inner product between two tangent vectors `u` and `v` at `p`. +""" +function inner(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + u, + v, + ) where {V, A} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, u)) + @assert(is_vector(M, p, v)) + + return u[1][1] * v[1][1] + (A * p[1][1])^2 * dot(u[2:end], v[2:end]) +end#=}}}=# + +""" + function norm( + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + v, + ) + +Norm of tangent vector `v` at `p`. +""" +function norm(#={{{=# + M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, + p, + v, + ) where {V, A, 𝔽} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, v)) + + return sqrt(inner(M, p, v, v)) +end#=}}}=# + +""" + function exp( + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + v, + ) + +Exponential map on Segre manifold. TODO: cite upcoming preprint. +""" +function exp(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + v, + ) where {V, A} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, v)) + + q = zeros.(size.(p)) # Initialize + exp!(M, q, p, v) + + return q +end#=}}}=# + +""" + function exp!( + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + q, + p, + v, + ) + +Exponential map on Segre manifold. TODO: cite prop 4.1 in upcoming preprint +""" +function exp!(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + q, + p, + v, + ) where {V, A} + + m = sqrt(sum([norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end])])) + if m == 0.0 + q .= deepcopy(p) # Initialize + q[1] .= q[1] .+ v[1] + return q + end + + t = norm(M, p, v) + P = v[1][1] / (p[1][1] * A * m) + f = atan(sqrt(P^2 + 1.0) * t / p[1][1] + P) - atan(P) + + q[1][1] = sqrt( + t^2 + + 2 * p[1][1] * P * t / sqrt(P^2 + 1.0) + + p[1][1]^2 + ) + + for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) + if all(xdot .== 0.0) + y .= deepcopy(x) + else + a = norm(Sphere(n - 1), x, xdot) + y .= + x * cos(a * f / (A * m)) .+ + xdot * sin(a * f / (A * m)) / a + end + end + + return 0 +end#=}}}=# + +""" + function log( + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + q, + ) + +Logarithmic map on Segre manifold. +TODO: cite theorem 5.1 in upcoming preprint +""" +function log(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + q, + ) where {V, A} + + @assert(is_point(M, p)) + @assert(is_point(M, q)) + + # Check for compatability + m(a, b) = sqrt(sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, a[2:end], b[2:end])])) + if A * m(p, q) < pi # Even if there are closer representations, we prioritize log being continuous + v = zeros.(size.(p)) # Initialize + log!(M, v, p, q) + else + # Find closest representation by flipping an even number of signs. + ds = [distance(Sphere(n - 1), x, y) for (n, x, y) in zip(V, p[2:end], q[2:end])] + flips = [false, (ds .> (pi / 2))...] + nbr_flips = sum(flips) + + # This code is pretty ugly. It can also be implemented slightly more efficiently, O(d) rather than O(log(d) d), by not sorting ds. + if isodd(nbr_flips) + if nbr_flips == length(V) + flips[argmin(ds) + 1] = false + else + is = sortperm(ds; rev=true) + + flips1 = deepcopy(flips) + flips1[is[nbr_flips] + 1] = false + q1 = deepcopy(q) + q1[flips1] = -q1[flips1] + + flips2 = deepcopy(flips) + flips2[is[nbr_flips + 1] + 1] = true + q2 = deepcopy(q) + q2[flips2] = -q2[flips2] + + m(p, q1) < m(p, q2) ? flips = flips1 : flips = flips2 + end + end + + q_ = deepcopy(q) + q_[flips] = -q[flips] + @assert(iseven(sum(flips))) # Should not be necessary but you never know... + @assert(A * m(p, q_) < pi) + + v = zeros.(size.(p)) # Initialize + log!(M, v, p, q_) + end + + return v +end#=}}}=# + +""" + function log!( + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + v, + p, + q + ) + +Logarithmic map on Segre manifold. +""" +function log!(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + v, + p, + q + ) where {V, A} + + for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + a = distance(Sphere(n - 1), x, y) + if a == 0.0 + xdot .= zeros(size(x)) + else + xdot .= a * (y - dot(x, y) * x) / sin(a) + end + end + + m = sqrt(sum([ + distance(Sphere(n - 1), x, y)^2 + for (n, x, y) in zip(V, p[2:end], q[2:end]) + ])) + if m == 0.0 + v[1][1] = q[1][1] - p[1][1] + else + v[1][1] = p[1][1] * A * m * (cos(A * m) - p[1][1] / q[1][1]) / sin(A * m) + + t = distance(M, p, q) + v .= t * v / norm(M, p, v) + end + + return 0 +end#=}}}=# + +""" + function distance( + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + q, + ) +Riemannian distance between two points `p` and `q` on the Segre manifold. +""" +function distance(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + q, + ) where {V, A} + + @assert(is_point(M, p)) + @assert(is_point(M, q)) + + m = sqrt(sum([ + distance(Sphere(n - 1), x, y)^2 + for (n, x, y) in zip(V, p[2:end], q[2:end]) + ])) + + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m / 2)^2) + # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(A * m)) but more stable for small m +end#=}}}=# + +""" + function riemann_tensor( + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + u, + v + ) + +Riemann tensor of the Segre manifold at `p`. +""" +function riemann_tensor(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + u, + v, + w + ) where {V, A} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, u)) + @assert(is_vector(M, p, v)) + @assert(is_vector(M, p, w)) + + u_ = deepcopy(u); u_[1][1] = 0.0 + v_ = deepcopy(v); v_[1][1] = 0.0 + w_ = deepcopy(w); w_[1][1] = 0.0 + + return [[0.0], [riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end])]...] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) +end#=}}}=# + +""" + function sectional_curvature( + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + u, + v + ) + +Sectional curvature of the Segre manifold in the plane spanned by tangent vectors `u` and `v` at `p`. +""" +function sectional_curvature(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + p, + u, + v + ) where {V, A, ℝ} + + @assert(is_point(M, p)) + @assert(is_vector(M, p, u)) + @assert(is_vector(M, p, v)) + + return inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) +end#=}}}=# diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl new file mode 100644 index 0000000000..cbbf388fd0 --- /dev/null +++ b/test/manifolds/segre.jl @@ -0,0 +1,192 @@ +include("../header.jl") + +# Tests are written for manifolds with this type +T = Union{ + Segre{V, ℝ}, + MetricManifold{ℝ, Segre{V, ℝ}, AlphaWarpedMetric{A}} + } where {V, A} + +# Approximate derivative of f at x +function finite_difference( + f::Function, + x::Float64, + h::Float64; + order=1::Int64 + ) + + # https://en.wikipedia.org/wiki/Finite_difference_coefficient + if order == 1 + return ( + (1 / 12) * f(x - 2 * h) + + (-2 / 3) * f(x - 1 * h) + + (2 / 3) * f(x + 1 * h) + + (-1 / 12) * f(x + 2 * h) + ) / h + elseif order == 2 + return ( + (-1 / 12) * f(x - 2 * h) + + (4 / 3) * f(x - 1 * h) + + (-5 / 2) * f(x) + + (4 / 3) * f(x + 1 * h) + + (-1 / 12) * f(x + 2 * h) + ) / h^2 + elseif order == 3 + return ( + (1 / 8) * f(x - 3 * h) + + (-1) * f(x - 2 * h) + + (13 / 8) * f(x - 1 * h) + + (-13 / 8) * f(x + 1 * h) + + (1) * f(x + 2 * h) + + (-1 / 8) * f(x + 3 * h) + ) / h^3 + end +end + +# Segre is a special case of warped Segre, with warping factor 1 +get_warping_factor(M::Segre{V, ℝ}) = 1.0 +get_warping_factor(M::MetricManifold{ℝ, Segre{V, ℝ}, AlphaWarpedMetric{A}}) where {A} = A + +@testset "Segre and warped Segre" begin + # List of manifolds to test + Ms = [ + [Segre(Tuple([rand(range(2, 7)) for _ in 1:1])) for _ in 1:5]..., + [Segre(Tuple([rand(range(2, 7)) for _ in 1:2])) for _ in 1:5]..., + [Segre(Tuple([rand(range(2, 7)) for _ in 1:3])) for _ in 1:5]..., + [Segre(Tuple([rand(range(2, 7)) for _ in 1:4])) for _ in 1:5]..., + [MetricManifold(Segre(Tuple([rand(range(2, 7)) for _ in 1:1])), AlphaWarpedMetric{rand() + 0.5}()) for _ in 1:5]..., + [MetricManifold(Segre(Tuple([rand(range(2, 7)) for _ in 1:2])), AlphaWarpedMetric{rand() + 0.5}()) for _ in 1:5]..., + [MetricManifold(Segre(Tuple([rand(range(2, 7)) for _ in 1:3])), AlphaWarpedMetric{rand() + 0.5}()) for _ in 1:5]..., + [MetricManifold(Segre(Tuple([rand(range(2, 7)) for _ in 1:4])), AlphaWarpedMetric{rand() + 0.5}()) for _ in 1:5]..., + ] + + @testset "exp maps to the manifold." begin; for M in Ms + p = rand(M) + v = rand(M; vector_at=p) + + @test(is_point(M, p)) + @test(is_vector(M, p, v)) + @test(is_point(M, exp(M, p, v))) + end; end + + @testset "Geodesics are unit speed." begin; for M in Ms + p = rand(M) + p[1][1] = p[1][1] + 0.5 # Keep away from 0 + v = rand(M, vector_at=p); v = v / norm(M, p, v) + + geodesic_speed = finite_difference( + t -> distance(M, p, exp(M, p, t * v)), + 0.5 * rand(), + 1e-5 + ) + @test(isapprox(geodesic_speed, 1.0; rtol=1e-6)) + end; end + + @testset "Geodesics are minimizing." begin; for M in Ms + p = rand(M) + v = rand(M, vector_at=p) + v = v / norm(M, p, v) + n = manifold_dimension(M) + + # We test the following: + # Geodesics are (locally) length-minizing. So let B_a be a one-parameter + # family of curves such that B_0 is a geodesic. Then the derivative of + # length(B_a) at a = 0 should be 0, and the second derivative at should + # be nonnegative. + + x = get_coordinates(M, p, v) + x0 = 0.0 * x + x1 = 0.2 * x + x2 = 0.4 * x + x3 = 0.6 * x + x4 = 0.8 * x + x5 = 1.0 * x + + function curve_length(y::Vector{Float64}) + @assert(length(y) == 4 * n) + + # Control points + y1 = y[1:n] + y2 = y[n + 1:2 * n] + y3 = y[2 * n + 1:3 * n] + y4 = y[3 * n + 1:4 * n] + + # Bezier curve from 0 to v + b(t) = ( + (1 - t)^5 * x0 + + 5 * t * (1 - t)^4 * (x1 + y1) + + 10 * t^2 * (1 - t)^3 * (x2 + y2) + + 10 * t^3 * (1 - t)^2 * (x3 + y3) + + 5 * t^4 * (1 - t) * (x4 + y4) + + t^5 * x5 + ) + + # Length of curve on manifold + ps = [exp(M, p, get_vector(M, p, b(t))) for t in 0.0:1e-3:1.0] + ds = [distance(M, p1, p2) for (p1, p2) in zip(ps[1:end - 1], ps[2:end])] + return sum(ds) + end + + dy = rand(4 * n); dy = dy / norm(dy) + f = a -> curve_length(a * dy) + @test(isapprox(finite_difference(f, 0.0, 1e-3), 0.0; atol=1e-5)) + @test(finite_difference(f, 0.0, 1e-2; order=2) >= 0.0) + end; end + + @testset "log is inverse of exp." begin; for M in Ms + # TODO: This function can be written for a general manifold that implements injectivity_radius + p = rand(M) + + # Make sure we choose p and q compatible + m(a, b) = sqrt(sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, a[2:end], b[2:end])])) + q = rand(M) + A = get_warping_factor(M) + while A * m(p, q) > pi + q = rand(M) + end + + v = rand(M, vector_at=p); v = v / norm(M, p, v) + + @test(isapprox(norm(embed(M, q) - embed(M, exp(M, p, log(M, p, q)))), 0.0,; atol=1e-10)) + end; end + + @testset "get_coordinates is left and right inverse of get_vector. " begin; for M in Ms + p = rand(M) + v = rand(M, vector_at=p) + X = rand(manifold_dimension(M)) + + @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) + @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) + end; end + + @testset "sectional_curvature is compatible with riemann_tensor." begin; for M in Ms + p = rand(M) + v = rand(M, vector_at=p) + u = rand(M, vector_at=p) + + @test(isapprox( + sectional_curvature(u, v), + inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) + )) + end; end + + @testset "Sectional curvature is difference between circumference and 2 pi r for small circles" begin; for M in Ms + p = rand(M) + p[1][1] = p[1][1] + 0.1 # Keep away from 0.0 + + u = rand(M, vector_at=p); u = u / norm(M, p, u) + v = rand(M, vector_at=p) + v = v - inner(M, p, u, v) * u + v = v / norm(M, p, v) + + r = 1e-2 + ps = [exp(M, p, r * (cos(theta) * u + sin(theta) * v)) for theta in 0.0:1e-3:(2 * pi)] + ds = [distance(M, p1, p2) for (p1, p2) in zip(ps, [ps[2:end]..., ps[1]])] + C = sum(ds) + K = 3 * (2 * pi * r - C) / (pi * r^3) # https://en.wikipedia.org/wiki/Bertrand%E2%80%93Diguet%E2%80%93Puiseux_theorem + + @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) + end; end + + # TODO: Test that distance and inner are compatible + # TODO: Test second_fundamental_form +end From 9139574bf07ce13e6526870585aecbc4b62e2e4f Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Fri, 4 Oct 2024 15:45:12 +0200 Subject: [PATCH 02/35] added formulas to Segre manifold documentation --- src/manifolds/Segre.jl | 429 +++++++++++++++++------------------ src/manifolds/SegreWarped.jl | 283 +++++++++++++---------- 2 files changed, 370 insertions(+), 342 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index a7a8dd7a67..01ea67ddf4 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -1,27 +1,31 @@ @doc raw""" - Seg(𝔽^n1 x ... x 𝔽^nd) -is the space of rank-one tensors in 𝔽^n1 βŠ— ... βŠ— 𝔽^nd. +````math + \mathcal{S} = \operatorname{Seg}(𝔽^{n_1} \times \dots \times 𝔽^{n_d}) +```` +is the space of rank-one tensors in ``𝔽^{n_1} \otimes \dots \otimes 𝔽^{n_d}``. -When 𝔽 = ℝ, - Seg(ℝ^n1 x ... x ℝ^nd) ~ ℝ^+ x S^(n1 - 1) x ... x S^(nd - 1) -is a local diffeomorphism. The geometry of this manifold is computed in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). -""" -abstract type AbstractSegre{𝔽} <: AbstractManifold{𝔽} end -struct Segre{V, 𝔽} <: AbstractSegre{𝔽} end +When ``𝔽 = ℝ``, the Segre manifold is represented as +````math + \mathcal{S} \sim ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}. +```` +This is a local diffeomorphism, and the manifold is a locally a [warped product](https://en.wikipedia.org/wiki/Warped_product) of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. The tuple ``(n_1, \dots, n_d)`` is called the _valence_ of the manifold. + +The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). + +# Constructor + Segre(valence::NTuple{V, Int}; field::AbstractNumbers=ℝ) +Generate a valence `V` Segre manifold. """ +struct Segre{V, 𝔽} <: AbstractManifold{𝔽} end + function Segre( - valence::NTuple{D, Int}; + valence::NTuple{V, Int}; field::AbstractNumbers=ℝ, - ) -""" -function Segre(#={{{=# - valence::NTuple{D, Int}; - field::AbstractNumbers=ℝ, - ) where {D} + ) where {V} return Segre{valence, field}() -end#=}}}=# +end valence(::Segre{V, 𝔽}) where {V, 𝔽} = V ndims(::Segre{V, 𝔽}) where {V, 𝔽} = length(V) @@ -83,15 +87,15 @@ function check_size(#={{{=# end#=}}}=# """ - check_point(M::Segre{V, 𝔽}, p; kwargs...) + check_point(M::Segre{V, ℝ}, p; kwargs...) Check whether `p` is a valid point on `M`, i.e. `p[1]` is a singleton containing a positive number and `p[i + 1]` is a point on `Sphere(V[i])`. The tolerance can be set using the `kwargs...`. """ function check_point(#={{{=# - M::Segre{V, 𝔽}, + M::Segre{V, ℝ}, p; kwargs... - ) where {V, 𝔽} + ) where {V} if p[1][1] <= 0.0 return DomainError( @@ -101,7 +105,7 @@ function check_point(#={{{=# end for (x, n) in zip(p[2:end], V) - e = check_point(Sphere(n - 1)::AbstractSphere{𝔽}, x; rtol=1e-10, atol=1e-10, kwargs...) + e = check_point(Sphere(n - 1)::AbstractSphere, x; rtol=1e-10, atol=1e-10, kwargs...) if !isnothing(e); return e; end end @@ -109,28 +113,23 @@ function check_point(#={{{=# end#=}}}=# """ - function check_vector( - M::Segre{V, 𝔽}, - p, - v, - kwargs... - ) + function check_vector(M::Segre{V, ℝ}, p, v, kwargs...) Check whether `v` is a tangent vector to `p` on `M`, i.e. after `check_point(M, p)`, `v` has to be of same dimension as `p` and orthogonal to `p`. The tolerance can be set using the `kwargs...`. """ function check_vector(#={{{=# - M::Segre{V, 𝔽}, + M::Segre{V, ℝ}, p, v, kwargs... - ) where {V, 𝔽} + ) where {V} e = check_point(M, p, kwargs...) if !isnothing(e); return e; end for (x, xdot, n) in zip(p[2:end], v[2:end], V) # check_vector(::AbstractSphere, ...) uses isapprox to compare the dot product to 0, which by default sets atol=0 - e = check_vector(Sphere(n - 1)::AbstractSphere{𝔽}, x, xdot; rtol=1e-10, atol=1e-10, kwargs...) + e = check_vector(Sphere(n - 1)::AbstractSphere, x, xdot; rtol=1e-10, atol=1e-10, kwargs...) if !isnothing(e); return e; end end @@ -138,12 +137,7 @@ function check_vector(#={{{=# end#=}}}=# """ - function get_coordinates( - M::Segre{V, 𝔽}, - p, - v; - kwargs... - ) + function get_coordinates(M::Segre{V, 𝔽}, p, v; kwargs...) """ function get_coordinates(#={{{=# M::Segre{V, 𝔽}, @@ -161,12 +155,7 @@ function get_coordinates(#={{{=# end#=}}}=# """ - function get_vector( - M::Segre{V, 𝔽}, - p, - X; - kwargs... - ) + function get_vector( M::Segre{V, 𝔽}, p, X; kwargs...) """ function get_vector(#={{{=# M::Segre{V, 𝔽}, @@ -192,15 +181,14 @@ function get_vector(#={{{=# return v end#=}}}=# -""" - function inner( - M::Segre{V, ℝ}, - p, - u, - v, - ) +@doc raw""" + function inner(M::Segre{V, ℝ}, p, u, v,) -Inner product between two tangent vectors `u` and `v` at `p`. This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric. +Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v = (\xi, v_1, \dots, v_d)`` at ``p = (\lambda, x_1, \dots, x_d``. This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric: +````math + \langle u, v \rangle_{p} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle_{x_1} + \dots + \langle u_d, v_d \rangle_{x_d}), +```` +where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ function inner(#={{{=# M::Segre{V, ℝ}, @@ -216,14 +204,10 @@ function inner(#={{{=# return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) end#=}}}=# -""" - function norm( - M::Segre{V, 𝔽}, - p, - v, - ) +@doc raw""" + function norm(M::Segre{V, 𝔽}, p, v) -Norm of tangent vector `v` at `p`. +Norm of tangent vector ``v`` at ``p``. """ function norm(#={{{=# M::Segre{V, 𝔽}, @@ -238,10 +222,7 @@ function norm(#={{{=# end#=}}}=# """ - function rand( - M::Segre{V, ℝ}; - vector_at=nothing, - ) + function rand(M::Segre{V, ℝ}; vector_at=nothing) """ function rand(#={{{=# M::Segre{V, ℝ}; @@ -261,13 +242,13 @@ function rand(#={{{=# end end#=}}}=# -""" - function embed( - M::Segre{V, 𝔽}, - v, - ) +@doc raw""" + function embed(M::Segre{V, 𝔽}, v) -Embed `p ∈ Segre((n1, ..., nd), 𝔽)` in `𝔽^{n1 x ... x nd}` +Embed ``p = (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: +````math + (\lambda, x_1, \dots, x_d) \mapsto \lambda x_1 \otimes \dots \otimes x_d. +```` """ function embed(#={{{=# M::Segre{V, 𝔽}, @@ -279,14 +260,13 @@ function embed(#={{{=# return kronecker(p...)[:] end#=}}}=# -""" - function embed_vector( - M::Segre{V, 𝔽}, - p, - v, - ) +@doc raw""" + function embed_vector(M::Segre{V, 𝔽}, p, v) -Embed `v ∈ T_p Segre((n1, ..., nd), 𝔽)` in `𝔽^{n1 x ... x nd}` +Embed tangent vector ``v = (\nu, u_1, \dots, u_d)`` at ``p = (\lambda, x_1, \dots, x_d`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: +````math + (\nu, u_1, \dots, u_d) \mapsto \nu x_1 \otimes \dots \otimes x_d + \lambda u_1 \otimes x_2 \otimes \dots \otimes x_d + \dots + \lambda x_1 \otimes \dots \otimes x_{d - 1} \otimes u_d. +```` """ function embed_vector(#={{{=# M::Segre{V, 𝔽}, @@ -309,15 +289,105 @@ function embed_vector(#={{{=# ]) end#=}}}=# +@doc raw""" + function m(M::Segre{V, ℝ}, p, q) +When ``p``, ``q \in ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}``, this is the distance between the ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` parts of ``p`` and ``q``. """ - function exp( - M::Segre{V, ℝ}, - p, - v, - ) +function m(#={{{=# + M::Segre{V, ℝ}, + p, + q + ) where {V} + + return sqrt(sum([ + distance(Sphere(n - 1), x, y)^2 + for (n, x, y) in zip(V, a[2:end], b[2:end]) + ])) +end#=}}}=# + +""" + function compatible(M::Segre{V, ℝ}, p, q) + +Check if two representations, `p` and `q`, are compatible. To check if two points are compatible, compose with `closest_representation`. +""" +function compatible(#={{{=# + M::Segre{V, ℝ}, + p, + q + ) where {V} + + return m(p, q) < pi +end#=}}}=# + +""" + function closest_representation(M::Segre{V, ℝ}, p, q) + +Find the representation of `q` that is closest to `p`. +""" +function closest_representation(#={{{=# + M::Segre{V, ℝ}, + p, + q + ) where {V} + + # Find closest representation by flipping an even number of signs. + ds = [distance(Sphere(n - 1), x, y) for (n, x, y) in zip(V, p[2:end], q[2:end])] + flips = [false, (ds .> (pi / 2))...] + nbr_flips = sum(flips) + + # This code is pretty ugly. + if isodd(nbr_flips) + if nbr_flips == length(V) + flips[argmin(ds) + 1] = false + else + is = sortperm(ds; rev=true) + + flips1 = deepcopy(flips) + flips1[is[nbr_flips] + 1] = false + q1 = deepcopy(q) + q1[flips1] = -q1[flips1] -Exponential map on Segre manifold. Theorem 1.1 in Swijsen 2021. + flips2 = deepcopy(flips) + flips2[is[nbr_flips + 1] + 1] = true + q2 = deepcopy(q) + q2[flips2] = -q2[flips2] + + m(p, q1) < m(p, q2) ? flips = flips1 : flips = flips2 + end + end + + q_ = deepcopy(q) + q_[flips] = -q[flips] + @assert(iseven(sum(flips))) # Should not be necessary but you never know... + + return q_ +end#=}}}=# + +@doc raw""" + function exp(M::Segre{V, ℝ}, p, v) + +Exponential map on the Segre manifold. + +Let ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``v = (\nu, u_1, \dots, u_d) \in T_p \mathcal{S}``. +Then +````math + \operatorname{exp}_p(v) = + \left( + \sqrt{t^2 + 2 \lambda \nu t + \lambda^2}, + x_1 \cos(\norm{u_1}_{T_{x_1} S^{n_1}} g(t) / M) + u_1 \sin(\norm{u_1}_{T_{x_1} S^{n_1}} g(t) / M), + \dots, + x_d \cos(\norm{u_d}_{T_{x_d} S^{n_d}} g(t) / M) + u_d \sin(\norm{u_d}_{T_{x_d} S^{n_d}} g(t) / M) + \right), +```` +where ``t = \norm{v}_{T_p \mathcal{S}}``, ``M = \sqrt{\norm{u_1}_{T_{x_1} S^{n_1}}^2 + \dots + \norm{u_d}_{T_{x_d} S^{n_d}}^2}``, and +````math + g(t) = \tan^{-1}(t \sqrt{P^2 + 1} / \lambda + P) - \tan^{-1}(P),\\ + P = \nu / (\lambda M). +```` +If ``M = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. + +For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ function exp(#={{{=# M::Segre{V, ℝ}, @@ -334,32 +404,22 @@ function exp(#={{{=# return q end#=}}}=# -""" - function exp!( - M::Segre{V, ℝ}, - q, - p, - v, - ) - -Exponential map on Segre manifold. Theorem 1.1 in Swijsen 2021. -""" function exp!(#={{{=# M::Segre{V, ℝ}, q, p, v, ) where {V} + m_ = m(p, q) - m = sqrt(sum([norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end])])) - if m == 0.0 + if m_ == 0.0 q .= deepcopy(p) # Initialize q[1] .= q[1] .+ v[1] return q end t = norm(M, p, v) - P = v[1][1] / (p[1][1] * m) + P = v[1][1] / (p[1][1] * m_) f = atan(sqrt(P^2 + 1.0) * t / p[1][1] + P) - atan(P) q[1][1] = sqrt( @@ -374,23 +434,34 @@ function exp!(#={{{=# else a = norm(Sphere(n - 1), x, xdot) y .= - x * cos(a * f / m) .+ - xdot * sin(a * f / m) / a + x * cos(a * f / m_) .+ + xdot * sin(a * f / m_) / a end end return 0 end#=}}}=# -# Theorem 6.2.1 in thesisLarsSwijsen -""" - function log( - M::Segre{V, ℝ}, - p, - q, - ) - -Logarithmic map on Segre manifold. +@doc raw""" + function log(M::Segre{V, ℝ}, p, q) + +Logarithmic map on the Segre manifold. + +Let ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``q = (\mu, y_1, \dots, y_d) \in T_p \mathcal{S}``. +Also, assume ``p`` and ``q`` are connected by a minimizing geodesic. +Then +````math + \operatorname{log}_p(q) = + c \left( + \frac{\lambda M (\operatorname{cos}(M) - \lambda / \mu)}{\operatorname{sin}(M)}, + a_1 (y_1 - \langle x_1, y_1 \rangle_{ℝ^{n_1 + 1}} x_1) / \operatorname{sin}(a_1), + \dots, + a_d (y_d - \langle x_d, y_d \rangle_{ℝ^{n_d + 1}} x_d) / \operatorname{sin}(a_d) + \right), +```` +where ``a_i`` is the distance on ``S^{n_i - 1}`` from ``x_i`` to ``y_i``, ``M = \sqrt{a_1^2 + \dots + a_d^2}``, and ``c`` is determined by ``\norm{\operatorname{log}_p(q)}_{T_p \mathcal{S}} = \operatorname{dist}(p, q)``. + +For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ function log(#={{{=# M::Segre{V, ℝ}, @@ -401,63 +472,15 @@ function log(#={{{=# @assert(is_point(M, p)) @assert(is_point(M, q)) - # Check for compatability - m(a, b) = sqrt(sum([ - distance(Sphere(n - 1), x, y)^2 - for (n, x, y) in zip(V, a[2:end], b[2:end]) - ])) - if m(p, q) < pi # Even if there are closer representations, we prioritize log being continuous - v = zeros.(size.(p)) # Initialize - log!(M, v, p, q) - else - # Find closest representation by flipping an even number of signs. - ds = [distance(Sphere(n - 1), x, y) for (n, x, y) in zip(V, p[2:end], q[2:end])] - flips = [false, (ds .> (pi / 2))...] - nbr_flips = sum(flips) - - # This code is pretty ugly. - if isodd(nbr_flips) - if nbr_flips == length(V) - flips[argmin(ds) + 1] = false - else - is = sortperm(ds; rev=true) - - flips1 = deepcopy(flips) - flips1[is[nbr_flips] + 1] = false - q1 = deepcopy(q) - q1[flips1] = -q1[flips1] - - flips2 = deepcopy(flips) - flips2[is[nbr_flips + 1] + 1] = true - q2 = deepcopy(q) - q2[flips2] = -q2[flips2] - - m(p, q1) < m(p, q2) ? flips = flips1 : flips = flips2 - end - end - - q_ = deepcopy(q) - q_[flips] = -q[flips] - @assert(iseven(sum(flips))) # Should not be necessary but you never know... - @assert(m(p, q_) < pi) + q_ = closest_representation(M, p, q) + @assert(compatible(M, p, q_)) - v = zeros.(size.(p)) # Initialize - log!(M, v, p, q_) - end + v = zeros.(size.(p)) # Initialize + log!(M, v, p, q_) return v end#=}}}=# -""" - function log!( - M::Segre{V, ℝ}, - v, - p, - q - ) - -Logarithmic map on Segre manifold. -""" function log!(#={{{=# M::Segre{V, ℝ}, v, @@ -490,13 +513,16 @@ function log!(#={{{=# return 0 end#=}}}=# -""" - function distance( - M::Segre{V, ℝ}, - p, - q - ) +@doc raw""" + function distance(M::Segre{V, ℝ}, p, q) + Riemannian distance between two points `p` and `q` on the Segre manifold. + +Assume ``p = (\lambda, x_1, \dots, x_d)``, ``q = (\mu, y_1, \dots, y_d) \in \mathcal{S}`` are connected by a minimizing geodesic. Then +````math + \operatorname{dist}_{\mathcal{S}}(p, q) = \sqrt{\lambda^2 - 2 \lambda \mu \cos(M) + \mu^2}, +```` +where ``M = \sqrt{\operatorname{dist}_{S^{n_1}}(x_1, y_1)^2 + \dots + \operatorname{dist}_{S^{n_d}}(x_d, y_d)^2}``. """ function distance(#={{{=# M::Segre{V, ℝ}, @@ -506,62 +532,24 @@ function distance(#={{{=# @assert(is_point(M, p)) @assert(is_point(M, q)) + q_ = closest_representation(M, p, q) + @assert(compatible(M, p, q_)) - m = sqrt(sum([ - distance(Sphere(n - 1), x, y)^2 - for (n, x, y) in zip(V, p[2:end], q[2:end]) - ])) - - return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m / 2)^2) + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m(p, q_) / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(m)) but more stable for small m end#=}}}=# -""" - function second_fundamental_form( - M::Segre{V, ℝ}, - p, - u, - v, - ) - -Second fundamental form of the Segre manifold embedded in `ℝ^{n1 x ... x nd}`. -""" -function second_fundamental_form(#={{{=# - M::Segre{V, ℝ}, - p, - u, - v, - ) where {V} - - @assert(is_point(M, p)) - @assert(is_vector(M, p, u)) - @assert(is_vector(M, p, v)) - - # TODO: Review this - h = 0 * embed(M, p) # Initialize - for i in 1:length(V) - for j in 1:length(V) - if i != j - p_ = 1 * p - p_[i + 1] = u[i + 1] - p_[j + 1] = v[j + 1] - h = h + kron(p_...)[:, 1] - end - end - end - - return h -end#=}}}=# - -""" - function riemann_tensor( - M::Segre{V, ℝ}, - p, - u, - v, - ) +@doc raw""" + function riemann_tensor(M::Segre{V, ℝ}, p, u, v, w) Riemann tensor of the Segre manifold at `p`. + +``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` +If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``u``, ``v``, ``w \in T_p (S^{n_1 - 1} \times \dots \times S^{n_d - 1}) \subset T_p \mathcal{S}`` then +````math + R_{\mathcal{S}}(u, v) w = R_{S^{n_1 - 1} \times \dots \times S^{n_d - 1}}(u, v) w + \lambda^{-2}(\langle u, w \rangle_p v - \langle v, w \rangle_p u). +```` +``R_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ function riemann_tensor(#={{{=# M::Segre{V, ℝ}, @@ -580,19 +568,20 @@ function riemann_tensor(#={{{=# v_ = deepcopy(v); v_[1][1] = 0.0 w_ = deepcopy(w); w_[1][1] = 0.0 - # return [[0.0], [riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end])]...] - (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) return [[0.0], [riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end])]...] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) end#=}}}=# -""" - function sectional_curvature( - M::Segre{V, ℝ}, - p, - u, - v - ) +@doc raw""" + function sectional_curvature(M::Segre{V, ℝ}, p, u, v) + +Sectional curvature of the Segre manifold at ``p``. -Sectional curvature of the Segre manifold in the plane spanned by tangent vectors `u` and `v` at `p`. +``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` +If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i - 1}``, and ``v_j \in T_{x_j} S^{n_j - 1}``, then +````math + K_{\mathcal{S}}(u_i, v_j) = -(1 - \delta_{i j}) \lambda^2. +```` +``K_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ function sectional_curvature(#={{{=# M::Segre{V, ℝ}, diff --git a/src/manifolds/SegreWarped.jl b/src/manifolds/SegreWarped.jl index 20ba1809c1..fb0e2bd80f 100644 --- a/src/manifolds/SegreWarped.jl +++ b/src/manifolds/SegreWarped.jl @@ -1,38 +1,28 @@ @doc raw""" - SegreWarpedMetric{A} <: AbstractMetric - -Is the alpha-warped metric on the Segre manifold, namely if - - p = (lambda, x1, ..., xd) ∈ Seg(ℝ^n1 x ... x ℝ^nd) ~ ℝ^+ x S^(n1 - 1) x ... x S^(nd - 1) -and - - u = (a, u1, ..., ud), v = (b, v1, ..., vd) ∈ T_p Seg(ℝ^n1 x ... x ℝ^nd) -then - - ⟨u, v⟩ := a * b + (alpha * lambda)^2 * (dot(u1, v1) + ... + dot(ud, vd)). - -Example: - - MetricManifold(Segre((2, 2, 3)), SegreWarpedMetric{1.5}()) - - -The geometry of this manifold is computed in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). + WarpedMetric{A} <: AbstractMetric + +is the warped metric on the Segre manifold ``\mathcal{S}``. We denote it ``\mathcal{S}_A``. It is a generalization of the metric +````math + \langle (\nu, u_1, \dots, u_d), (\xi, v_1, \dots, v_d) \rangle_{(\lambda, x_1, \dots, x_d)} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle + \dots + \langle u_d, v_d \rangle), +```` +on the Segre that is induced from its Euclidean embedding, to the metric +````math + \langle (\nu, u_1, \dots, u_d), (\xi, v_1, \dots, v_d) \rangle_{(\lambda, x_1, \dots, x_d)} = \nu \xi + (A \lambda)^2 (\langle u_1, v_1 \rangle + \dots + \langle u_d, v_d \rangle). +```` +``A`` is called the _warping factor_ and ``A = 1`` corresponds to the usual Segre manifold. + +The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -struct SegreWarpedMetric{A} <: AbstractMetric end +struct WarpedMetric{A} <: AbstractMetric end -valence(::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}) where {V, A, 𝔽} = V -ndims(::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}) where {V, A, 𝔽} = length(V) +valence(::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}) where {V, A, 𝔽} = V +ndims(::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}) where {V, A, 𝔽} = length(V) """ - function get_coordinates( - M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, - p, - v; - kwargs... - ) + function get_coordinates(M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, p, v; kwargs...) """ function get_coordinates(#={{{=# - M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, + M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, p, v; kwargs... @@ -42,15 +32,10 @@ function get_coordinates(#={{{=# end#=}}}=# """ - function get_vector( - M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, - p, - X; - kwargs... - ) + function get_vector(M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, p, X; kwargs...) """ function get_vector(#={{{=# - M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, + M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, p, X; kwargs... @@ -59,18 +44,17 @@ function get_vector(#={{{=# return get_vector(M.manifold, p, X; kwargs...) end#=}}}=# -""" - function inner( - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, - p, - u, - v, - ) +@doc raw""" + function inner( M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, u, v) -Inner product between two tangent vectors `u` and `v` at `p`. +Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v = (\xi, v_1, \dots, v_d)`` at ``p = (\lambda, x_1, \dots, x_d``: +````math + \langle u, v \rangle_{p} = \nu \xi + (A \lambda)^2 (\langle u_1, v_1 \rangle_{x_1} + \dots + \langle u_d, v_d \rangle_{x_d}), +```` +where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ function inner(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, u, v, @@ -83,17 +67,13 @@ function inner(#={{{=# return u[1][1] * v[1][1] + (A * p[1][1])^2 * dot(u[2:end], v[2:end]) end#=}}}=# -""" - function norm( - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, - p, - v, - ) +@doc raw""" + function norm(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, v) -Norm of tangent vector `v` at `p`. +Norm of tangent vector ``v`` at ``p``. """ function norm(#={{{=# - M::MetricManifold{𝔽, Segre{V, 𝔽}, SegreWarpedMetric{A}}, + M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, p, v, ) where {V, A, 𝔽} @@ -104,17 +84,78 @@ function norm(#={{{=# return sqrt(inner(M, p, v, v)) end#=}}}=# +@doc raw""" + function m(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) + +When ``p``, ``q \in ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}``, this is the distance between the ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` parts of ``p`` and ``q``. """ - function exp( - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, - p, - v, - ) +function m(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, + p, + q + ) where {V} + + return sqrt(sum([ + distance(Sphere(n - 1), x, y)^2 + for (n, x, y) in zip(V, a[2:end], b[2:end]) + ])) +end#=}}}=# + +""" + function compatible(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) -Exponential map on Segre manifold. TODO: cite upcoming preprint. +Check if two representations, `p` and `q`, are compatible. To check if two points are compatible, compose with `closest_representation`. +""" +function compatible(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, + p, + q + ) where {V, A} + + return A * m(p, q) < pi +end#=}}}=# + +""" + function closest_representation(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) + +Find the representation of ``q`` that is closest to ``p``. +""" +function closest_representation(#={{{=# + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, + p, + q + ) where {V} + + return closest_representation(M.manifold, p ,q) +end#=}}}=# + +@doc raw""" + function exp(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, v) + +Exponential map on the warped Segre manifold. + +Let ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``v = (\nu, u_1, \dots, u_d) \in T_p \mathcal{S}_A``. +Then +````math + \operatorname{exp}_p(v) = + \left( + \sqrt{t^2 + 2 \lambda \nu t + \lambda^2}, + x_1 \cos(\norm{u_1}_{T_{x_1} S^{n_1}} g(t) / (A M)) + u_1 \sin(\norm{u_1}_{T_{x_1} S^{n_1}} g(t) / (A M)), + \dots, + x_d \cos(\norm{u_d}_{T_{x_d} S^{n_d}} g(t) / (A M)) + u_d \sin(\norm{u_d}_{T_{x_d} S^{n_d}} g(t) / (A M)) + \right), +```` +where ``t = \norm{v}_{T_p \mathcal{S}_A}``, ``M = \sqrt{\norm{u_1}_{T_{x_1} S^{n_1}}^2 + \dots + \norm{u_d}_{T_{x_d} S^{n_d}}^2}``, and +````math + g(t) = \tan^{-1}(t \sqrt{P^2 + 1} / \lambda + P) - \tan^{-1}(P),\\ + P = \nu / (\lambda A M). +```` +If ``M = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. + +For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ function exp(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, v, ) where {V, A} @@ -128,32 +169,22 @@ function exp(#={{{=# return q end#=}}}=# -""" - function exp!( - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, - q, - p, - v, - ) - -Exponential map on Segre manifold. TODO: cite prop 4.1 in upcoming preprint -""" function exp!(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, q, p, v, ) where {V, A} - m = sqrt(sum([norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end])])) - if m == 0.0 + m_ = m(p, q) + if m_ == 0.0 q .= deepcopy(p) # Initialize q[1] .= q[1] .+ v[1] return q end t = norm(M, p, v) - P = v[1][1] / (p[1][1] * A * m) + P = v[1][1] / (p[1][1] * A * m_) f = atan(sqrt(P^2 + 1.0) * t / p[1][1] + P) - atan(P) q[1][1] = sqrt( @@ -168,26 +199,37 @@ function exp!(#={{{=# else a = norm(Sphere(n - 1), x, xdot) y .= - x * cos(a * f / (A * m)) .+ - xdot * sin(a * f / (A * m)) / a + x * cos(a * f / (A * m_)) .+ + xdot * sin(a * f / (A * m_)) / a end end return 0 end#=}}}=# -""" - function log( - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, - p, - q, - ) - -Logarithmic map on Segre manifold. -TODO: cite theorem 5.1 in upcoming preprint +@doc raw""" + function log(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) + +Logarithmic map on the warped Segre manifold. + +Let ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``q = (\mu, y_1, \dots, y_d) \in T_p \mathcal{S}_A``. +Also, assume ``p`` and ``q`` are connected by a minimizing geodesic. +Then +````math + \operatorname{log}_p(q) = + c \left( + \frac{\lambda A M (\cos(A M) - \lambda / \mu)}{\sin(A M)}, + a_1 (y_1 - \langle x_1, y_1 \rangle_{ℝ^{n_1 + 1}} x_1) / \sin(a_1), + \dots, + a_d (y_d - \langle x_d, y_d \rangle_{ℝ^{n_d + 1}} x_d) / \sin(a_d) + \right), +```` +where ``a_i`` is the distance on ``S^{n_i - 1}`` from ``x_i`` to ``y_i``, ``M = \sqrt{a_1^2 + \dots + a_d^2}``, and ``c`` is determined by ``\norm{\operatorname{log}_p(q)}_{T_p \mathcal{S}_A} = \operatorname{dist}(p, q)``. + +For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ function log(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q, ) where {V, A} @@ -239,18 +281,8 @@ function log(#={{{=# return v end#=}}}=# -""" - function log!( - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, - v, - p, - q - ) - -Logarithmic map on Segre manifold. -""" function log!(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, v, p, q @@ -281,16 +313,19 @@ function log!(#={{{=# return 0 end#=}}}=# -""" - function distance( - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, - p, - q, - ) -Riemannian distance between two points `p` and `q` on the Segre manifold. +@doc raw""" + function distance(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) + +Riemannian distance between two points `p` and `q` on the warped Segre manifold. + +Assume ``p = (\lambda, x_1, \dots, x_d)``, ``q = (\mu, y_1, \dots, y_d) \in \mathcal{S}_A`` are connected by a minimizing geodesic. Then +````math + \operatorname{dist}_{\operatorname{Seg}(ℝ^{n_1} \times \dots \times ℝ^{n_d})}(p, q) = \sqrt{\lambda^2 - 2 \lambda \mu \cos(A M) + \mu^2}, +```` +where ``M = \sqrt{\operatorname{dist}_{S^{n_1}}(x_1, y_1)^2 + \dots + \operatorname{dist}_{S^{n_d}}(x_d, y_d)^2}``. """ function distance(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q, ) where {V, A} @@ -307,18 +342,20 @@ function distance(#={{{=# # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(A * m)) but more stable for small m end#=}}}=# -""" - function riemann_tensor( - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, - p, - u, - v - ) +@doc raw""" + function riemann_tensor(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, u, v) + +Riemann tensor of the warped Segre manifold at ``p``. -Riemann tensor of the Segre manifold at `p`. +``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` +If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``u``, ``v``, ``w \in T_{(x_1, \dots, x_d)} (S^{n_1 - 1} \times \dots \times S^{n_d - 1}) \subset T_p \mathcal{S}_A`` then +````math + R_{\mathcal{S}_A}(u, v) w = R_{S^{n_1 - 1} \times \dots \times S^{n_d - 1}}(u, v) w + \lambda^{-2}(\langle u, w \rangle_{p} v - \langle v, w \rangle_{p} u). +```` +``R_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ function riemann_tensor(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, u, v, @@ -337,18 +374,20 @@ function riemann_tensor(#={{{=# return [[0.0], [riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end])]...] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) end#=}}}=# -""" - function sectional_curvature( - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, - p, - u, - v - ) +@doc raw""" + function sectional_curvature(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, u, v) + +Sectional curvature of the warped Segre manifold at ``p``. -Sectional curvature of the Segre manifold in the plane spanned by tangent vectors `u` and `v` at `p`. +``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` +If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i - 1}``, and ``v_j \in T_{x_j} S^{n_j - 1}``, then +````math + K_{\mathcal{S}}(u_i, v_j) = -(1 - \delta_{i j}) \lambda^2. +```` +``K_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ function sectional_curvature(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, SegreWarpedMetric{A}}, + M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, u, v From fd384fb2598ad4bdf208b394c9a847c8343e8f1d Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Sun, 6 Oct 2024 14:02:39 +0200 Subject: [PATCH 03/35] Setup docs, fix a few type errors, runs formatter. --- NEWS.md | 8 +- docs/make.jl | 1 + docs/src/manifolds/segre.md | 31 +++ src/Manifolds.jl | 2 +- src/manifolds/Segre.jl | 357 +++++++++++++--------------------- src/manifolds/SegreWarped.jl | 261 ++++++++----------------- test/manifolds/segre.jl | 367 ++++++++++++++++++++--------------- test/runtests.jl | 1 + 8 files changed, 467 insertions(+), 561 deletions(-) create mode 100644 docs/src/manifolds/segre.md diff --git a/NEWS.md b/NEWS.md index 95c19c0631..21740fd8a2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,12 @@ 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.4] - unreleased + +### Added + +* The Segre manifold including its warped metric + ## [0.10.3] - 2024-10-04 ### Changed @@ -14,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed * Fixed `solve_exp_ode` only returning the starting position ([#744](https://github.com/JuliaManifolds/Manifolds.jl/issues/744)) -* Fixed documentation of `solve_exp_ode` function signature ([#740](https://github.com/JuliaManifolds/Manifolds.jl/issues/740)) +* Fixed documentation of `solve_exp_ode` function signature ([#740](https://github.com/JuliaManifolds/Manifolds.jl/issues/740)) ## [0.10.2] - 2024-09-24 diff --git a/docs/make.jl b/docs/make.jl index 8807884d80..4c819e03a8 100755 --- a/docs/make.jl +++ b/docs/make.jl @@ -140,6 +140,7 @@ makedocs(; "Projective space" => "manifolds/projectivespace.md", "Orthogonal and Unitary Matrices" => "manifolds/generalunitary.md", "Rotations" => "manifolds/rotations.md", + "Segre-Veronese" => "manifolds/segre.md", "Shape spaces" => "manifolds/shapespace.md", "Skew-Hermitian matrices" => "manifolds/skewhermitian.md", "Spectrahedron" => "manifolds/spectrahedron.md", diff --git a/docs/src/manifolds/segre.md b/docs/src/manifolds/segre.md new file mode 100644 index 0000000000..450600e666 --- /dev/null +++ b/docs/src/manifolds/segre.md @@ -0,0 +1,31 @@ +# The Segre-Veronese manifold + +```@docs +Segre +``` + +```@autodocs +Modules = [Manifolds] +Pages = ["manifolds/Segre.jl"] +Order = [:function] +``` + +## A warped metric + +```@docs +WarpedMetric +``` + +```@autodocs +Modules = [Manifolds] +Pages = ["manifolds/SegreWarped.jl"] +Order = [:function] +``` + + +## Literature + +```@bibliography +Pages = ["sphere.md"] +Canonical=false +``` \ No newline at end of file diff --git a/src/Manifolds.jl b/src/Manifolds.jl index b513c99b40..d1ed9dc782 100644 --- a/src/Manifolds.jl +++ b/src/Manifolds.jl @@ -771,7 +771,7 @@ export AbstractMetric, ProductMetric, RealSymplecticMetric, RiemannianMetric, - SegreWarpedMetric, + WarpedMetric, StiefelSubmersionMetric export AbstractAtlas, RetractionAtlas # Vector transport types diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 01ea67ddf4..69b96c62a8 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -17,30 +17,22 @@ The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024]( Generate a valence `V` Segre manifold. """ -struct Segre{V, 𝔽} <: AbstractManifold{𝔽} end +struct Segre{𝔽,V} <: AbstractManifold{𝔽} end -function Segre( - valence::NTuple{V, Int}; - field::AbstractNumbers=ℝ, - ) where {V} - - return Segre{valence, field}() +function Segre(valence::NTuple{V,Int}; field::AbstractNumbers=ℝ) where {V} + return Segre{valence,field}() end -valence(::Segre{V, 𝔽}) where {V, 𝔽} = V -ndims(::Segre{V, 𝔽}) where {V, 𝔽} = length(V) -manifold_dimension(::Segre{V, 𝔽}) where {V, 𝔽} = (1 + sum(V .- 1)) +valence(::Segre{𝔽,V}) where {𝔽,V} = V +ndims(::Segre{𝔽,V}) where {𝔽,V} = length(V) +manifold_dimension(::Segre{𝔽,V}) where {𝔽,V} = (1 + sum(V .- 1)) """ - check_size(M::Segre{V, 𝔽}, p) + check_size(M::Segre{𝔽, V}, p) Check whether `p` has the right size for `Segre` manifold `M`. """ -function check_size(#={{{=# - M::Segre{V, 𝔽}, - p; - ) where {V, 𝔽} - +function check_size(M::Segre{𝔽,V}, p;) where {𝔽,V} p_size = only.(size.(p)) M_size = [1, V...] @@ -48,23 +40,18 @@ function check_size(#={{{=# return DomainError( p_size, "The point $(p) can not belong to the manifold $(M), since its size $(p_size) is not equal to the manifolds representation size ($(M_size)).", - ) + ) end return nothing -end#=}}}=# +end """ - check_size(M::Segre{V, 𝔽}, p, v) + check_size(M::Segre{𝔽, V}, p, v) Check whether `p` and `v` have the right size for `Segre` manifold `M`. """ -function check_size(#={{{=# - M::Segre{V, 𝔽}, - p, - v; - ) where {V, 𝔽} - +function check_size(M::Segre{𝔽,V}, p, v;) where {𝔽,V} p_size = only.(size.(p)) v_size = only.(size.(v)) M_size = [1, V...] @@ -73,97 +60,89 @@ function check_size(#={{{=# return DomainError( p_size, "The point $(p) can not belong to the manifold $(M), since its size $(p_size) is not equal to the manifolds representation size ($(M_size)).", - ) + ) end if v_size != M_size return DomainError( v_size, "The vector $(v) can not belong to the manifold $(M), since its size $(v_size) is not equal to the manifolds representation size ($(M_size)).", - ) + ) end return nothing -end#=}}}=# +end """ - check_point(M::Segre{V, ℝ}, p; kwargs...) + check_point(M::Segre{ℝ, V}, p; kwargs...) Check whether `p` is a valid point on `M`, i.e. `p[1]` is a singleton containing a positive number and `p[i + 1]` is a point on `Sphere(V[i])`. The tolerance can be set using the `kwargs...`. """ -function check_point(#={{{=# - M::Segre{V, ℝ}, - p; - kwargs... - ) where {V} - +function check_point({ℝ, V}M::Segre{ℝ,V}, p; kwargs...) where {V} if p[1][1] <= 0.0 - return DomainError( - p[1][1], - "$(p) has non-positive modulus." - ) + return DomainError(p[1][1], "$(p) has non-positive modulus.") end for (x, n) in zip(p[2:end], V) e = check_point(Sphere(n - 1)::AbstractSphere, x; rtol=1e-10, atol=1e-10, kwargs...) - if !isnothing(e); return e; end + if !isnothing(e) + return e + end end - + return nothing -end#=}}}=# +end """ - function check_vector(M::Segre{V, ℝ}, p, v, kwargs...) + function check_vector(M::Segre{ℝ, V}, p, v, kwargs...) Check whether `v` is a tangent vector to `p` on `M`, i.e. after `check_point(M, p)`, `v` has to be of same dimension as `p` and orthogonal to `p`. The tolerance can be set using the `kwargs...`. """ -function check_vector(#={{{=# - M::Segre{V, ℝ}, - p, - v, - kwargs... - ) where {V} - +function check_vector(M::Segre{ℝ,V}, p, v, kwargs...) where {V} e = check_point(M, p, kwargs...) - if !isnothing(e); return e; end + if !isnothing(e) + return e + end for (x, xdot, n) in zip(p[2:end], v[2:end], V) # check_vector(::AbstractSphere, ...) uses isapprox to compare the dot product to 0, which by default sets atol=0 - e = check_vector(Sphere(n - 1)::AbstractSphere, x, xdot; rtol=1e-10, atol=1e-10, kwargs...) - if !isnothing(e); return e; end + e = check_vector( + Sphere(n - 1)::AbstractSphere, + x, + xdot; + rtol=1e-10, + atol=1e-10, + kwargs..., + ) + if !isnothing(e) + return e + end end - + return nothing -end#=}}}=# +end """ - function get_coordinates(M::Segre{V, 𝔽}, p, v; kwargs...) + function get_coordinates(M::Segre{𝔽, V}, p, v; kwargs...) """ -function get_coordinates(#={{{=# - M::Segre{V, 𝔽}, - p, - v; - kwargs... - ) where {V, 𝔽} - +function get_coordinates(M::Segre{𝔽,V}, p, v; kwargs...) where {𝔽,V} @assert(is_point(M, p)) @assert(is_vector(M, p, v)) - coords = [v[1], [get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end])]...] + coords = [ + v[1], + [ + get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + ]..., + ] return vcat(coords...) -end#=}}}=# +end """ - function get_vector( M::Segre{V, 𝔽}, p, X; kwargs...) + function get_vector( M::Segre{𝔽, V}, p, X; kwargs...) """ -function get_vector(#={{{=# - M::Segre{V, 𝔽}, - p, - X; - kwargs... - ) where {V, 𝔽} - +function get_vector(M::Segre{𝔽,V}, p, X; kwargs...) where {𝔽,V} @assert(is_point(M, p)) X_ = deepcopy(X) @@ -171,7 +150,13 @@ function get_vector(#={{{=# v[1] = [X_[1]] X_ = drop(X_, 1) for (i, n) in enumerate(V) - v[i + 1] = get_vector(Sphere(n - 1), p[i + 1], take(X_, n - 1), DefaultOrthonormalBasis(); kwargs...) + v[i + 1] = get_vector( + Sphere(n - 1), + p[i + 1], + take(X_, n - 1), + DefaultOrthonormalBasis(); + kwargs..., + ) X_ = drop(X_, n - 1) end @@ -179,10 +164,10 @@ function get_vector(#={{{=# check_vector(M, p, v) return v -end#=}}}=# +end @doc raw""" - function inner(M::Segre{V, ℝ}, p, u, v,) + function inner(M::Segre{ℝ, V}, p, u, v,) Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v = (\xi, v_1, \dots, v_d)`` at ``p = (\lambda, x_1, \dots, x_d``. This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric: ````math @@ -190,45 +175,30 @@ Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v ```` where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ -function inner(#={{{=# - M::Segre{V, ℝ}, - p, - u, - v, - ) where {V} - +function inner(M::Segre{ℝ,V}, p, u, v) where {V} @assert(is_point(M, p)) @assert(is_vector(M, p, u)) @assert(is_vector(M, p, v)) return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) -end#=}}}=# +end @doc raw""" - function norm(M::Segre{V, 𝔽}, p, v) + function norm(M::Segre{𝔽, V}, p, v) Norm of tangent vector ``v`` at ``p``. """ -function norm(#={{{=# - M::Segre{V, 𝔽}, - p, - v, - ) where {V, 𝔽} - +function norm(M::Segre{𝔽,V}, p, v) where {𝔽,V} @assert(is_point(M, p)) @assert(is_vector(M, p, v)) return sqrt(inner(M, p, v, v)) -end#=}}}=# +end """ - function rand(M::Segre{V, ℝ}; vector_at=nothing) + function rand(M::Segre{ℝ, V}; vector_at=nothing) """ -function rand(#={{{=# - M::Segre{V, ℝ}; - vector_at=nothing, - ) where {V} - +function rand(M::Segre{ℝ,V}; vector_at=nothing) where {V} if isnothing(vector_at) lambda = abs.(rand(Euclidean(1))) xs = [rand(Sphere(n - 1)) for n in V] @@ -240,96 +210,67 @@ function rand(#={{{=# xdots = [rand(Sphere(n - 1); vector_at=vector_at[i + 1]) for (i, n) in enumerate(V)] return [lambdadot, xdots...] end -end#=}}}=# +end @doc raw""" - function embed(M::Segre{V, 𝔽}, v) + function embed(M::Segre{𝔽, V}, v) Embed ``p = (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: ````math (\lambda, x_1, \dots, x_d) \mapsto \lambda x_1 \otimes \dots \otimes x_d. ```` """ -function embed(#={{{=# - M::Segre{V, 𝔽}, - p, - ) where {V, 𝔽} - +function embed(M::Segre{𝔽,V}, p) where {𝔽,V} @assert(is_point(M, p)) return kronecker(p...)[:] -end#=}}}=# +end @doc raw""" - function embed_vector(M::Segre{V, 𝔽}, p, v) + function embed_vector(M::Segre{𝔽, V}, p, v) Embed tangent vector ``v = (\nu, u_1, \dots, u_d)`` at ``p = (\lambda, x_1, \dots, x_d`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: ````math (\nu, u_1, \dots, u_d) \mapsto \nu x_1 \otimes \dots \otimes x_d + \lambda u_1 \otimes x_2 \otimes \dots \otimes x_d + \dots + \lambda x_1 \otimes \dots \otimes x_{d - 1} \otimes u_d. ```` """ -function embed_vector(#={{{=# - M::Segre{V, 𝔽}, - p, - v, - ) where {V, 𝔽} - +function embed_vector(M::Segre{𝔽,V}, p, v) where {𝔽,V} @assert(is_point(M, p)) @assert(is_vector(M, p, v)) # Product rule return sum([ - kronecker([ - i == j ? - xdot : - x - for (j, (x, xdot)) in enumerate(zip(p, v)) - ]...)[:] - for (i, _) in enumerate(p) - ]) -end#=}}}=# + kronecker([i == j ? xdot : x for (j, (x, xdot)) in enumerate(zip(p, v))]...)[:] for + (i, _) in enumerate(p) + ]) +end @doc raw""" - function m(M::Segre{V, ℝ}, p, q) + function m(M::Segre{ℝ, V}, p, q) When ``p``, ``q \in ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}``, this is the distance between the ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` parts of ``p`` and ``q``. """ -function m(#={{{=# - M::Segre{V, ℝ}, - p, - q - ) where {V} - - return sqrt(sum([ - distance(Sphere(n - 1), x, y)^2 - for (n, x, y) in zip(V, a[2:end], b[2:end]) - ])) -end#=}}}=# +function m(M::Segre{ℝ,V}, p, q) where {V} + return sqrt( + sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, a[2:end], b[2:end])]), + ) +end """ - function compatible(M::Segre{V, ℝ}, p, q) + function compatible(M::Segre{ℝ, V}, p, q) Check if two representations, `p` and `q`, are compatible. To check if two points are compatible, compose with `closest_representation`. """ -function compatible(#={{{=# - M::Segre{V, ℝ}, - p, - q - ) where {V} - +function compatible(M::Segre{ℝ,V}, p, q) where {V} return m(p, q) < pi -end#=}}}=# +end """ - function closest_representation(M::Segre{V, ℝ}, p, q) + function closest_representation(M::Segre{ℝ, V}, p, q) Find the representation of `q` that is closest to `p`. """ -function closest_representation(#={{{=# - M::Segre{V, ℝ}, - p, - q - ) where {V} +function closest_representation(M::Segre{ℝ,V}, p, q) where {V} # Find closest representation by flipping an even number of signs. ds = [distance(Sphere(n - 1), x, y) for (n, x, y) in zip(V, p[2:end], q[2:end])] @@ -362,10 +303,10 @@ function closest_representation(#={{{=# @assert(iseven(sum(flips))) # Should not be necessary but you never know... return q_ -end#=}}}=# +end @doc raw""" - function exp(M::Segre{V, ℝ}, p, v) + function exp(M::Segre{ℝ, V}, p, v) Exponential map on the Segre manifold. @@ -389,12 +330,7 @@ If ``M = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -function exp(#={{{=# - M::Segre{V, ℝ}, - p, - v, - ) where {V} - +function exp(M::Segre{ℝ,V}, p, v) where {V} @assert(is_point(M, p)) @assert(is_vector(M, p, v)) @@ -402,14 +338,9 @@ function exp(#={{{=# exp!(M, q, p, v) return q -end#=}}}=# - -function exp!(#={{{=# - M::Segre{V, ℝ}, - q, - p, - v, - ) where {V} +end + +function exp!(M::Segre{ℝ,V}, q, p, v) where {V} m_ = m(p, q) if m_ == 0.0 @@ -423,27 +354,23 @@ function exp!(#={{{=# f = atan(sqrt(P^2 + 1.0) * t / p[1][1] + P) - atan(P) q[1][1] = sqrt( - t^2 + - 2 * p[1][1] * P * t / sqrt(P^2 + 1.0) + - p[1][1]^2 # This factor is wrong in Swijsen21 on arxiv - ) + t^2 + 2 * p[1][1] * P * t / sqrt(P^2 + 1.0) + p[1][1]^2, # This factor is wrong in Swijsen21 on arxiv + ) for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) if all(xdot .== 0.0) y .= deepcopy(x) else a = norm(Sphere(n - 1), x, xdot) - y .= - x * cos(a * f / m_) .+ - xdot * sin(a * f / m_) / a + y .= x * cos(a * f / m_) .+ xdot * sin(a * f / m_) / a end end return 0 -end#=}}}=# +end @doc raw""" - function log(M::Segre{V, ℝ}, p, q) + function log(M::Segre{ℝ, V}, p, q) Logarithmic map on the Segre manifold. @@ -463,12 +390,7 @@ where ``a_i`` is the distance on ``S^{n_i - 1}`` from ``x_i`` to ``y_i``, ``M = For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -function log(#={{{=# - M::Segre{V, ℝ}, - p, - q, - ) where {V} - +function log(M::Segre{ℝ,V}, p, q) where {V} @assert(is_point(M, p)) @assert(is_point(M, q)) @@ -479,15 +401,9 @@ function log(#={{{=# log!(M, v, p, q_) return v -end#=}}}=# - -function log!(#={{{=# - M::Segre{V, ℝ}, - v, - p, - q - ) where {V} +end +function log!(M::Segre{ℝ,V}, v, p, q) where {V} for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) a = distance(Sphere(n - 1), x, y) if a == 0.0 @@ -497,10 +413,9 @@ function log!(#={{{=# end end - m = sqrt(sum([ - distance(Sphere(n - 1), x, y)^2 - for (n, x, y) in zip(V, p[2:end], q[2:end]) - ])) + m = sqrt( + sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), + ) if m == 0.0 v[1][1] = q[1][1] - p[1][1] else @@ -511,10 +426,10 @@ function log!(#={{{=# end return 0 -end#=}}}=# +end @doc raw""" - function distance(M::Segre{V, ℝ}, p, q) + function distance(M::Segre{ℝ, V}, p, q) Riemannian distance between two points `p` and `q` on the Segre manifold. @@ -524,12 +439,7 @@ Assume ``p = (\lambda, x_1, \dots, x_d)``, ``q = (\mu, y_1, \dots, y_d) \in \mat ```` where ``M = \sqrt{\operatorname{dist}_{S^{n_1}}(x_1, y_1)^2 + \dots + \operatorname{dist}_{S^{n_d}}(x_d, y_d)^2}``. """ -function distance(#={{{=# - M::Segre{V, ℝ}, - p, - q - ) where {V} - +function distance(M::Segre{ℝ,V}, p, q) where {V} @assert(is_point(M, p)) @assert(is_point(M, q)) q_ = closest_representation(M, p, q) @@ -537,10 +447,10 @@ function distance(#={{{=# return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m(p, q_) / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(m)) but more stable for small m -end#=}}}=# +end @doc raw""" - function riemann_tensor(M::Segre{V, ℝ}, p, u, v, w) + function riemann_tensor(M::Segre{ℝ, V}, p, u, v, w) Riemann tensor of the Segre manifold at `p`. @@ -551,28 +461,30 @@ If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``u``, ``v``, ``w \in ```` ``R_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ -function riemann_tensor(#={{{=# - M::Segre{V, ℝ}, - p, - u, - v, - w, - ) where {V} - +function riemann_tensor(M::Segre{ℝ,V}, p, u, v, w) where {V} @assert(is_point(M, p)) @assert(is_vector(M, p, u)) @assert(is_vector(M, p, v)) @assert(is_vector(M, p, w)) - u_ = deepcopy(u); u_[1][1] = 0.0 - v_ = deepcopy(v); v_[1][1] = 0.0 - w_ = deepcopy(w); w_[1][1] = 0.0 - - return [[0.0], [riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end])]...] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) -end#=}}}=# + u_ = deepcopy(u) + u_[1][1] = 0.0 + v_ = deepcopy(v) + v_[1][1] = 0.0 + w_ = deepcopy(w) + w_[1][1] = 0.0 + + return [ + [0.0], + [ + riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for + (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end]) + ]..., + ] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) +end @doc raw""" - function sectional_curvature(M::Segre{V, ℝ}, p, u, v) + function sectional_curvature(M::Segre{ℝ, V}, p, u, v) Sectional curvature of the Segre manifold at ``p``. @@ -583,16 +495,11 @@ If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i ```` ``K_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ -function sectional_curvature(#={{{=# - M::Segre{V, ℝ}, - p, - u, - v - ) where {V} - +function sectional_curvature(M::Segre{ℝ,V}, p, u, v) where {V} @assert(is_point(M, p)) @assert(is_vector(M, p, u)) @assert(is_vector(M, p, v)) - return inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) -end#=}}}=# + return inner(M, p, riemann_tensor(M, p, u, v, v), u) / + (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) +end diff --git a/src/manifolds/SegreWarped.jl b/src/manifolds/SegreWarped.jl index fb0e2bd80f..9030121635 100644 --- a/src/manifolds/SegreWarped.jl +++ b/src/manifolds/SegreWarped.jl @@ -15,37 +15,35 @@ The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024]( """ struct WarpedMetric{A} <: AbstractMetric end -valence(::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}) where {V, A, 𝔽} = V -ndims(::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}) where {V, A, 𝔽} = length(V) +valence(::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}) where {V,A,𝔽} = V +ndims(::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}) where {V,A,𝔽} = length(V) """ - function get_coordinates(M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, p, v; kwargs...) + function get_coordinates(M::MetricManifold{𝔽, Segre{𝔽, V}, WarpedMetric{A}}, p, v; kwargs...) """ -function get_coordinates(#={{{=# - M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, +function get_coordinates( + M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, v; - kwargs... - ) where {V, A, 𝔽} - + kwargs..., +) where {V,A,𝔽} return get_coordinates(M.manifold, p, v; kwargs...) -end#=}}}=# +end """ - function get_vector(M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, p, X; kwargs...) + function get_vector(M::MetricManifold{𝔽, Segre{𝔽, V}, WarpedMetric{A}}, p, X; kwargs...) """ -function get_vector(#={{{=# - M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, +function get_vector( + M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, X; - kwargs... - ) where {V, A, 𝔽} - + kwargs..., +) where {V,A,𝔽} return get_vector(M.manifold, p, X; kwargs...) -end#=}}}=# +end @doc raw""" - function inner( M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, u, v) + function inner( M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, u, v) Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v = (\xi, v_1, \dots, v_d)`` at ``p = (\lambda, x_1, \dots, x_d``: ````math @@ -53,84 +51,50 @@ Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v ```` where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ -function inner(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - p, - u, - v, - ) where {V, A} - - @assert(is_point(M, p)) - @assert(is_vector(M, p, u)) - @assert(is_vector(M, p, v)) - +function inner(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, u, v) where {A} return u[1][1] * v[1][1] + (A * p[1][1])^2 * dot(u[2:end], v[2:end]) -end#=}}}=# +end @doc raw""" - function norm(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, v) + function norm(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, v) Norm of tangent vector ``v`` at ``p``. """ -function norm(#={{{=# - M::MetricManifold{𝔽, Segre{V, 𝔽}, WarpedMetric{A}}, - p, - v, - ) where {V, A, 𝔽} - - @assert(is_point(M, p)) - @assert(is_vector(M, p, v)) - +function norm(M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, v) where {V,A,𝔽} return sqrt(inner(M, p, v, v)) -end#=}}}=# +end @doc raw""" - function m(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) + function m(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) When ``p``, ``q \in ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}``, this is the distance between the ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` parts of ``p`` and ``q``. """ -function m(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - p, - q - ) where {V} - - return sqrt(sum([ - distance(Sphere(n - 1), x, y)^2 - for (n, x, y) in zip(V, a[2:end], b[2:end]) - ])) -end#=}}}=# +function m(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric}, p, q) + return sqrt( + sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), + ) +end """ - function compatible(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) + function compatible(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) Check if two representations, `p` and `q`, are compatible. To check if two points are compatible, compose with `closest_representation`. """ -function compatible(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - p, - q - ) where {V, A} - +function compatible(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, q) where {A} return A * m(p, q) < pi -end#=}}}=# +end """ - function closest_representation(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) + function closest_representation(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) Find the representation of ``q`` that is closest to ``p``. """ -function closest_representation(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - p, - q - ) where {V} - - return closest_representation(M.manifold, p ,q) -end#=}}}=# +function closest_representation(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric}, p, q) + return closest_representation(M.manifold, p, q) +end @doc raw""" - function exp(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, v) + function exp(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, v) Exponential map on the warped Segre manifold. @@ -154,28 +118,9 @@ If ``M = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -function exp(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - p, - v, - ) where {V, A} - - @assert(is_point(M, p)) - @assert(is_vector(M, p, v)) - - q = zeros.(size.(p)) # Initialize - exp!(M, q, p, v) - - return q -end#=}}}=# - -function exp!(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - q, - p, - v, - ) where {V, A} +exp(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric}, p, v) +function exp!(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, q, p, v) where {A} m_ = m(p, q) if m_ == 0.0 q .= deepcopy(p) # Initialize @@ -187,28 +132,22 @@ function exp!(#={{{=# P = v[1][1] / (p[1][1] * A * m_) f = atan(sqrt(P^2 + 1.0) * t / p[1][1] + P) - atan(P) - q[1][1] = sqrt( - t^2 + - 2 * p[1][1] * P * t / sqrt(P^2 + 1.0) + - p[1][1]^2 - ) + q[1][1] = sqrt(t^2 + 2 * p[1][1] * P * t / sqrt(P^2 + 1.0) + p[1][1]^2) for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) if all(xdot .== 0.0) y .= deepcopy(x) else a = norm(Sphere(n - 1), x, xdot) - y .= - x * cos(a * f / (A * m_)) .+ - xdot * sin(a * f / (A * m_)) / a + y .= x * cos(a * f / (A * m_)) .+ xdot * sin(a * f / (A * m_)) / a end end return 0 -end#=}}}=# +end @doc raw""" - function log(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) + function log(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) Logarithmic map on the warped Segre manifold. @@ -228,17 +167,16 @@ where ``a_i`` is the distance on ``S^{n_i - 1}`` from ``x_i`` to ``y_i``, ``M = For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -function log(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - p, - q, - ) where {V, A} - - @assert(is_point(M, p)) - @assert(is_point(M, q)) +function log(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, q) where {A} # Check for compatability - m(a, b) = sqrt(sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, a[2:end], b[2:end])])) + function m(a, b) + return sqrt( + sum([ + distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, a[2:end], b[2:end]) + ]), + ) + end if A * m(p, q) < pi # Even if there are closer representations, we prioritize log being continuous v = zeros.(size.(p)) # Initialize log!(M, v, p, q) @@ -268,26 +206,16 @@ function log(#={{{=# m(p, q1) < m(p, q2) ? flips = flips1 : flips = flips2 end end - q_ = deepcopy(q) q_[flips] = -q[flips] - @assert(iseven(sum(flips))) # Should not be necessary but you never know... - @assert(A * m(p, q_) < pi) - - v = zeros.(size.(p)) # Initialize + v = zeros.(size.(p)) log!(M, v, p, q_) end return v -end#=}}}=# - -function log!(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - v, - p, - q - ) where {V, A} +end +function log!(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, v, p, q) where {A} for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) a = distance(Sphere(n - 1), x, y) if a == 0.0 @@ -297,10 +225,9 @@ function log!(#={{{=# end end - m = sqrt(sum([ - distance(Sphere(n - 1), x, y)^2 - for (n, x, y) in zip(V, p[2:end], q[2:end]) - ])) + m = sqrt( + sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), + ) if m == 0.0 v[1][1] = q[1][1] - p[1][1] else @@ -311,10 +238,10 @@ function log!(#={{{=# end return 0 -end#=}}}=# +end @doc raw""" - function distance(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, q) + function distance(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) Riemannian distance between two points `p` and `q` on the warped Segre manifold. @@ -324,26 +251,17 @@ Assume ``p = (\lambda, x_1, \dots, x_d)``, ``q = (\mu, y_1, \dots, y_d) \in \mat ```` where ``M = \sqrt{\operatorname{dist}_{S^{n_1}}(x_1, y_1)^2 + \dots + \operatorname{dist}_{S^{n_d}}(x_d, y_d)^2}``. """ -function distance(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - p, - q, - ) where {V, A} - - @assert(is_point(M, p)) - @assert(is_point(M, q)) - - m = sqrt(sum([ - distance(Sphere(n - 1), x, y)^2 - for (n, x, y) in zip(V, p[2:end], q[2:end]) - ])) +function distance(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, q) where {A} + m = sqrt( + sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), + ) return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(A * m)) but more stable for small m -end#=}}}=# +end @doc raw""" - function riemann_tensor(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, u, v) + function riemann_tensor(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, u, v) Riemann tensor of the warped Segre manifold at ``p``. @@ -354,28 +272,25 @@ If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``u``, ``v``, ``w \i ```` ``R_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ -function riemann_tensor(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, - p, - u, - v, - w - ) where {V, A} - - @assert(is_point(M, p)) - @assert(is_vector(M, p, u)) - @assert(is_vector(M, p, v)) - @assert(is_vector(M, p, w)) - - u_ = deepcopy(u); u_[1][1] = 0.0 - v_ = deepcopy(v); v_[1][1] = 0.0 - w_ = deepcopy(w); w_[1][1] = 0.0 - - return [[0.0], [riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end])]...] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) -end#=}}}=# +function riemann_tensor(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, u, v, w) where {A} + # Can we avoid the deep-copies here? That looks a bit inefficient + u_ = deepcopy(u) + u_[1][1] = 0.0 + v_ = deepcopy(v) + v_[1][1] = 0.0 + w_ = deepcopy(w) + w_[1][1] = 0.0 + return [ + [0.0], + [ + riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for + (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end]) + ]..., + ] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) +end @doc raw""" - function sectional_curvature(M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, p, u, v) + function sectional_curvature(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, u, v) Sectional curvature of the warped Segre manifold at ``p``. @@ -386,16 +301,12 @@ If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i ```` ``K_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ -function sectional_curvature(#={{{=# - M::MetricManifold{ℝ, Segre{V, ℝ}, WarpedMetric{A}}, +function sectional_curvature( + M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, u, - v - ) where {V, A, ℝ} - - @assert(is_point(M, p)) - @assert(is_vector(M, p, u)) - @assert(is_vector(M, p, v)) - - return inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) -end#=}}}=# + v, +) where {A} + return inner(M, p, riemann_tensor(M, p, u, v, v), u) / + (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) +end diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index cbbf388fd0..ed6b02678c 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1,50 +1,42 @@ -include("../header.jl") +using Manifolds # Tests are written for manifolds with this type -T = Union{ - Segre{V, ℝ}, - MetricManifold{ℝ, Segre{V, ℝ}, AlphaWarpedMetric{A}} - } where {V, A} +T = Union{Segre{V,ℝ},MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}} where {V,A} # Approximate derivative of f at x -function finite_difference( - f::Function, - x::Float64, - h::Float64; - order=1::Int64 - ) +function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64) # https://en.wikipedia.org/wiki/Finite_difference_coefficient if order == 1 return ( - (1 / 12) * f(x - 2 * h) + - (-2 / 3) * f(x - 1 * h) + - (2 / 3) * f(x + 1 * h) + + (1 / 12) * f(x - 2 * h) + + (-2 / 3) * f(x - 1 * h) + + (2 / 3) * f(x + 1 * h) + (-1 / 12) * f(x + 2 * h) - ) / h + ) / h elseif order == 2 - return ( - (-1 / 12) * f(x - 2 * h) + - (4 / 3) * f(x - 1 * h) + - (-5 / 2) * f(x) + - (4 / 3) * f(x + 1 * h) + - (-1 / 12) * f(x + 2 * h) + return ( + (-1 / 12) * f(x - 2 * h) + + (4 / 3) * f(x - 1 * h) + + (-5 / 2) * f(x) + + (4 / 3) * f(x + 1 * h) + + (-1 / 12) * f(x + 2 * h) ) / h^2 elseif order == 3 - return ( - (1 / 8) * f(x - 3 * h) + - (-1) * f(x - 2 * h) + - (13 / 8) * f(x - 1 * h) + - (-13 / 8) * f(x + 1 * h) + - (1) * f(x + 2 * h) + - (-1 / 8) * f(x + 3 * h) + return ( + (1 / 8) * f(x - 3 * h) + + (-1) * f(x - 2 * h) + + (13 / 8) * f(x - 1 * h) + + (-13 / 8) * f(x + 1 * h) + + (1) * f(x + 2 * h) + + (-1 / 8) * f(x + 3 * h) ) / h^3 end end # Segre is a special case of warped Segre, with warping factor 1 -get_warping_factor(M::Segre{V, ℝ}) = 1.0 -get_warping_factor(M::MetricManifold{ℝ, Segre{V, ℝ}, AlphaWarpedMetric{A}}) where {A} = A +get_warping_factor(M::Segre{V,ℝ}) = 1.0 +get_warping_factor(M::MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}) where {A} = A @testset "Segre and warped Segre" begin # List of manifolds to test @@ -53,139 +45,196 @@ get_warping_factor(M::MetricManifold{ℝ, Segre{V, ℝ}, AlphaWarpedMetric{A}}) [Segre(Tuple([rand(range(2, 7)) for _ in 1:2])) for _ in 1:5]..., [Segre(Tuple([rand(range(2, 7)) for _ in 1:3])) for _ in 1:5]..., [Segre(Tuple([rand(range(2, 7)) for _ in 1:4])) for _ in 1:5]..., - [MetricManifold(Segre(Tuple([rand(range(2, 7)) for _ in 1:1])), AlphaWarpedMetric{rand() + 0.5}()) for _ in 1:5]..., - [MetricManifold(Segre(Tuple([rand(range(2, 7)) for _ in 1:2])), AlphaWarpedMetric{rand() + 0.5}()) for _ in 1:5]..., - [MetricManifold(Segre(Tuple([rand(range(2, 7)) for _ in 1:3])), AlphaWarpedMetric{rand() + 0.5}()) for _ in 1:5]..., - [MetricManifold(Segre(Tuple([rand(range(2, 7)) for _ in 1:4])), AlphaWarpedMetric{rand() + 0.5}()) for _ in 1:5]..., - ] - - @testset "exp maps to the manifold." begin; for M in Ms - p = rand(M) - v = rand(M; vector_at=p) - - @test(is_point(M, p)) - @test(is_vector(M, p, v)) - @test(is_point(M, exp(M, p, v))) - end; end - - @testset "Geodesics are unit speed." begin; for M in Ms - p = rand(M) - p[1][1] = p[1][1] + 0.5 # Keep away from 0 - v = rand(M, vector_at=p); v = v / norm(M, p, v) - - geodesic_speed = finite_difference( - t -> distance(M, p, exp(M, p, t * v)), - 0.5 * rand(), - 1e-5 + [ + MetricManifold( + Segre(Tuple([rand(range(2, 7)) for _ in 1:1])), + AlphaWarpedMetric{rand() + 0.5}(), + ) for _ in 1:5 + ]..., + [ + MetricManifold( + Segre(Tuple([rand(range(2, 7)) for _ in 1:2])), + AlphaWarpedMetric{rand() + 0.5}(), + ) for _ in 1:5 + ]..., + [ + MetricManifold( + Segre(Tuple([rand(range(2, 7)) for _ in 1:3])), + AlphaWarpedMetric{rand() + 0.5}(), + ) for _ in 1:5 + ]..., + [ + MetricManifold( + Segre(Tuple([rand(range(2, 7)) for _ in 1:4])), + AlphaWarpedMetric{rand() + 0.5}(), + ) for _ in 1:5 + ]..., + ] + + @testset "exp maps to the manifold." begin + for M in Ms + p = rand(M) + v = rand(M; vector_at=p) + + @test(is_point(M, p)) + @test(is_vector(M, p, v)) + @test(is_point(M, exp(M, p, v))) + end + end + + @testset "Geodesics are unit speed." begin + for M in Ms + p = rand(M) + p[1][1] = p[1][1] + 0.5 # Keep away from 0 + v = rand(M, vector_at=p) + v = v / norm(M, p, v) + + geodesic_speed = + finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.5 * rand(), 1e-5) + @test(isapprox(geodesic_speed, 1.0; rtol=1e-6)) + end + end + + @testset "Geodesics are minimizing." begin + for M in Ms + p = rand(M) + v = rand(M, vector_at=p) + v = v / norm(M, p, v) + n = manifold_dimension(M) + + # We test the following: + # Geodesics are (locally) length-minizing. So let B_a be a one-parameter + # family of curves such that B_0 is a geodesic. Then the derivative of + # length(B_a) at a = 0 should be 0, and the second derivative at should + # be nonnegative. + + x = get_coordinates(M, p, v) + x0 = 0.0 * x + x1 = 0.2 * x + x2 = 0.4 * x + x3 = 0.6 * x + x4 = 0.8 * x + x5 = 1.0 * x + + function curve_length(y::Vector{Float64}) + @assert(length(y) == 4 * n) + + # Control points + y1 = y[1:n] + y2 = y[(n + 1):(2 * n)] + y3 = y[(2 * n + 1):(3 * n)] + y4 = y[(3 * n + 1):(4 * n)] + + # Bezier curve from 0 to v + function b(t) + return ( + (1 - t)^5 * x0 + + 5 * t * (1 - t)^4 * (x1 + y1) + + 10 * t^2 * (1 - t)^3 * (x2 + y2) + + 10 * t^3 * (1 - t)^2 * (x3 + y3) + + 5 * t^4 * (1 - t) * (x4 + y4) + + t^5 * x5 + ) + end + + # Length of curve on manifold + ps = [exp(M, p, get_vector(M, p, b(t))) for t in 0.0:1e-3:1.0] + ds = [distance(M, p1, p2) for (p1, p2) in zip(ps[1:(end - 1)], ps[2:end])] + return sum(ds) + end + + dy = rand(4 * n) + dy = dy / norm(dy) + f = a -> curve_length(a * dy) + @test(isapprox(finite_difference(f, 0.0, 1e-3), 0.0; atol=1e-5)) + @test(finite_difference(f, 0.0, 1e-2; order=2) >= 0.0) + end + end + + @testset "log is inverse of exp." begin + for M in Ms + # TODO: This function can be written for a general manifold that implements injectivity_radius + p = rand(M) + + # Make sure we choose p and q compatible + function m(a, b) + return sqrt( + sum([ + distance(Sphere(n - 1), x, y)^2 for + (n, x, y) in zip(V, a[2:end], b[2:end]) + ]), + ) + end + q = rand(M) + A = get_warping_factor(M) + while A * m(p, q) > pi + q = rand(M) + end + + v = rand(M, vector_at=p) + v = v / norm(M, p, v) + + @test( + isapprox( + norm(embed(M, q) - embed(M, exp(M, p, log(M, p, q)))), + 0.0, + ; + atol=1e-10, + ) ) - @test(isapprox(geodesic_speed, 1.0; rtol=1e-6)) - end; end - - @testset "Geodesics are minimizing." begin; for M in Ms - p = rand(M) - v = rand(M, vector_at=p) - v = v / norm(M, p, v) - n = manifold_dimension(M) - - # We test the following: - # Geodesics are (locally) length-minizing. So let B_a be a one-parameter - # family of curves such that B_0 is a geodesic. Then the derivative of - # length(B_a) at a = 0 should be 0, and the second derivative at should - # be nonnegative. - - x = get_coordinates(M, p, v) - x0 = 0.0 * x - x1 = 0.2 * x - x2 = 0.4 * x - x3 = 0.6 * x - x4 = 0.8 * x - x5 = 1.0 * x - - function curve_length(y::Vector{Float64}) - @assert(length(y) == 4 * n) - - # Control points - y1 = y[1:n] - y2 = y[n + 1:2 * n] - y3 = y[2 * n + 1:3 * n] - y4 = y[3 * n + 1:4 * n] - - # Bezier curve from 0 to v - b(t) = ( - (1 - t)^5 * x0 + - 5 * t * (1 - t)^4 * (x1 + y1) + - 10 * t^2 * (1 - t)^3 * (x2 + y2) + - 10 * t^3 * (1 - t)^2 * (x3 + y3) + - 5 * t^4 * (1 - t) * (x4 + y4) + - t^5 * x5 + end + end + + @testset "get_coordinates is left and right inverse of get_vector. " begin + for M in Ms + p = rand(M) + v = rand(M, vector_at=p) + X = rand(manifold_dimension(M)) + + @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) + @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) + end + end + + @testset "sectional_curvature is compatible with riemann_tensor." begin + for M in Ms + p = rand(M) + v = rand(M, vector_at=p) + u = rand(M, vector_at=p) + + @test( + isapprox( + sectional_curvature(u, v), + inner(M, p, riemann_tensor(M, p, u, v, v), u) / + (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2), ) - - # Length of curve on manifold - ps = [exp(M, p, get_vector(M, p, b(t))) for t in 0.0:1e-3:1.0] - ds = [distance(M, p1, p2) for (p1, p2) in zip(ps[1:end - 1], ps[2:end])] - return sum(ds) + ) end - - dy = rand(4 * n); dy = dy / norm(dy) - f = a -> curve_length(a * dy) - @test(isapprox(finite_difference(f, 0.0, 1e-3), 0.0; atol=1e-5)) - @test(finite_difference(f, 0.0, 1e-2; order=2) >= 0.0) - end; end - - @testset "log is inverse of exp." begin; for M in Ms - # TODO: This function can be written for a general manifold that implements injectivity_radius - p = rand(M) - - # Make sure we choose p and q compatible - m(a, b) = sqrt(sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, a[2:end], b[2:end])])) - q = rand(M) - A = get_warping_factor(M) - while A * m(p, q) > pi - q = rand(M) + end + + @testset "Sectional curvature is difference between circumference and 2 pi r for small circles" begin + for M in Ms + p = rand(M) + p[1][1] = p[1][1] + 0.1 # Keep away from 0.0 + + u = rand(M, vector_at=p) + u = u / norm(M, p, u) + v = rand(M, vector_at=p) + v = v - inner(M, p, u, v) * u + v = v / norm(M, p, v) + + r = 1e-2 + ps = [ + exp(M, p, r * (cos(theta) * u + sin(theta) * v)) for + theta in 0.0:1e-3:(2 * pi) + ] + ds = [distance(M, p1, p2) for (p1, p2) in zip(ps, [ps[2:end]..., ps[1]])] + C = sum(ds) + K = 3 * (2 * pi * r - C) / (pi * r^3) # https://en.wikipedia.org/wiki/Bertrand%E2%80%93Diguet%E2%80%93Puiseux_theorem + + @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) end - - v = rand(M, vector_at=p); v = v / norm(M, p, v) - - @test(isapprox(norm(embed(M, q) - embed(M, exp(M, p, log(M, p, q)))), 0.0,; atol=1e-10)) - end; end - - @testset "get_coordinates is left and right inverse of get_vector. " begin; for M in Ms - p = rand(M) - v = rand(M, vector_at=p) - X = rand(manifold_dimension(M)) - - @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) - @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) - end; end - - @testset "sectional_curvature is compatible with riemann_tensor." begin; for M in Ms - p = rand(M) - v = rand(M, vector_at=p) - u = rand(M, vector_at=p) - - @test(isapprox( - sectional_curvature(u, v), - inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) - )) - end; end - - @testset "Sectional curvature is difference between circumference and 2 pi r for small circles" begin; for M in Ms - p = rand(M) - p[1][1] = p[1][1] + 0.1 # Keep away from 0.0 - - u = rand(M, vector_at=p); u = u / norm(M, p, u) - v = rand(M, vector_at=p) - v = v - inner(M, p, u, v) * u - v = v / norm(M, p, v) - - r = 1e-2 - ps = [exp(M, p, r * (cos(theta) * u + sin(theta) * v)) for theta in 0.0:1e-3:(2 * pi)] - ds = [distance(M, p1, p2) for (p1, p2) in zip(ps, [ps[2:end]..., ps[1]])] - C = sum(ds) - K = 3 * (2 * pi * r - C) / (pi * r^3) # https://en.wikipedia.org/wiki/Bertrand%E2%80%93Diguet%E2%80%93Puiseux_theorem - - @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) - end; end + end # TODO: Test that distance and inner are compatible # TODO: Test second_fundamental_form diff --git a/test/runtests.jl b/test/runtests.jl index f6bd62c799..19f4937aef 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -160,6 +160,7 @@ end include_test("manifolds/probability_simplex.jl") include_test("manifolds/projective_space.jl") include_test("manifolds/rotations.jl") + include_test("manifolds/segre.jl") include_test("manifolds/shape_space.jl") include_test("manifolds/skewhermitian.jl") include_test("manifolds/spectrahedron.jl") From b34518ee9134fc302792d7abaa4d556fe4f2fa1f Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Sun, 6 Oct 2024 14:10:28 +0200 Subject: [PATCH 04/35] Fix a bit of tests, version number and docs. --- Project.toml | 2 +- src/manifolds/Segre.jl | 2 +- test/manifolds/segre.jl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index 074f5a4b82..24e970544a 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.10.3" +version = "0.10.4" [deps] Einsum = "b7d42ee7-0b51-5a75-98ca-779d3107e4c0" diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 69b96c62a8..b6ca63c3c9 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -78,7 +78,7 @@ end Check whether `p` is a valid point on `M`, i.e. `p[1]` is a singleton containing a positive number and `p[i + 1]` is a point on `Sphere(V[i])`. The tolerance can be set using the `kwargs...`. """ -function check_point({ℝ, V}M::Segre{ℝ,V}, p; kwargs...) where {V} +function check_point(M::Segre{ℝ}, p; kwargs...) where {V} if p[1][1] <= 0.0 return DomainError(p[1][1], "$(p) has non-positive modulus.") end diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index ed6b02678c..d7155e0953 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1,4 +1,4 @@ -using Manifolds +using Manifolds, Test # Tests are written for manifolds with this type T = Union{Segre{V,ℝ},MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}} where {V,A} From b1417c1350e45f81477c0e334a2f93d9f0c3464f Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Sun, 6 Oct 2024 14:12:32 +0200 Subject: [PATCH 05/35] Comment our tests so CI runs at least. --- test/manifolds/segre.jl | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index d7155e0953..558682e8b4 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1,10 +1,15 @@ using Manifolds, Test -# Tests are written for manifolds with this type -T = Union{Segre{V,ℝ},MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}} where {V,A} +@testset "The Segre manifold" begin + @testset "Basic functions on the Segre manifold" begin + end + @testset "The warped metric" begin end + #= + # Tests are written for manifolds with this type + T = Union{Segre{V,ℝ},MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}} where {V,A} -# Approximate derivative of f at x -function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64) + # Approximate derivative of f at x + function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64) # https://en.wikipedia.org/wiki/Finite_difference_coefficient if order == 1 @@ -32,13 +37,12 @@ function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64) (-1 / 8) * f(x + 3 * h) ) / h^3 end -end + end -# Segre is a special case of warped Segre, with warping factor 1 -get_warping_factor(M::Segre{V,ℝ}) = 1.0 -get_warping_factor(M::MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}) where {A} = A + # Segre is a special case of warped Segre, with warping factor 1 + get_warping_factor(M::Segre{V,ℝ}) = 1.0 + get_warping_factor(M::MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}) where {A} = A -@testset "Segre and warped Segre" begin # List of manifolds to test Ms = [ [Segre(Tuple([rand(range(2, 7)) for _ in 1:1])) for _ in 1:5]..., @@ -238,4 +242,5 @@ get_warping_factor(M::MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}) whe # TODO: Test that distance and inner are compatible # TODO: Test second_fundamental_form + =# end From 2b2da054f8764b11c85b1dd3076a84fcff6c7a24 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Sun, 6 Oct 2024 14:16:59 +0200 Subject: [PATCH 06/35] runs formatter. --- test/manifolds/segre.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index 558682e8b4..f1b0db9fbf 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1,8 +1,7 @@ using Manifolds, Test @testset "The Segre manifold" begin - @testset "Basic functions on the Segre manifold" begin - end + @testset "Basic functions on the Segre manifold" begin end @testset "The warped metric" begin end #= # Tests are written for manifolds with this type From f0d662472f9dc0518776828f2bfedaaf6a6fbcb9 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Thu, 10 Oct 2024 16:30:08 +0200 Subject: [PATCH 07/35] added formulas in documentation --- docs/src/manifolds/segre.md | 6 +- src/manifolds/Segre.jl | 128 ++++++++++++++++------------------- src/manifolds/SegreWarped.jl | 121 ++++++++++++--------------------- test/manifolds/segre.jl | 12 ++-- 4 files changed, 110 insertions(+), 157 deletions(-) diff --git a/docs/src/manifolds/segre.md b/docs/src/manifolds/segre.md index 450600e666..bfaef2ab84 100644 --- a/docs/src/manifolds/segre.md +++ b/docs/src/manifolds/segre.md @@ -1,4 +1,4 @@ -# The Segre-Veronese manifold +# The Segre manifold ```@docs Segre @@ -26,6 +26,6 @@ Order = [:function] ## Literature ```@bibliography -Pages = ["sphere.md"] +Pages = ["segre.md"] Canonical=false -``` \ No newline at end of file +``` diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index b6ca63c3c9..0557a9f293 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -1,14 +1,17 @@ @doc raw""" + Segre{𝔽,V} <: AbstractManifold{𝔽} + +The Segre manifold ````math \mathcal{S} = \operatorname{Seg}(𝔽^{n_1} \times \dots \times 𝔽^{n_d}) ```` -is the space of rank-one tensors in ``𝔽^{n_1} \otimes \dots \otimes 𝔽^{n_d}``. +is the set of rank-one tensors in ``𝔽^{n_1} \otimes \dots \otimes 𝔽^{n_d}``. When ``𝔽 = ℝ``, the Segre manifold is represented as ````math \mathcal{S} \sim ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}. ```` -This is a local diffeomorphism, and the manifold is a locally a [warped product](https://en.wikipedia.org/wiki/Warped_product) of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. The tuple ``(n_1, \dots, n_d)`` is called the _valence_ of the manifold. +This is a local diffeomorphism, and the metric is a locally a [warped product](https://en.wikipedia.org/wiki/Warped_product) of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. The tuple ``(n_1, \dots, n_d)`` is called the _valence_ of the manifold. The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). @@ -20,7 +23,7 @@ Generate a valence `V` Segre manifold. struct Segre{𝔽,V} <: AbstractManifold{𝔽} end function Segre(valence::NTuple{V,Int}; field::AbstractNumbers=ℝ) where {V} - return Segre{valence,field}() + return Segre{field, valence}() end valence(::Segre{𝔽,V}) where {𝔽,V} = V @@ -169,16 +172,13 @@ end @doc raw""" function inner(M::Segre{ℝ, V}, p, u, v,) -Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v = (\xi, v_1, \dots, v_d)`` at ``p = (\lambda, x_1, \dots, x_d``. This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric: +Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v = (\xi, v_1, \dots, v_d)`` at ``p \doteq (\lambda, x_1, \dots, x_d)``. This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric: ````math \langle u, v \rangle_{p} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle_{x_1} + \dots + \langle u_d, v_d \rangle_{x_d}), ```` where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ function inner(M::Segre{ℝ,V}, p, u, v) where {V} - @assert(is_point(M, p)) - @assert(is_vector(M, p, u)) - @assert(is_vector(M, p, v)) return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) end @@ -189,8 +189,6 @@ end Norm of tangent vector ``v`` at ``p``. """ function norm(M::Segre{𝔽,V}, p, v) where {𝔽,V} - @assert(is_point(M, p)) - @assert(is_vector(M, p, v)) return sqrt(inner(M, p, v, v)) end @@ -215,13 +213,12 @@ end @doc raw""" function embed(M::Segre{𝔽, V}, v) -Embed ``p = (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: +Embed ``p \doteq (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: ````math (\lambda, x_1, \dots, x_d) \mapsto \lambda x_1 \otimes \dots \otimes x_d. ```` """ function embed(M::Segre{𝔽,V}, p) where {𝔽,V} - @assert(is_point(M, p)) return kronecker(p...)[:] end @@ -229,14 +226,12 @@ end @doc raw""" function embed_vector(M::Segre{𝔽, V}, p, v) -Embed tangent vector ``v = (\nu, u_1, \dots, u_d)`` at ``p = (\lambda, x_1, \dots, x_d`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: +Embed tangent vector ``v = (\nu, u_1, \dots, u_d)`` at ``p \doteq (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: ````math (\nu, u_1, \dots, u_d) \mapsto \nu x_1 \otimes \dots \otimes x_d + \lambda u_1 \otimes x_2 \otimes \dots \otimes x_d + \dots + \lambda x_1 \otimes \dots \otimes x_{d - 1} \otimes u_d. ```` """ function embed_vector(M::Segre{𝔽,V}, p, v) where {𝔽,V} - @assert(is_point(M, p)) - @assert(is_vector(M, p, v)) # Product rule return sum([ @@ -248,11 +243,16 @@ end @doc raw""" function m(M::Segre{ℝ, V}, p, q) -When ``p``, ``q \in ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}``, this is the distance between the ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` parts of ``p`` and ``q``. +Let ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}``. +Then +````math + m(p, q) = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} +```` +is the distance between ``(x_1, \dots, x_d)`` and ``(y_1, \dots, y_d)`` on ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. """ function m(M::Segre{ℝ,V}, p, q) where {V} return sqrt( - sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, a[2:end], b[2:end])]), + sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), ) end @@ -262,7 +262,7 @@ end Check if two representations, `p` and `q`, are compatible. To check if two points are compatible, compose with `closest_representation`. """ function compatible(M::Segre{ℝ,V}, p, q) where {V} - return m(p, q) < pi + return m(M, p, q) < pi end """ @@ -294,7 +294,7 @@ function closest_representation(M::Segre{ℝ,V}, p, q) where {V} q2 = deepcopy(q) q2[flips2] = -q2[flips2] - m(p, q1) < m(p, q2) ? flips = flips1 : flips = flips2 + m(M, p, q1) < m(M, p, q2) ? flips = flips1 : flips = flips2 end end @@ -310,38 +310,37 @@ end Exponential map on the Segre manifold. -Let ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``v = (\nu, u_1, \dots, u_d) \in T_p \mathcal{S}``. +Let ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``v = (\nu, u_1, \dots, u_d) \in T_p \mathcal{S}``. Then ````math - \operatorname{exp}_p(v) = + \operatorname{exp}_p(v) \doteq \left( - \sqrt{t^2 + 2 \lambda \nu t + \lambda^2}, - x_1 \cos(\norm{u_1}_{T_{x_1} S^{n_1}} g(t) / M) + u_1 \sin(\norm{u_1}_{T_{x_1} S^{n_1}} g(t) / M), - \dots, - x_d \cos(\norm{u_d}_{T_{x_d} S^{n_d}} g(t) / M) + u_d \sin(\norm{u_d}_{T_{x_d} S^{n_d}} g(t) / M) + \sqrt{t^2 + 2 \lambda \nu t + \lambda^2},\\ + x_1 \cos\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{m} \mathclose{\Big)},\\ + \dots,\\ + x_d \cos\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{m} \mathclose{\Big)} \right), ```` -where ``t = \norm{v}_{T_p \mathcal{S}}``, ``M = \sqrt{\norm{u_1}_{T_{x_1} S^{n_1}}^2 + \dots + \norm{u_d}_{T_{x_d} S^{n_d}}^2}``, and +where ````math - g(t) = \tan^{-1}(t \sqrt{P^2 + 1} / \lambda + P) - \tan^{-1}(P),\\ - P = \nu / (\lambda M). + g = \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{\lambda} + P \mathclose{\Big)} - \tan^{-1}(P),\\ + m = \sqrt{\lVert u_1 \rVert_{x_1}^2 + \dots + \lVert u_d \rVert_{x_d}^2},\\ + P = \frac{\nu}{\lambda m},\\ + t = \lVert v \rVert_{p}. ```` -If ``M = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. +If ``m = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ function exp(M::Segre{ℝ,V}, p, v) where {V} - @assert(is_point(M, p)) - @assert(is_vector(M, p, v)) q = zeros.(size.(p)) # Initialize exp!(M, q, p, v) - return q end function exp!(M::Segre{ℝ,V}, q, p, v) where {V} - m_ = m(p, q) + m_ = m(M, p, q) if m_ == 0.0 q .= deepcopy(p) # Initialize @@ -374,32 +373,31 @@ end Logarithmic map on the Segre manifold. -Let ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``q = (\mu, y_1, \dots, y_d) \in T_p \mathcal{S}``. -Also, assume ``p`` and ``q`` are connected by a minimizing geodesic. -Then +Let ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}``. +Assume ``p`` and ``q`` are connected by a geodesic. +Let +````math + m = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} +```` +and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimizes ``m``. Then ````math \operatorname{log}_p(q) = c \left( - \frac{\lambda M (\operatorname{cos}(M) - \lambda / \mu)}{\operatorname{sin}(M)}, - a_1 (y_1 - \langle x_1, y_1 \rangle_{ℝ^{n_1 + 1}} x_1) / \operatorname{sin}(a_1), + \frac{\lambda m \mathopen{\Big(} \operatorname{cos}(m) - \frac{\lambda}{\mu} \mathclose{\Big)}}{\operatorname{sin}(m)}, + \frac{\sphericalangle(x_1, y_1) (y_1 - \langle x_1, y_1 \rangle x_1)}{\sin(\sphericalangle(x_1, y_1))}, \dots, - a_d (y_d - \langle x_d, y_d \rangle_{ℝ^{n_d + 1}} x_d) / \operatorname{sin}(a_d) + \frac{\sphericalangle(x_d, y_d) (y_d - \langle x_d, y_d \rangle x_d)}{\sin(\sphericalangle(x_d, y_d))} \right), ```` -where ``a_i`` is the distance on ``S^{n_i - 1}`` from ``x_i`` to ``y_i``, ``M = \sqrt{a_1^2 + \dots + a_d^2}``, and ``c`` is determined by ``\norm{\operatorname{log}_p(q)}_{T_p \mathcal{S}} = \operatorname{dist}(p, q)``. +where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \operatorname{dist}(p, q)``. For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ function log(M::Segre{ℝ,V}, p, q) where {V} - @assert(is_point(M, p)) - @assert(is_point(M, q)) q_ = closest_representation(M, p, q) - @assert(compatible(M, p, q_)) - v = zeros.(size.(p)) # Initialize log!(M, v, p, q_) - return v end @@ -413,13 +411,11 @@ function log!(M::Segre{ℝ,V}, v, p, q) where {V} end end - m = sqrt( - sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), - ) - if m == 0.0 + m_ = m(M, p, q) + if m_ == 0.0 v[1][1] = q[1][1] - p[1][1] else - v[1][1] = m * p[1][1] * (q[1][1] * cos(m) - p[1][1]) / (q[1][1] * sin(m)) + v[1][1] = m_ * p[1][1] * (q[1][1] * cos(m_) - p[1][1]) / (q[1][1] * sin(m_)) t = distance(M, p, q) v .= t * v / norm(M, p, v) @@ -433,40 +429,35 @@ end Riemannian distance between two points `p` and `q` on the Segre manifold. -Assume ``p = (\lambda, x_1, \dots, x_d)``, ``q = (\mu, y_1, \dots, y_d) \in \mathcal{S}`` are connected by a minimizing geodesic. Then +Assume ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}`` are connected by a geodesic. Let +````math + m = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} +```` +and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimizes ``m``. Then ````math - \operatorname{dist}_{\mathcal{S}}(p, q) = \sqrt{\lambda^2 - 2 \lambda \mu \cos(M) + \mu^2}, + \operatorname{dist}_{\mathcal{S}}(p, q) = \sqrt{\lambda^2 - 2 \lambda \mu \cos(m) + \mu^2}. ```` -where ``M = \sqrt{\operatorname{dist}_{S^{n_1}}(x_1, y_1)^2 + \dots + \operatorname{dist}_{S^{n_d}}(x_d, y_d)^2}``. """ function distance(M::Segre{ℝ,V}, p, q) where {V} - @assert(is_point(M, p)) - @assert(is_point(M, q)) - q_ = closest_representation(M, p, q) - @assert(compatible(M, p, q_)) - return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m(p, q_) / 2)^2) + q_ = closest_representation(M, p, q) + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m(M, p, q_) / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(m)) but more stable for small m end @doc raw""" function riemann_tensor(M::Segre{ℝ, V}, p, u, v, w) -Riemann tensor of the Segre manifold at `p`. +Riemann tensor of the Segre manifold at ``p``. -``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` -If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``u``, ``v``, ``w \in T_p (S^{n_1 - 1} \times \dots \times S^{n_d - 1}) \subset T_p \mathcal{S}`` then +``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. +If ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``u``, ``v``, ``w \in T_p (S^{n_1 - 1} \times \dots \times S^{n_d - 1}) \subset T_p \mathcal{S}`` then ````math R_{\mathcal{S}}(u, v) w = R_{S^{n_1 - 1} \times \dots \times S^{n_d - 1}}(u, v) w + \lambda^{-2}(\langle u, w \rangle_p v - \langle v, w \rangle_p u). ```` ``R_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ function riemann_tensor(M::Segre{ℝ,V}, p, u, v, w) where {V} - @assert(is_point(M, p)) - @assert(is_vector(M, p, u)) - @assert(is_vector(M, p, v)) - @assert(is_vector(M, p, w)) - u_ = deepcopy(u) u_[1][1] = 0.0 v_ = deepcopy(v) @@ -489,16 +480,13 @@ end Sectional curvature of the Segre manifold at ``p``. ``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` -If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i - 1}``, and ``v_j \in T_{x_j} S^{n_j - 1}``, then +If ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i - 1}``, and ``v_j \in T_{x_j} S^{n_j - 1}``, then ````math - K_{\mathcal{S}}(u_i, v_j) = -(1 - \delta_{i j}) \lambda^2. + K_{\mathcal{S}}(u_i, v_j) = \frac{\delta_{i j} - 1}{\lambda^2}. ```` ``K_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ function sectional_curvature(M::Segre{ℝ,V}, p, u, v) where {V} - @assert(is_point(M, p)) - @assert(is_vector(M, p, u)) - @assert(is_vector(M, p, v)) return inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) diff --git a/src/manifolds/SegreWarped.jl b/src/manifolds/SegreWarped.jl index 9030121635..a26497a994 100644 --- a/src/manifolds/SegreWarped.jl +++ b/src/manifolds/SegreWarped.jl @@ -1,7 +1,7 @@ @doc raw""" WarpedMetric{A} <: AbstractMetric -is the warped metric on the Segre manifold ``\mathcal{S}``. We denote it ``\mathcal{S}_A``. It is a generalization of the metric +is the ``A``-warped metric on the Segre manifold ``\mathcal{S}``. We denote it ``\mathcal{S}_A``. It is a generalization of the metric ````math \langle (\nu, u_1, \dots, u_d), (\xi, v_1, \dots, v_d) \rangle_{(\lambda, x_1, \dots, x_d)} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle + \dots + \langle u_d, v_d \rangle), ```` @@ -81,7 +81,7 @@ end Check if two representations, `p` and `q`, are compatible. To check if two points are compatible, compose with `closest_representation`. """ function compatible(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, q) where {A} - return A * m(p, q) < pi + return A * m(M, p, q) < pi end """ @@ -98,30 +98,32 @@ end Exponential map on the warped Segre manifold. -Let ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``v = (\nu, u_1, \dots, u_d) \in T_p \mathcal{S}_A``. +Let ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``v = (\nu, u_1, \dots, u_d) \in T_p \mathcal{S}_A``. Then ````math - \operatorname{exp}_p(v) = + \operatorname{exp}_p(v) \doteq \left( - \sqrt{t^2 + 2 \lambda \nu t + \lambda^2}, - x_1 \cos(\norm{u_1}_{T_{x_1} S^{n_1}} g(t) / (A M)) + u_1 \sin(\norm{u_1}_{T_{x_1} S^{n_1}} g(t) / (A M)), - \dots, - x_d \cos(\norm{u_d}_{T_{x_d} S^{n_d}} g(t) / (A M)) + u_d \sin(\norm{u_d}_{T_{x_d} S^{n_d}} g(t) / (A M)) + \sqrt{t^2 + 2 \lambda \nu t + \lambda^2},\\ + x_1 \cos\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)},\\ + \dots,\\ + x_d \cos\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} \right), ```` -where ``t = \norm{v}_{T_p \mathcal{S}_A}``, ``M = \sqrt{\norm{u_1}_{T_{x_1} S^{n_1}}^2 + \dots + \norm{u_d}_{T_{x_d} S^{n_d}}^2}``, and +where ````math - g(t) = \tan^{-1}(t \sqrt{P^2 + 1} / \lambda + P) - \tan^{-1}(P),\\ - P = \nu / (\lambda A M). + g = \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{\lambda} + P \mathclose{\Big)} - \tan^{-1}(P),\\ + m = \sqrt{\lVert u_1 \rVert_{x_1}^2 + \dots + \lVert u_d \rVert_{x_d}^2},\\ + P = \frac{\nu}{\lambda A m},\\ + t = \lVert v \rVert_{p}. ```` -If ``M = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. +If ``m = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ exp(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric}, p, v) function exp!(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, q, p, v) where {A} - m_ = m(p, q) + m_ = m(M, p, q) if m_ == 0.0 q .= deepcopy(p) # Initialize q[1] .= q[1] .+ v[1] @@ -151,67 +153,31 @@ end Logarithmic map on the warped Segre manifold. -Let ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``q = (\mu, y_1, \dots, y_d) \in T_p \mathcal{S}_A``. -Also, assume ``p`` and ``q`` are connected by a minimizing geodesic. -Then +Let ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}_A``. +Assume ``p`` and ``q`` are connected by a geodesic. +Let +````math + m = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} +```` +and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimizes ``m``. Then ````math \operatorname{log}_p(q) = c \left( - \frac{\lambda A M (\cos(A M) - \lambda / \mu)}{\sin(A M)}, - a_1 (y_1 - \langle x_1, y_1 \rangle_{ℝ^{n_1 + 1}} x_1) / \sin(a_1), + \frac{\lambda A m \mathopen{\Big(} \cos(A m) - \frac{\lambda}{\mu} \mathclose{\Big)}}{\sin(A m)}, + \frac{\sphericalangle(x_1, y_1) (y_1 - \langle x_1, y_1 \rangle x_1)}{\sin(\sphericalangle(x_1, y_1))}, \dots, - a_d (y_d - \langle x_d, y_d \rangle_{ℝ^{n_d + 1}} x_d) / \sin(a_d) + \frac{\sphericalangle(x_d, y_d) (y_d - \langle x_d, y_d \rangle x_d)}{\sin(\sphericalangle(x_d, y_d))} \right), ```` -where ``a_i`` is the distance on ``S^{n_i - 1}`` from ``x_i`` to ``y_i``, ``M = \sqrt{a_1^2 + \dots + a_d^2}``, and ``c`` is determined by ``\norm{\operatorname{log}_p(q)}_{T_p \mathcal{S}_A} = \operatorname{dist}(p, q)``. +where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \operatorname{dist}(p, q)``. For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ function log(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, q) where {A} - # Check for compatability - function m(a, b) - return sqrt( - sum([ - distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, a[2:end], b[2:end]) - ]), - ) - end - if A * m(p, q) < pi # Even if there are closer representations, we prioritize log being continuous - v = zeros.(size.(p)) # Initialize - log!(M, v, p, q) - else - # Find closest representation by flipping an even number of signs. - ds = [distance(Sphere(n - 1), x, y) for (n, x, y) in zip(V, p[2:end], q[2:end])] - flips = [false, (ds .> (pi / 2))...] - nbr_flips = sum(flips) - - # This code is pretty ugly. It can also be implemented slightly more efficiently, O(d) rather than O(log(d) d), by not sorting ds. - if isodd(nbr_flips) - if nbr_flips == length(V) - flips[argmin(ds) + 1] = false - else - is = sortperm(ds; rev=true) - - flips1 = deepcopy(flips) - flips1[is[nbr_flips] + 1] = false - q1 = deepcopy(q) - q1[flips1] = -q1[flips1] - - flips2 = deepcopy(flips) - flips2[is[nbr_flips + 1] + 1] = true - q2 = deepcopy(q) - q2[flips2] = -q2[flips2] - - m(p, q1) < m(p, q2) ? flips = flips1 : flips = flips2 - end - end - q_ = deepcopy(q) - q_[flips] = -q[flips] - v = zeros.(size.(p)) - log!(M, v, p, q_) - end - + q_ = closest_representation(M, p, q) + v = zeros.(size.(p)) # Initialize + log!(M, v, p, q_) return v end @@ -225,13 +191,11 @@ function log!(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, v, p, q) where end end - m = sqrt( - sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), - ) + m_ = m(p, q) if m == 0.0 v[1][1] = q[1][1] - p[1][1] else - v[1][1] = p[1][1] * A * m * (cos(A * m) - p[1][1] / q[1][1]) / sin(A * m) + v[1][1] = p[1][1] * A * m_ * (cos(A * m_) - p[1][1] / q[1][1]) / sin(A * m_) t = distance(M, p, q) v .= t * v / norm(M, p, v) @@ -245,18 +209,20 @@ end Riemannian distance between two points `p` and `q` on the warped Segre manifold. -Assume ``p = (\lambda, x_1, \dots, x_d)``, ``q = (\mu, y_1, \dots, y_d) \in \mathcal{S}_A`` are connected by a minimizing geodesic. Then +Assume ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}_A`` are connected by a geodesic. Let ````math - \operatorname{dist}_{\operatorname{Seg}(ℝ^{n_1} \times \dots \times ℝ^{n_d})}(p, q) = \sqrt{\lambda^2 - 2 \lambda \mu \cos(A M) + \mu^2}, + m = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} +```` +and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimizes ``m``. Then +````math + \operatorname{dist}_{\mathcal{S}_A}(p, q) = \sqrt{\lambda^2 - 2 \lambda \mu \cos(A m) + \mu^2}. ```` -where ``M = \sqrt{\operatorname{dist}_{S^{n_1}}(x_1, y_1)^2 + \dots + \operatorname{dist}_{S^{n_d}}(x_d, y_d)^2}``. """ function distance(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, q) where {A} - m = sqrt( - sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), - ) - return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m / 2)^2) + q_ = closest_representation(M, p, q) + m_ = m(p, q_) + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m_ / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(A * m)) but more stable for small m end @@ -265,8 +231,7 @@ end Riemann tensor of the warped Segre manifold at ``p``. -``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` -If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``u``, ``v``, ``w \in T_{(x_1, \dots, x_d)} (S^{n_1 - 1} \times \dots \times S^{n_d - 1}) \subset T_p \mathcal{S}_A`` then +``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. If ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``u``, ``v``, ``w \in T_{(x_1, \dots, x_d)} (S^{n_1 - 1} \times \dots \times S^{n_d - 1}) \subset T_p \mathcal{S}_A`` then ````math R_{\mathcal{S}_A}(u, v) w = R_{S^{n_1 - 1} \times \dots \times S^{n_d - 1}}(u, v) w + \lambda^{-2}(\langle u, w \rangle_{p} v - \langle v, w \rangle_{p} u). ```` @@ -297,9 +262,9 @@ Sectional curvature of the warped Segre manifold at ``p``. ``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i - 1}``, and ``v_j \in T_{x_j} S^{n_j - 1}``, then ````math - K_{\mathcal{S}}(u_i, v_j) = -(1 - \delta_{i j}) \lambda^2. + K_{\mathcal{S}_A}(u_i, v_j) = -(1 - \delta_{i j}) \lambda^2. ```` -``K_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. +``K_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ function sectional_curvature( M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index f1b0db9fbf..30404cdb7c 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -5,7 +5,7 @@ using Manifolds, Test @testset "The warped metric" begin end #= # Tests are written for manifolds with this type - T = Union{Segre{V,ℝ},MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}} where {V,A} + T = Union{Segre{V,ℝ},MetricManifold{ℝ,Segre{V,ℝ},WarpedMetric{A}}} where {V,A} # Approximate derivative of f at x function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64) @@ -40,7 +40,7 @@ using Manifolds, Test # Segre is a special case of warped Segre, with warping factor 1 get_warping_factor(M::Segre{V,ℝ}) = 1.0 - get_warping_factor(M::MetricManifold{ℝ,Segre{V,ℝ},AlphaWarpedMetric{A}}) where {A} = A + get_warping_factor(M::MetricManifold{ℝ,Segre{V,ℝ},WarpedMetric{A}}) where {A} = A # List of manifolds to test Ms = [ @@ -51,25 +51,25 @@ using Manifolds, Test [ MetricManifold( Segre(Tuple([rand(range(2, 7)) for _ in 1:1])), - AlphaWarpedMetric{rand() + 0.5}(), + WarpedMetric{rand() + 0.5}(), ) for _ in 1:5 ]..., [ MetricManifold( Segre(Tuple([rand(range(2, 7)) for _ in 1:2])), - AlphaWarpedMetric{rand() + 0.5}(), + WarpedMetric{rand() + 0.5}(), ) for _ in 1:5 ]..., [ MetricManifold( Segre(Tuple([rand(range(2, 7)) for _ in 1:3])), - AlphaWarpedMetric{rand() + 0.5}(), + WarpedMetric{rand() + 0.5}(), ) for _ in 1:5 ]..., [ MetricManifold( Segre(Tuple([rand(range(2, 7)) for _ in 1:4])), - AlphaWarpedMetric{rand() + 0.5}(), + WarpedMetric{rand() + 0.5}(), ) for _ in 1:5 ]..., ] From fc7a1b253fd4c6771885e65e177d93bbcf3bb61e Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Fri, 6 Dec 2024 10:37:33 +0100 Subject: [PATCH 08/35] wrote tests for the Segre and the Segre with warped metric --- src/Manifolds.jl | 1 + src/manifolds/Segre.jl | 86 +++----- src/manifolds/SegreWarped.jl | 103 ++++----- test/manifolds/segre.jl | 413 ++++++++++++++++++++++------------- 4 files changed, 340 insertions(+), 263 deletions(-) diff --git a/src/Manifolds.jl b/src/Manifolds.jl index d1ed9dc782..0a5efcecdf 100644 --- a/src/Manifolds.jl +++ b/src/Manifolds.jl @@ -841,6 +841,7 @@ export Γ—, christoffel_symbols_first, christoffel_symbols_second, christoffel_symbols_second_jacobian, + connected_by_geodesic, convert, complex_dot, decorated_manifold, diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 0557a9f293..4a0d539021 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -81,7 +81,7 @@ end Check whether `p` is a valid point on `M`, i.e. `p[1]` is a singleton containing a positive number and `p[i + 1]` is a point on `Sphere(V[i])`. The tolerance can be set using the `kwargs...`. """ -function check_point(M::Segre{ℝ}, p; kwargs...) where {V} +function check_point(M::Segre{ℝ,V}, p; kwargs...) where {V} if p[1][1] <= 0.0 return DomainError(p[1][1], "$(p) has non-positive modulus.") end @@ -151,16 +151,16 @@ function get_vector(M::Segre{𝔽,V}, p, X; kwargs...) where {𝔽,V} X_ = deepcopy(X) v = eltype(p)[[] for _ in p] # Initialize v[1] = [X_[1]] - X_ = drop(X_, 1) + X_ = X_[2:end] for (i, n) in enumerate(V) v[i + 1] = get_vector( Sphere(n - 1), p[i + 1], - take(X_, n - 1), + X_[1:n - 1], DefaultOrthonormalBasis(); kwargs..., ) - X_ = drop(X_, n - 1) + X_ = X_[n:end] end @assert(length(X_) == 0) @@ -257,12 +257,14 @@ function m(M::Segre{ℝ,V}, p, q) where {V} end """ - function compatible(M::Segre{ℝ, V}, p, q) + function connected_by_geodesic(M::Segre{ℝ, V}, p, q) -Check if two representations, `p` and `q`, are compatible. To check if two points are compatible, compose with `closest_representation`. +Check if two points, `p` and `q`, can be connected by a geodesic. """ -function compatible(M::Segre{ℝ,V}, p, q) where {V} - return m(M, p, q) < pi +function connected_by_geodesic(M::Segre{ℝ,V}, p, q) where {V} + q_ = closest_representation(M, p, q) + + return m(M, p, q_) < pi end """ @@ -332,36 +334,24 @@ If ``m = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -function exp(M::Segre{ℝ,V}, p, v) where {V} - - q = zeros.(size.(p)) # Initialize - exp!(M, q, p, v) - return q -end +exp(M::Segre{ℝ,V}, p, v) where {V} function exp!(M::Segre{ℝ,V}, q, p, v) where {V} - m_ = m(M, p, q) - - if m_ == 0.0 - q .= deepcopy(p) # Initialize - q[1] .= q[1] .+ v[1] - return q - end - - t = norm(M, p, v) - P = v[1][1] / (p[1][1] * m_) - f = atan(sqrt(P^2 + 1.0) * t / p[1][1] + P) - atan(P) - - q[1][1] = sqrt( - t^2 + 2 * p[1][1] * P * t / sqrt(P^2 + 1.0) + p[1][1]^2, # This factor is wrong in Swijsen21 on arxiv + m_ = sqrt( + sum([norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end])]), ) - for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) - if all(xdot .== 0.0) - y .= deepcopy(x) - else + q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * m_)^2) + + f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * m_)) + if m_ == 0 + for (x, y) in zip(p[2:end], q[2:end]) + y .= x + end + else + for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) a = norm(Sphere(n - 1), x, xdot) - y .= x * cos(a * f / m_) .+ xdot * sin(a * f / m_) / a + y .= x * cos(a * f / m_) .+ xdot * (f / m_) * sinc(a * f / (m_ * pi)) end end @@ -396,29 +386,23 @@ For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024 function log(M::Segre{ℝ,V}, p, q) where {V} q_ = closest_representation(M, p, q) - v = zeros.(size.(p)) # Initialize - log!(M, v, p, q_) - return v + if connected_by_geodesic(M, p, q_) + v = zeros.(size.(p)) # Initialize + log!(M, v, p, q_) + return v + else + return Nothing + end end function log!(M::Segre{ℝ,V}, v, p, q) where {V} - for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) - a = distance(Sphere(n - 1), x, y) - if a == 0.0 - xdot .= zeros(size(x)) - else - xdot .= a * (y - dot(x, y) * x) / sin(a) - end - end - m_ = m(M, p, q) - if m_ == 0.0 - v[1][1] = q[1][1] - p[1][1] - else - v[1][1] = m_ * p[1][1] * (q[1][1] * cos(m_) - p[1][1]) / (q[1][1] * sin(m_)) - t = distance(M, p, q) - v .= t * v / norm(M, p, v) + v[1][1] = q[1][1] * cos(m_) - p[1][1] + + for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + a = distance(Sphere(n - 1), x, y) + xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(m_ / pi) / sinc(a / pi) end return 0 diff --git a/src/manifolds/SegreWarped.jl b/src/manifolds/SegreWarped.jl index a26497a994..19fa5b3f4c 100644 --- a/src/manifolds/SegreWarped.jl +++ b/src/manifolds/SegreWarped.jl @@ -51,7 +51,7 @@ Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v ```` where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ -function inner(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, u, v) where {A} +function inner(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v) where {V, A} return u[1][1] * v[1][1] + (A * p[1][1])^2 * dot(u[2:end], v[2:end]) end @@ -65,31 +65,33 @@ function norm(M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, v) where end @doc raw""" - function m(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) + function m(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) When ``p``, ``q \in ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}``, this is the distance between the ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` parts of ``p`` and ``q``. """ -function m(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric}, p, q) +function m(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} return sqrt( sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), ) end """ - function compatible(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) + function connected_by_geodesic(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) -Check if two representations, `p` and `q`, are compatible. To check if two points are compatible, compose with `closest_representation`. +Check if two points, `p` and `q`, can be connected by a geodesic. """ -function compatible(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, q) where {A} +function connected_by_geodesic(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} + q_ = closest_representation(M.manifold, p, q) + return A * m(M, p, q) < pi end """ - function closest_representation(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) + function closest_representation(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) Find the representation of ``q`` that is closest to ``p``. """ -function closest_representation(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric}, p, q) +function closest_representation(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} return closest_representation(M.manifold, p, q) end @@ -120,28 +122,24 @@ If ``m = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -exp(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric}, p, v) +exp(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, v) where {V,A} -function exp!(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, q, p, v) where {A} - m_ = m(M, p, q) - if m_ == 0.0 - q .= deepcopy(p) # Initialize - q[1] .= q[1] .+ v[1] - return q - end - - t = norm(M, p, v) - P = v[1][1] / (p[1][1] * A * m_) - f = atan(sqrt(P^2 + 1.0) * t / p[1][1] + P) - atan(P) +function exp!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) where {V,A} + m_ = sqrt( + sum([norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end])]), + ) - q[1][1] = sqrt(t^2 + 2 * p[1][1] * P * t / sqrt(P^2 + 1.0) + p[1][1]^2) + q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * A * m_)^2) - for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) - if all(xdot .== 0.0) - y .= deepcopy(x) - else + f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * A * m_)) + if m_ == 0 + for (x, y) in zip(p[2:end], q[2:end]) + y .= x + end + else + for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) a = norm(Sphere(n - 1), x, xdot) - y .= x * cos(a * f / (A * m_)) .+ xdot * sin(a * f / (A * m_)) / a + y .= x * cos(a * f / (A * m_)) .+ xdot * (f / (A * m_)) * sinc(a * f / (A * m_ * pi)) end end @@ -149,7 +147,7 @@ function exp!(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, q, p, v) where end @doc raw""" - function log(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) + function log(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) Logarithmic map on the warped Segre manifold. @@ -173,39 +171,33 @@ where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \oper For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -function log(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, q) where {A} +function log(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} q_ = closest_representation(M, p, q) - v = zeros.(size.(p)) # Initialize - log!(M, v, p, q_) - return v + if connected_by_geodesic(M, p, q) + v = zeros.(size.(p)) # Initialize + log!(M, v, p, q_) + return v + else + return Nothing + end end -function log!(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, v, p, q) where {A} - for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) - a = distance(Sphere(n - 1), x, y) - if a == 0.0 - xdot .= zeros(size(x)) - else - xdot .= a * (y - dot(x, y) * x) / sin(a) - end - end +function log!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, v, p, q) where {V,A} + m_ = m(M, p, q) - m_ = m(p, q) - if m == 0.0 - v[1][1] = q[1][1] - p[1][1] - else - v[1][1] = p[1][1] * A * m_ * (cos(A * m_) - p[1][1] / q[1][1]) / sin(A * m_) + v[1][1] = q[1][1] * cos(A * m_) - p[1][1] - t = distance(M, p, q) - v .= t * v / norm(M, p, v) + for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + a = distance(Sphere(n - 1), x, y) + xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(A * m_ / pi) / sinc(a / pi) end return 0 end @doc raw""" - function distance(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, q) + function distance(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) Riemannian distance between two points `p` and `q` on the warped Segre manifold. @@ -218,16 +210,15 @@ and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimi \operatorname{dist}_{\mathcal{S}_A}(p, q) = \sqrt{\lambda^2 - 2 \lambda \mu \cos(A m) + \mu^2}. ```` """ -function distance(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, q) where {A} +function distance(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} q_ = closest_representation(M, p, q) - m_ = m(p, q_) - return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m_ / 2)^2) + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m(M, p, q_) / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(A * m)) but more stable for small m end @doc raw""" - function riemann_tensor(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, u, v) + function riemann_tensor(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, u, v) Riemann tensor of the warped Segre manifold at ``p``. @@ -237,7 +228,7 @@ Riemann tensor of the warped Segre manifold at ``p``. ```` ``R_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ -function riemann_tensor(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, u, v, w) where {A} +function riemann_tensor(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v, w) where {V,A} # Can we avoid the deep-copies here? That looks a bit inefficient u_ = deepcopy(u) u_[1][1] = 0.0 @@ -255,7 +246,7 @@ function riemann_tensor(M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, p, u, end @doc raw""" - function sectional_curvature(M::MetricManifold{ℝ, Segre{ℝ}, WarpedMetric{A}}, p, u, v) + function sectional_curvature(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, u, v) Sectional curvature of the warped Segre manifold at ``p``. @@ -267,11 +258,11 @@ If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i ``K_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ function sectional_curvature( - M::MetricManifold{ℝ,Segre{ℝ},WarpedMetric{A}}, + M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v, -) where {A} +) where {V,A} return inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) end diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index 30404cdb7c..6a4426a620 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1,16 +1,8 @@ using Manifolds, Test -@testset "The Segre manifold" begin - @testset "Basic functions on the Segre manifold" begin end - @testset "The warped metric" begin end - #= - # Tests are written for manifolds with this type - T = Union{Segre{V,ℝ},MetricManifold{ℝ,Segre{V,ℝ},WarpedMetric{A}}} where {V,A} - - # Approximate derivative of f at x - function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64) - - # https://en.wikipedia.org/wiki/Finite_difference_coefficient +# Approximate derivative of f at x +# https://en.wikipedia.org/wiki/Finite_difference_coefficient +function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64)#={{{=# if order == 1 return ( (1 / 12) * f(x - 2 * h) + @@ -36,81 +28,237 @@ using Manifolds, Test (-1 / 8) * f(x + 3 * h) ) / h^3 end - end +end#=}}}=# - # Segre is a special case of warped Segre, with warping factor 1 - get_warping_factor(M::Segre{V,ℝ}) = 1.0 - get_warping_factor(M::MetricManifold{ℝ,Segre{V,ℝ},WarpedMetric{A}}) where {A} = A - - # List of manifolds to test - Ms = [ - [Segre(Tuple([rand(range(2, 7)) for _ in 1:1])) for _ in 1:5]..., - [Segre(Tuple([rand(range(2, 7)) for _ in 1:2])) for _ in 1:5]..., - [Segre(Tuple([rand(range(2, 7)) for _ in 1:3])) for _ in 1:5]..., - [Segre(Tuple([rand(range(2, 7)) for _ in 1:4])) for _ in 1:5]..., - [ - MetricManifold( - Segre(Tuple([rand(range(2, 7)) for _ in 1:1])), - WarpedMetric{rand() + 0.5}(), - ) for _ in 1:5 - ]..., - [ - MetricManifold( - Segre(Tuple([rand(range(2, 7)) for _ in 1:2])), - WarpedMetric{rand() + 0.5}(), - ) for _ in 1:5 - ]..., - [ - MetricManifold( - Segre(Tuple([rand(range(2, 7)) for _ in 1:3])), - WarpedMetric{rand() + 0.5}(), - ) for _ in 1:5 - ]..., - [ - MetricManifold( - Segre(Tuple([rand(range(2, 7)) for _ in 1:4])), - WarpedMetric{rand() + 0.5}(), - ) for _ in 1:5 - ]..., +# Manifolds to test +Ms = [ + Segre{ℝ, (10,)}(), + Segre{ℝ, (2,)}(), + Segre{ℝ, (7,)}(), + Segre{ℝ, (7, 2)}(), + Segre{ℝ, (9, 8)}(), + Segre{ℝ, (2, 2)}(), + Segre{ℝ, (7, 9, 9)}(), + Segre{ℝ, (10, 7, 3)}(), + Segre{ℝ, (5, 6, 3)}(), + Segre{ℝ, (9, 3, 6, 6)}(), + Segre{ℝ, (5, 4, 10, 10)}(), + Segre{ℝ, (10, 6, 3, 4)}(), + MetricManifold(Segre{ℝ, (10,)}(), WarpedMetric{1.2025837056880606}()), + MetricManifold(Segre{ℝ, (9,)}(), WarpedMetric{1.1157384770946328}()), + MetricManifold(Segre{ℝ, (4,)}(), WarpedMetric{1.108519951945247}()), + MetricManifold(Segre{ℝ, (2, 9)}(), WarpedMetric{1.1302422072971439}()), + MetricManifold(Segre{ℝ, (4, 7)}(), WarpedMetric{1.4990018903833313}()), + MetricManifold(Segre{ℝ, (2, 2)}(), WarpedMetric{1.1978398577942357}()), + MetricManifold(Segre{ℝ, (9, 6, 10)}(), WarpedMetric{1.4545138169484464}()), + MetricManifold(Segre{ℝ, (9, 9, 2)}(), WarpedMetric{0.886048645869852}()), + MetricManifold(Segre{ℝ, (10, 10, 7)}(), WarpedMetric{1.2810851738110494}()), + MetricManifold(Segre{ℝ, (9, 3, 8, 10)}(), WarpedMetric{1.396673190458706}()), + MetricManifold(Segre{ℝ, (10, 9, 7, 6)}(), WarpedMetric{1.294280190668267}()), + MetricManifold(Segre{ℝ, (7, 2, 8, 8)}(), WarpedMetric{1.2374529454448573}()) ] - @testset "exp maps to the manifold." begin - for M in Ms - p = rand(M) - v = rand(M; vector_at=p) +# ps[i] is a point on Ms[i] +ps = [ + [[0.4679314536763416], [-0.317396495862958, 0.09740239786995583, -0.03435690079466174, -0.507098294482249, -0.3456993992812562, 0.03370180478069075, 0.12197903860091835, -0.19063489706041362, -0.6772451984545433, -0.030292993087650443]], + [[0.3298310216639224], [0.2514005595224343, -0.96788313275509]], + [[0.42312947328046224], [0.33560958022362747, -0.7750899034491946, 0.23449838016304786, 0.36554747855051023, -0.28711573724812484, -0.014134328816621394, 0.12390389837644036]], + [[1.5024828708442504], [-0.20674979086955983, 0.006156775886150006, -0.3570727686996312, -0.02472149296318015, -0.8820637035264094, -0.19877726490312608, 0.10749756092041758], [0.13573491868289245, 0.9907451901726038]], + [[0.3013653757380563], [0.5977968840579448, -0.22702223761000456, 0.5118227538696087, -0.11912796582968001, 0.06221848112591997, 0.1884433539067577, -0.10700788275590943, -0.3518682598612047, 0.37456880426014166], [0.013604873029341946, -0.16528022578112536, 0.20155485791540892, -0.3541277493897382, 0.676862752046083, -0.2658785210172399, 0.5147053312531512, -0.112740319727795]], + [[2.851092491176718], [0.3804764585148756, -0.9247906057675856], [0.43841826755186564, -0.8987710624384948]], + [[0.5567549635823631], [0.20108807178297264, 0.11422009200726954, -0.4229195164047098, 0.8118482504243884, -0.2985123290622806, -0.10304198468607091, 0.0939765805139303], [0.04424901152619659, -0.7169306819079923, -0.031129292324036512, 0.6372250118096429, -0.02583896509973039, 0.014153747195613426, 0.16225623748001994, -0.11092394734951527, 0.19372269982536366], [0.42796852361059873, 0.1000612228302854, -0.6494403216595616, 0.012394320858700462, -0.44765471097923526, 0.28788160552521874, 0.26926315361113184, 0.14434420119149496, 0.09108177932795573]], + [[0.36252817849574176], [-0.4152409797128937, 0.3949651690781115, 0.059637140694856684, -0.29809447149493, -0.45495068818315665, 0.15339000916151824, 0.5145387514659299, 0.0726835092343826, 0.15840576161081632, 0.23135797656647117], [-0.539717469908245, 0.4395297187977435, 0.21328340065082524, 0.45891791025442036, -0.08479985319672712, -0.07573386931397807, -0.4964842269000107], [0.3787170228715312, 0.8302726053139932, 0.40892642058497286]], + [[0.2755990738257318], [0.21794010543619222, -0.832205317244186, -0.08165195766640711, -0.32019564073885964, 0.3882578136419659], [0.8072220207586441, 0.1839997459775723, 0.25829762282479984, -0.16088661411000194, 0.4709383701765526, -0.012312173701218641], [-0.5999408691302599, 0.19608311412450938, -0.7756431949694802]], + [[0.13874530878036045], [0.22313639103335817, -0.582683687448744, 0.019810748294280565, -0.532091804219692, 0.4183784535017075, 0.14178309829111962, -0.20220724006960822, 0.29098277220121593, 0.08046116169937856], [0.9267624891781729, -0.13156790592635095, 0.35185391113703934], [-0.20128032438008028, -0.8385905159101716, 0.32092863797763976, -0.004535145988646948, 0.2201729511393691, -0.3236669445683654], [-0.4807744861170881, -0.7965214809133648, 0.05085093394774735, -0.18228152610151416, -0.3136581939724126, -0.014682951172671068]], + [[0.21051807193802943], [0.23403384696597218, 0.42054682357471496, -0.5698122696955275, 0.5838315012795727, -0.32066069773765116], [0.5766960203474961, -0.6743800959552224, 0.13162023644111331, 0.4419381174485529], [-0.21057589355060127, 0.08811991196707877, 0.3405460927874034, -0.3897589394700625, 0.7083087794882124, -0.1136094071563721, 0.08025571453602402, 0.38379031842997346, -0.10397276906281434, 0.029227598658195648], [-0.5554668166067296, -0.20795381463643023, 0.2553028805249397, 0.10256974403643938, -0.08894446390830917, 0.04610645378979823, 0.27966690408533734, -0.07380638485934377, -0.33321238127988634, 0.6064514324865661]], + [[0.4828275813633084], [0.23384095547788736, 0.3512388738563172, 0.20430444349630456, 0.6579221192887889, 0.09844835569247844, 0.363573528638023, 0.2687104582601494, -0.14301608669058016, -0.09631021994329247, -0.3217692977748192], [-0.5116624664211036, 0.07668016024356412, 0.5061460483419392, 0.3214705004283764, -0.46018395871455636, 0.40127956928413683], [-0.38096699727867506, 0.2861444037357305, -0.8791959549470149], [0.692923641553941, -0.3060961599674285, 0.22172696315719087, 0.6140025420451529]], + [[1.1838757652294163], [0.210872386528422, 0.07121151449265378, -0.5646662541775129, 0.3616416663029674, 0.06637879222702027, 0.07584789624963773, -0.5828313418578935, 0.2675952004007925, 0.22734623628568493, 0.16638557775398255]], + [[0.3032739397640297297], [-0.48082028355309697, 0.3388907360614881, 0.454066186534629, -0.17812152265340722, -0.2993680565146906, -0.4376744632861303, -0.07894707721342749, -0.15363745968032946, 0.3241053320409901]], + [[1.1617468533361055], [-0.02260630098657834, 0.2972001146356296, 0.7596474220087696, -0.5780111082424827]], + [[1.2844162220009774], [-0.30842015389728145, 0.951250234517699], [0.30279327531038325, 0.08852690888227953, 0.05590206678861999, -0.11020418544430191, 0.34622673649276936, 0.039237251633264296, 0.2036788352046126, 0.7474907644209177, -0.4044368794841003]], + [[0.18104388996897572], [0.5520877166363866, -0.052976780373050814, -0.8311689032169315, -0.03938106404973989], [0.034274688844047635, 0.16403282417490214, 0.2354752745921137, 0.49694577571607884, -0.1464762658164691, -0.0454250584931338, -0.8037387865251501]], + [[1.6905902450546004], [-0.12543067772892338, -0.99210238639188], [0.8762083930519261, -0.48193241429204725]], + [[0.5007028223906543], [-0.06769241297456885, -0.5449485746545011, 0.398606571568952, 0.6501033139153659, -0.04258821690222594, -0.13267612920115782, 0.28917066939208946, -0.0862022715614269, 0.08037444499516286], [-0.435703924552393, 0.003588856443541161, -0.6651813230937048, 0.2132673584452006, -0.23794057413100464, -0.5153487505082289], [0.10026563183607826, -0.41453578717039885, 0.22729656824470607, -0.4898014879827773, 0.3079502543279662, 0.32626734055020185, 0.22241280421779944, -0.20185051232763798, 0.26385177592505493, -0.4067248155023813]], + [[0.42070460277285854], [-0.11765364391216213, -0.02107059901087521, 0.01919962552849528, 0.0075532937836861914, -0.407416349154066, 0.2526422092654315, 0.18892381530643113, -0.039220900801933495, -0.8474911902514953], [-0.32443831265566164, -0.2349409435382715, -0.24293165040461917, 0.17482035071905289, 0.4202882276170908, 0.29174253040759934, -0.12773231584125186, 0.17922569173029038, 0.6631525474037887], [0.2845093749411345, -0.9586732579824081]], + [[0.10062440822372039], [0.07996808517600432, -0.26307264663569147, -0.4495698788298603, 0.6111308460433761, -0.11895028828957643, 0.20924569495870432, 0.3301577806915321, -0.004487812699664358, 0.3268240075329048, -0.27392104072489637], [0.12284217101173843, 0.35404646594484673, -0.035991021401721314, 0.5860476109030441, -0.4404194916015131, 0.2346021425142989, -0.16531437985938108, 0.29739181674429876, 0.0961161858068593, 0.3752295207239467], [0.37225889195343176, -0.40269820383703075, 0.5891470410337922, -0.5231944785778554, 0.017605742011659636, 0.24075511508976774, 0.14197812515009833]], + [[0.18481028402754704], [0.3100324954044331, 0.20571167887073383, 0.2759549800636245, -0.5098047663273968, -0.40513901097801985, -0.006849531735112356, 0.32426009440794523, 0.0980343539650855, 0.496558786543343], [0.7400543367573574, -0.6634600702609377, -0.11018309224186618], [-0.3047981091301781, -0.2991724005041669, -0.180567141067543, -0.46275630707119686, 0.5780573143957574, 0.04795327307127396, 0.27896164368216786, -0.3956977653578857], [-0.5375940335785957, -0.33527871549213856, -0.34423023822843113, -0.057618837476544824, 0.2307053118861316, -0.5816558302641435, 0.1347923363882464, 0.005386448290725161, 0.17361223551501662, -0.19203856057632393]], + [[0.4228588017696557], [-0.141865030134013, 0.44059694416524103, -0.4181744594149625, -0.3452888941246838, -0.3554076392829921, 0.06722507728789844, -0.08166976238961376, -0.07165859365772556, -0.13418586367363106, 0.5753345078159252], [0.45050543565810647, 0.3522148480832122, 0.20063517590059027, -0.2069225940646595, 0.5565420673454308, -0.2904080923745975, 0.3836714803715129, 0.18159571033346678, 0.12514543453657165], [0.14887119923616898, 0.10387753894769929, -0.13940282319720718, -0.6456183547647123, -0.468455996706801, 0.3389787430786487, -0.4432076338534407], [-0.08150071800245477, -0.5444374572967173, 0.6051990477077818, 0.2041079018657187, -0.4187164733526199, 0.3371884933536173]], + [[0.17800461834682948], [0.40442214560226664, -0.18410967602595124, -0.37808224287777675, 0.5298695372118921, 0.20342335952859486, 0.47237240617396475, 0.3381149112046999], [-0.0671758988249334, -0.997741148102584], [0.5860119193049029, -0.1655879827363143, 0.42146580605026046, -0.05072788682343524, 0.01966945374695293, -0.18509497429620517, -0.2917989581694971, 0.5737335943846366], [-0.45925413330012654, -0.054244623817065345, -0.11041902728376159, 0.03752800032819433, 0.24065851466537416, -0.17318765966122213, -0.5175866433893724, -0.6455509506489918]] + ] - @test(is_point(M, p)) - @test(is_vector(M, p, v)) - @test(is_point(M, exp(M, p, v))) - end - end +# qs[i] is a point on Ms[i] that is connected to ps[i] by a geodesic and uses the closest representation to ps[i] +qs = [ + [[0.2285468999681258], [0.0072000169737206285, 0.46919050788513217, -0.0578728225972693, 0.14417171957969074, 0.5393873747379379, 0.3535952408499787, -0.19179220675967715, 0.0603486044844522, -0.3902812557079805, 0.38335320681028]], + [[0.5], [0.2514005595224343, -0.96788313275509]], # m = 0 + [[0.7626963166735549], [-0.04331677552451647, -0.008943154324947739, -0.8741092621910937, 0.26370232932220805, 0.2684875896184496, 0.30167858701939854, -0.03663605553981364]], + [[0.9263875479802128], [-0.2876490379709154, 0.5934703502895091, 0.00669105544965959, -0.5238009412763243, 0.48771046854635186, 0.22195505041284128, 0.05927252688380565], [-0.8467814852966212, 0.5319408953623024]], + [[0.5053216839247762], [-0.59015897645163, 0.41560724598915816, 0.3244409818454344, 0.2767905184327968, 0.2788412597376433, 0.1764703807465072, 0.301994778424145, 0.2876603862925981, 0.11943395810822663], [-0.03534714586479288, 0.15957987916099206, -0.28718149774238777, -0.19635088853199553, 0.684165557894705, -0.5666526357569592, 0.2510512156243137, 0.007316029468452894]], + [[0.18066790739255756], [-0.992558358800348, -0.12176988287569214], [-0.7201988141976301, -0.6937677334874601]], + [[0.05929877942048794], [-0.2492472329981639, 0.19078207722614024, -0.6950020535594956, 0.6155692112895002, 0.12163736596071065, 0.07617216946811589, -0.13757492254479187], [-0.3446138929389734, -0.44528715923871226, 0.09867730315307487, 0.3856741902911293, -0.03976898819561624, -0.09854548801276108, 0.5786967392957476, 0.419483004838766, -0.048271382271637374], [-0.13898349823957276, 0.37007148419755803, -0.5672020653516858, 0.2664429979574558, 0.26019214805889984, -0.183973837333837, -0.537331406376888, -0.2092584392846679, -0.13023121083469708]], + [[0.4428343667970336], [-0.127255572630727, 0.22668672002145898, 0.3495203443639004, -0.2800785570522293, 0.3076023585481211, 0.2954405117453133, 0.6120999631203197, 0.09785748462223727, 0.40179977381828863, -0.06496817376226975], [0.08909415980355775, 0.880431882384782, -0.3060967538577087, 0.013454468756813096, -0.29939494476539896, -0.16687570624161663, 0.07443689564200096], [0.14631014012300886, 0.5274221714215308, 0.8369105065598011]], + [[0.9747973672469175], [0.5036745603591766, 0.08655987562606954, 0.45670653353901913, 0.16988849841032172, 0.7080793497266027], [-0.04773379921570165, 0.14480351638724792, 0.46223423790321516, 0.1869203226531565, -0.4654696219322667, -0.7151865207075913], [-0.6614475098892549, 0.6975530383411345, -0.27551216009888874]], + [[0.5944460845919239], [0.18440528974038717, -0.3234774292705488, -0.07521274368923382, -0.5055464117085976, 0.17461559395815557, 0.20174607290008786, -0.5921554567742019, 0.22060599004214254, 0.3600218594053353], [0.9391716922907767, -0.20920363981570536, -0.27237909150215467], [0.594536709760007, -0.6154768837189905, 0.2868298100684849, 0.08944875927641796, 0.42003473849671874, 0.031823015747801525], [0.04047760394645142, 0.5651446411453817, 0.4996377449872775, 0.5242952935259201, -0.18199312205158755, -0.34832193537003325]], + [[0.35664035777449904], [0.13343426198137742, -0.25425996956084335, -0.922195129235849, 0.08550784318326136, 0.2445234507695054], [0.4047997839831198, -0.5275627401918468, -0.1815584055185977, 0.7244661727327466], [-0.48114822474834057, 0.07687937224998155, 0.18315655165440772, 0.4530633997597068, 0.3699870416956907, 0.2678528031163627, -0.09413476091065198, 0.11453703309553476, 0.49851411436369913, 0.21128473391689526], [-0.3768156565668107, 0.14736306468252625, -0.06614007558247408, -0.48760209381974895, -0.3574364962985913, 0.5633803923618522, 0.024688951851943863, -0.3699931126715858, -0.003533128694901466, 0.10718456273036511]], + [[0.11597881520641286], [0.004793068006686758, 0.5431793112729557, -0.2543049740455072, 0.24843954495843448, 0.3105833349418175, 0.22857210987819054, 0.244361879116985, -0.4284169847117112, 0.3591924409584363, 0.2399161670796564], [0.16123153683830393, 0.11403720071692096, 0.07121418589008548, 0.7353846315348165, 0.6113006204016374, 0.20359136354078292], [-0.12820954768918336, -0.7223351856222379, -0.6795544065734709], [-0.5181411756487838, -0.5982091832712966, 0.13154159318612907, 0.5969692658832942]], + [[0.9068920036691095], [0.028598193298964708, 0.4294897666239807, 0.5582305652867099, 0.20015138065027618, -0.36032666340358765, -0.06085371828646839, 0.3481371808459643, 0.3824819666832563, 0.15057862863095645, 0.19832899484009994]], + [[0.26091111882856616], [-0.2735468559596818, 0.7908310184653957, -0.3965289688792057, -0.20393895097120848, 0.009693462487979644, 0.22432025309225306, 0.14645403468888063, 0.07594795417367314, 0.15264889046998872]], + [[0.7507973403445075], [-0.3623234540901233, -0.8628926515811954, 0.04303829727534214, -0.3496937108828457]], + [[1.8900272913460916], [-0.24462417095922365, 0.9696179737311559], [0.0029148214868594184, 0.046733730849394826, 0.3464166332779196, -0.41612585782053313, 0.4403234930433767, -0.07014699792539351, -0.6626027503215617, 0.06409791188610743, -0.25037156781949155]], + [[0.0038033069402429436], [-0.6935787317124584, 0.4529983876547129, -0.5165298785674818, 0.2166515364483497], [-0.4548679332583842, 0.38597993504553063, 0.20134736150306345, 0.16454891197012098, -0.6254798836839162, 0.4249626997707289, -0.06840444087211281]], + [[0.05069728715399965], [0.9989195510484316, 0.046472901062876736], [0.9990218321402392, 0.0442196665202251]], + [[1.3388920951283048], [-0.2894849285247092, -0.375237468281043, 0.10659685105991663, 0.5326935539788507, -0.2687936085300003, -0.28583226069914086, -0.06940771783985483, 0.566949781731537, 0.0083926101085135], [-0.2692873331242094, -0.352948146454535, -0.36201078692503574, 0.26291906209331745, -0.430264386434885, -0.6462246148490923], [-0.2899662461053266, 0.561676369276759, 0.29953621040966766, 0.026981212635263388, -0.1879070254370779, -0.10235375900374745, -0.04777542564881818, -0.6562458092558364, 0.02736625708068412, -0.17468256196490237]], + [[1.1931486977771844], [0.22644039039058186, -0.11411958485037178, 0.30437736829730944, -0.62733810852234, -0.6264916698299722, 0.07060731738622097, 0.2251625848885129, -0.02341401611326633, -0.02791368478545802], [0.6571431019356029, 0.006127671303832962, -0.03377055193505131, -0.2634138473656534, 0.0015253787707612755, -0.3506356042585966, 0.27828523163579455, 0.4040591774006482, 0.3659835342176074], [0.5769596212360408, -0.8167726706147582]], + [[0.09396735191763278], [0.08808204191629705, -0.269420904705849, -0.6118443181714507, 0.2480461224526081, 0.1084861630557538, 0.2683009932904934, 0.38655863782557004, 0.32133983398494953, 0.33119696155689554, -0.19401189178526185], [-0.5120308222265519, 0.7045182787166198, -0.09497155095499868, -0.018552062467794783, -0.10973828476807547, -0.3071753378516766, -0.055696702155718036, -0.19520860631422926, 0.2906599716297778, 0.004872010410999308], [-0.071497555279541, -0.7200146974217542, 0.13219105850125198, 0.5589884484433559, 0.2558843206526261, -0.11634032369835579, 0.2598317093251373]], + [[0.5595013700016621], [-0.16410496932023275, 0.2124425044194968, 0.019103430387761126, -0.49321855967754313, 0.2187406652190155, -0.2438450092656317, -0.29126737061752705, -0.6546701444600094, 0.2521323190300214], [0.5091077043894671, -0.7810695653023092, -0.36157942348777083], [0.09792086442785906, -0.46300382891140285, -0.34321497128243517, -0.4715033116632154, 0.23250354333074766, 0.3343541579831825, 0.33398745563364823, -0.39815681352786747], [0.1472380561455175, -0.2928950599225513, -0.06829513714619305, 0.2630794095929546, -0.07520704498840525, -0.097452294891074, 0.1546325256973868, -0.7547590605905541, 0.42527618176727117, -0.17050835599699163]], + [[0.0879788405568045], [0.4752198883185735, 0.4601150437982469, 0.004558213453811248, -0.3747084951936111, -0.06469017263215665, 0.006333332718496339, -0.19475186049495816, -0.4040009330690733, 0.3550915844479287, 0.30095342923066604], [0.3443393165370433, 0.3660193874394325, -0.08495542638537015, 0.09676362754304287, 0.5155711330857424, -0.004321193772576179, -0.6430158188019451, 0.16550949028930745, 0.15551404574943303], [0.4892943761703814, 0.06614536658571389, -0.2830598467537517, -0.19219480553946047, -0.5053021840588248, -0.4208210443148484, -0.4546794862909613], [-0.045503401271809414, -0.49376674883678284, -0.011090272673863474, 0.6509068904350033, -0.5051014195999987, 0.2742145509818364]], + [[1.4349423523410283], [0.06370019368643771, 0.31519275409207537, -0.717868367412602, 0.2601814359189934, 0.03539231049664084, -0.46547257907453504, 0.309271891789521], [0.6968005890360706, -0.7172649016360588], [0.39039913946740623, -0.5538051672666193, -0.10251421913304977, -0.18753950466778713, 0.5673704705466129, 0.37985274492764076, 0.06722234077506756, -0.1564989325835006], [-0.7130313109989243, 0.24441120802232372, 0.5661277861967524, -0.06364217193543024, 0.2700793817903238, -0.14762085346258608, 0.0921868105034791, 0.06375984394161507]] + ] + +# vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representation to ps[i] for t in [-1, 1] +vs = [ + [[0.6940789907123062], [0.14913995456500687, -0.030547142938236793, 0.31162623436384285, -0.20563967625033036, 0.19319043822673818, 0.317062500120066, -0.8754858218076765, -0.3259209038205042, -0.033243255319008624, -1.1548635082931478]], + [[0.2389420207891795], [0.0, 0.0]], # m = 0 + [[0.46132409636616317], [0.7034437676859567, 0.6114140712984324, -0.08829607209219353, 0.03327833095019875, -0.6185892330923073, 0.1326136814054642, 0.5700109876145869]], + [[0.45470843046349313], [0.433513329547113, -0.7320515075884788, -0.38765391945909755, 0.19640702045402264, 0.14944186690806377, -0.9671407596317976, -0.9289295848779034], [-0.5045110500803344, 0.06911945375717096]], + [[-0.19135891857701476], [-0.0069569775655274405, 0.4648330993586129, -0.5249300916156493, -0.6942918549175187, 0.03839836910376858, 0.48996587981873707, 0.19149786106059058, 0.25496379149224513, 0.8306443019906313], [-0.14991071399697806, -0.0899250894563053, 0.48363972474877626, -0.06740963522851286, -0.17392353118572687, -0.8626165876780832, -0.4781319504914857, -0.002601732145143469]], + [[0.032475437742255364], [-0.0793840052835045, -0.032660090840698486], [-0.16688671771785502, -0.08140692187036919]], + [[-0.14362437882603868], [0.21703580244995338, -0.07582942569056315, -0.4131524696769127, 0.07113227925464494, 0.9216831076067749, -0.3117658924120991, -0.2601938828890881], [-0.40993096871840384, 0.06033520676657045, 0.3353505686920585, 0.32669207217743906, -0.26949939576113957, 0.4622586254534011, -0.23046667729151138, 0.39890816877066293, -0.352075854880814], [0.27574595870419494, -0.20132897843112602, 0.7181884086912088, 0.20902304397906357, -0.9797911979282492, -0.22738728408774556, -0.08434852248139064, -0.03906999050989374, 0.23241083119724726]], + [[0.167542758489263], [-0.7172648711179583, -0.12978356499468247, -0.14709754758453525, 0.7429222145447074, -0.301380485416464, 0.10648701938150486, -0.5862695196566239, -0.6731434017042006, -0.1027873036321029, 0.8518198213004147], [0.36528861191780526, -0.05502523773982651, 0.3349143864166638, 0.5976408658825734, 0.22224119027517705, 0.5079433605241578, 0.13504430515015828], [-0.09838274427397142, 0.1575018337179488, -0.22867252665062765]], + [[0.0005576618010449276], [-0.5529387542450745, -0.18931262357519596, -0.4740879804055004, 0.7218017303773806, 0.4001673857383268], [0.04653671285987987, -0.3342761936754844, 0.10416238554693465, -0.3780599114751379, -0.13425764881025848, 0.045590813877080076], [-0.3467728705815678, 1.0951463617116348, 0.5450739839349461]], + [[-0.10835780918855986], [-0.2879956140065193, 0.43075721925722893, -0.3291055923326802, 0.017387780693294552, 0.060086501392198954, -0.22944578876172467, -0.2678362137267055, 0.821848362075142, 0.5607641072034037], [0.1257205818761756, 0.5344739830694265, -0.1312860116480018], [-0.32028258895073813, 0.05581149125388041, -0.38726569273936556, -0.4124721885803405, 0.09543462429188473, -0.2587175245909177], [0.23313088537058163, 0.398484868218528, 0.17079789329674128, -0.5464610930958373, -1.0423151616550292, 0.3909668100967531]], + [[-0.13373401585247496], [-0.0462149976885849, -0.22586363815314267, -0.24082866649963608, -0.17798976955515672, -0.22606766311009552], [-1.1531492828944132, -1.048323182821658, 0.3469323589434465, -0.19825175056321256], [-0.33544764292008533, 0.5454762716081148, -0.44056401394680517, 0.6346538879978276, 0.4071906233657455, 0.20386210363713045, 0.1131664536677318, 0.13733952167695518, 0.3499954521074497, -0.40947620073175056], [0.5235561961524053, -0.33651887371172584, 0.165664680004435, 0.3177740663156395, -0.5050069337944564, 0.007676908750572816, -0.15745475915753057, -0.13379200089703605, 0.7775600848786371, 0.6495661761313964]], + [[0.14255661510910747], [-0.01620371146007782, -0.2176640728621523, -0.26783759524037853, 0.1887922975530844, -0.03868441552368684, 0.24619823528128237, 0.16400437859951833, 0.8207953853819989, -0.683215714398723, 0.2095762101658616], [-0.587587477362466, 0.9611453504625634, -0.4956705989932666, -0.8797827478845143, 0.2660001180346881, 0.7021729654279507], [0.6165274130606305, 0.1402548199881536, -0.22150177598219462], [0.42439566636895776, 0.04342532989904936, 0.1811774237827697, -0.5227232167013833]], + [[-0.25050034943799143], [0.3488629827096742, -0.01790447096652751, 0.41078746198742494, 0.2674738658616262, -0.3676063246452534, 0.27995679376647054, -0.6476807696598814, -0.05608263854802896, -1.002407614041255, -0.41159169074078095]], + [[1.5189255716984038], [0.14389418968383233, -0.7434685056546961, 0.17177099801922532, -0.0699519450185816, -0.48084553564682225, -0.2504085373789058, 0.5705781638468338, -0.7229621177887824, -0.2742605768830553]], + [[-0.2000130047239455], [0.28376287916446385, -0.011498145899119377, 0.276592098504903, 0.3464992149574739]], + [[0.7638265778356526], [0.043718096583251764, 0.014174547965435269], [0.1589574325807131, 0.8748133883099838, -0.3528071207217161, -0.2644899757823254, 0.24010835273681236, -0.1673897092037622, -0.6222042985569745, -0.09191448012128656, 0.039882538236865134]], + [[0.13319966661993943], [-0.27617394286645647, -0.22020251242074337, -0.2045923981917276, 0.7425959288733582], [-0.7440711602827321, -0.42811046699670163, -0.07153818588627878, -0.1126683907082826, -0.31430569035654404, 1.0115723034951567, -0.20961404535149197]], + [[0.4767148797604099], [0.3384876432473121, -0.04279471058404047], [-0.27439746807899096, -0.49888606251189316]], + [[-0.2827629165886028], [-0.5431768324825607, -0.2133080279346807, -0.10499961310795408, 0.09083087776121102, 0.37394345246532357, 0.41219715056530515, -0.17844896356814216, 0.6017127772767268, 0.04825845645947814], [0.1686105642978755, 0.27823583527578005, -0.06479699938479212, 0.4075789329243761, -0.1242362543997863, 0.16905085277591742], [0.4498529143568951, -0.38162629109703405, -0.6140545422956211, 0.15825503736095084, -0.2582602332898444, 0.7274993022330352, -0.2411292264007391, -0.5521909388447415, -0.32703914771404785, 0.28418328300445966]], + [[-0.05589178950257751], [-0.1019705158920252, -0.4021433820745908, 0.48255194721701017, 0.008131662295720925, 0.07202859076099435, -0.18565046869387167, 0.3240465427833554, -0.4904527437336233, 0.04012334309767329], [-0.47219983715545033, -0.3425847967691243, -0.26741555241645554, 0.5136974943331476, -1.3528826516837709, -0.5084770566734448, 0.5426586250054705, -0.31969383279201147, 0.6862705068300334], [0.09849573584104232, 0.029230981468574946]], + [[-0.05719286771089035], [0.4242973237170861, -0.5219356456168175, 0.3310684379655346, 0.12413567167651018, -0.5923469397738462, -0.37146828706242285, -0.5751410323943549, -0.055651487469272024, 0.5472629066920902, 0.29283912917169935], [0.1875320328414897, 0.6808265997858123, -0.2995863467195515, -0.13554874838930378, 0.6373044353809255, 0.8178243633205413, -0.9612380226211692, 0.07781549715708687, -0.3845106658570097, -0.6707841245616247], [-0.2707020905807271, -0.5625117726096117, 0.10488366055899745, -0.28409682013973964, -0.25019752929639916, -0.8986902851125926, -0.8128844484365579]], + [[-0.13762858893746074], [-0.44703815295307797, 0.5944800147380626, 1.4927738811624347, 0.2690676585035225, 0.1392293231358478, -0.40920070507884104, -0.7332317211680289, -0.3830957876846897, 0.1418909392355959], [-0.28919223043248377, -0.334256240757651, 0.07031663871919733], [1.4923062450401439, -0.07045305045420008, 1.1439824974086474, -0.48836659931427834, 0.9029762904802794, -0.4051626818191545, 0.7052172856721804, 0.7200604408974567], [-0.4660428754709174, 0.3303812040550049, 0.0416448317248993, 0.0923448025024135, -0.11839363942123281, 0.12128945856537898, -0.3046909560916853, -0.9180764335769804, -0.8185102432606277, -0.8637091370051597]], + [[0.08588821780925351], [-0.19846651453049668, -0.12131137905689643, -0.012056169732668959, 0.387028828005472, -0.1673202197809444, 0.15365077102586527, -0.5066602440919681, -0.5263849388489793, -1.0529289245626894, -0.2368951143092367], [-0.5124015057222998, 0.10937701513453171, 1.100622688156337, -0.3529295809332267, -0.14952258183921502, 0.28769664553265084, -0.29663286648941295, 0.8048977491005426, 0.26266525195090656], [0.5229761285972861, 0.058988804914361245, 0.16088566715699476, 0.0876297447684608, -0.12424872326482747, -0.18192414077364386, 0.0034228886467715103], [-0.4422179502033592, 0.06409501421449978, -0.03443123742857476, -0.40737856180759047, -0.49232052745173593, -0.3063601971060485]], + [[0.0020120000622140064], [-0.4605158014626578, 0.04861856501815409, 0.12440850145559806, 0.41986549071776175, 0.45760378449565353, 0.3823068642538414, -0.7509927996480504], [0.7945555246182702, -0.05349582066856984], [-0.2002746258874713, 0.06644197619406682, 0.3105130297384215, -0.019792549607544785, -0.0029621125749771035, 0.5952370789475336, -0.15048879670202958, 0.10947909205995154], [0.47460069009979067, 0.34348555903411404, 0.8553181291195778, 0.36336966197832254, -0.4154570058919746, 0.7084181186043732, -0.8911752856098722, -0.12208726470275424]] + ] + +# us[i] is a tangent vector to Ms[i] at ps[i] +us = [ + [[-0.37772914799158225], [-0.59695867308892, 0.3750933177933997, 0.34564315403507745, 0.046043813336741984, -0.0545409875155681, 0.2577121584084208, -0.3308621558840682, 0.15972331014082508, 0.23275600794660842, -0.33394550809020124]], + [[1.3683817863110515], [1.309120423677036, 0.34003444822705764]], + [[-0.12929062734170355], [0.15850990687718194, 0.17487391887026144, 1.0186159795799787, -0.34163759242980707, 0.14845978504467341, -0.13138435258479628, 0.07372358714600029]], + [[-0.2603225446842325], [0.3602679784109386, 0.17337068990715637, -0.19313197776041668, -0.25410123672991486, 0.08222041883237792, -0.21642611657517966, 0.2574667569083157], [1.3205385203894777, -0.18091754616690692]], + [[-0.3096239639876968], [0.8763931296077601, 0.9630409930052396, -0.024742767752841448, -0.5119584268098544, -0.65137269579901, -0.5585309447674137, 0.36820697176827755, 0.788214538036487, 0.2908132604789067], [0.2655385329237167, -0.33415351180043346, -0.5131255776726478, 0.27265294689102404, -0.0733048224201999, -0.5967809983817592, 0.11338960014259027, 0.23310946516775605]], + [[-0.5123951975200387], [-0.7694459734927109, -0.31656471982654616], [-1.1392866599419809, -0.5557411721084375]], + [[-0.14766117733667908], [-1.0051180880053472, 0.9460677967957836, 0.5835821685582908, 0.6948551934342009, 0.6374252884087097, -0.009680426176410788, -0.36146835559128143], [0.4688516869504158, -0.28425151202447, -0.3187195701047898, -0.35633492041750464, 0.554715750802327, -0.10721116773599117, 0.28645702408100504, -0.1610220090851739, -0.28845747034499986], [0.09417372769886223, 0.1989812337413881, -0.08400464069697863, -0.6790036003882072, -0.22919842842946442, 0.3185935243022103, -0.9397877219225759, -0.548382602086301, 0.3462072647694016]], + [[-0.0360207524796129], [0.20350245773360448, 0.37364752980981, -0.13027127184216153, -0.08190812987077147, 0.4553806555417341, -0.5133558357167839, -0.01992655851146799, 0.7876406853642887, 0.14590589840824297, 0.5882183495667237], [0.1421766874190634, 0.16985174267090664, 0.2674424928046712, 0.19679295366232205, 0.020504602587278625, -0.7983181858070574, 0.41087597326194303], [0.08272242498791532, 0.043641892904065484, -0.1652205757255303]], + [[0.07334723852895442], [-0.335402461448991, -0.04149991778158621, 0.8259416067042924, -0.36669745774013474, -0.0293979473512328], [0.25357991790389556, -0.6762696649693698, -0.1500007754391727, -0.21823190285300317, -0.1554963524472741, 0.2760192231713663], [-0.6373006596520467, -0.671494722883091, 0.3231820209261418]], + [[-0.8237610837914967], [0.3004390493463726, 0.4405860908850111, -0.7157767786794753, -0.26422248721975317, 0.43563297876352225, -0.05301527548401603, 0.2653406121711885, -0.16921344490396534, -0.10660913986306259], [0.2301095438238535, 0.13543635311552182, -0.5554515952958057], [-0.047141475305190236, 0.26349478946841576, 0.7660038342835548, -0.44707592462720674, -0.008237239351391848, 0.10681017970047482], [-0.10101942119876328, -0.09752768648570287, -0.03101236164578546, -0.017267002331470507, 0.426143631920239, -0.3979129485173604]], + [[-0.17314190690191722], [-1.1339790699243253, -0.6846816962035396, 0.2090090635616599, 0.6968343188160526, -0.8282658301524312], [0.26096836011459945, 0.5854265047018472, 0.7062605498807286, 0.34245153599846784], [-0.4642499534514001, 0.3677311750533016, -0.5795938822926545, -0.2327468766014096, 0.008116599138855707, 0.25047446112097677, 0.1664040210464276, -0.13265399018639917, -0.38415949773048125, -0.10878478149940779], [0.36290342984947627, -0.5552686774454564, -0.03722341001087248, -0.08247270899765498, 0.42071065664777474, 0.029450006187029542, -0.6467198752580883, 0.3282922917661867, 0.13054924199752604, 0.6409942919440069]], + [[0.15795465249466936], [0.5351607860771331, -0.41785689120228914, -0.030904801558696852, 0.20801945515978773, 0.39257256533026225, -0.08950160299890557, 0.6172225568521781, 0.8206592397973528, 0.5312616693613874, 0.34916321649313975], [-0.48125632002442126, -0.3885025059033661, -0.39789961820933506, -0.8112377504395194, -0.13593743657921403, 0.45648408250913297], [-0.6908584605178826, -0.25115275205263854, 0.217617378343041], [-0.05159880494311214, -0.08968056529390697, -0.31839202789900106, 0.12849987939389101]], + [[-0.11566741406383592], [-0.6189044291634334, -0.4887938523139652, 0.377907148579411, 0.4086524760594208, 0.07938663795474155, -0.6960459002055371, -0.5157245121702985, -0.0949098978719522, 0.35850803987739277, -0.4702399492568731]], + [[0.996024398644524], [-0.7416787110144638, 0.14070197751838798, -0.13795012958209601, -0.4757150483429905, -0.1360189820310271, 0.3238908388104348, 0.5189337739664109, 0.6803924956106052, -0.5549192083475457]], + [[-0.5889817889278641], [0.08753868748426015, 0.07610237172143071, -0.1871044108743123, -0.21019436123666874]], + [[-0.44426957903450753], [0.02248238255936011, 0.0072893752214958085], [-0.11483810063446695, 0.7180538788465062, 1.2336105712455359, 0.5094984474406282, 0.44539460730056, -0.22600080346686421, 0.23177494146123226, 0.04078051728077603, 0.6543369295727094]], + [[-0.8389592975128012], [-0.3425282245979182, 0.7830546276591328, -0.3052977538552278, 0.5882182554997865], [0.03745255029472473, -0.18373865390118915, 0.31498165370594844, 0.46034942779621935, 0.11932816285894, 0.030905964762235363, 0.31751727602532254]], + [[-0.4656394904731537], [-0.49930548339416325, 0.06312677606155825], [0.1221872729023376, 0.22215047352319392]], + [[0.26115469823295706], [0.9332535998779934, 0.8409422500428906, 1.1570765490059969, 0.009748111907376684, 0.1823249755535606, 0.42856570496684815, 0.5854663071660117, 0.3272130825134361, -0.2809222008539077], [-0.3442363693316475, -0.5817781819508783, 0.35114374833485607, 1.1229502716222781, 0.45619247794084083, 0.08783351766172355], [0.06361430009419232, 0.6926810562240848, -0.4297785211478541, -0.46202875308860125, -0.36949007474336926, 0.8488609929914562, 0.030242445794160633, -0.14503901054294097, 0.2058457533515663, 0.2491580414140638]], + [[0.9549180463751705], [0.3895017091001908, 0.49171007245983317, -0.7574299513534506, -0.34411683885229793, 0.0513658453673059, 0.06981342473422567, -0.1439873053399203, -0.18295666103878877, -0.11403644383556799], [-0.15850209669311577, 0.2414976982465587, -0.09000199478941477, -0.47413124486427444, 0.09572564708049942, -0.36176114242096513, -0.1257338263899131, -0.06322697714974733, 0.19138488813360416], [-0.19020791605007967, -0.056448779449793374]], + [[-0.5581377638463701], [-0.25985100085298074, -0.12823304129983562, 0.6940528086313831, 0.3949636485406578, 0.6535818467393291, 0.5759145253409661, 0.2526448903910712, -0.5437798878532403, -0.36348766005250244, -0.17477846468203878], [0.11703814560342424, 0.5421400308047751, 0.5209685317484212, 0.004412884829451791, -0.10761650749037417, 0.4539634764966858, 0.15393382881531487, 0.37298468621560743, 0.20920463087073315, -1.1982965330635182], [-0.2361677344675108, -0.08561184124338428, 0.33089548131311, 0.09448935004937808, -0.5233825679847084, -0.09673390251592129, -0.4195453536456808]], + [[0.1798820030601053], [-0.1533759903297747, 0.2964688376499158, -0.14860837418627715, -0.5551072496477686, 0.19870817329497556, -0.3760368493600557, 0.4044751294601737, -0.32878881969363477, -0.5566640994443255], [0.5598006445911394, 0.4954191143909883, 0.7768169558982286], [0.035077508613607256, -0.18338072549214748, -0.11985026451776065, 0.7471592115103867, 0.34655767438419205, 0.22412820486882898, 0.6981705844979219, 0.3181720496138494], [0.18466074016625922, 0.5419495972646897, 0.5887579351606795, -0.5653359894384714, 0.16017679421854783, -0.49769950032627924, -0.6930225262597705, 0.3904417023562996, 0.6252695138324811, -0.5591798774189761]], + [[0.02775921877564232], [-0.32610417589316576, -0.9533681500385859, -0.7953634329826215, -1.0380444511104359, 1.8624955384484987, 0.44685665513406264, -0.8501002862266008, -1.070462937138491, -0.02354710201871483, 0.28743720819281715], [0.2653138406460859, -0.2282890286319614, 0.02811495791663485, 0.03337784871438022, 0.1768829048441087, -0.2345694568284544, -0.46257070907000497, -0.2368037688836088, 0.12834132594241648], [-0.5490049782150824, -0.15079368647293154, 0.4956415766510821, -0.04311702187664941, -0.13959940872666987, 0.1745102984539435, -0.031814296573279166], [1.060646643382475, -0.07879165090994764, -0.13387349603704785, -0.2653272097959495, -0.9301322737127853, -0.6249913037816839]], + [[0.16969505385956252], [0.0930186150799604, 0.1546667070131112, 0.5068773816789583, 0.21700722366006517, -0.408452920217741, 0.26880615167829464, 0.06987247642683876], [-0.0984469609988096, 0.006628235293547613], [0.016225795251541872, -0.7366173566083619, 1.1134825891599547, -0.7078026064080831, -0.024735556978746676, -0.65431320330066, 0.7988331267058175, -0.913679346443505], [-0.41346861893716785, -0.30448423297022137, 0.7646027070405849, -0.3087443669597033, 0.3795212472780163, -0.002675858285340116, 0.4202373636203284, -0.023732041788181002]] + ] + +# When testing that exp(Ms[i], ps[i], t * vs[i]) is an extremum of the length functional, we parametrize curves in Ms[i] and take a derivative along dys[i] +dys = [ + [0.24768051036976024, 0.15340874919881428, 0.10461792180729243, 0.1621738878738882, 0.13788895788409475, 0.13920478959340893, 0.1980520199776914, 0.225220769065586, 0.09192923424127934, 0.15861132814448145, 0.07788788182581427, 0.2033127058413462, 0.11406283238286104, 0.020870012361419343, 0.2719578430552649, 0.15170700765742606, 0.07022129511933332, 0.04843952826362164, 0.2555544578976192, 0.06681340738035137, 0.15586613310716685, 0.018646851863471762, 0.1979297092698637, 0.23753411269988997, 0.21343310337377225, 0.08016910818336964, 0.1464783972931314, 0.025950651929534232, 0.1449831966165307, 0.23373068876892722, 0.11880598168141776, 0.19121899600576953, 0.15179084381364852, 0.04935589775227154, 0.1560593153225572, 0.04411343229804097, 0.2392666728301238, 0.1484349911958273, 0.17060958026859915, 0.01433037040599356], + [0.49490048799897596, 0.3065322528949179, 0.20904131890947963, 0.32404623250194, 0.27552152748971576, 0.2781507442742417, 0.3957357855481444, 0.45002276663457547], + [0.2774747194904695, 0.17186273392192533, 0.11720271596589263, 0.18168225662692275, 0.15447602176127323, 0.15595013869479196, 0.2218762736147053, 0.2523132305670958, 0.10298766925985375, 0.17769114622380935, 0.08725724171457977, 0.22776978268478074, 0.1277837823108223, 0.023380526861408162, 0.30467244314999586, 0.16995628493998063, 0.07866841899027918, 0.05426646003407173, 0.2862958470725858, 0.07485058652127569, 0.17461572368939868, 0.02088993591975766, 0.22173924979601844, 0.2661077821279658, 0.17616832761102516, 0.24286311298519137, 0.32029952947731805, 0.07192152273314319], + [0.2703013619564934, 0.1674196883015804, 0.11417275710290055, 0.17698535383607492, 0.15048246250457872, 0.15191847013635482, 0.2161402633508973, 0.2457903551976426, 0.10032520193833194, 0.1730974227854145, 0.08500144200281991, 0.22188141170224845, 0.12448027862860386, 0.022776086648557087, 0.29679596211605436, 0.16556252539583352, 0.07663466003347703, 0.05286354765112583, 0.278894443170582, 0.07291552728513738, 0.17010150697308607, 0.020349883191748984, 0.21600678191201325, 0.2592282859804155, 0.23292611292832396, 0.08749101451887183, 0.15985638202387917, 0.02832074493766232, 0.1582246235190211, 0.255077492415341, 0.12965662340215453, 0.20868317404203518], + [0.19457563274485226, 0.1205165654713542, 0.08218692016467483, 0.12740238140112917, 0.10832435377645168, 0.10935805960596295, 0.15558792674492308, 0.17693145731489499, 0.07221879869975649, 0.12460366577951727, 0.061188035614062594, 0.15972067533731096, 0.08960675892678109, 0.016395298340405255, 0.21364769199403277, 0.11917969226849504, 0.0551652324585789, 0.03805366779842952, 0.2007613367396708, 0.052488025793646274, 0.12244706467838061, 0.014648802986629832, 0.15549184052751536, 0.1866047118849567, 0.167671170717676, 0.06298014699696033, 0.11507214190657873, 0.02038660414496235, 0.11389752539236134, 0.18361677546291374, 0.09333293534087271, 0.15021996314975533, 0.11924555321621164, 0.0387735596171921, 0.12259882692942942, 0.03465512481835747, 0.18796579590043078, 0.11660922488526533, 0.13402938722767327, 0.011257813079646883, 0.09066268061997902, 0.07657067329789471, 0.17155609506972255, 0.02437048731808387, 0.2215711733203188, 0.2103628283958812, 0.13577361182582945, 0.05424502888292601, 0.028934213909226063, 0.0924565622310047, 0.1986597950667768, 0.0790211436628239, 0.07639807345045613, 0.12722079565692512, 0.1446707992261107, 0.06036826781167918, 0.0585884798528245, 0.15137516172871096, 0.22086742806031712, 0.08175559977855866, 0.10596354820935999, 0.010750489568562414, 0.05896893496182565, 0.16027814898868079], + [0.387733284839387, 0.24015485982792192, 0.1637748986177967, 0.253876310924278, 0.2158592878529835, 0.21791916632378672, 0.3100419978963423, 0.35257351688061767, 0.2461713430135757, 0.3393682593390343, 0.44757514819657734, 0.1005005728492324], + [0.16353440643700792, 0.10129020125571776, 0.06907539765598648, 0.10707750259980159, 0.0910430491609086, 0.09191184484141025, 0.13076652451317197, 0.14870505851042468, 0.06069752009721213, 0.1047252743607885, 0.05142652727905344, 0.13423996349664308, 0.07531152759015192, 0.013779707893699597, 0.17956384365300332, 0.10016660338980309, 0.04636455972831437, 0.03198285359980099, 0.16873328677427074, 0.0441144557626597, 0.10291272221322205, 0.012311836110395775, 0.1306857672142806, 0.1568351101623881, 0.14092209282890691, 0.05293273783140711, 0.09671434268855209, 0.017134268875714943, 0.09572711622173373, 0.1543238480770115, 0.07844325605769907, 0.12625492803046978, 0.10022195734569302, 0.03258789894704945, 0.10304027338340047, 0.029126490235301297, 0.15797905641835802, 0.09800621027247283, 0.11264728258206483, 0.009461820854890907, 0.07619899497188476, 0.06435512726649247, 0.14418724370624061, 0.020482591380646117, 0.18622326856315144, 0.17680302406232687, 0.11411324587011096, 0.04559115895133764, 0.024318253167761508, 0.0777066933426362, 0.16696701026147626, 0.06641466684484068, 0.06421006278332052, 0.1069248857665583, 0.12159103864374035, 0.05073753945931583, 0.04924168633871106, 0.12722583436268306, 0.18563179386637813, 0.0687128870870491, 0.08905886988994213, 0.009035432164352614, 0.049561446318667116, 0.1347085017272271, 0.1200359392924501, 0.027268283817115106, 0.04224558795450571, 0.04315262171954351, 0.05403346926811662, 0.0023262859537098515, 0.010721414504714139, 0.13403654903491943, 0.10987330337776338, 0.013298908898025385, 0.14340914694684173, 0.17825169707180502, 0.10868078009526573, 0.0016445884181541684, 0.07063958523304881, 0.1101738445443299, 0.11758054831650003, 0.060827727766064016, 0.14865227744166581, 0.11702503201869387, 0.09342064187053477, 0.15738531812684184, 0.03201521439082036, 0.06114448967602477, 0.10382777552410098, 0.1431354723068435, 0.18877393058117947, 0.04238816261102419], + [0.18931478384099465, 0.11725809249396936, 0.07996478698818024, 0.12395773281339016, 0.10539552836400544, 0.10640128531778455, 0.15138120999255955, 0.17214766373220333, 0.07026617913163342, 0.12123468761259337, 0.05953366088302137, 0.15540221917752278, 0.08718401146951676, 0.015952009599231567, 0.2078711812851488, 0.11595736507064407, 0.05367369958461762, 0.03702478975393335, 0.19533324153872214, 0.051068878035693224, 0.11913639572715305, 0.014252735205439095, 0.15128772171130855, 0.18155937717307144, 0.16313775262089256, 0.061277317960149645, 0.11196087281767074, 0.01983540026317905, 0.11081801505923433, 0.17865222723918714, 0.09080944119283771, 0.14615838299541906, 0.1160214452995229, 0.03772521745978412, 0.11928405469835733, 0.0337181350584281, 0.18288366080789226, 0.11345639683447971, 0.13040556062135805, 0.010953429366412056, 0.08821138362439966, 0.0745003896914418, 0.16691763812644678, 0.02371156898547879, 0.21558043106834748, 0.2046751323592965, 0.13210262565520578, 0.052778376061538665, 0.028151903578888155, 0.08995676306701976, 0.19328852040933758, 0.07688460533499909, 0.07433245652145608, 0.12378105670329538, 0.1407592548832129, 0.058736057595709795, 0.05700439074739889, 0.14728234783203958, 0.2148957133578259, 0.07954512844968857, 0.1030985532015983, 0.010459822641440727, 0.05737455928138075, 0.1559446201057239, 0.13895900193366503, 0.03156699173602045, 0.04890539260876352, 0.04995541568895709, 0.06255157417661084, 0.002693013244577135, 0.012411591625591608, 0.15516673744807902], + [0.2208827351133444, 0.13681070045747248, 0.09329879317581574, 0.14462749557513332, 0.12297007186353966, 0.12414353725437031, 0.17662379572008607, 0.20085302392695362, 0.08198295726125182, 0.14145038674302837, 0.06946080797470483, 0.18131530204975832, 0.1017218123213999, 0.018611982853869447, 0.24253338351044798, 0.13529307872148416, 0.06262370707329344, 0.04319861693798904, 0.22790476144676877, 0.059584535506577115, 0.1390022078881141, 0.016629357048352854, 0.17651471841061875, 0.21183412621988404, 0.19034072388880155, 0.07149521720826639, 0.13063017748479328, 0.023142922984180615, 0.12929674993937262, 0.20844221347143077, 0.1059517769179363, 0.17053007029227615, 0.13536784423072898, 0.04401583989479429, 0.13917448876740884, 0.039340582618640645, 0.21337923212968313, 0.13237507784892918, 0.15215048882937396, 0.012779896996084542, 0.10292049721512919, 0.08692321596963569, 0.19475089953352745, 0.027665436925096435, 0.2515281389291008, 0.23880439830403508, 0.15413053686754696, 0.06157908971918815], + [0.1715795373556408, 0.1062732072642473, 0.07247358541051933, 0.11234521687243985, 0.0955219430260548, 0.09643347940647069, 0.13719962830095694, 0.15602065459839623, 0.0636835553069129, 0.10987726996268543, 0.053956472834027505, 0.14084394430027286, 0.07901650388441198, 0.014457605324831525, 0.1883975482043314, 0.10509433361797467, 0.04864548006260954, 0.03355626099441541, 0.17703417838482685, 0.046284681464683716, 0.10797554869382073, 0.0129175210883459, 0.1371148981191942, 0.164550666915154, 0.14785480326481754, 0.05553678192838664, 0.1014722377736982, 0.01797719507885178, 0.10043644436402703, 0.1619158624347057, 0.08230229880238973, 0.1324660822900412, 0.10515241073061003, 0.03419107175394852, 0.10810937478733341, 0.030559377859677404, 0.16575088999747303, 0.10282765922416374, 0.11818900408120409, 0.009927298359990544, 0.07994763052677145, 0.06752109970877263, 0.15128058435355177, 0.021490239451779292, 0.19538458579496817, 0.1855009091519671, 0.1197270859333567, 0.047834031570543896, 0.02551459792914639, 0.08152950063326206, 0.17518100929637484, 0.06968195903934253, 0.06736889872885857, 0.11218509200201603, 0.1275727512737259, 0.053233590023432004, 0.05166414789821036, 0.13348475269051732, 0.19476401329869034, 0.07209324101046329, 0.09344015137889938, 0.009479933332347762, 0.051999638579474684, 0.14133553242896432, 0.12594114827928685, 0.028609756342773685, 0.04432387406709532, 0.04527552966766203, 0.056691664223667886, 0.002440728384874828, 0.011248858149159562, 0.14063052279470464, 0.11527855802353276, 0.013953153258528188, 0.15046420885860654, 0.18702085012439856, 0.11402736815129268, 0.0017254945064788542, 0.07411472372909801, 0.11559388441532585, 0.10893561836452229, 0.15017707070132247, 0.198060728501197, 0.04447346273248423], + [0.15352324557245492, 0.09508947248635916, 0.0648467773137381, 0.10052248994615477, 0.08546962500750059, 0.08628523522382116, 0.12276133012550565, 0.1396017126485001, 0.05698177213314873, 0.09831425914354645, 0.04827832594018572, 0.1260221339994952, 0.07070114721768485, 0.012936149187027587, 0.1685714013686324, 0.09403465842703182, 0.04352623918178691, 0.030024944562363123, 0.15840386366444553, 0.04141388086399268, 0.09661266683324013, 0.011558136784825031, 0.12268551658326957, 0.14723406319463364, 0.13229520035155487, 0.04969233010940552, 0.09079373635463328, 0.01608535246877302, 0.08986694538383312, 0.14487653419367338, 0.07364115922533956, 0.11852592211670533, 0.09408662375438188, 0.03059295057071266, 0.09673240964485387, 0.027343440505776938, 0.1483079799672769, 0.09200651908735905, 0.10575130214923645, 0.008882592222129873, 0.07153428610112707, 0.06041546988453471, 0.1353604669880599, 0.019228699177151067, 0.1748231532056124, 0.16597959213878738, 0.107127522889412, 0.04280018403537061, 0.022829551495057773, 0.0729496870082825, 0.1567457141121245, 0.06234892968263987, 0.0602792858804522, 0.10037921592768378, 0.11414754418852645, 0.04763151620423726, 0.04622723541111018, 0.11943739203007579, 0.17426788708699534, 0.06450645872078792, 0.0836069121502298, 0.008482305963885847, 0.046527420497518554, 0.12646198951003412, 0.1126876440684275, 0.025598988763302813, 0.039659420394756825, 0.04051092785723106, 0.05072567756422609, 0.0021838766380988884, 0.010065076749004063, 0.1258311720542961, 0.10314713890387746, 0.012484783484285916, 0.13463000333533406, 0.16733958106731892, 0.10202761886684918, 0.0015439108936574257, 0.06631520930151812, 0.1034292817038221, 0.11038256588952834, 0.057104008819336624, 0.13955216270266796, 0.1098610568880544, 0.08770166753227544, 0.14775058882543593, 0.03005532430797646, 0.057401379369977516, 0.02755102955172378, 0.05922224994122391, 0.17215444540682492, 0.11921375673164347, 0.014339320851720466, 0.07226503986645506, 0.0717760634504068, 0.17528349052139683, 0.14331799583358729, 0.055100951418902915, 0.14579838397697775, 0.0716513592338211, 0.1554316797606585, 0.029621643272853243, 0.09658002282375533, 0.07404757373098435], + [0.17846031137802032, 0.11053503204293935, 0.07537995974563472, 0.11685054461552731, 0.09935261487813324, 0.1003007061761313, 0.1427016808932576, 0.16227747801487458, 0.06623742717159986, 0.11428362678390792, 0.056120264054923916, 0.14649214319442222, 0.08218526582214918, 0.015037391916391805, 0.19595276705818235, 0.10930888257761537, 0.050596287021758744, 0.03490195205115243, 0.1841336973279205, 0.048140814420656146, 0.11230564167550687, 0.013435546401317802, 0.14261355281660268, 0.17114956543023846, 0.15378415536045742, 0.057763947546553146, 0.1055415315159862, 0.018698126133919378, 0.10446420016714315, 0.16840909861672573, 0.08560282943855643, 0.13777830769824043, 0.10936928872956436, 0.03556222032998324, 0.11244483453432241, 0.031784886312244846, 0.17239792049806787, 0.10695130879960922, 0.12292868249243113, 0.0103254081679582, 0.0831537330012127, 0.07022886682365666, 0.15734731894762363, 0.02235205248399433, 0.20322000255288147, 0.19293996544324854, 0.12452844532248876, 0.04975229738993509, 0.026537797929146605, 0.0847990401055136, 0.18220621146533902, 0.0724763820863788, 0.07007056219895538, 0.11668399833223729, 0.13268874171440578, 0.055368391812715356, 0.05373601108320975, 0.13883782936185077, 0.20257454352772494, 0.07498436257180507, 0.09718733811319212, 0.009860102669626628, 0.0540849557905192, 0.1470034452521622, 0.1309917073073869, 0.029757080034537288, 0.046101373680117005, 0.04709119308060735, 0.058965143546946014, 0.0025386077749533845, 0.011699965851902326, 0.14627016294592948, 0.11990152017630731, 0.014512710044560078, 0.15649820472762588, 0.1945208598983612, 0.11860015442119298, 0.0017946912064986773, 0.07708691186744215, 0.12022949195506588], + [0.24768051036976024, 0.15340874919881428, 0.10461792180729243, 0.1621738878738882, 0.13788895788409475, 0.13920478959340893, 0.1980520199776914, 0.225220769065586, 0.09192923424127934, 0.15861132814448145, 0.07788788182581427, 0.2033127058413462, 0.11406283238286104, 0.020870012361419343, 0.2719578430552649, 0.15170700765742606, 0.07022129511933332, 0.04843952826362164, 0.2555544578976192, 0.06681340738035137, 0.15586613310716685, 0.018646851863471762, 0.1979297092698637, 0.23753411269988997, 0.21343310337377225, 0.08016910818336964, 0.1464783972931314, 0.025950651929534232, 0.1449831966165307, 0.23373068876892722, 0.11880598168141776, 0.19121899600576953, 0.15179084381364852, 0.04935589775227154, 0.1560593153225572, 0.04411343229804097, 0.2392666728301238, 0.1484349911958273, 0.17060958026859915, 0.01433037040599356], + [0.24802588780879425, 0.153622669627372, 0.10476380599437246, 0.16240003082711635, 0.1380812367802985, 0.1393989033476937, 0.19832819309827035, 0.22553482757717827, 0.0920574247212134, 0.15883250329562493, 0.07799649237864552, 0.2035962147115505, 0.11422188700075789, 0.020899114495500196, 0.2723370739572822, 0.1519185550969481, 0.07031921502040975, 0.04850707463695044, 0.25591081514216235, 0.06690657516129511, 0.15608348022827995, 0.018672853917218492, 0.19820571183459643, 0.23786534152126568, 0.21373072460581133, 0.08028089978632086, 0.14668265371062417, 0.025986838748155147, 0.14518536805535576, 0.23405661391576318, 0.11897165037143213, 0.19148564083396585, 0.1574713038353601, 0.21708766594943277, 0.28630563284911986, 0.06428837755455744], + [0.37258942960245, 0.23077503463910054, 0.15737827636974977, 0.24396056148760667, 0.20742838461456795, 0.20940780958141045, 0.29793256257804646, 0.33880291087698405, 0.13829049729675522, 0.23860135056090637, 0.1171678846232154, 0.3058462895900371, 0.17158639407244533, 0.03139506612744243, 0.40911017773906017, 0.2282150798437472], + [0.24768051036976024, 0.15340874919881428, 0.10461792180729243, 0.1621738878738882, 0.13788895788409475, 0.13920478959340893, 0.1980520199776914, 0.225220769065586, 0.09192923424127934, 0.15861132814448145, 0.07788788182581427, 0.2033127058413462, 0.11406283238286104, 0.020870012361419343, 0.2719578430552649, 0.15170700765742606, 0.07022129511933332, 0.04843952826362164, 0.2555544578976192, 0.06681340738035137, 0.15586613310716685, 0.018646851863471762, 0.1979297092698637, 0.23753411269988997, 0.21343310337377225, 0.08016910818336964, 0.1464783972931314, 0.025950651929534232, 0.1449831966165307, 0.23373068876892722, 0.11880598168141776, 0.19121899600576953, 0.15179084381364852, 0.04935589775227154, 0.1560593153225572, 0.04411343229804097, 0.2392666728301238, 0.1484349911958273, 0.17060958026859915, 0.01433037040599356], + [0.24768051036976024, 0.15340874919881428, 0.10461792180729243, 0.1621738878738882, 0.13788895788409475, 0.13920478959340893, 0.1980520199776914, 0.225220769065586, 0.09192923424127934, 0.15861132814448145, 0.07788788182581427, 0.2033127058413462, 0.11406283238286104, 0.020870012361419343, 0.2719578430552649, 0.15170700765742606, 0.07022129511933332, 0.04843952826362164, 0.2555544578976192, 0.06681340738035137, 0.15586613310716685, 0.018646851863471762, 0.1979297092698637, 0.23753411269988997, 0.21343310337377225, 0.08016910818336964, 0.1464783972931314, 0.025950651929534232, 0.1449831966165307, 0.23373068876892722, 0.11880598168141776, 0.19121899600576953, 0.15179084381364852, 0.04935589775227154, 0.1560593153225572, 0.04411343229804097, 0.2392666728301238, 0.1484349911958273, 0.17060958026859915, 0.01433037040599356], + [0.387733284839387, 0.24015485982792192, 0.1637748986177967, 0.253876310924278, 0.2158592878529835, 0.21791916632378672, 0.3100419978963423, 0.35257351688061767, 0.2461713430135757, 0.3393682593390343, 0.44757514819657734, 0.1005005728492324], + [0.16353440643700792, 0.10129020125571776, 0.06907539765598648, 0.10707750259980159, 0.0910430491609086, 0.09191184484141025, 0.13076652451317197, 0.14870505851042468, 0.06069752009721213, 0.1047252743607885, 0.05142652727905344, 0.13423996349664308, 0.07531152759015192, 0.013779707893699597, 0.17956384365300332, 0.10016660338980309, 0.04636455972831437, 0.03198285359980099, 0.16873328677427074, 0.0441144557626597, 0.10291272221322205, 0.012311836110395775, 0.1306857672142806, 0.1568351101623881, 0.14092209282890691, 0.05293273783140711, 0.09671434268855209, 0.017134268875714943, 0.09572711622173373, 0.1543238480770115, 0.07844325605769907, 0.12625492803046978, 0.10022195734569302, 0.03258789894704945, 0.10304027338340047, 0.029126490235301297, 0.15797905641835802, 0.09800621027247283, 0.11264728258206483, 0.009461820854890907, 0.07619899497188476, 0.06435512726649247, 0.14418724370624061, 0.020482591380646117, 0.18622326856315144, 0.17680302406232687, 0.11411324587011096, 0.04559115895133764, 0.024318253167761508, 0.0777066933426362, 0.16696701026147626, 0.06641466684484068, 0.06421006278332052, 0.1069248857665583, 0.12159103864374035, 0.05073753945931583, 0.04924168633871106, 0.12722583436268306, 0.18563179386637813, 0.0687128870870491, 0.08905886988994213, 0.009035432164352614, 0.049561446318667116, 0.1347085017272271, 0.1200359392924501, 0.027268283817115106, 0.04224558795450571, 0.04315262171954351, 0.05403346926811662, 0.0023262859537098515, 0.010721414504714139, 0.13403654903491943, 0.10987330337776338, 0.013298908898025385, 0.14340914694684173, 0.17825169707180502, 0.10868078009526573, 0.0016445884181541684, 0.07063958523304881, 0.1101738445443299, 0.11758054831650003, 0.060827727766064016, 0.14865227744166581, 0.11702503201869387, 0.09342064187053477, 0.15738531812684184, 0.03201521439082036, 0.06114448967602477, 0.10382777552410098, 0.1431354723068435, 0.18877393058117947, 0.04238816261102419], + [0.18931478384099465, 0.11725809249396936, 0.07996478698818024, 0.12395773281339016, 0.10539552836400544, 0.10640128531778455, 0.15138120999255955, 0.17214766373220333, 0.07026617913163342, 0.12123468761259337, 0.05953366088302137, 0.15540221917752278, 0.08718401146951676, 0.015952009599231567, 0.2078711812851488, 0.11595736507064407, 0.05367369958461762, 0.03702478975393335, 0.19533324153872214, 0.051068878035693224, 0.11913639572715305, 0.014252735205439095, 0.15128772171130855, 0.18155937717307144, 0.16313775262089256, 0.061277317960149645, 0.11196087281767074, 0.01983540026317905, 0.11081801505923433, 0.17865222723918714, 0.09080944119283771, 0.14615838299541906, 0.1160214452995229, 0.03772521745978412, 0.11928405469835733, 0.0337181350584281, 0.18288366080789226, 0.11345639683447971, 0.13040556062135805, 0.010953429366412056, 0.08821138362439966, 0.0745003896914418, 0.16691763812644678, 0.02371156898547879, 0.21558043106834748, 0.2046751323592965, 0.13210262565520578, 0.052778376061538665, 0.028151903578888155, 0.08995676306701976, 0.19328852040933758, 0.07688460533499909, 0.07433245652145608, 0.12378105670329538, 0.1407592548832129, 0.058736057595709795, 0.05700439074739889, 0.14728234783203958, 0.2148957133578259, 0.07954512844968857, 0.1030985532015983, 0.010459822641440727, 0.05737455928138075, 0.1559446201057239, 0.13895900193366503, 0.03156699173602045, 0.04890539260876352, 0.04995541568895709, 0.06255157417661084, 0.002693013244577135, 0.012411591625591608, 0.15516673744807902], + [0.15582045376539008, 0.09651232095756643, 0.06581709648315832, 0.10202663406854806, 0.08674852920264194, 0.08757634360644034, 0.12459823978884935, 0.1416906093289221, 0.05783440518753825, 0.09978536093497073, 0.04900072706893626, 0.12790783591802443, 0.07175906684433664, 0.013129716146784482, 0.17109377902469772, 0.09544172344153798, 0.04417753360227171, 0.03047421560521984, 0.1607741018133701, 0.042033567518396465, 0.09805830725702788, 0.011731084187142908, 0.12452129182889228, 0.14943716471837143, 0.13427476779100272, 0.0504358893497519, 0.09215230661051434, 0.016326041775071437, 0.09121164782573381, 0.147044359398728, 0.07474307101517241, 0.12029945627009313, 0.09549446633957638, 0.031050720834981428, 0.09817984181142858, 0.027752587507058002, 0.15052715078657608, 0.09338323652622518, 0.10733368634652816, 0.009015504756326845, 0.07260467220125497, 0.06131948225009717, 0.13738590080822852, 0.019516423196562774, 0.17743907744797185, 0.168463187880263, 0.10873049983503855, 0.04344061430414566, 0.02317115600283071, 0.07404125211975868, 0.15909114093868224, 0.06328187290927392, 0.061181260489395074, 0.10188121620373095, 0.11585556353592591, 0.04834423895093465, 0.04691894553961334, 0.12122456474448282, 0.17687550273822134, 0.06547168561472232, 0.08485794408914797, 0.00860922891084781, 0.04722362237342663, 0.12835427310079645, 0.11437381855119912, 0.02598203308013339, 0.04025285460153236, 0.04111710339130102, 0.05148469905089557, 0.0022165545513796675, 0.01021568310626363, 0.12771401655964718, 0.10469055633023704, 0.012671596541814639, 0.13664450703816816, 0.16984352667631633, 0.10355428462415937, 0.0015670128333073261, 0.067307501000118, 0.10497692090616872, 0.11203424888888858, 0.057958470933006, 0.14164031795438256, 0.11150493641279158, 0.0890139703593684, 0.14996141925632728, 0.030505049930856305, 0.05826029111642219, 0.027963282761809472, 0.06010840784689968, 0.17473043708133734, 0.12099758313300277, 0.014553883833494794, 0.07334636042494769, 0.07285006732780068, 0.17790630291056034, 0.0989301973089577, 0.13638374168904252, 0.17986942419707855, 0.040388703981232836], + [0.1490765359911958, 0.09233526241995971, 0.06296852894216698, 0.0976109157574458, 0.08299404810701023, 0.08378603465806785, 0.11920562114578914, 0.13555823199591513, 0.0553313289630816, 0.09546664504785775, 0.04687997291732666, 0.12237197777320692, 0.06865333050063585, 0.012561461312757724, 0.16368883089666822, 0.09131100042306806, 0.042265527528094815, 0.029155289884568912, 0.153815789880318, 0.040214352413767675, 0.09381433834769744, 0.011223362220940966, 0.11913200349775391, 0.1429695160437834, 0.12846334848596738, 0.04825302129601608, 0.08816394973267236, 0.015619449792770343, 0.08726400271162271, 0.1406802714694426, 0.07150818680750592, 0.11509288921319505, 0.0913614606055903, 0.029706843936407743, 0.0939306128799265, 0.026551453999575543, 0.14401232745525105, 0.08934160493420577, 0.10268827852213556, 0.008625313216639324, 0.06946233801138785, 0.05866557169947423, 0.13143983149579208, 0.018671751331583056, 0.16975950445661273, 0.161172091881058, 0.1040246378463513, 0.04156050213755719, 0.022168307101803907, 0.07083674267232855, 0.15220566764447255, 0.06054302998342982, 0.058533332184146566, 0.09747179158578337, 0.11084132839998145, 0.046251897641031985, 0.044888291006624594, 0.11597795894213936, 0.1692203212911706, 0.06263806747503713, 0.08118528762078707, 0.008236621012006807, 0.04517978141038145, 0.12279909313025451, 0.10942371341935776, 0.0248575292652322, 0.038510708849485854, 0.0393375529042932, 0.049256438455844605, 0.002120621948981863, 0.00977354778184982, 0.12218654692727692, 0.10015954331772974, 0.012123169149384955, 0.13073052528871054, 0.16249268953840867, 0.09907244951333158, 0.0014991924320470194, 0.06439442866999417, 0.10043351401912919, 0.1071854004601844, 0.055450025136289674, 0.13551011723482043, 0.10667899665704653, 0.08516144084638168, 0.14347108081661994, 0.029184789698902848, 0.0557387825256351, 0.026753030352160315, 0.057506912662784994, 0.16716809419341475, 0.11576080110723733, 0.01392399094397694, 0.0701719259281324, 0.06969711242341488, 0.1702065083755876, 0.13916687524684004, 0.05350498510320062, 0.1415754204215561, 0.06957602019036072, 0.15092969351716987, 0.028763669977259567, 0.09378263985254962, 0.07190282975849477, 0.09464849295042106, 0.13048104587817877, 0.1720846656652933, 0.03864067866059161], + [0.14423132094112415, 0.08933422540125728, 0.060921955602620925, 0.09443841194968906, 0.08029661481691686, 0.08106286059575217, 0.1153312564391741, 0.13115238246727773, 0.053532976284372855, 0.09236383331232718, 0.04535630221478635, 0.11839470164137629, 0.06642199243011034, 0.01215319463954323, 0.15836869395012684, 0.08834325348324733, 0.04089183334666819, 0.028207698445053192, 0.1488165418423116, 0.0389073245555702, 0.09076522910288898, 0.010858585811402444, 0.11526003147710948, 0.13832278846703247, 0.12428809350483766, 0.0466847244246111, 0.08529848674563507, 0.015111793824602163, 0.08442778937693121, 0.1361079478368881, 0.06918406154782372, 0.11135219457426855, 0.08839207363278813, 0.028741326148019417, 0.0908777245352768, 0.02568849120221335, 0.1393317069153209, 0.08643786635491431, 0.09935075267171747, 0.008344977366795651, 0.06720470596146004, 0.056758851040656824, 0.12716783627194342, 0.018064890902733784, 0.16424206134984198, 0.15593375279542385, 0.10064367827736079, 0.04020972235785182, 0.021447803271404914, 0.06853444037229196, 0.14725875103768507, 0.058575289063624865, 0.056630909511498614, 0.09430380952603941, 0.10723881597934645, 0.04474864034400212, 0.04342935300735328, 0.11220849818557717, 0.163720402460575, 0.060602234637766365, 0.07854664180835778, 0.007968918252321884, 0.0437113695279008, 0.11880793509714194, 0.10586727565020065, 0.024049621608251144, 0.03725905200848255, 0.038059022368970546, 0.047655528994591224, 0.002051698497585555, 0.009455892555355895, 0.11821529758108007, 0.09690420522267214, 0.011729147640724243, 0.12648158359965736, 0.15721142901244226, 0.0958524436268398, 0.001450466388834312, 0.06230151141203584, 0.09716927145794031, 0.10370171127996149, 0.05364781465071019, 0.13110583150938676, 0.10321176637367188, 0.08239356398278831, 0.1388080516188944, 0.02823623947037694, 0.05392718698398778, 0.02588351601554489, 0.05563785019185841, 0.16173487587711605, 0.1119983983118956, 0.01347143997725202, 0.06789123118741493, 0.06743184984661066, 0.16467453695890372, 0.1346437393023796, 0.05176599138864854, 0.1369740030812226, 0.06731469329603086, 0.14602424801785077, 0.027828806782710006, 0.09073456085723504, 0.06956587800031083, 0.049289988943616116, 0.15151295985733645, 0.12735852037121487, 0.003333862247204956, 0.05712354925607144, 0.08951490067034465, 0.08782182415229184, 0.0578016188069583, 0.09157227240732324, 0.12624021265090699, 0.16649165126886764, 0.03738479760227176], + [0.1694589116999309, 0.10495973076633594, 0.07157785304667531, 0.11095669378356957, 0.09434134604936262, 0.09524161635770365, 0.1355039187996205, 0.1540923278989471, 0.06289646272400928, 0.10851924929627423, 0.053289601467273046, 0.13910319312249428, 0.07803990476341967, 0.014278917532309872, 0.18606906148410648, 0.10379542732894517, 0.04804424955083078, 0.0331415246623844, 0.17484613646324135, 0.04571262908307061, 0.10664103222246049, 0.012757867862499155, 0.13542023583479298, 0.16251691410696706, 0.1460274018511314, 0.05485037883855437, 0.10021809853261156, 0.017755007155458, 0.09919510694134144, 0.15991467431380685, 0.08128508912194579, 0.13082887672960547, 0.10385278664144561, 0.03376848952138687, 0.10677320430144628, 0.030181681301506596, 0.1637023031134973, 0.10155676774358248, 0.11672825510064294, 0.009804602589163004, 0.07895952320919036, 0.06668657725609006, 0.14941084223083015, 0.021224632294707106, 0.19296974325749094, 0.18320822324566463, 0.118247327134454, 0.047242830101371744, 0.02519925198639844, 0.08052184229937957, 0.17301587149245923, 0.06882072959230966, 0.06653625739386522, 0.11079854796562234, 0.12599602450612882, 0.052575653077750396, 0.0510256083660385, 0.13183495694235145, 0.19235684068489467, 0.07120220948743744, 0.0922852841648866, 0.009362766739239825, 0.05135695257298015, 0.13958870550104785, 0.12438458719824694, 0.028256155999520978, 0.043776056151534036, 0.044715949829245226, 0.05599098744442927, 0.0024105623679280823, 0.011109828649743763, 0.13889240938555025, 0.11385378050363983, 0.013780700207108917, 0.14860455667344946, 0.1847093786107272, 0.11261805462777208, 0.0017041683741461791, 0.07319870782750477, 0.11416520964027846, 0.12184024260650132, 0.06303138754099037, 0.15403763468383044, 0.12126460112952524, 0.09680507390833237, 0.16308705494091372, 0.03317505781633879, 0.06335962506420917] + ] - @testset "Geodesics are unit speed." begin - for M in Ms - p = rand(M) - p[1][1] = p[1][1] + 0.5 # Keep away from 0 - v = rand(M, vector_at=p) - v = v / norm(M, p, v) +# Xs are tangent vectors in a chart +Xs = [ + [-0.597609995187605, -0.4256244780566225, 0.039001131483688445, 0.2861310539156201, -0.5445479395430848, 0.5398107502679328, -0.370911828798264, 0.9784991722126772, -0.858313200235999, 0.6327050201672981], + [-0.5103976757921316, -0.7856231887301031], + [0.06161321757315563, -0.2461307077230097, 0.04558383266520161, 0.6251649963255619, 0.5702228612959974, -0.6849942773520477, 0.47667344530694655], + [0.20291047527778772, -0.33259407228555404, 0.2518919563557016, 0.7589380540013582, 0.5699565849101806, -0.0840258727078147, 0.17702183701764684, -0.020864846013727956], + [-0.5689099191621423, 0.544600536529926, -0.34916078856459043, 0.9822571022455582, 0.030233304809939243, 0.5950623927405945, 0.10709287674567114, -0.45335793482945186, -0.42415769187544816, 0.44897078165811233, -0.059509496330804046, -0.988472595808626, 0.7941397305966094, -0.1645857296563873, 0.6909105365607005, 0.8511592194074467], + [-0.9098421775458598, -0.20952423053057156, 0.9924786336664817], + [-0.33715222274078416, -0.26704690491931915, -0.5195355208430397, 0.645753717662719, 0.10444433627227578, 0.33684638019021196, 0.06539241093725567, 0.09555909109964422, 0.7542247481144044, -0.20290163218931467, -0.2664420819862636, 0.339548396803274, 0.9402884626822843, -0.6574225234652968, 0.07702642759782674, -0.5460026086958019, -0.6357161050460245, -0.5843960906310703, -0.2548940878123618, 0.6267033715997288, 0.08231062546698587, 0.15159625893365325, -0.12967230344148017], + [0.42221703960978085, 0.6412610989675429, -0.3378728652151137, -0.7259095427151108, 0.3792220940510249, 0.09853495773970455, -0.03328822790230723, 0.10717331421952858, 0.9602549746343043, 0.36453406652382325, 0.05098955982227471, -0.8550440747345822, -0.13618136406595704, -0.6238820462729322, 0.15657227739200308, -0.7875237399365813, 0.3339506933166785, -0.7658809531191957], + [0.8929561594617814, 0.9142838995513609, -0.9454002503436634, 0.599611685359211, -0.08033334402177683, 0.352934685220305, 0.9826231085574035, -0.13566440227650745, -0.15023573234217635, 0.8858256604892685, -0.9499508153272389, 0.6730026466902008], + [-0.34597205746030824, 0.9028413427061659, 0.32181983134495096, 0.9413815779327186, 0.16359943156565016, 0.7838434998605843, -0.35087705212133735, -0.2339200570289206, -0.9229212375554967, 0.9129319387405792, -0.9083283912242541, 0.13034732808854765, 0.9882693345252747, 0.19949043337639316, 0.5191850007789172, 0.6832919121607344, 0.08923979072216182, -0.1641363924011765, 0.060902972183083826, -0.13189846296393637, 0.8496859744073246], + [0.09276610111152617, 0.09805875319182467, 0.40149199598583674, 0.4121056057132706, -0.5187299383130162, 0.9808043473462107, 0.9121302771494377, -0.05119856203718953, 0.6638686937978975, 0.8072960740642445, 0.588215689842168, 0.5571754021224098, -0.8228465883832383, 0.09319381915262914, -0.2212392016482081, 0.4600044998096078, -0.7708333499135387, -0.7406857285885389, -0.8937974999435008, 0.19396510657575705, 0.5206418037886062, 0.4451978368270184, 0.8422191864577384, -0.018333885981625553, 0.6610697223081674, -0.14582004740489873], + [0.22774235157623135, -0.9570617965471404, -0.7677114506774323, 0.7761020139166568, 0.5705454599965643, -0.38571286832595675, -0.789873188052665, 0.9318173591345504, 0.2627790302374746, -0.23646863157711917, -0.5637044935797642, 0.20520758669977424, 0.7064722394615206, -0.584610567954003, 0.6716584109355441, 0.25481219283479906, -0.9870528012093185, 0.4129387951226837, 0.2284244974693428, -0.7618228616844276], + [-0.3508209068712791, 0.5477811869201115, 0.9576443316471701, 0.3815048454137753, -0.3581096313769696, -0.3297365896057076, 0.46016273166688904, -0.8346220116109249, -0.3150517800054915, 0.5838284430955387], + [0.6225357146388626, 0.7513896391924713, 0.15368488777021372, 0.9474331253267687, -0.7931484910144164, 0.5669848314865438, 0.5833361007240527, -0.15116391703821175, 0.12146654441996918], + [-0.6912699112418559, -0.2315737570979124, 0.6276350160464672, 0.706838194684831], + [0.30756479319371266, -0.43184860921312285, 0.37624726262849206, 0.8139529250407125, -0.585675532332042, -0.5857479127690419, -0.45612298630613823, 0.2559126942459271, -0.7348456829025003, -0.8876636700373159], + [0.9692875025266756, -0.23787854062334635, -0.24748080007875295, 0.7036144791890337, 0.882878776380204, 0.6653207722292824, -0.8471461307631554, 0.054870797521041625, 0.3479947908450005, -0.40254986389467895], + [-0.5561604381577363, -0.6690805833024565, -0.49296974074635713], + [0.5526596524494152, 0.9690315932495712, -0.8680156139856099, 0.39561955960098705, -0.7189141230781315, 0.1091438241240188, -0.1514792667377174, -0.8842187642857129, -0.90929587555064, 0.0553477365473245, -0.38102440387803127, -0.21972849843690567, -0.1366925641984078, 0.234658614104986, 0.6618349090074298, 0.3456641681297574, -0.13000537043751015, 0.015349401356097525, 0.4014083014273322, -0.05782560373055445, -0.3626979339434868, -0.46909114377791794, 0.037734998042463275], + [-0.23849715068438293, 0.7921459122177519, 0.7585522723532372, 0.8898425015365772, 0.6681429223463302, -0.7046659515927074, -0.2533112691118138, -0.9895684050716598, 0.7064520294805683, -0.06906516907342031, 0.8213751152386364, -0.6183596959717537, 0.5207021021865952, 0.7449011143255648, 0.9149814958723772, -0.8454584370536609, 0.8033846014701953, 0.7737784202696005], + [0.4835975048151546, -0.5987307405530511, 0.277769205131432, -0.5497708234569545, -0.9238315028510387, 0.5332814495117155, -0.5911554383083086, -0.9275056197495566, 0.5302218322249228, -0.7802927767456045, 0.20312945269109162, -0.2622275493784205, -0.17603338014279468, 0.45721842042830585, -0.07856217105142416, 0.458134032752032, 0.7601845863976819, -0.0687601004445304, 0.5084467209402248, -0.5503154953218936, 0.8116513645055918, -0.10424664785069293, -0.4650749134336116, 0.17127951460844226, -0.21534156550417394], + [-0.6945216072262328, 0.06573632900997772, -0.106647523045865, 0.13865277008666044, -0.7820633695316517, -0.10880551946361727, 0.2658232882927578, -0.08490107870171215, 0.8401971948812119, -0.5389907554930264, 0.9847445142919777, 0.6022812602894703, 0.45645830164530143, -0.24553265752254427, 0.06468186895698413, 0.692893319789019, -0.19092820288195367, 0.45737634128864624, 0.10728439355457109, 0.5890201396380044, -0.9502112271317584, -0.2302405122715243, 0.8242967867244597, -0.7636718337376485, -0.2653389884306485, 0.500710013837995, -0.24084472766713083], + [-0.8374018409716684, 0.4276765409684762, -0.6486173821583863, 0.08856823496937882, 0.557143175184845, -0.1985822093439542, -0.1801379487124286, 0.043017831672796714, -0.1929487463516646, -0.5763738177808153, -0.49637049997464744, 0.12581361013858916, 0.3855284958072094, 0.15109520635764673, 0.41672543545469565, -0.7485533043159125, 0.1884036602694128, 0.6381773143883831, 0.20656419313369856, 0.5496422308632847, 0.685510222422288, 0.17777973619459675, -0.2579184029541337, -0.2079419738929984, 0.6082747209746782, 0.5014782256507726, -0.7783280743075152, -0.5276060845071164, -0.9311912948488923], + [0.6670456246431664, 0.07506905805544695, 0.8002014930850021, -0.761108481031973, -0.3309405791117992, -0.4968484241950417, 0.5855902060858931, 0.9782616605547247, 0.5179425134945737, 0.9992716621826399, 0.04240304791255256, 0.269024423156097, 0.3525829475191862, -0.43198618097746966, 0.3216754129865127, -0.7577084174756146, -0.4026041614694662, 0.1403933118873224, 0.7634052300441858, -0.5740345150905044, 0.912328468664054, -0.6498208158571068] + ] + +for (M, p, q, v, u, dy, X) in zip(Ms, ps, qs, vs, us, dys, Xs) + V = typeof(M).parameters[2] - geodesic_speed = - finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.5 * rand(), 1e-5) - @test(isapprox(geodesic_speed, 1.0; rtol=1e-6)) + @testset "Manifold $M" begin + @testset "rand()" begin + @test(is_point(M, rand(M))) + @test(is_vector(M, p, rand(M, vector_at=p))) end - end - @testset "Geodesics are minimizing." begin - for M in Ms - p = rand(M) - v = rand(M, vector_at=p) - v = v / norm(M, p, v) - n = manifold_dimension(M) + @testset "exp()" begin + @test(is_point(M, exp(M, p, v))) + @test(isapprox(p, exp(M, p, 0.0 * v); atol=1e-5)) + + geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), -1.0, 1e-3) + @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) + geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), -0.811, 1e-3) + @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) + geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), -0.479, 1e-3) + @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) + geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.181, 1e-3) + @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) + geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.703, 1e-3) + @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) + geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), 1.0, 1e-3) + @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) - # We test the following: - # Geodesics are (locally) length-minizing. So let B_a be a one-parameter - # family of curves such that B_0 is a geodesic. Then the derivative of - # length(B_a) at a = 0 should be 0, and the second derivative at should - # be nonnegative. + # Geodesics are (locally) length-minizing. So let B_a be a one-parameter + # family of curves such that B_0 is a geodesic. Then the derivative of + # length(B_a) at a = 0 should be 0, and the second derivative should be + # nonnegative. + + n = manifold_dimension(M) x = get_coordinates(M, p, v) x0 = 0.0 * x x1 = 0.2 * x @@ -128,7 +276,7 @@ using Manifolds, Test y3 = y[(2 * n + 1):(3 * n)] y4 = y[(3 * n + 1):(4 * n)] - # Bezier curve from 0 to v + # Bezier curve from 0 to v with control points y1, ..., y4 function b(t) return ( (1 - t)^5 * x0 + @@ -141,105 +289,58 @@ using Manifolds, Test end # Length of curve on manifold - ps = [exp(M, p, get_vector(M, p, b(t))) for t in 0.0:1e-3:1.0] - ds = [distance(M, p1, p2) for (p1, p2) in zip(ps[1:(end - 1)], ps[2:end])] + ps_ = [exp(M, p, get_vector(M, p, b(t))) for t in 0.0:1e-3:1.0] + ds = [distance(M, p1, p2) for (p1, p2) in zip(ps_[1:(end - 1)], ps_[2:end])] return sum(ds) end - dy = rand(4 * n) - dy = dy / norm(dy) + # dy = rand(4 * n); dy = dy / norm(dy) f = a -> curve_length(a * dy) @test(isapprox(finite_difference(f, 0.0, 1e-3), 0.0; atol=1e-5)) - @test(finite_difference(f, 0.0, 1e-2; order=2) >= 0.0) + @test(finite_difference(f, 0.0, 1e-3; order=2) >= 0.0) end - end - - @testset "log is inverse of exp." begin - for M in Ms - # TODO: This function can be written for a general manifold that implements injectivity_radius - p = rand(M) - - # Make sure we choose p and q compatible - function m(a, b) - return sqrt( - sum([ - distance(Sphere(n - 1), x, y)^2 for - (n, x, y) in zip(V, a[2:end], b[2:end]) - ]), - ) - end - q = rand(M) - A = get_warping_factor(M) - while A * m(p, q) > pi - q = rand(M) - end - v = rand(M, vector_at=p) - v = v / norm(M, p, v) - - @test( - isapprox( - norm(embed(M, q) - embed(M, exp(M, p, log(M, p, q)))), - 0.0, - ; - atol=1e-10, - ) - ) + @testset "log()" begin + @test(is_vector(M, p, log(M, p, q))) + @test(isapprox(0.0 * v, log(M, p, p); atol=1e-5)) + @test(isapprox(q, exp(M, p, log(M, p, q)), atol=1e-10)) end - end - @testset "get_coordinates is left and right inverse of get_vector. " begin - for M in Ms - p = rand(M) - v = rand(M, vector_at=p) - X = rand(manifold_dimension(M)) + @testset "riemann_tensor()" begin - @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) - @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) - end - end + # Test Riemann tensor by testing that sectional curvature is difference + # between circumference and 2 pi r for small circles. Since the sectional + # curvature contains the same information as the Riemann tensor, this + # should be fine. - @testset "sectional_curvature is compatible with riemann_tensor." begin - for M in Ms - p = rand(M) - v = rand(M, vector_at=p) - u = rand(M, vector_at=p) - - @test( - isapprox( - sectional_curvature(u, v), - inner(M, p, riemann_tensor(M, p, u, v, v), u) / - (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2), - ) - ) - end - end + sectional_curvature(M, p, u, v,) = inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) - @testset "Sectional curvature is difference between circumference and 2 pi r for small circles" begin - for M in Ms - p = rand(M) - p[1][1] = p[1][1] + 0.1 # Keep away from 0.0 - - u = rand(M, vector_at=p) - u = u / norm(M, p, u) - v = rand(M, vector_at=p) - v = v - inner(M, p, u, v) * u - v = v / norm(M, p, v) + # Orthonormalize + u_ = u / norm(M, p, u) + v_ = v - inner(M, p, u_, v) * u_ + v_ = v_ / norm(M, p, v_) r = 1e-2 - ps = [ - exp(M, p, r * (cos(theta) * u + sin(theta) * v)) for + ps_ = [ + exp(M, p, r * (cos(theta) * u_ + sin(theta) * v_)) for theta in 0.0:1e-3:(2 * pi) ] - ds = [distance(M, p1, p2) for (p1, p2) in zip(ps, [ps[2:end]..., ps[1]])] + ds = [distance(M, p1, p2) for (p1, p2) in zip(ps_, [ps_[2:end]..., ps_[1]])] C = sum(ds) K = 3 * (2 * pi * r - C) / (pi * r^3) # https://en.wikipedia.org/wiki/Bertrand%E2%80%93Diguet%E2%80%93Puiseux_theorem @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) end - end - # TODO: Test that distance and inner are compatible - # TODO: Test second_fundamental_form - =# + @testset "get_coordinates()" begin + @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) + end + + @testset "get_vector()" begin + @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) + end + + end end + +# TODO: Test that distance and inner are compatible From 09e5207cfd87aab34e18a405cf27b130bb3bed41 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Fri, 6 Dec 2024 11:05:00 +0100 Subject: [PATCH 09/35] formatting --- src/manifolds/Segre.jl | 14 +- src/manifolds/SegreWarped.jl | 32 +- test/manifolds/segre.jl | 4161 ++++++++++++++++++++++++++++++++-- 3 files changed, 4011 insertions(+), 196 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 4a0d539021..1c8cdab793 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -23,7 +23,7 @@ Generate a valence `V` Segre manifold. struct Segre{𝔽,V} <: AbstractManifold{𝔽} end function Segre(valence::NTuple{V,Int}; field::AbstractNumbers=ℝ) where {V} - return Segre{field, valence}() + return Segre{field,valence}() end valence(::Segre{𝔽,V}) where {𝔽,V} = V @@ -156,7 +156,7 @@ function get_vector(M::Segre{𝔽,V}, p, X; kwargs...) where {𝔽,V} v[i + 1] = get_vector( Sphere(n - 1), p[i + 1], - X_[1:n - 1], + X_[1:(n - 1)], DefaultOrthonormalBasis(); kwargs..., ) @@ -179,7 +179,6 @@ Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ function inner(M::Segre{ℝ,V}, p, u, v) where {V} - return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) end @@ -189,7 +188,6 @@ end Norm of tangent vector ``v`` at ``p``. """ function norm(M::Segre{𝔽,V}, p, v) where {𝔽,V} - return sqrt(inner(M, p, v, v)) end @@ -219,7 +217,6 @@ Embed ``p \doteq (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times ```` """ function embed(M::Segre{𝔽,V}, p) where {𝔽,V} - return kronecker(p...)[:] end @@ -338,7 +335,9 @@ exp(M::Segre{ℝ,V}, p, v) where {V} function exp!(M::Segre{ℝ,V}, q, p, v) where {V} m_ = sqrt( - sum([norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end])]), + sum([ + norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + ]), ) q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * m_)^2) @@ -384,7 +383,6 @@ where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \oper For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ function log(M::Segre{ℝ,V}, p, q) where {V} - q_ = closest_representation(M, p, q) if connected_by_geodesic(M, p, q_) v = zeros.(size.(p)) # Initialize @@ -423,7 +421,6 @@ and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimi ```` """ function distance(M::Segre{ℝ,V}, p, q) where {V} - q_ = closest_representation(M, p, q) return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m(M, p, q_) / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(m)) but more stable for small m @@ -471,7 +468,6 @@ If ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^ ``K_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ function sectional_curvature(M::Segre{ℝ,V}, p, u, v) where {V} - return inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) end diff --git a/src/manifolds/SegreWarped.jl b/src/manifolds/SegreWarped.jl index 19fa5b3f4c..bb7acd00b8 100644 --- a/src/manifolds/SegreWarped.jl +++ b/src/manifolds/SegreWarped.jl @@ -51,7 +51,7 @@ Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v ```` where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ -function inner(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v) where {V, A} +function inner(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v) where {V,A} return u[1][1] * v[1][1] + (A * p[1][1])^2 * dot(u[2:end], v[2:end]) end @@ -80,7 +80,11 @@ end Check if two points, `p` and `q`, can be connected by a geodesic. """ -function connected_by_geodesic(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} +function connected_by_geodesic( + M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, + p, + q, +) where {V,A} q_ = closest_representation(M.manifold, p, q) return A * m(M, p, q) < pi @@ -91,7 +95,11 @@ end Find the representation of ``q`` that is closest to ``p``. """ -function closest_representation(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} +function closest_representation( + M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, + p, + q, +) where {V,A} return closest_representation(M.manifold, p, q) end @@ -126,7 +134,9 @@ exp(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, v) where {V,A} function exp!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) where {V,A} m_ = sqrt( - sum([norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end])]), + sum([ + norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + ]), ) q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * A * m_)^2) @@ -139,7 +149,9 @@ function exp!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) wher else for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) a = norm(Sphere(n - 1), x, xdot) - y .= x * cos(a * f / (A * m_)) .+ xdot * (f / (A * m_)) * sinc(a * f / (A * m_ * pi)) + y .= + x * cos(a * f / (A * m_)) .+ + xdot * (f / (A * m_)) * sinc(a * f / (A * m_ * pi)) end end @@ -172,7 +184,6 @@ where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \oper For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ function log(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} - q_ = closest_representation(M, p, q) if connected_by_geodesic(M, p, q) v = zeros.(size.(p)) # Initialize @@ -211,7 +222,6 @@ and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimi ```` """ function distance(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} - q_ = closest_representation(M, p, q) return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m(M, p, q_) / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(A * m)) but more stable for small m @@ -228,7 +238,13 @@ Riemann tensor of the warped Segre manifold at ``p``. ```` ``R_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ -function riemann_tensor(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v, w) where {V,A} +function riemann_tensor( + M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, + p, + u, + v, + w, +) where {V,A} # Can we avoid the deep-copies here? That looks a bit inefficient u_ = deepcopy(u) u_[1][1] = 0.0 diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index 6a4426a620..4e423afdda 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -2,7 +2,7 @@ using Manifolds, Test # Approximate derivative of f at x # https://en.wikipedia.org/wiki/Finite_difference_coefficient -function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64)#={{{=# +function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64) #={{{=# if order == 1 return ( (1 / 12) * f(x - 2 * h) + @@ -28,203 +28,4000 @@ function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64)# (-1 / 8) * f(x + 3 * h) ) / h^3 end -end#=}}}=# +end #=}}}=# # Manifolds to test -Ms = [ - Segre{ℝ, (10,)}(), - Segre{ℝ, (2,)}(), - Segre{ℝ, (7,)}(), - Segre{ℝ, (7, 2)}(), - Segre{ℝ, (9, 8)}(), - Segre{ℝ, (2, 2)}(), - Segre{ℝ, (7, 9, 9)}(), - Segre{ℝ, (10, 7, 3)}(), - Segre{ℝ, (5, 6, 3)}(), - Segre{ℝ, (9, 3, 6, 6)}(), - Segre{ℝ, (5, 4, 10, 10)}(), - Segre{ℝ, (10, 6, 3, 4)}(), - MetricManifold(Segre{ℝ, (10,)}(), WarpedMetric{1.2025837056880606}()), - MetricManifold(Segre{ℝ, (9,)}(), WarpedMetric{1.1157384770946328}()), - MetricManifold(Segre{ℝ, (4,)}(), WarpedMetric{1.108519951945247}()), - MetricManifold(Segre{ℝ, (2, 9)}(), WarpedMetric{1.1302422072971439}()), - MetricManifold(Segre{ℝ, (4, 7)}(), WarpedMetric{1.4990018903833313}()), - MetricManifold(Segre{ℝ, (2, 2)}(), WarpedMetric{1.1978398577942357}()), - MetricManifold(Segre{ℝ, (9, 6, 10)}(), WarpedMetric{1.4545138169484464}()), - MetricManifold(Segre{ℝ, (9, 9, 2)}(), WarpedMetric{0.886048645869852}()), - MetricManifold(Segre{ℝ, (10, 10, 7)}(), WarpedMetric{1.2810851738110494}()), - MetricManifold(Segre{ℝ, (9, 3, 8, 10)}(), WarpedMetric{1.396673190458706}()), - MetricManifold(Segre{ℝ, (10, 9, 7, 6)}(), WarpedMetric{1.294280190668267}()), - MetricManifold(Segre{ℝ, (7, 2, 8, 8)}(), WarpedMetric{1.2374529454448573}()) - ] +Ms = [ + Segre{ℝ,(10,)}(), + Segre{ℝ,(2,)}(), + Segre{ℝ,(7,)}(), + Segre{ℝ,(7, 2)}(), + Segre{ℝ,(9, 8)}(), + Segre{ℝ,(2, 2)}(), + Segre{ℝ,(7, 9, 9)}(), + Segre{ℝ,(10, 7, 3)}(), + Segre{ℝ,(5, 6, 3)}(), + Segre{ℝ,(9, 3, 6, 6)}(), + Segre{ℝ,(5, 4, 10, 10)}(), + Segre{ℝ,(10, 6, 3, 4)}(), + MetricManifold(Segre{ℝ,(10,)}(), WarpedMetric{1.2025837056880606}()), + MetricManifold(Segre{ℝ,(9,)}(), WarpedMetric{1.1157384770946328}()), + MetricManifold(Segre{ℝ,(4,)}(), WarpedMetric{1.108519951945247}()), + MetricManifold(Segre{ℝ,(2, 9)}(), WarpedMetric{1.1302422072971439}()), + MetricManifold(Segre{ℝ,(4, 7)}(), WarpedMetric{1.4990018903833313}()), + MetricManifold(Segre{ℝ,(2, 2)}(), WarpedMetric{1.1978398577942357}()), + MetricManifold(Segre{ℝ,(9, 6, 10)}(), WarpedMetric{1.4545138169484464}()), + MetricManifold(Segre{ℝ,(9, 9, 2)}(), WarpedMetric{0.886048645869852}()), + MetricManifold(Segre{ℝ,(10, 10, 7)}(), WarpedMetric{1.2810851738110494}()), + MetricManifold(Segre{ℝ,(9, 3, 8, 10)}(), WarpedMetric{1.396673190458706}()), + MetricManifold(Segre{ℝ,(10, 9, 7, 6)}(), WarpedMetric{1.294280190668267}()), + MetricManifold(Segre{ℝ,(7, 2, 8, 8)}(), WarpedMetric{1.2374529454448573}()), +] # ps[i] is a point on Ms[i] ps = [ - [[0.4679314536763416], [-0.317396495862958, 0.09740239786995583, -0.03435690079466174, -0.507098294482249, -0.3456993992812562, 0.03370180478069075, 0.12197903860091835, -0.19063489706041362, -0.6772451984545433, -0.030292993087650443]], + [ + [0.4679314536763416], + [ + -0.317396495862958, + 0.09740239786995583, + -0.03435690079466174, + -0.507098294482249, + -0.3456993992812562, + 0.03370180478069075, + 0.12197903860091835, + -0.19063489706041362, + -0.6772451984545433, + -0.030292993087650443, + ], + ], [[0.3298310216639224], [0.2514005595224343, -0.96788313275509]], - [[0.42312947328046224], [0.33560958022362747, -0.7750899034491946, 0.23449838016304786, 0.36554747855051023, -0.28711573724812484, -0.014134328816621394, 0.12390389837644036]], - [[1.5024828708442504], [-0.20674979086955983, 0.006156775886150006, -0.3570727686996312, -0.02472149296318015, -0.8820637035264094, -0.19877726490312608, 0.10749756092041758], [0.13573491868289245, 0.9907451901726038]], - [[0.3013653757380563], [0.5977968840579448, -0.22702223761000456, 0.5118227538696087, -0.11912796582968001, 0.06221848112591997, 0.1884433539067577, -0.10700788275590943, -0.3518682598612047, 0.37456880426014166], [0.013604873029341946, -0.16528022578112536, 0.20155485791540892, -0.3541277493897382, 0.676862752046083, -0.2658785210172399, 0.5147053312531512, -0.112740319727795]], - [[2.851092491176718], [0.3804764585148756, -0.9247906057675856], [0.43841826755186564, -0.8987710624384948]], - [[0.5567549635823631], [0.20108807178297264, 0.11422009200726954, -0.4229195164047098, 0.8118482504243884, -0.2985123290622806, -0.10304198468607091, 0.0939765805139303], [0.04424901152619659, -0.7169306819079923, -0.031129292324036512, 0.6372250118096429, -0.02583896509973039, 0.014153747195613426, 0.16225623748001994, -0.11092394734951527, 0.19372269982536366], [0.42796852361059873, 0.1000612228302854, -0.6494403216595616, 0.012394320858700462, -0.44765471097923526, 0.28788160552521874, 0.26926315361113184, 0.14434420119149496, 0.09108177932795573]], - [[0.36252817849574176], [-0.4152409797128937, 0.3949651690781115, 0.059637140694856684, -0.29809447149493, -0.45495068818315665, 0.15339000916151824, 0.5145387514659299, 0.0726835092343826, 0.15840576161081632, 0.23135797656647117], [-0.539717469908245, 0.4395297187977435, 0.21328340065082524, 0.45891791025442036, -0.08479985319672712, -0.07573386931397807, -0.4964842269000107], [0.3787170228715312, 0.8302726053139932, 0.40892642058497286]], - [[0.2755990738257318], [0.21794010543619222, -0.832205317244186, -0.08165195766640711, -0.32019564073885964, 0.3882578136419659], [0.8072220207586441, 0.1839997459775723, 0.25829762282479984, -0.16088661411000194, 0.4709383701765526, -0.012312173701218641], [-0.5999408691302599, 0.19608311412450938, -0.7756431949694802]], - [[0.13874530878036045], [0.22313639103335817, -0.582683687448744, 0.019810748294280565, -0.532091804219692, 0.4183784535017075, 0.14178309829111962, -0.20220724006960822, 0.29098277220121593, 0.08046116169937856], [0.9267624891781729, -0.13156790592635095, 0.35185391113703934], [-0.20128032438008028, -0.8385905159101716, 0.32092863797763976, -0.004535145988646948, 0.2201729511393691, -0.3236669445683654], [-0.4807744861170881, -0.7965214809133648, 0.05085093394774735, -0.18228152610151416, -0.3136581939724126, -0.014682951172671068]], - [[0.21051807193802943], [0.23403384696597218, 0.42054682357471496, -0.5698122696955275, 0.5838315012795727, -0.32066069773765116], [0.5766960203474961, -0.6743800959552224, 0.13162023644111331, 0.4419381174485529], [-0.21057589355060127, 0.08811991196707877, 0.3405460927874034, -0.3897589394700625, 0.7083087794882124, -0.1136094071563721, 0.08025571453602402, 0.38379031842997346, -0.10397276906281434, 0.029227598658195648], [-0.5554668166067296, -0.20795381463643023, 0.2553028805249397, 0.10256974403643938, -0.08894446390830917, 0.04610645378979823, 0.27966690408533734, -0.07380638485934377, -0.33321238127988634, 0.6064514324865661]], - [[0.4828275813633084], [0.23384095547788736, 0.3512388738563172, 0.20430444349630456, 0.6579221192887889, 0.09844835569247844, 0.363573528638023, 0.2687104582601494, -0.14301608669058016, -0.09631021994329247, -0.3217692977748192], [-0.5116624664211036, 0.07668016024356412, 0.5061460483419392, 0.3214705004283764, -0.46018395871455636, 0.40127956928413683], [-0.38096699727867506, 0.2861444037357305, -0.8791959549470149], [0.692923641553941, -0.3060961599674285, 0.22172696315719087, 0.6140025420451529]], - [[1.1838757652294163], [0.210872386528422, 0.07121151449265378, -0.5646662541775129, 0.3616416663029674, 0.06637879222702027, 0.07584789624963773, -0.5828313418578935, 0.2675952004007925, 0.22734623628568493, 0.16638557775398255]], - [[0.3032739397640297297], [-0.48082028355309697, 0.3388907360614881, 0.454066186534629, -0.17812152265340722, -0.2993680565146906, -0.4376744632861303, -0.07894707721342749, -0.15363745968032946, 0.3241053320409901]], - [[1.1617468533361055], [-0.02260630098657834, 0.2972001146356296, 0.7596474220087696, -0.5780111082424827]], - [[1.2844162220009774], [-0.30842015389728145, 0.951250234517699], [0.30279327531038325, 0.08852690888227953, 0.05590206678861999, -0.11020418544430191, 0.34622673649276936, 0.039237251633264296, 0.2036788352046126, 0.7474907644209177, -0.4044368794841003]], - [[0.18104388996897572], [0.5520877166363866, -0.052976780373050814, -0.8311689032169315, -0.03938106404973989], [0.034274688844047635, 0.16403282417490214, 0.2354752745921137, 0.49694577571607884, -0.1464762658164691, -0.0454250584931338, -0.8037387865251501]], - [[1.6905902450546004], [-0.12543067772892338, -0.99210238639188], [0.8762083930519261, -0.48193241429204725]], - [[0.5007028223906543], [-0.06769241297456885, -0.5449485746545011, 0.398606571568952, 0.6501033139153659, -0.04258821690222594, -0.13267612920115782, 0.28917066939208946, -0.0862022715614269, 0.08037444499516286], [-0.435703924552393, 0.003588856443541161, -0.6651813230937048, 0.2132673584452006, -0.23794057413100464, -0.5153487505082289], [0.10026563183607826, -0.41453578717039885, 0.22729656824470607, -0.4898014879827773, 0.3079502543279662, 0.32626734055020185, 0.22241280421779944, -0.20185051232763798, 0.26385177592505493, -0.4067248155023813]], - [[0.42070460277285854], [-0.11765364391216213, -0.02107059901087521, 0.01919962552849528, 0.0075532937836861914, -0.407416349154066, 0.2526422092654315, 0.18892381530643113, -0.039220900801933495, -0.8474911902514953], [-0.32443831265566164, -0.2349409435382715, -0.24293165040461917, 0.17482035071905289, 0.4202882276170908, 0.29174253040759934, -0.12773231584125186, 0.17922569173029038, 0.6631525474037887], [0.2845093749411345, -0.9586732579824081]], - [[0.10062440822372039], [0.07996808517600432, -0.26307264663569147, -0.4495698788298603, 0.6111308460433761, -0.11895028828957643, 0.20924569495870432, 0.3301577806915321, -0.004487812699664358, 0.3268240075329048, -0.27392104072489637], [0.12284217101173843, 0.35404646594484673, -0.035991021401721314, 0.5860476109030441, -0.4404194916015131, 0.2346021425142989, -0.16531437985938108, 0.29739181674429876, 0.0961161858068593, 0.3752295207239467], [0.37225889195343176, -0.40269820383703075, 0.5891470410337922, -0.5231944785778554, 0.017605742011659636, 0.24075511508976774, 0.14197812515009833]], - [[0.18481028402754704], [0.3100324954044331, 0.20571167887073383, 0.2759549800636245, -0.5098047663273968, -0.40513901097801985, -0.006849531735112356, 0.32426009440794523, 0.0980343539650855, 0.496558786543343], [0.7400543367573574, -0.6634600702609377, -0.11018309224186618], [-0.3047981091301781, -0.2991724005041669, -0.180567141067543, -0.46275630707119686, 0.5780573143957574, 0.04795327307127396, 0.27896164368216786, -0.3956977653578857], [-0.5375940335785957, -0.33527871549213856, -0.34423023822843113, -0.057618837476544824, 0.2307053118861316, -0.5816558302641435, 0.1347923363882464, 0.005386448290725161, 0.17361223551501662, -0.19203856057632393]], - [[0.4228588017696557], [-0.141865030134013, 0.44059694416524103, -0.4181744594149625, -0.3452888941246838, -0.3554076392829921, 0.06722507728789844, -0.08166976238961376, -0.07165859365772556, -0.13418586367363106, 0.5753345078159252], [0.45050543565810647, 0.3522148480832122, 0.20063517590059027, -0.2069225940646595, 0.5565420673454308, -0.2904080923745975, 0.3836714803715129, 0.18159571033346678, 0.12514543453657165], [0.14887119923616898, 0.10387753894769929, -0.13940282319720718, -0.6456183547647123, -0.468455996706801, 0.3389787430786487, -0.4432076338534407], [-0.08150071800245477, -0.5444374572967173, 0.6051990477077818, 0.2041079018657187, -0.4187164733526199, 0.3371884933536173]], - [[0.17800461834682948], [0.40442214560226664, -0.18410967602595124, -0.37808224287777675, 0.5298695372118921, 0.20342335952859486, 0.47237240617396475, 0.3381149112046999], [-0.0671758988249334, -0.997741148102584], [0.5860119193049029, -0.1655879827363143, 0.42146580605026046, -0.05072788682343524, 0.01966945374695293, -0.18509497429620517, -0.2917989581694971, 0.5737335943846366], [-0.45925413330012654, -0.054244623817065345, -0.11041902728376159, 0.03752800032819433, 0.24065851466537416, -0.17318765966122213, -0.5175866433893724, -0.6455509506489918]] - ] + [ + [0.42312947328046224], + [ + 0.33560958022362747, + -0.7750899034491946, + 0.23449838016304786, + 0.36554747855051023, + -0.28711573724812484, + -0.014134328816621394, + 0.12390389837644036, + ], + ], + [ + [1.5024828708442504], + [ + -0.20674979086955983, + 0.006156775886150006, + -0.3570727686996312, + -0.02472149296318015, + -0.8820637035264094, + -0.19877726490312608, + 0.10749756092041758, + ], + [0.13573491868289245, 0.9907451901726038], + ], + [ + [0.3013653757380563], + [ + 0.5977968840579448, + -0.22702223761000456, + 0.5118227538696087, + -0.11912796582968001, + 0.06221848112591997, + 0.1884433539067577, + -0.10700788275590943, + -0.3518682598612047, + 0.37456880426014166, + ], + [ + 0.013604873029341946, + -0.16528022578112536, + 0.20155485791540892, + -0.3541277493897382, + 0.676862752046083, + -0.2658785210172399, + 0.5147053312531512, + -0.112740319727795, + ], + ], + [ + [2.851092491176718], + [0.3804764585148756, -0.9247906057675856], + [0.43841826755186564, -0.8987710624384948], + ], + [ + [0.5567549635823631], + [ + 0.20108807178297264, + 0.11422009200726954, + -0.4229195164047098, + 0.8118482504243884, + -0.2985123290622806, + -0.10304198468607091, + 0.0939765805139303, + ], + [ + 0.04424901152619659, + -0.7169306819079923, + -0.031129292324036512, + 0.6372250118096429, + -0.02583896509973039, + 0.014153747195613426, + 0.16225623748001994, + -0.11092394734951527, + 0.19372269982536366, + ], + [ + 0.42796852361059873, + 0.1000612228302854, + -0.6494403216595616, + 0.012394320858700462, + -0.44765471097923526, + 0.28788160552521874, + 0.26926315361113184, + 0.14434420119149496, + 0.09108177932795573, + ], + ], + [ + [0.36252817849574176], + [ + -0.4152409797128937, + 0.3949651690781115, + 0.059637140694856684, + -0.29809447149493, + -0.45495068818315665, + 0.15339000916151824, + 0.5145387514659299, + 0.0726835092343826, + 0.15840576161081632, + 0.23135797656647117, + ], + [ + -0.539717469908245, + 0.4395297187977435, + 0.21328340065082524, + 0.45891791025442036, + -0.08479985319672712, + -0.07573386931397807, + -0.4964842269000107, + ], + [0.3787170228715312, 0.8302726053139932, 0.40892642058497286], + ], + [ + [0.2755990738257318], + [ + 0.21794010543619222, + -0.832205317244186, + -0.08165195766640711, + -0.32019564073885964, + 0.3882578136419659, + ], + [ + 0.8072220207586441, + 0.1839997459775723, + 0.25829762282479984, + -0.16088661411000194, + 0.4709383701765526, + -0.012312173701218641, + ], + [-0.5999408691302599, 0.19608311412450938, -0.7756431949694802], + ], + [ + [0.13874530878036045], + [ + 0.22313639103335817, + -0.582683687448744, + 0.019810748294280565, + -0.532091804219692, + 0.4183784535017075, + 0.14178309829111962, + -0.20220724006960822, + 0.29098277220121593, + 0.08046116169937856, + ], + [0.9267624891781729, -0.13156790592635095, 0.35185391113703934], + [ + -0.20128032438008028, + -0.8385905159101716, + 0.32092863797763976, + -0.004535145988646948, + 0.2201729511393691, + -0.3236669445683654, + ], + [ + -0.4807744861170881, + -0.7965214809133648, + 0.05085093394774735, + -0.18228152610151416, + -0.3136581939724126, + -0.014682951172671068, + ], + ], + [ + [0.21051807193802943], + [ + 0.23403384696597218, + 0.42054682357471496, + -0.5698122696955275, + 0.5838315012795727, + -0.32066069773765116, + ], + [0.5766960203474961, -0.6743800959552224, 0.13162023644111331, 0.4419381174485529], + [ + -0.21057589355060127, + 0.08811991196707877, + 0.3405460927874034, + -0.3897589394700625, + 0.7083087794882124, + -0.1136094071563721, + 0.08025571453602402, + 0.38379031842997346, + -0.10397276906281434, + 0.029227598658195648, + ], + [ + -0.5554668166067296, + -0.20795381463643023, + 0.2553028805249397, + 0.10256974403643938, + -0.08894446390830917, + 0.04610645378979823, + 0.27966690408533734, + -0.07380638485934377, + -0.33321238127988634, + 0.6064514324865661, + ], + ], + [ + [0.4828275813633084], + [ + 0.23384095547788736, + 0.3512388738563172, + 0.20430444349630456, + 0.6579221192887889, + 0.09844835569247844, + 0.363573528638023, + 0.2687104582601494, + -0.14301608669058016, + -0.09631021994329247, + -0.3217692977748192, + ], + [ + -0.5116624664211036, + 0.07668016024356412, + 0.5061460483419392, + 0.3214705004283764, + -0.46018395871455636, + 0.40127956928413683, + ], + [-0.38096699727867506, 0.2861444037357305, -0.8791959549470149], + [0.692923641553941, -0.3060961599674285, 0.22172696315719087, 0.6140025420451529], + ], + [ + [1.1838757652294163], + [ + 0.210872386528422, + 0.07121151449265378, + -0.5646662541775129, + 0.3616416663029674, + 0.06637879222702027, + 0.07584789624963773, + -0.5828313418578935, + 0.2675952004007925, + 0.22734623628568493, + 0.16638557775398255, + ], + ], + [ + [0.3032739397640297297], + [ + -0.48082028355309697, + 0.3388907360614881, + 0.454066186534629, + -0.17812152265340722, + -0.2993680565146906, + -0.4376744632861303, + -0.07894707721342749, + -0.15363745968032946, + 0.3241053320409901, + ], + ], + [ + [1.1617468533361055], + [-0.02260630098657834, 0.2972001146356296, 0.7596474220087696, -0.5780111082424827], + ], + [ + [1.2844162220009774], + [-0.30842015389728145, 0.951250234517699], + [ + 0.30279327531038325, + 0.08852690888227953, + 0.05590206678861999, + -0.11020418544430191, + 0.34622673649276936, + 0.039237251633264296, + 0.2036788352046126, + 0.7474907644209177, + -0.4044368794841003, + ], + ], + [ + [0.18104388996897572], + [ + 0.5520877166363866, + -0.052976780373050814, + -0.8311689032169315, + -0.03938106404973989, + ], + [ + 0.034274688844047635, + 0.16403282417490214, + 0.2354752745921137, + 0.49694577571607884, + -0.1464762658164691, + -0.0454250584931338, + -0.8037387865251501, + ], + ], + [ + [1.6905902450546004], + [-0.12543067772892338, -0.99210238639188], + [0.8762083930519261, -0.48193241429204725], + ], + [ + [0.5007028223906543], + [ + -0.06769241297456885, + -0.5449485746545011, + 0.398606571568952, + 0.6501033139153659, + -0.04258821690222594, + -0.13267612920115782, + 0.28917066939208946, + -0.0862022715614269, + 0.08037444499516286, + ], + [ + -0.435703924552393, + 0.003588856443541161, + -0.6651813230937048, + 0.2132673584452006, + -0.23794057413100464, + -0.5153487505082289, + ], + [ + 0.10026563183607826, + -0.41453578717039885, + 0.22729656824470607, + -0.4898014879827773, + 0.3079502543279662, + 0.32626734055020185, + 0.22241280421779944, + -0.20185051232763798, + 0.26385177592505493, + -0.4067248155023813, + ], + ], + [ + [0.42070460277285854], + [ + -0.11765364391216213, + -0.02107059901087521, + 0.01919962552849528, + 0.0075532937836861914, + -0.407416349154066, + 0.2526422092654315, + 0.18892381530643113, + -0.039220900801933495, + -0.8474911902514953, + ], + [ + -0.32443831265566164, + -0.2349409435382715, + -0.24293165040461917, + 0.17482035071905289, + 0.4202882276170908, + 0.29174253040759934, + -0.12773231584125186, + 0.17922569173029038, + 0.6631525474037887, + ], + [0.2845093749411345, -0.9586732579824081], + ], + [ + [0.10062440822372039], + [ + 0.07996808517600432, + -0.26307264663569147, + -0.4495698788298603, + 0.6111308460433761, + -0.11895028828957643, + 0.20924569495870432, + 0.3301577806915321, + -0.004487812699664358, + 0.3268240075329048, + -0.27392104072489637, + ], + [ + 0.12284217101173843, + 0.35404646594484673, + -0.035991021401721314, + 0.5860476109030441, + -0.4404194916015131, + 0.2346021425142989, + -0.16531437985938108, + 0.29739181674429876, + 0.0961161858068593, + 0.3752295207239467, + ], + [ + 0.37225889195343176, + -0.40269820383703075, + 0.5891470410337922, + -0.5231944785778554, + 0.017605742011659636, + 0.24075511508976774, + 0.14197812515009833, + ], + ], + [ + [0.18481028402754704], + [ + 0.3100324954044331, + 0.20571167887073383, + 0.2759549800636245, + -0.5098047663273968, + -0.40513901097801985, + -0.006849531735112356, + 0.32426009440794523, + 0.0980343539650855, + 0.496558786543343, + ], + [0.7400543367573574, -0.6634600702609377, -0.11018309224186618], + [ + -0.3047981091301781, + -0.2991724005041669, + -0.180567141067543, + -0.46275630707119686, + 0.5780573143957574, + 0.04795327307127396, + 0.27896164368216786, + -0.3956977653578857, + ], + [ + -0.5375940335785957, + -0.33527871549213856, + -0.34423023822843113, + -0.057618837476544824, + 0.2307053118861316, + -0.5816558302641435, + 0.1347923363882464, + 0.005386448290725161, + 0.17361223551501662, + -0.19203856057632393, + ], + ], + [ + [0.4228588017696557], + [ + -0.141865030134013, + 0.44059694416524103, + -0.4181744594149625, + -0.3452888941246838, + -0.3554076392829921, + 0.06722507728789844, + -0.08166976238961376, + -0.07165859365772556, + -0.13418586367363106, + 0.5753345078159252, + ], + [ + 0.45050543565810647, + 0.3522148480832122, + 0.20063517590059027, + -0.2069225940646595, + 0.5565420673454308, + -0.2904080923745975, + 0.3836714803715129, + 0.18159571033346678, + 0.12514543453657165, + ], + [ + 0.14887119923616898, + 0.10387753894769929, + -0.13940282319720718, + -0.6456183547647123, + -0.468455996706801, + 0.3389787430786487, + -0.4432076338534407, + ], + [ + -0.08150071800245477, + -0.5444374572967173, + 0.6051990477077818, + 0.2041079018657187, + -0.4187164733526199, + 0.3371884933536173, + ], + ], + [ + [0.17800461834682948], + [ + 0.40442214560226664, + -0.18410967602595124, + -0.37808224287777675, + 0.5298695372118921, + 0.20342335952859486, + 0.47237240617396475, + 0.3381149112046999, + ], + [-0.0671758988249334, -0.997741148102584], + [ + 0.5860119193049029, + -0.1655879827363143, + 0.42146580605026046, + -0.05072788682343524, + 0.01966945374695293, + -0.18509497429620517, + -0.2917989581694971, + 0.5737335943846366, + ], + [ + -0.45925413330012654, + -0.054244623817065345, + -0.11041902728376159, + 0.03752800032819433, + 0.24065851466537416, + -0.17318765966122213, + -0.5175866433893724, + -0.6455509506489918, + ], + ], +] # qs[i] is a point on Ms[i] that is connected to ps[i] by a geodesic and uses the closest representation to ps[i] qs = [ - [[0.2285468999681258], [0.0072000169737206285, 0.46919050788513217, -0.0578728225972693, 0.14417171957969074, 0.5393873747379379, 0.3535952408499787, -0.19179220675967715, 0.0603486044844522, -0.3902812557079805, 0.38335320681028]], + [ + [0.2285468999681258], + [ + 0.0072000169737206285, + 0.46919050788513217, + -0.0578728225972693, + 0.14417171957969074, + 0.5393873747379379, + 0.3535952408499787, + -0.19179220675967715, + 0.0603486044844522, + -0.3902812557079805, + 0.38335320681028, + ], + ], [[0.5], [0.2514005595224343, -0.96788313275509]], # m = 0 - [[0.7626963166735549], [-0.04331677552451647, -0.008943154324947739, -0.8741092621910937, 0.26370232932220805, 0.2684875896184496, 0.30167858701939854, -0.03663605553981364]], - [[0.9263875479802128], [-0.2876490379709154, 0.5934703502895091, 0.00669105544965959, -0.5238009412763243, 0.48771046854635186, 0.22195505041284128, 0.05927252688380565], [-0.8467814852966212, 0.5319408953623024]], - [[0.5053216839247762], [-0.59015897645163, 0.41560724598915816, 0.3244409818454344, 0.2767905184327968, 0.2788412597376433, 0.1764703807465072, 0.301994778424145, 0.2876603862925981, 0.11943395810822663], [-0.03534714586479288, 0.15957987916099206, -0.28718149774238777, -0.19635088853199553, 0.684165557894705, -0.5666526357569592, 0.2510512156243137, 0.007316029468452894]], - [[0.18066790739255756], [-0.992558358800348, -0.12176988287569214], [-0.7201988141976301, -0.6937677334874601]], - [[0.05929877942048794], [-0.2492472329981639, 0.19078207722614024, -0.6950020535594956, 0.6155692112895002, 0.12163736596071065, 0.07617216946811589, -0.13757492254479187], [-0.3446138929389734, -0.44528715923871226, 0.09867730315307487, 0.3856741902911293, -0.03976898819561624, -0.09854548801276108, 0.5786967392957476, 0.419483004838766, -0.048271382271637374], [-0.13898349823957276, 0.37007148419755803, -0.5672020653516858, 0.2664429979574558, 0.26019214805889984, -0.183973837333837, -0.537331406376888, -0.2092584392846679, -0.13023121083469708]], - [[0.4428343667970336], [-0.127255572630727, 0.22668672002145898, 0.3495203443639004, -0.2800785570522293, 0.3076023585481211, 0.2954405117453133, 0.6120999631203197, 0.09785748462223727, 0.40179977381828863, -0.06496817376226975], [0.08909415980355775, 0.880431882384782, -0.3060967538577087, 0.013454468756813096, -0.29939494476539896, -0.16687570624161663, 0.07443689564200096], [0.14631014012300886, 0.5274221714215308, 0.8369105065598011]], - [[0.9747973672469175], [0.5036745603591766, 0.08655987562606954, 0.45670653353901913, 0.16988849841032172, 0.7080793497266027], [-0.04773379921570165, 0.14480351638724792, 0.46223423790321516, 0.1869203226531565, -0.4654696219322667, -0.7151865207075913], [-0.6614475098892549, 0.6975530383411345, -0.27551216009888874]], - [[0.5944460845919239], [0.18440528974038717, -0.3234774292705488, -0.07521274368923382, -0.5055464117085976, 0.17461559395815557, 0.20174607290008786, -0.5921554567742019, 0.22060599004214254, 0.3600218594053353], [0.9391716922907767, -0.20920363981570536, -0.27237909150215467], [0.594536709760007, -0.6154768837189905, 0.2868298100684849, 0.08944875927641796, 0.42003473849671874, 0.031823015747801525], [0.04047760394645142, 0.5651446411453817, 0.4996377449872775, 0.5242952935259201, -0.18199312205158755, -0.34832193537003325]], - [[0.35664035777449904], [0.13343426198137742, -0.25425996956084335, -0.922195129235849, 0.08550784318326136, 0.2445234507695054], [0.4047997839831198, -0.5275627401918468, -0.1815584055185977, 0.7244661727327466], [-0.48114822474834057, 0.07687937224998155, 0.18315655165440772, 0.4530633997597068, 0.3699870416956907, 0.2678528031163627, -0.09413476091065198, 0.11453703309553476, 0.49851411436369913, 0.21128473391689526], [-0.3768156565668107, 0.14736306468252625, -0.06614007558247408, -0.48760209381974895, -0.3574364962985913, 0.5633803923618522, 0.024688951851943863, -0.3699931126715858, -0.003533128694901466, 0.10718456273036511]], - [[0.11597881520641286], [0.004793068006686758, 0.5431793112729557, -0.2543049740455072, 0.24843954495843448, 0.3105833349418175, 0.22857210987819054, 0.244361879116985, -0.4284169847117112, 0.3591924409584363, 0.2399161670796564], [0.16123153683830393, 0.11403720071692096, 0.07121418589008548, 0.7353846315348165, 0.6113006204016374, 0.20359136354078292], [-0.12820954768918336, -0.7223351856222379, -0.6795544065734709], [-0.5181411756487838, -0.5982091832712966, 0.13154159318612907, 0.5969692658832942]], - [[0.9068920036691095], [0.028598193298964708, 0.4294897666239807, 0.5582305652867099, 0.20015138065027618, -0.36032666340358765, -0.06085371828646839, 0.3481371808459643, 0.3824819666832563, 0.15057862863095645, 0.19832899484009994]], - [[0.26091111882856616], [-0.2735468559596818, 0.7908310184653957, -0.3965289688792057, -0.20393895097120848, 0.009693462487979644, 0.22432025309225306, 0.14645403468888063, 0.07594795417367314, 0.15264889046998872]], - [[0.7507973403445075], [-0.3623234540901233, -0.8628926515811954, 0.04303829727534214, -0.3496937108828457]], - [[1.8900272913460916], [-0.24462417095922365, 0.9696179737311559], [0.0029148214868594184, 0.046733730849394826, 0.3464166332779196, -0.41612585782053313, 0.4403234930433767, -0.07014699792539351, -0.6626027503215617, 0.06409791188610743, -0.25037156781949155]], - [[0.0038033069402429436], [-0.6935787317124584, 0.4529983876547129, -0.5165298785674818, 0.2166515364483497], [-0.4548679332583842, 0.38597993504553063, 0.20134736150306345, 0.16454891197012098, -0.6254798836839162, 0.4249626997707289, -0.06840444087211281]], - [[0.05069728715399965], [0.9989195510484316, 0.046472901062876736], [0.9990218321402392, 0.0442196665202251]], - [[1.3388920951283048], [-0.2894849285247092, -0.375237468281043, 0.10659685105991663, 0.5326935539788507, -0.2687936085300003, -0.28583226069914086, -0.06940771783985483, 0.566949781731537, 0.0083926101085135], [-0.2692873331242094, -0.352948146454535, -0.36201078692503574, 0.26291906209331745, -0.430264386434885, -0.6462246148490923], [-0.2899662461053266, 0.561676369276759, 0.29953621040966766, 0.026981212635263388, -0.1879070254370779, -0.10235375900374745, -0.04777542564881818, -0.6562458092558364, 0.02736625708068412, -0.17468256196490237]], - [[1.1931486977771844], [0.22644039039058186, -0.11411958485037178, 0.30437736829730944, -0.62733810852234, -0.6264916698299722, 0.07060731738622097, 0.2251625848885129, -0.02341401611326633, -0.02791368478545802], [0.6571431019356029, 0.006127671303832962, -0.03377055193505131, -0.2634138473656534, 0.0015253787707612755, -0.3506356042585966, 0.27828523163579455, 0.4040591774006482, 0.3659835342176074], [0.5769596212360408, -0.8167726706147582]], - [[0.09396735191763278], [0.08808204191629705, -0.269420904705849, -0.6118443181714507, 0.2480461224526081, 0.1084861630557538, 0.2683009932904934, 0.38655863782557004, 0.32133983398494953, 0.33119696155689554, -0.19401189178526185], [-0.5120308222265519, 0.7045182787166198, -0.09497155095499868, -0.018552062467794783, -0.10973828476807547, -0.3071753378516766, -0.055696702155718036, -0.19520860631422926, 0.2906599716297778, 0.004872010410999308], [-0.071497555279541, -0.7200146974217542, 0.13219105850125198, 0.5589884484433559, 0.2558843206526261, -0.11634032369835579, 0.2598317093251373]], - [[0.5595013700016621], [-0.16410496932023275, 0.2124425044194968, 0.019103430387761126, -0.49321855967754313, 0.2187406652190155, -0.2438450092656317, -0.29126737061752705, -0.6546701444600094, 0.2521323190300214], [0.5091077043894671, -0.7810695653023092, -0.36157942348777083], [0.09792086442785906, -0.46300382891140285, -0.34321497128243517, -0.4715033116632154, 0.23250354333074766, 0.3343541579831825, 0.33398745563364823, -0.39815681352786747], [0.1472380561455175, -0.2928950599225513, -0.06829513714619305, 0.2630794095929546, -0.07520704498840525, -0.097452294891074, 0.1546325256973868, -0.7547590605905541, 0.42527618176727117, -0.17050835599699163]], - [[0.0879788405568045], [0.4752198883185735, 0.4601150437982469, 0.004558213453811248, -0.3747084951936111, -0.06469017263215665, 0.006333332718496339, -0.19475186049495816, -0.4040009330690733, 0.3550915844479287, 0.30095342923066604], [0.3443393165370433, 0.3660193874394325, -0.08495542638537015, 0.09676362754304287, 0.5155711330857424, -0.004321193772576179, -0.6430158188019451, 0.16550949028930745, 0.15551404574943303], [0.4892943761703814, 0.06614536658571389, -0.2830598467537517, -0.19219480553946047, -0.5053021840588248, -0.4208210443148484, -0.4546794862909613], [-0.045503401271809414, -0.49376674883678284, -0.011090272673863474, 0.6509068904350033, -0.5051014195999987, 0.2742145509818364]], - [[1.4349423523410283], [0.06370019368643771, 0.31519275409207537, -0.717868367412602, 0.2601814359189934, 0.03539231049664084, -0.46547257907453504, 0.309271891789521], [0.6968005890360706, -0.7172649016360588], [0.39039913946740623, -0.5538051672666193, -0.10251421913304977, -0.18753950466778713, 0.5673704705466129, 0.37985274492764076, 0.06722234077506756, -0.1564989325835006], [-0.7130313109989243, 0.24441120802232372, 0.5661277861967524, -0.06364217193543024, 0.2700793817903238, -0.14762085346258608, 0.0921868105034791, 0.06375984394161507]] - ] + [ + [0.7626963166735549], + [ + -0.04331677552451647, + -0.008943154324947739, + -0.8741092621910937, + 0.26370232932220805, + 0.2684875896184496, + 0.30167858701939854, + -0.03663605553981364, + ], + ], + [ + [0.9263875479802128], + [ + -0.2876490379709154, + 0.5934703502895091, + 0.00669105544965959, + -0.5238009412763243, + 0.48771046854635186, + 0.22195505041284128, + 0.05927252688380565, + ], + [-0.8467814852966212, 0.5319408953623024], + ], + [ + [0.5053216839247762], + [ + -0.59015897645163, + 0.41560724598915816, + 0.3244409818454344, + 0.2767905184327968, + 0.2788412597376433, + 0.1764703807465072, + 0.301994778424145, + 0.2876603862925981, + 0.11943395810822663, + ], + [ + -0.03534714586479288, + 0.15957987916099206, + -0.28718149774238777, + -0.19635088853199553, + 0.684165557894705, + -0.5666526357569592, + 0.2510512156243137, + 0.007316029468452894, + ], + ], + [ + [0.18066790739255756], + [-0.992558358800348, -0.12176988287569214], + [-0.7201988141976301, -0.6937677334874601], + ], + [ + [0.05929877942048794], + [ + -0.2492472329981639, + 0.19078207722614024, + -0.6950020535594956, + 0.6155692112895002, + 0.12163736596071065, + 0.07617216946811589, + -0.13757492254479187, + ], + [ + -0.3446138929389734, + -0.44528715923871226, + 0.09867730315307487, + 0.3856741902911293, + -0.03976898819561624, + -0.09854548801276108, + 0.5786967392957476, + 0.419483004838766, + -0.048271382271637374, + ], + [ + -0.13898349823957276, + 0.37007148419755803, + -0.5672020653516858, + 0.2664429979574558, + 0.26019214805889984, + -0.183973837333837, + -0.537331406376888, + -0.2092584392846679, + -0.13023121083469708, + ], + ], + [ + [0.4428343667970336], + [ + -0.127255572630727, + 0.22668672002145898, + 0.3495203443639004, + -0.2800785570522293, + 0.3076023585481211, + 0.2954405117453133, + 0.6120999631203197, + 0.09785748462223727, + 0.40179977381828863, + -0.06496817376226975, + ], + [ + 0.08909415980355775, + 0.880431882384782, + -0.3060967538577087, + 0.013454468756813096, + -0.29939494476539896, + -0.16687570624161663, + 0.07443689564200096, + ], + [0.14631014012300886, 0.5274221714215308, 0.8369105065598011], + ], + [ + [0.9747973672469175], + [ + 0.5036745603591766, + 0.08655987562606954, + 0.45670653353901913, + 0.16988849841032172, + 0.7080793497266027, + ], + [ + -0.04773379921570165, + 0.14480351638724792, + 0.46223423790321516, + 0.1869203226531565, + -0.4654696219322667, + -0.7151865207075913, + ], + [-0.6614475098892549, 0.6975530383411345, -0.27551216009888874], + ], + [ + [0.5944460845919239], + [ + 0.18440528974038717, + -0.3234774292705488, + -0.07521274368923382, + -0.5055464117085976, + 0.17461559395815557, + 0.20174607290008786, + -0.5921554567742019, + 0.22060599004214254, + 0.3600218594053353, + ], + [0.9391716922907767, -0.20920363981570536, -0.27237909150215467], + [ + 0.594536709760007, + -0.6154768837189905, + 0.2868298100684849, + 0.08944875927641796, + 0.42003473849671874, + 0.031823015747801525, + ], + [ + 0.04047760394645142, + 0.5651446411453817, + 0.4996377449872775, + 0.5242952935259201, + -0.18199312205158755, + -0.34832193537003325, + ], + ], + [ + [0.35664035777449904], + [ + 0.13343426198137742, + -0.25425996956084335, + -0.922195129235849, + 0.08550784318326136, + 0.2445234507695054, + ], + [0.4047997839831198, -0.5275627401918468, -0.1815584055185977, 0.7244661727327466], + [ + -0.48114822474834057, + 0.07687937224998155, + 0.18315655165440772, + 0.4530633997597068, + 0.3699870416956907, + 0.2678528031163627, + -0.09413476091065198, + 0.11453703309553476, + 0.49851411436369913, + 0.21128473391689526, + ], + [ + -0.3768156565668107, + 0.14736306468252625, + -0.06614007558247408, + -0.48760209381974895, + -0.3574364962985913, + 0.5633803923618522, + 0.024688951851943863, + -0.3699931126715858, + -0.003533128694901466, + 0.10718456273036511, + ], + ], + [ + [0.11597881520641286], + [ + 0.004793068006686758, + 0.5431793112729557, + -0.2543049740455072, + 0.24843954495843448, + 0.3105833349418175, + 0.22857210987819054, + 0.244361879116985, + -0.4284169847117112, + 0.3591924409584363, + 0.2399161670796564, + ], + [ + 0.16123153683830393, + 0.11403720071692096, + 0.07121418589008548, + 0.7353846315348165, + 0.6113006204016374, + 0.20359136354078292, + ], + [-0.12820954768918336, -0.7223351856222379, -0.6795544065734709], + [-0.5181411756487838, -0.5982091832712966, 0.13154159318612907, 0.5969692658832942], + ], + [ + [0.9068920036691095], + [ + 0.028598193298964708, + 0.4294897666239807, + 0.5582305652867099, + 0.20015138065027618, + -0.36032666340358765, + -0.06085371828646839, + 0.3481371808459643, + 0.3824819666832563, + 0.15057862863095645, + 0.19832899484009994, + ], + ], + [ + [0.26091111882856616], + [ + -0.2735468559596818, + 0.7908310184653957, + -0.3965289688792057, + -0.20393895097120848, + 0.009693462487979644, + 0.22432025309225306, + 0.14645403468888063, + 0.07594795417367314, + 0.15264889046998872, + ], + ], + [ + [0.7507973403445075], + [ + -0.3623234540901233, + -0.8628926515811954, + 0.04303829727534214, + -0.3496937108828457, + ], + ], + [ + [1.8900272913460916], + [-0.24462417095922365, 0.9696179737311559], + [ + 0.0029148214868594184, + 0.046733730849394826, + 0.3464166332779196, + -0.41612585782053313, + 0.4403234930433767, + -0.07014699792539351, + -0.6626027503215617, + 0.06409791188610743, + -0.25037156781949155, + ], + ], + [ + [0.0038033069402429436], + [-0.6935787317124584, 0.4529983876547129, -0.5165298785674818, 0.2166515364483497], + [ + -0.4548679332583842, + 0.38597993504553063, + 0.20134736150306345, + 0.16454891197012098, + -0.6254798836839162, + 0.4249626997707289, + -0.06840444087211281, + ], + ], + [ + [0.05069728715399965], + [0.9989195510484316, 0.046472901062876736], + [0.9990218321402392, 0.0442196665202251], + ], + [ + [1.3388920951283048], + [ + -0.2894849285247092, + -0.375237468281043, + 0.10659685105991663, + 0.5326935539788507, + -0.2687936085300003, + -0.28583226069914086, + -0.06940771783985483, + 0.566949781731537, + 0.0083926101085135, + ], + [ + -0.2692873331242094, + -0.352948146454535, + -0.36201078692503574, + 0.26291906209331745, + -0.430264386434885, + -0.6462246148490923, + ], + [ + -0.2899662461053266, + 0.561676369276759, + 0.29953621040966766, + 0.026981212635263388, + -0.1879070254370779, + -0.10235375900374745, + -0.04777542564881818, + -0.6562458092558364, + 0.02736625708068412, + -0.17468256196490237, + ], + ], + [ + [1.1931486977771844], + [ + 0.22644039039058186, + -0.11411958485037178, + 0.30437736829730944, + -0.62733810852234, + -0.6264916698299722, + 0.07060731738622097, + 0.2251625848885129, + -0.02341401611326633, + -0.02791368478545802, + ], + [ + 0.6571431019356029, + 0.006127671303832962, + -0.03377055193505131, + -0.2634138473656534, + 0.0015253787707612755, + -0.3506356042585966, + 0.27828523163579455, + 0.4040591774006482, + 0.3659835342176074, + ], + [0.5769596212360408, -0.8167726706147582], + ], + [ + [0.09396735191763278], + [ + 0.08808204191629705, + -0.269420904705849, + -0.6118443181714507, + 0.2480461224526081, + 0.1084861630557538, + 0.2683009932904934, + 0.38655863782557004, + 0.32133983398494953, + 0.33119696155689554, + -0.19401189178526185, + ], + [ + -0.5120308222265519, + 0.7045182787166198, + -0.09497155095499868, + -0.018552062467794783, + -0.10973828476807547, + -0.3071753378516766, + -0.055696702155718036, + -0.19520860631422926, + 0.2906599716297778, + 0.004872010410999308, + ], + [ + -0.071497555279541, + -0.7200146974217542, + 0.13219105850125198, + 0.5589884484433559, + 0.2558843206526261, + -0.11634032369835579, + 0.2598317093251373, + ], + ], + [ + [0.5595013700016621], + [ + -0.16410496932023275, + 0.2124425044194968, + 0.019103430387761126, + -0.49321855967754313, + 0.2187406652190155, + -0.2438450092656317, + -0.29126737061752705, + -0.6546701444600094, + 0.2521323190300214, + ], + [0.5091077043894671, -0.7810695653023092, -0.36157942348777083], + [ + 0.09792086442785906, + -0.46300382891140285, + -0.34321497128243517, + -0.4715033116632154, + 0.23250354333074766, + 0.3343541579831825, + 0.33398745563364823, + -0.39815681352786747, + ], + [ + 0.1472380561455175, + -0.2928950599225513, + -0.06829513714619305, + 0.2630794095929546, + -0.07520704498840525, + -0.097452294891074, + 0.1546325256973868, + -0.7547590605905541, + 0.42527618176727117, + -0.17050835599699163, + ], + ], + [ + [0.0879788405568045], + [ + 0.4752198883185735, + 0.4601150437982469, + 0.004558213453811248, + -0.3747084951936111, + -0.06469017263215665, + 0.006333332718496339, + -0.19475186049495816, + -0.4040009330690733, + 0.3550915844479287, + 0.30095342923066604, + ], + [ + 0.3443393165370433, + 0.3660193874394325, + -0.08495542638537015, + 0.09676362754304287, + 0.5155711330857424, + -0.004321193772576179, + -0.6430158188019451, + 0.16550949028930745, + 0.15551404574943303, + ], + [ + 0.4892943761703814, + 0.06614536658571389, + -0.2830598467537517, + -0.19219480553946047, + -0.5053021840588248, + -0.4208210443148484, + -0.4546794862909613, + ], + [ + -0.045503401271809414, + -0.49376674883678284, + -0.011090272673863474, + 0.6509068904350033, + -0.5051014195999987, + 0.2742145509818364, + ], + ], + [ + [1.4349423523410283], + [ + 0.06370019368643771, + 0.31519275409207537, + -0.717868367412602, + 0.2601814359189934, + 0.03539231049664084, + -0.46547257907453504, + 0.309271891789521, + ], + [0.6968005890360706, -0.7172649016360588], + [ + 0.39039913946740623, + -0.5538051672666193, + -0.10251421913304977, + -0.18753950466778713, + 0.5673704705466129, + 0.37985274492764076, + 0.06722234077506756, + -0.1564989325835006, + ], + [ + -0.7130313109989243, + 0.24441120802232372, + 0.5661277861967524, + -0.06364217193543024, + 0.2700793817903238, + -0.14762085346258608, + 0.0921868105034791, + 0.06375984394161507, + ], + ], +] # vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representation to ps[i] for t in [-1, 1] vs = [ - [[0.6940789907123062], [0.14913995456500687, -0.030547142938236793, 0.31162623436384285, -0.20563967625033036, 0.19319043822673818, 0.317062500120066, -0.8754858218076765, -0.3259209038205042, -0.033243255319008624, -1.1548635082931478]], + [ + [0.6940789907123062], + [ + 0.14913995456500687, + -0.030547142938236793, + 0.31162623436384285, + -0.20563967625033036, + 0.19319043822673818, + 0.317062500120066, + -0.8754858218076765, + -0.3259209038205042, + -0.033243255319008624, + -1.1548635082931478, + ], + ], [[0.2389420207891795], [0.0, 0.0]], # m = 0 - [[0.46132409636616317], [0.7034437676859567, 0.6114140712984324, -0.08829607209219353, 0.03327833095019875, -0.6185892330923073, 0.1326136814054642, 0.5700109876145869]], - [[0.45470843046349313], [0.433513329547113, -0.7320515075884788, -0.38765391945909755, 0.19640702045402264, 0.14944186690806377, -0.9671407596317976, -0.9289295848779034], [-0.5045110500803344, 0.06911945375717096]], - [[-0.19135891857701476], [-0.0069569775655274405, 0.4648330993586129, -0.5249300916156493, -0.6942918549175187, 0.03839836910376858, 0.48996587981873707, 0.19149786106059058, 0.25496379149224513, 0.8306443019906313], [-0.14991071399697806, -0.0899250894563053, 0.48363972474877626, -0.06740963522851286, -0.17392353118572687, -0.8626165876780832, -0.4781319504914857, -0.002601732145143469]], - [[0.032475437742255364], [-0.0793840052835045, -0.032660090840698486], [-0.16688671771785502, -0.08140692187036919]], - [[-0.14362437882603868], [0.21703580244995338, -0.07582942569056315, -0.4131524696769127, 0.07113227925464494, 0.9216831076067749, -0.3117658924120991, -0.2601938828890881], [-0.40993096871840384, 0.06033520676657045, 0.3353505686920585, 0.32669207217743906, -0.26949939576113957, 0.4622586254534011, -0.23046667729151138, 0.39890816877066293, -0.352075854880814], [0.27574595870419494, -0.20132897843112602, 0.7181884086912088, 0.20902304397906357, -0.9797911979282492, -0.22738728408774556, -0.08434852248139064, -0.03906999050989374, 0.23241083119724726]], - [[0.167542758489263], [-0.7172648711179583, -0.12978356499468247, -0.14709754758453525, 0.7429222145447074, -0.301380485416464, 0.10648701938150486, -0.5862695196566239, -0.6731434017042006, -0.1027873036321029, 0.8518198213004147], [0.36528861191780526, -0.05502523773982651, 0.3349143864166638, 0.5976408658825734, 0.22224119027517705, 0.5079433605241578, 0.13504430515015828], [-0.09838274427397142, 0.1575018337179488, -0.22867252665062765]], - [[0.0005576618010449276], [-0.5529387542450745, -0.18931262357519596, -0.4740879804055004, 0.7218017303773806, 0.4001673857383268], [0.04653671285987987, -0.3342761936754844, 0.10416238554693465, -0.3780599114751379, -0.13425764881025848, 0.045590813877080076], [-0.3467728705815678, 1.0951463617116348, 0.5450739839349461]], - [[-0.10835780918855986], [-0.2879956140065193, 0.43075721925722893, -0.3291055923326802, 0.017387780693294552, 0.060086501392198954, -0.22944578876172467, -0.2678362137267055, 0.821848362075142, 0.5607641072034037], [0.1257205818761756, 0.5344739830694265, -0.1312860116480018], [-0.32028258895073813, 0.05581149125388041, -0.38726569273936556, -0.4124721885803405, 0.09543462429188473, -0.2587175245909177], [0.23313088537058163, 0.398484868218528, 0.17079789329674128, -0.5464610930958373, -1.0423151616550292, 0.3909668100967531]], - [[-0.13373401585247496], [-0.0462149976885849, -0.22586363815314267, -0.24082866649963608, -0.17798976955515672, -0.22606766311009552], [-1.1531492828944132, -1.048323182821658, 0.3469323589434465, -0.19825175056321256], [-0.33544764292008533, 0.5454762716081148, -0.44056401394680517, 0.6346538879978276, 0.4071906233657455, 0.20386210363713045, 0.1131664536677318, 0.13733952167695518, 0.3499954521074497, -0.40947620073175056], [0.5235561961524053, -0.33651887371172584, 0.165664680004435, 0.3177740663156395, -0.5050069337944564, 0.007676908750572816, -0.15745475915753057, -0.13379200089703605, 0.7775600848786371, 0.6495661761313964]], - [[0.14255661510910747], [-0.01620371146007782, -0.2176640728621523, -0.26783759524037853, 0.1887922975530844, -0.03868441552368684, 0.24619823528128237, 0.16400437859951833, 0.8207953853819989, -0.683215714398723, 0.2095762101658616], [-0.587587477362466, 0.9611453504625634, -0.4956705989932666, -0.8797827478845143, 0.2660001180346881, 0.7021729654279507], [0.6165274130606305, 0.1402548199881536, -0.22150177598219462], [0.42439566636895776, 0.04342532989904936, 0.1811774237827697, -0.5227232167013833]], - [[-0.25050034943799143], [0.3488629827096742, -0.01790447096652751, 0.41078746198742494, 0.2674738658616262, -0.3676063246452534, 0.27995679376647054, -0.6476807696598814, -0.05608263854802896, -1.002407614041255, -0.41159169074078095]], - [[1.5189255716984038], [0.14389418968383233, -0.7434685056546961, 0.17177099801922532, -0.0699519450185816, -0.48084553564682225, -0.2504085373789058, 0.5705781638468338, -0.7229621177887824, -0.2742605768830553]], - [[-0.2000130047239455], [0.28376287916446385, -0.011498145899119377, 0.276592098504903, 0.3464992149574739]], - [[0.7638265778356526], [0.043718096583251764, 0.014174547965435269], [0.1589574325807131, 0.8748133883099838, -0.3528071207217161, -0.2644899757823254, 0.24010835273681236, -0.1673897092037622, -0.6222042985569745, -0.09191448012128656, 0.039882538236865134]], - [[0.13319966661993943], [-0.27617394286645647, -0.22020251242074337, -0.2045923981917276, 0.7425959288733582], [-0.7440711602827321, -0.42811046699670163, -0.07153818588627878, -0.1126683907082826, -0.31430569035654404, 1.0115723034951567, -0.20961404535149197]], - [[0.4767148797604099], [0.3384876432473121, -0.04279471058404047], [-0.27439746807899096, -0.49888606251189316]], - [[-0.2827629165886028], [-0.5431768324825607, -0.2133080279346807, -0.10499961310795408, 0.09083087776121102, 0.37394345246532357, 0.41219715056530515, -0.17844896356814216, 0.6017127772767268, 0.04825845645947814], [0.1686105642978755, 0.27823583527578005, -0.06479699938479212, 0.4075789329243761, -0.1242362543997863, 0.16905085277591742], [0.4498529143568951, -0.38162629109703405, -0.6140545422956211, 0.15825503736095084, -0.2582602332898444, 0.7274993022330352, -0.2411292264007391, -0.5521909388447415, -0.32703914771404785, 0.28418328300445966]], - [[-0.05589178950257751], [-0.1019705158920252, -0.4021433820745908, 0.48255194721701017, 0.008131662295720925, 0.07202859076099435, -0.18565046869387167, 0.3240465427833554, -0.4904527437336233, 0.04012334309767329], [-0.47219983715545033, -0.3425847967691243, -0.26741555241645554, 0.5136974943331476, -1.3528826516837709, -0.5084770566734448, 0.5426586250054705, -0.31969383279201147, 0.6862705068300334], [0.09849573584104232, 0.029230981468574946]], - [[-0.05719286771089035], [0.4242973237170861, -0.5219356456168175, 0.3310684379655346, 0.12413567167651018, -0.5923469397738462, -0.37146828706242285, -0.5751410323943549, -0.055651487469272024, 0.5472629066920902, 0.29283912917169935], [0.1875320328414897, 0.6808265997858123, -0.2995863467195515, -0.13554874838930378, 0.6373044353809255, 0.8178243633205413, -0.9612380226211692, 0.07781549715708687, -0.3845106658570097, -0.6707841245616247], [-0.2707020905807271, -0.5625117726096117, 0.10488366055899745, -0.28409682013973964, -0.25019752929639916, -0.8986902851125926, -0.8128844484365579]], - [[-0.13762858893746074], [-0.44703815295307797, 0.5944800147380626, 1.4927738811624347, 0.2690676585035225, 0.1392293231358478, -0.40920070507884104, -0.7332317211680289, -0.3830957876846897, 0.1418909392355959], [-0.28919223043248377, -0.334256240757651, 0.07031663871919733], [1.4923062450401439, -0.07045305045420008, 1.1439824974086474, -0.48836659931427834, 0.9029762904802794, -0.4051626818191545, 0.7052172856721804, 0.7200604408974567], [-0.4660428754709174, 0.3303812040550049, 0.0416448317248993, 0.0923448025024135, -0.11839363942123281, 0.12128945856537898, -0.3046909560916853, -0.9180764335769804, -0.8185102432606277, -0.8637091370051597]], - [[0.08588821780925351], [-0.19846651453049668, -0.12131137905689643, -0.012056169732668959, 0.387028828005472, -0.1673202197809444, 0.15365077102586527, -0.5066602440919681, -0.5263849388489793, -1.0529289245626894, -0.2368951143092367], [-0.5124015057222998, 0.10937701513453171, 1.100622688156337, -0.3529295809332267, -0.14952258183921502, 0.28769664553265084, -0.29663286648941295, 0.8048977491005426, 0.26266525195090656], [0.5229761285972861, 0.058988804914361245, 0.16088566715699476, 0.0876297447684608, -0.12424872326482747, -0.18192414077364386, 0.0034228886467715103], [-0.4422179502033592, 0.06409501421449978, -0.03443123742857476, -0.40737856180759047, -0.49232052745173593, -0.3063601971060485]], - [[0.0020120000622140064], [-0.4605158014626578, 0.04861856501815409, 0.12440850145559806, 0.41986549071776175, 0.45760378449565353, 0.3823068642538414, -0.7509927996480504], [0.7945555246182702, -0.05349582066856984], [-0.2002746258874713, 0.06644197619406682, 0.3105130297384215, -0.019792549607544785, -0.0029621125749771035, 0.5952370789475336, -0.15048879670202958, 0.10947909205995154], [0.47460069009979067, 0.34348555903411404, 0.8553181291195778, 0.36336966197832254, -0.4154570058919746, 0.7084181186043732, -0.8911752856098722, -0.12208726470275424]] - ] + [ + [0.46132409636616317], + [ + 0.7034437676859567, + 0.6114140712984324, + -0.08829607209219353, + 0.03327833095019875, + -0.6185892330923073, + 0.1326136814054642, + 0.5700109876145869, + ], + ], + [ + [0.45470843046349313], + [ + 0.433513329547113, + -0.7320515075884788, + -0.38765391945909755, + 0.19640702045402264, + 0.14944186690806377, + -0.9671407596317976, + -0.9289295848779034, + ], + [-0.5045110500803344, 0.06911945375717096], + ], + [ + [-0.19135891857701476], + [ + -0.0069569775655274405, + 0.4648330993586129, + -0.5249300916156493, + -0.6942918549175187, + 0.03839836910376858, + 0.48996587981873707, + 0.19149786106059058, + 0.25496379149224513, + 0.8306443019906313, + ], + [ + -0.14991071399697806, + -0.0899250894563053, + 0.48363972474877626, + -0.06740963522851286, + -0.17392353118572687, + -0.8626165876780832, + -0.4781319504914857, + -0.002601732145143469, + ], + ], + [ + [0.032475437742255364], + [-0.0793840052835045, -0.032660090840698486], + [-0.16688671771785502, -0.08140692187036919], + ], + [ + [-0.14362437882603868], + [ + 0.21703580244995338, + -0.07582942569056315, + -0.4131524696769127, + 0.07113227925464494, + 0.9216831076067749, + -0.3117658924120991, + -0.2601938828890881, + ], + [ + -0.40993096871840384, + 0.06033520676657045, + 0.3353505686920585, + 0.32669207217743906, + -0.26949939576113957, + 0.4622586254534011, + -0.23046667729151138, + 0.39890816877066293, + -0.352075854880814, + ], + [ + 0.27574595870419494, + -0.20132897843112602, + 0.7181884086912088, + 0.20902304397906357, + -0.9797911979282492, + -0.22738728408774556, + -0.08434852248139064, + -0.03906999050989374, + 0.23241083119724726, + ], + ], + [ + [0.167542758489263], + [ + -0.7172648711179583, + -0.12978356499468247, + -0.14709754758453525, + 0.7429222145447074, + -0.301380485416464, + 0.10648701938150486, + -0.5862695196566239, + -0.6731434017042006, + -0.1027873036321029, + 0.8518198213004147, + ], + [ + 0.36528861191780526, + -0.05502523773982651, + 0.3349143864166638, + 0.5976408658825734, + 0.22224119027517705, + 0.5079433605241578, + 0.13504430515015828, + ], + [-0.09838274427397142, 0.1575018337179488, -0.22867252665062765], + ], + [ + [0.0005576618010449276], + [ + -0.5529387542450745, + -0.18931262357519596, + -0.4740879804055004, + 0.7218017303773806, + 0.4001673857383268, + ], + [ + 0.04653671285987987, + -0.3342761936754844, + 0.10416238554693465, + -0.3780599114751379, + -0.13425764881025848, + 0.045590813877080076, + ], + [-0.3467728705815678, 1.0951463617116348, 0.5450739839349461], + ], + [ + [-0.10835780918855986], + [ + -0.2879956140065193, + 0.43075721925722893, + -0.3291055923326802, + 0.017387780693294552, + 0.060086501392198954, + -0.22944578876172467, + -0.2678362137267055, + 0.821848362075142, + 0.5607641072034037, + ], + [0.1257205818761756, 0.5344739830694265, -0.1312860116480018], + [ + -0.32028258895073813, + 0.05581149125388041, + -0.38726569273936556, + -0.4124721885803405, + 0.09543462429188473, + -0.2587175245909177, + ], + [ + 0.23313088537058163, + 0.398484868218528, + 0.17079789329674128, + -0.5464610930958373, + -1.0423151616550292, + 0.3909668100967531, + ], + ], + [ + [-0.13373401585247496], + [ + -0.0462149976885849, + -0.22586363815314267, + -0.24082866649963608, + -0.17798976955515672, + -0.22606766311009552, + ], + [-1.1531492828944132, -1.048323182821658, 0.3469323589434465, -0.19825175056321256], + [ + -0.33544764292008533, + 0.5454762716081148, + -0.44056401394680517, + 0.6346538879978276, + 0.4071906233657455, + 0.20386210363713045, + 0.1131664536677318, + 0.13733952167695518, + 0.3499954521074497, + -0.40947620073175056, + ], + [ + 0.5235561961524053, + -0.33651887371172584, + 0.165664680004435, + 0.3177740663156395, + -0.5050069337944564, + 0.007676908750572816, + -0.15745475915753057, + -0.13379200089703605, + 0.7775600848786371, + 0.6495661761313964, + ], + ], + [ + [0.14255661510910747], + [ + -0.01620371146007782, + -0.2176640728621523, + -0.26783759524037853, + 0.1887922975530844, + -0.03868441552368684, + 0.24619823528128237, + 0.16400437859951833, + 0.8207953853819989, + -0.683215714398723, + 0.2095762101658616, + ], + [ + -0.587587477362466, + 0.9611453504625634, + -0.4956705989932666, + -0.8797827478845143, + 0.2660001180346881, + 0.7021729654279507, + ], + [0.6165274130606305, 0.1402548199881536, -0.22150177598219462], + [0.42439566636895776, 0.04342532989904936, 0.1811774237827697, -0.5227232167013833], + ], + [ + [-0.25050034943799143], + [ + 0.3488629827096742, + -0.01790447096652751, + 0.41078746198742494, + 0.2674738658616262, + -0.3676063246452534, + 0.27995679376647054, + -0.6476807696598814, + -0.05608263854802896, + -1.002407614041255, + -0.41159169074078095, + ], + ], + [ + [1.5189255716984038], + [ + 0.14389418968383233, + -0.7434685056546961, + 0.17177099801922532, + -0.0699519450185816, + -0.48084553564682225, + -0.2504085373789058, + 0.5705781638468338, + -0.7229621177887824, + -0.2742605768830553, + ], + ], + [ + [-0.2000130047239455], + [0.28376287916446385, -0.011498145899119377, 0.276592098504903, 0.3464992149574739], + ], + [ + [0.7638265778356526], + [0.043718096583251764, 0.014174547965435269], + [ + 0.1589574325807131, + 0.8748133883099838, + -0.3528071207217161, + -0.2644899757823254, + 0.24010835273681236, + -0.1673897092037622, + -0.6222042985569745, + -0.09191448012128656, + 0.039882538236865134, + ], + ], + [ + [0.13319966661993943], + [ + -0.27617394286645647, + -0.22020251242074337, + -0.2045923981917276, + 0.7425959288733582, + ], + [ + -0.7440711602827321, + -0.42811046699670163, + -0.07153818588627878, + -0.1126683907082826, + -0.31430569035654404, + 1.0115723034951567, + -0.20961404535149197, + ], + ], + [ + [0.4767148797604099], + [0.3384876432473121, -0.04279471058404047], + [-0.27439746807899096, -0.49888606251189316], + ], + [ + [-0.2827629165886028], + [ + -0.5431768324825607, + -0.2133080279346807, + -0.10499961310795408, + 0.09083087776121102, + 0.37394345246532357, + 0.41219715056530515, + -0.17844896356814216, + 0.6017127772767268, + 0.04825845645947814, + ], + [ + 0.1686105642978755, + 0.27823583527578005, + -0.06479699938479212, + 0.4075789329243761, + -0.1242362543997863, + 0.16905085277591742, + ], + [ + 0.4498529143568951, + -0.38162629109703405, + -0.6140545422956211, + 0.15825503736095084, + -0.2582602332898444, + 0.7274993022330352, + -0.2411292264007391, + -0.5521909388447415, + -0.32703914771404785, + 0.28418328300445966, + ], + ], + [ + [-0.05589178950257751], + [ + -0.1019705158920252, + -0.4021433820745908, + 0.48255194721701017, + 0.008131662295720925, + 0.07202859076099435, + -0.18565046869387167, + 0.3240465427833554, + -0.4904527437336233, + 0.04012334309767329, + ], + [ + -0.47219983715545033, + -0.3425847967691243, + -0.26741555241645554, + 0.5136974943331476, + -1.3528826516837709, + -0.5084770566734448, + 0.5426586250054705, + -0.31969383279201147, + 0.6862705068300334, + ], + [0.09849573584104232, 0.029230981468574946], + ], + [ + [-0.05719286771089035], + [ + 0.4242973237170861, + -0.5219356456168175, + 0.3310684379655346, + 0.12413567167651018, + -0.5923469397738462, + -0.37146828706242285, + -0.5751410323943549, + -0.055651487469272024, + 0.5472629066920902, + 0.29283912917169935, + ], + [ + 0.1875320328414897, + 0.6808265997858123, + -0.2995863467195515, + -0.13554874838930378, + 0.6373044353809255, + 0.8178243633205413, + -0.9612380226211692, + 0.07781549715708687, + -0.3845106658570097, + -0.6707841245616247, + ], + [ + -0.2707020905807271, + -0.5625117726096117, + 0.10488366055899745, + -0.28409682013973964, + -0.25019752929639916, + -0.8986902851125926, + -0.8128844484365579, + ], + ], + [ + [-0.13762858893746074], + [ + -0.44703815295307797, + 0.5944800147380626, + 1.4927738811624347, + 0.2690676585035225, + 0.1392293231358478, + -0.40920070507884104, + -0.7332317211680289, + -0.3830957876846897, + 0.1418909392355959, + ], + [-0.28919223043248377, -0.334256240757651, 0.07031663871919733], + [ + 1.4923062450401439, + -0.07045305045420008, + 1.1439824974086474, + -0.48836659931427834, + 0.9029762904802794, + -0.4051626818191545, + 0.7052172856721804, + 0.7200604408974567, + ], + [ + -0.4660428754709174, + 0.3303812040550049, + 0.0416448317248993, + 0.0923448025024135, + -0.11839363942123281, + 0.12128945856537898, + -0.3046909560916853, + -0.9180764335769804, + -0.8185102432606277, + -0.8637091370051597, + ], + ], + [ + [0.08588821780925351], + [ + -0.19846651453049668, + -0.12131137905689643, + -0.012056169732668959, + 0.387028828005472, + -0.1673202197809444, + 0.15365077102586527, + -0.5066602440919681, + -0.5263849388489793, + -1.0529289245626894, + -0.2368951143092367, + ], + [ + -0.5124015057222998, + 0.10937701513453171, + 1.100622688156337, + -0.3529295809332267, + -0.14952258183921502, + 0.28769664553265084, + -0.29663286648941295, + 0.8048977491005426, + 0.26266525195090656, + ], + [ + 0.5229761285972861, + 0.058988804914361245, + 0.16088566715699476, + 0.0876297447684608, + -0.12424872326482747, + -0.18192414077364386, + 0.0034228886467715103, + ], + [ + -0.4422179502033592, + 0.06409501421449978, + -0.03443123742857476, + -0.40737856180759047, + -0.49232052745173593, + -0.3063601971060485, + ], + ], + [ + [0.0020120000622140064], + [ + -0.4605158014626578, + 0.04861856501815409, + 0.12440850145559806, + 0.41986549071776175, + 0.45760378449565353, + 0.3823068642538414, + -0.7509927996480504, + ], + [0.7945555246182702, -0.05349582066856984], + [ + -0.2002746258874713, + 0.06644197619406682, + 0.3105130297384215, + -0.019792549607544785, + -0.0029621125749771035, + 0.5952370789475336, + -0.15048879670202958, + 0.10947909205995154, + ], + [ + 0.47460069009979067, + 0.34348555903411404, + 0.8553181291195778, + 0.36336966197832254, + -0.4154570058919746, + 0.7084181186043732, + -0.8911752856098722, + -0.12208726470275424, + ], + ], +] # us[i] is a tangent vector to Ms[i] at ps[i] us = [ - [[-0.37772914799158225], [-0.59695867308892, 0.3750933177933997, 0.34564315403507745, 0.046043813336741984, -0.0545409875155681, 0.2577121584084208, -0.3308621558840682, 0.15972331014082508, 0.23275600794660842, -0.33394550809020124]], + [ + [-0.37772914799158225], + [ + -0.59695867308892, + 0.3750933177933997, + 0.34564315403507745, + 0.046043813336741984, + -0.0545409875155681, + 0.2577121584084208, + -0.3308621558840682, + 0.15972331014082508, + 0.23275600794660842, + -0.33394550809020124, + ], + ], [[1.3683817863110515], [1.309120423677036, 0.34003444822705764]], - [[-0.12929062734170355], [0.15850990687718194, 0.17487391887026144, 1.0186159795799787, -0.34163759242980707, 0.14845978504467341, -0.13138435258479628, 0.07372358714600029]], - [[-0.2603225446842325], [0.3602679784109386, 0.17337068990715637, -0.19313197776041668, -0.25410123672991486, 0.08222041883237792, -0.21642611657517966, 0.2574667569083157], [1.3205385203894777, -0.18091754616690692]], - [[-0.3096239639876968], [0.8763931296077601, 0.9630409930052396, -0.024742767752841448, -0.5119584268098544, -0.65137269579901, -0.5585309447674137, 0.36820697176827755, 0.788214538036487, 0.2908132604789067], [0.2655385329237167, -0.33415351180043346, -0.5131255776726478, 0.27265294689102404, -0.0733048224201999, -0.5967809983817592, 0.11338960014259027, 0.23310946516775605]], - [[-0.5123951975200387], [-0.7694459734927109, -0.31656471982654616], [-1.1392866599419809, -0.5557411721084375]], - [[-0.14766117733667908], [-1.0051180880053472, 0.9460677967957836, 0.5835821685582908, 0.6948551934342009, 0.6374252884087097, -0.009680426176410788, -0.36146835559128143], [0.4688516869504158, -0.28425151202447, -0.3187195701047898, -0.35633492041750464, 0.554715750802327, -0.10721116773599117, 0.28645702408100504, -0.1610220090851739, -0.28845747034499986], [0.09417372769886223, 0.1989812337413881, -0.08400464069697863, -0.6790036003882072, -0.22919842842946442, 0.3185935243022103, -0.9397877219225759, -0.548382602086301, 0.3462072647694016]], - [[-0.0360207524796129], [0.20350245773360448, 0.37364752980981, -0.13027127184216153, -0.08190812987077147, 0.4553806555417341, -0.5133558357167839, -0.01992655851146799, 0.7876406853642887, 0.14590589840824297, 0.5882183495667237], [0.1421766874190634, 0.16985174267090664, 0.2674424928046712, 0.19679295366232205, 0.020504602587278625, -0.7983181858070574, 0.41087597326194303], [0.08272242498791532, 0.043641892904065484, -0.1652205757255303]], - [[0.07334723852895442], [-0.335402461448991, -0.04149991778158621, 0.8259416067042924, -0.36669745774013474, -0.0293979473512328], [0.25357991790389556, -0.6762696649693698, -0.1500007754391727, -0.21823190285300317, -0.1554963524472741, 0.2760192231713663], [-0.6373006596520467, -0.671494722883091, 0.3231820209261418]], - [[-0.8237610837914967], [0.3004390493463726, 0.4405860908850111, -0.7157767786794753, -0.26422248721975317, 0.43563297876352225, -0.05301527548401603, 0.2653406121711885, -0.16921344490396534, -0.10660913986306259], [0.2301095438238535, 0.13543635311552182, -0.5554515952958057], [-0.047141475305190236, 0.26349478946841576, 0.7660038342835548, -0.44707592462720674, -0.008237239351391848, 0.10681017970047482], [-0.10101942119876328, -0.09752768648570287, -0.03101236164578546, -0.017267002331470507, 0.426143631920239, -0.3979129485173604]], - [[-0.17314190690191722], [-1.1339790699243253, -0.6846816962035396, 0.2090090635616599, 0.6968343188160526, -0.8282658301524312], [0.26096836011459945, 0.5854265047018472, 0.7062605498807286, 0.34245153599846784], [-0.4642499534514001, 0.3677311750533016, -0.5795938822926545, -0.2327468766014096, 0.008116599138855707, 0.25047446112097677, 0.1664040210464276, -0.13265399018639917, -0.38415949773048125, -0.10878478149940779], [0.36290342984947627, -0.5552686774454564, -0.03722341001087248, -0.08247270899765498, 0.42071065664777474, 0.029450006187029542, -0.6467198752580883, 0.3282922917661867, 0.13054924199752604, 0.6409942919440069]], - [[0.15795465249466936], [0.5351607860771331, -0.41785689120228914, -0.030904801558696852, 0.20801945515978773, 0.39257256533026225, -0.08950160299890557, 0.6172225568521781, 0.8206592397973528, 0.5312616693613874, 0.34916321649313975], [-0.48125632002442126, -0.3885025059033661, -0.39789961820933506, -0.8112377504395194, -0.13593743657921403, 0.45648408250913297], [-0.6908584605178826, -0.25115275205263854, 0.217617378343041], [-0.05159880494311214, -0.08968056529390697, -0.31839202789900106, 0.12849987939389101]], - [[-0.11566741406383592], [-0.6189044291634334, -0.4887938523139652, 0.377907148579411, 0.4086524760594208, 0.07938663795474155, -0.6960459002055371, -0.5157245121702985, -0.0949098978719522, 0.35850803987739277, -0.4702399492568731]], - [[0.996024398644524], [-0.7416787110144638, 0.14070197751838798, -0.13795012958209601, -0.4757150483429905, -0.1360189820310271, 0.3238908388104348, 0.5189337739664109, 0.6803924956106052, -0.5549192083475457]], - [[-0.5889817889278641], [0.08753868748426015, 0.07610237172143071, -0.1871044108743123, -0.21019436123666874]], - [[-0.44426957903450753], [0.02248238255936011, 0.0072893752214958085], [-0.11483810063446695, 0.7180538788465062, 1.2336105712455359, 0.5094984474406282, 0.44539460730056, -0.22600080346686421, 0.23177494146123226, 0.04078051728077603, 0.6543369295727094]], - [[-0.8389592975128012], [-0.3425282245979182, 0.7830546276591328, -0.3052977538552278, 0.5882182554997865], [0.03745255029472473, -0.18373865390118915, 0.31498165370594844, 0.46034942779621935, 0.11932816285894, 0.030905964762235363, 0.31751727602532254]], - [[-0.4656394904731537], [-0.49930548339416325, 0.06312677606155825], [0.1221872729023376, 0.22215047352319392]], - [[0.26115469823295706], [0.9332535998779934, 0.8409422500428906, 1.1570765490059969, 0.009748111907376684, 0.1823249755535606, 0.42856570496684815, 0.5854663071660117, 0.3272130825134361, -0.2809222008539077], [-0.3442363693316475, -0.5817781819508783, 0.35114374833485607, 1.1229502716222781, 0.45619247794084083, 0.08783351766172355], [0.06361430009419232, 0.6926810562240848, -0.4297785211478541, -0.46202875308860125, -0.36949007474336926, 0.8488609929914562, 0.030242445794160633, -0.14503901054294097, 0.2058457533515663, 0.2491580414140638]], - [[0.9549180463751705], [0.3895017091001908, 0.49171007245983317, -0.7574299513534506, -0.34411683885229793, 0.0513658453673059, 0.06981342473422567, -0.1439873053399203, -0.18295666103878877, -0.11403644383556799], [-0.15850209669311577, 0.2414976982465587, -0.09000199478941477, -0.47413124486427444, 0.09572564708049942, -0.36176114242096513, -0.1257338263899131, -0.06322697714974733, 0.19138488813360416], [-0.19020791605007967, -0.056448779449793374]], - [[-0.5581377638463701], [-0.25985100085298074, -0.12823304129983562, 0.6940528086313831, 0.3949636485406578, 0.6535818467393291, 0.5759145253409661, 0.2526448903910712, -0.5437798878532403, -0.36348766005250244, -0.17477846468203878], [0.11703814560342424, 0.5421400308047751, 0.5209685317484212, 0.004412884829451791, -0.10761650749037417, 0.4539634764966858, 0.15393382881531487, 0.37298468621560743, 0.20920463087073315, -1.1982965330635182], [-0.2361677344675108, -0.08561184124338428, 0.33089548131311, 0.09448935004937808, -0.5233825679847084, -0.09673390251592129, -0.4195453536456808]], - [[0.1798820030601053], [-0.1533759903297747, 0.2964688376499158, -0.14860837418627715, -0.5551072496477686, 0.19870817329497556, -0.3760368493600557, 0.4044751294601737, -0.32878881969363477, -0.5566640994443255], [0.5598006445911394, 0.4954191143909883, 0.7768169558982286], [0.035077508613607256, -0.18338072549214748, -0.11985026451776065, 0.7471592115103867, 0.34655767438419205, 0.22412820486882898, 0.6981705844979219, 0.3181720496138494], [0.18466074016625922, 0.5419495972646897, 0.5887579351606795, -0.5653359894384714, 0.16017679421854783, -0.49769950032627924, -0.6930225262597705, 0.3904417023562996, 0.6252695138324811, -0.5591798774189761]], - [[0.02775921877564232], [-0.32610417589316576, -0.9533681500385859, -0.7953634329826215, -1.0380444511104359, 1.8624955384484987, 0.44685665513406264, -0.8501002862266008, -1.070462937138491, -0.02354710201871483, 0.28743720819281715], [0.2653138406460859, -0.2282890286319614, 0.02811495791663485, 0.03337784871438022, 0.1768829048441087, -0.2345694568284544, -0.46257070907000497, -0.2368037688836088, 0.12834132594241648], [-0.5490049782150824, -0.15079368647293154, 0.4956415766510821, -0.04311702187664941, -0.13959940872666987, 0.1745102984539435, -0.031814296573279166], [1.060646643382475, -0.07879165090994764, -0.13387349603704785, -0.2653272097959495, -0.9301322737127853, -0.6249913037816839]], - [[0.16969505385956252], [0.0930186150799604, 0.1546667070131112, 0.5068773816789583, 0.21700722366006517, -0.408452920217741, 0.26880615167829464, 0.06987247642683876], [-0.0984469609988096, 0.006628235293547613], [0.016225795251541872, -0.7366173566083619, 1.1134825891599547, -0.7078026064080831, -0.024735556978746676, -0.65431320330066, 0.7988331267058175, -0.913679346443505], [-0.41346861893716785, -0.30448423297022137, 0.7646027070405849, -0.3087443669597033, 0.3795212472780163, -0.002675858285340116, 0.4202373636203284, -0.023732041788181002]] - ] + [ + [-0.12929062734170355], + [ + 0.15850990687718194, + 0.17487391887026144, + 1.0186159795799787, + -0.34163759242980707, + 0.14845978504467341, + -0.13138435258479628, + 0.07372358714600029, + ], + ], + [ + [-0.2603225446842325], + [ + 0.3602679784109386, + 0.17337068990715637, + -0.19313197776041668, + -0.25410123672991486, + 0.08222041883237792, + -0.21642611657517966, + 0.2574667569083157, + ], + [1.3205385203894777, -0.18091754616690692], + ], + [ + [-0.3096239639876968], + [ + 0.8763931296077601, + 0.9630409930052396, + -0.024742767752841448, + -0.5119584268098544, + -0.65137269579901, + -0.5585309447674137, + 0.36820697176827755, + 0.788214538036487, + 0.2908132604789067, + ], + [ + 0.2655385329237167, + -0.33415351180043346, + -0.5131255776726478, + 0.27265294689102404, + -0.0733048224201999, + -0.5967809983817592, + 0.11338960014259027, + 0.23310946516775605, + ], + ], + [ + [-0.5123951975200387], + [-0.7694459734927109, -0.31656471982654616], + [-1.1392866599419809, -0.5557411721084375], + ], + [ + [-0.14766117733667908], + [ + -1.0051180880053472, + 0.9460677967957836, + 0.5835821685582908, + 0.6948551934342009, + 0.6374252884087097, + -0.009680426176410788, + -0.36146835559128143, + ], + [ + 0.4688516869504158, + -0.28425151202447, + -0.3187195701047898, + -0.35633492041750464, + 0.554715750802327, + -0.10721116773599117, + 0.28645702408100504, + -0.1610220090851739, + -0.28845747034499986, + ], + [ + 0.09417372769886223, + 0.1989812337413881, + -0.08400464069697863, + -0.6790036003882072, + -0.22919842842946442, + 0.3185935243022103, + -0.9397877219225759, + -0.548382602086301, + 0.3462072647694016, + ], + ], + [ + [-0.0360207524796129], + [ + 0.20350245773360448, + 0.37364752980981, + -0.13027127184216153, + -0.08190812987077147, + 0.4553806555417341, + -0.5133558357167839, + -0.01992655851146799, + 0.7876406853642887, + 0.14590589840824297, + 0.5882183495667237, + ], + [ + 0.1421766874190634, + 0.16985174267090664, + 0.2674424928046712, + 0.19679295366232205, + 0.020504602587278625, + -0.7983181858070574, + 0.41087597326194303, + ], + [0.08272242498791532, 0.043641892904065484, -0.1652205757255303], + ], + [ + [0.07334723852895442], + [ + -0.335402461448991, + -0.04149991778158621, + 0.8259416067042924, + -0.36669745774013474, + -0.0293979473512328, + ], + [ + 0.25357991790389556, + -0.6762696649693698, + -0.1500007754391727, + -0.21823190285300317, + -0.1554963524472741, + 0.2760192231713663, + ], + [-0.6373006596520467, -0.671494722883091, 0.3231820209261418], + ], + [ + [-0.8237610837914967], + [ + 0.3004390493463726, + 0.4405860908850111, + -0.7157767786794753, + -0.26422248721975317, + 0.43563297876352225, + -0.05301527548401603, + 0.2653406121711885, + -0.16921344490396534, + -0.10660913986306259, + ], + [0.2301095438238535, 0.13543635311552182, -0.5554515952958057], + [ + -0.047141475305190236, + 0.26349478946841576, + 0.7660038342835548, + -0.44707592462720674, + -0.008237239351391848, + 0.10681017970047482, + ], + [ + -0.10101942119876328, + -0.09752768648570287, + -0.03101236164578546, + -0.017267002331470507, + 0.426143631920239, + -0.3979129485173604, + ], + ], + [ + [-0.17314190690191722], + [ + -1.1339790699243253, + -0.6846816962035396, + 0.2090090635616599, + 0.6968343188160526, + -0.8282658301524312, + ], + [0.26096836011459945, 0.5854265047018472, 0.7062605498807286, 0.34245153599846784], + [ + -0.4642499534514001, + 0.3677311750533016, + -0.5795938822926545, + -0.2327468766014096, + 0.008116599138855707, + 0.25047446112097677, + 0.1664040210464276, + -0.13265399018639917, + -0.38415949773048125, + -0.10878478149940779, + ], + [ + 0.36290342984947627, + -0.5552686774454564, + -0.03722341001087248, + -0.08247270899765498, + 0.42071065664777474, + 0.029450006187029542, + -0.6467198752580883, + 0.3282922917661867, + 0.13054924199752604, + 0.6409942919440069, + ], + ], + [ + [0.15795465249466936], + [ + 0.5351607860771331, + -0.41785689120228914, + -0.030904801558696852, + 0.20801945515978773, + 0.39257256533026225, + -0.08950160299890557, + 0.6172225568521781, + 0.8206592397973528, + 0.5312616693613874, + 0.34916321649313975, + ], + [ + -0.48125632002442126, + -0.3885025059033661, + -0.39789961820933506, + -0.8112377504395194, + -0.13593743657921403, + 0.45648408250913297, + ], + [-0.6908584605178826, -0.25115275205263854, 0.217617378343041], + [ + -0.05159880494311214, + -0.08968056529390697, + -0.31839202789900106, + 0.12849987939389101, + ], + ], + [ + [-0.11566741406383592], + [ + -0.6189044291634334, + -0.4887938523139652, + 0.377907148579411, + 0.4086524760594208, + 0.07938663795474155, + -0.6960459002055371, + -0.5157245121702985, + -0.0949098978719522, + 0.35850803987739277, + -0.4702399492568731, + ], + ], + [ + [0.996024398644524], + [ + -0.7416787110144638, + 0.14070197751838798, + -0.13795012958209601, + -0.4757150483429905, + -0.1360189820310271, + 0.3238908388104348, + 0.5189337739664109, + 0.6803924956106052, + -0.5549192083475457, + ], + ], + [ + [-0.5889817889278641], + [ + 0.08753868748426015, + 0.07610237172143071, + -0.1871044108743123, + -0.21019436123666874, + ], + ], + [ + [-0.44426957903450753], + [0.02248238255936011, 0.0072893752214958085], + [ + -0.11483810063446695, + 0.7180538788465062, + 1.2336105712455359, + 0.5094984474406282, + 0.44539460730056, + -0.22600080346686421, + 0.23177494146123226, + 0.04078051728077603, + 0.6543369295727094, + ], + ], + [ + [-0.8389592975128012], + [-0.3425282245979182, 0.7830546276591328, -0.3052977538552278, 0.5882182554997865], + [ + 0.03745255029472473, + -0.18373865390118915, + 0.31498165370594844, + 0.46034942779621935, + 0.11932816285894, + 0.030905964762235363, + 0.31751727602532254, + ], + ], + [ + [-0.4656394904731537], + [-0.49930548339416325, 0.06312677606155825], + [0.1221872729023376, 0.22215047352319392], + ], + [ + [0.26115469823295706], + [ + 0.9332535998779934, + 0.8409422500428906, + 1.1570765490059969, + 0.009748111907376684, + 0.1823249755535606, + 0.42856570496684815, + 0.5854663071660117, + 0.3272130825134361, + -0.2809222008539077, + ], + [ + -0.3442363693316475, + -0.5817781819508783, + 0.35114374833485607, + 1.1229502716222781, + 0.45619247794084083, + 0.08783351766172355, + ], + [ + 0.06361430009419232, + 0.6926810562240848, + -0.4297785211478541, + -0.46202875308860125, + -0.36949007474336926, + 0.8488609929914562, + 0.030242445794160633, + -0.14503901054294097, + 0.2058457533515663, + 0.2491580414140638, + ], + ], + [ + [0.9549180463751705], + [ + 0.3895017091001908, + 0.49171007245983317, + -0.7574299513534506, + -0.34411683885229793, + 0.0513658453673059, + 0.06981342473422567, + -0.1439873053399203, + -0.18295666103878877, + -0.11403644383556799, + ], + [ + -0.15850209669311577, + 0.2414976982465587, + -0.09000199478941477, + -0.47413124486427444, + 0.09572564708049942, + -0.36176114242096513, + -0.1257338263899131, + -0.06322697714974733, + 0.19138488813360416, + ], + [-0.19020791605007967, -0.056448779449793374], + ], + [ + [-0.5581377638463701], + [ + -0.25985100085298074, + -0.12823304129983562, + 0.6940528086313831, + 0.3949636485406578, + 0.6535818467393291, + 0.5759145253409661, + 0.2526448903910712, + -0.5437798878532403, + -0.36348766005250244, + -0.17477846468203878, + ], + [ + 0.11703814560342424, + 0.5421400308047751, + 0.5209685317484212, + 0.004412884829451791, + -0.10761650749037417, + 0.4539634764966858, + 0.15393382881531487, + 0.37298468621560743, + 0.20920463087073315, + -1.1982965330635182, + ], + [ + -0.2361677344675108, + -0.08561184124338428, + 0.33089548131311, + 0.09448935004937808, + -0.5233825679847084, + -0.09673390251592129, + -0.4195453536456808, + ], + ], + [ + [0.1798820030601053], + [ + -0.1533759903297747, + 0.2964688376499158, + -0.14860837418627715, + -0.5551072496477686, + 0.19870817329497556, + -0.3760368493600557, + 0.4044751294601737, + -0.32878881969363477, + -0.5566640994443255, + ], + [0.5598006445911394, 0.4954191143909883, 0.7768169558982286], + [ + 0.035077508613607256, + -0.18338072549214748, + -0.11985026451776065, + 0.7471592115103867, + 0.34655767438419205, + 0.22412820486882898, + 0.6981705844979219, + 0.3181720496138494, + ], + [ + 0.18466074016625922, + 0.5419495972646897, + 0.5887579351606795, + -0.5653359894384714, + 0.16017679421854783, + -0.49769950032627924, + -0.6930225262597705, + 0.3904417023562996, + 0.6252695138324811, + -0.5591798774189761, + ], + ], + [ + [0.02775921877564232], + [ + -0.32610417589316576, + -0.9533681500385859, + -0.7953634329826215, + -1.0380444511104359, + 1.8624955384484987, + 0.44685665513406264, + -0.8501002862266008, + -1.070462937138491, + -0.02354710201871483, + 0.28743720819281715, + ], + [ + 0.2653138406460859, + -0.2282890286319614, + 0.02811495791663485, + 0.03337784871438022, + 0.1768829048441087, + -0.2345694568284544, + -0.46257070907000497, + -0.2368037688836088, + 0.12834132594241648, + ], + [ + -0.5490049782150824, + -0.15079368647293154, + 0.4956415766510821, + -0.04311702187664941, + -0.13959940872666987, + 0.1745102984539435, + -0.031814296573279166, + ], + [ + 1.060646643382475, + -0.07879165090994764, + -0.13387349603704785, + -0.2653272097959495, + -0.9301322737127853, + -0.6249913037816839, + ], + ], + [ + [0.16969505385956252], + [ + 0.0930186150799604, + 0.1546667070131112, + 0.5068773816789583, + 0.21700722366006517, + -0.408452920217741, + 0.26880615167829464, + 0.06987247642683876, + ], + [-0.0984469609988096, 0.006628235293547613], + [ + 0.016225795251541872, + -0.7366173566083619, + 1.1134825891599547, + -0.7078026064080831, + -0.024735556978746676, + -0.65431320330066, + 0.7988331267058175, + -0.913679346443505, + ], + [ + -0.41346861893716785, + -0.30448423297022137, + 0.7646027070405849, + -0.3087443669597033, + 0.3795212472780163, + -0.002675858285340116, + 0.4202373636203284, + -0.023732041788181002, + ], + ], +] # When testing that exp(Ms[i], ps[i], t * vs[i]) is an extremum of the length functional, we parametrize curves in Ms[i] and take a derivative along dys[i] dys = [ - [0.24768051036976024, 0.15340874919881428, 0.10461792180729243, 0.1621738878738882, 0.13788895788409475, 0.13920478959340893, 0.1980520199776914, 0.225220769065586, 0.09192923424127934, 0.15861132814448145, 0.07788788182581427, 0.2033127058413462, 0.11406283238286104, 0.020870012361419343, 0.2719578430552649, 0.15170700765742606, 0.07022129511933332, 0.04843952826362164, 0.2555544578976192, 0.06681340738035137, 0.15586613310716685, 0.018646851863471762, 0.1979297092698637, 0.23753411269988997, 0.21343310337377225, 0.08016910818336964, 0.1464783972931314, 0.025950651929534232, 0.1449831966165307, 0.23373068876892722, 0.11880598168141776, 0.19121899600576953, 0.15179084381364852, 0.04935589775227154, 0.1560593153225572, 0.04411343229804097, 0.2392666728301238, 0.1484349911958273, 0.17060958026859915, 0.01433037040599356], - [0.49490048799897596, 0.3065322528949179, 0.20904131890947963, 0.32404623250194, 0.27552152748971576, 0.2781507442742417, 0.3957357855481444, 0.45002276663457547], - [0.2774747194904695, 0.17186273392192533, 0.11720271596589263, 0.18168225662692275, 0.15447602176127323, 0.15595013869479196, 0.2218762736147053, 0.2523132305670958, 0.10298766925985375, 0.17769114622380935, 0.08725724171457977, 0.22776978268478074, 0.1277837823108223, 0.023380526861408162, 0.30467244314999586, 0.16995628493998063, 0.07866841899027918, 0.05426646003407173, 0.2862958470725858, 0.07485058652127569, 0.17461572368939868, 0.02088993591975766, 0.22173924979601844, 0.2661077821279658, 0.17616832761102516, 0.24286311298519137, 0.32029952947731805, 0.07192152273314319], - [0.2703013619564934, 0.1674196883015804, 0.11417275710290055, 0.17698535383607492, 0.15048246250457872, 0.15191847013635482, 0.2161402633508973, 0.2457903551976426, 0.10032520193833194, 0.1730974227854145, 0.08500144200281991, 0.22188141170224845, 0.12448027862860386, 0.022776086648557087, 0.29679596211605436, 0.16556252539583352, 0.07663466003347703, 0.05286354765112583, 0.278894443170582, 0.07291552728513738, 0.17010150697308607, 0.020349883191748984, 0.21600678191201325, 0.2592282859804155, 0.23292611292832396, 0.08749101451887183, 0.15985638202387917, 0.02832074493766232, 0.1582246235190211, 0.255077492415341, 0.12965662340215453, 0.20868317404203518], - [0.19457563274485226, 0.1205165654713542, 0.08218692016467483, 0.12740238140112917, 0.10832435377645168, 0.10935805960596295, 0.15558792674492308, 0.17693145731489499, 0.07221879869975649, 0.12460366577951727, 0.061188035614062594, 0.15972067533731096, 0.08960675892678109, 0.016395298340405255, 0.21364769199403277, 0.11917969226849504, 0.0551652324585789, 0.03805366779842952, 0.2007613367396708, 0.052488025793646274, 0.12244706467838061, 0.014648802986629832, 0.15549184052751536, 0.1866047118849567, 0.167671170717676, 0.06298014699696033, 0.11507214190657873, 0.02038660414496235, 0.11389752539236134, 0.18361677546291374, 0.09333293534087271, 0.15021996314975533, 0.11924555321621164, 0.0387735596171921, 0.12259882692942942, 0.03465512481835747, 0.18796579590043078, 0.11660922488526533, 0.13402938722767327, 0.011257813079646883, 0.09066268061997902, 0.07657067329789471, 0.17155609506972255, 0.02437048731808387, 0.2215711733203188, 0.2103628283958812, 0.13577361182582945, 0.05424502888292601, 0.028934213909226063, 0.0924565622310047, 0.1986597950667768, 0.0790211436628239, 0.07639807345045613, 0.12722079565692512, 0.1446707992261107, 0.06036826781167918, 0.0585884798528245, 0.15137516172871096, 0.22086742806031712, 0.08175559977855866, 0.10596354820935999, 0.010750489568562414, 0.05896893496182565, 0.16027814898868079], - [0.387733284839387, 0.24015485982792192, 0.1637748986177967, 0.253876310924278, 0.2158592878529835, 0.21791916632378672, 0.3100419978963423, 0.35257351688061767, 0.2461713430135757, 0.3393682593390343, 0.44757514819657734, 0.1005005728492324], - [0.16353440643700792, 0.10129020125571776, 0.06907539765598648, 0.10707750259980159, 0.0910430491609086, 0.09191184484141025, 0.13076652451317197, 0.14870505851042468, 0.06069752009721213, 0.1047252743607885, 0.05142652727905344, 0.13423996349664308, 0.07531152759015192, 0.013779707893699597, 0.17956384365300332, 0.10016660338980309, 0.04636455972831437, 0.03198285359980099, 0.16873328677427074, 0.0441144557626597, 0.10291272221322205, 0.012311836110395775, 0.1306857672142806, 0.1568351101623881, 0.14092209282890691, 0.05293273783140711, 0.09671434268855209, 0.017134268875714943, 0.09572711622173373, 0.1543238480770115, 0.07844325605769907, 0.12625492803046978, 0.10022195734569302, 0.03258789894704945, 0.10304027338340047, 0.029126490235301297, 0.15797905641835802, 0.09800621027247283, 0.11264728258206483, 0.009461820854890907, 0.07619899497188476, 0.06435512726649247, 0.14418724370624061, 0.020482591380646117, 0.18622326856315144, 0.17680302406232687, 0.11411324587011096, 0.04559115895133764, 0.024318253167761508, 0.0777066933426362, 0.16696701026147626, 0.06641466684484068, 0.06421006278332052, 0.1069248857665583, 0.12159103864374035, 0.05073753945931583, 0.04924168633871106, 0.12722583436268306, 0.18563179386637813, 0.0687128870870491, 0.08905886988994213, 0.009035432164352614, 0.049561446318667116, 0.1347085017272271, 0.1200359392924501, 0.027268283817115106, 0.04224558795450571, 0.04315262171954351, 0.05403346926811662, 0.0023262859537098515, 0.010721414504714139, 0.13403654903491943, 0.10987330337776338, 0.013298908898025385, 0.14340914694684173, 0.17825169707180502, 0.10868078009526573, 0.0016445884181541684, 0.07063958523304881, 0.1101738445443299, 0.11758054831650003, 0.060827727766064016, 0.14865227744166581, 0.11702503201869387, 0.09342064187053477, 0.15738531812684184, 0.03201521439082036, 0.06114448967602477, 0.10382777552410098, 0.1431354723068435, 0.18877393058117947, 0.04238816261102419], - [0.18931478384099465, 0.11725809249396936, 0.07996478698818024, 0.12395773281339016, 0.10539552836400544, 0.10640128531778455, 0.15138120999255955, 0.17214766373220333, 0.07026617913163342, 0.12123468761259337, 0.05953366088302137, 0.15540221917752278, 0.08718401146951676, 0.015952009599231567, 0.2078711812851488, 0.11595736507064407, 0.05367369958461762, 0.03702478975393335, 0.19533324153872214, 0.051068878035693224, 0.11913639572715305, 0.014252735205439095, 0.15128772171130855, 0.18155937717307144, 0.16313775262089256, 0.061277317960149645, 0.11196087281767074, 0.01983540026317905, 0.11081801505923433, 0.17865222723918714, 0.09080944119283771, 0.14615838299541906, 0.1160214452995229, 0.03772521745978412, 0.11928405469835733, 0.0337181350584281, 0.18288366080789226, 0.11345639683447971, 0.13040556062135805, 0.010953429366412056, 0.08821138362439966, 0.0745003896914418, 0.16691763812644678, 0.02371156898547879, 0.21558043106834748, 0.2046751323592965, 0.13210262565520578, 0.052778376061538665, 0.028151903578888155, 0.08995676306701976, 0.19328852040933758, 0.07688460533499909, 0.07433245652145608, 0.12378105670329538, 0.1407592548832129, 0.058736057595709795, 0.05700439074739889, 0.14728234783203958, 0.2148957133578259, 0.07954512844968857, 0.1030985532015983, 0.010459822641440727, 0.05737455928138075, 0.1559446201057239, 0.13895900193366503, 0.03156699173602045, 0.04890539260876352, 0.04995541568895709, 0.06255157417661084, 0.002693013244577135, 0.012411591625591608, 0.15516673744807902], - [0.2208827351133444, 0.13681070045747248, 0.09329879317581574, 0.14462749557513332, 0.12297007186353966, 0.12414353725437031, 0.17662379572008607, 0.20085302392695362, 0.08198295726125182, 0.14145038674302837, 0.06946080797470483, 0.18131530204975832, 0.1017218123213999, 0.018611982853869447, 0.24253338351044798, 0.13529307872148416, 0.06262370707329344, 0.04319861693798904, 0.22790476144676877, 0.059584535506577115, 0.1390022078881141, 0.016629357048352854, 0.17651471841061875, 0.21183412621988404, 0.19034072388880155, 0.07149521720826639, 0.13063017748479328, 0.023142922984180615, 0.12929674993937262, 0.20844221347143077, 0.1059517769179363, 0.17053007029227615, 0.13536784423072898, 0.04401583989479429, 0.13917448876740884, 0.039340582618640645, 0.21337923212968313, 0.13237507784892918, 0.15215048882937396, 0.012779896996084542, 0.10292049721512919, 0.08692321596963569, 0.19475089953352745, 0.027665436925096435, 0.2515281389291008, 0.23880439830403508, 0.15413053686754696, 0.06157908971918815], - [0.1715795373556408, 0.1062732072642473, 0.07247358541051933, 0.11234521687243985, 0.0955219430260548, 0.09643347940647069, 0.13719962830095694, 0.15602065459839623, 0.0636835553069129, 0.10987726996268543, 0.053956472834027505, 0.14084394430027286, 0.07901650388441198, 0.014457605324831525, 0.1883975482043314, 0.10509433361797467, 0.04864548006260954, 0.03355626099441541, 0.17703417838482685, 0.046284681464683716, 0.10797554869382073, 0.0129175210883459, 0.1371148981191942, 0.164550666915154, 0.14785480326481754, 0.05553678192838664, 0.1014722377736982, 0.01797719507885178, 0.10043644436402703, 0.1619158624347057, 0.08230229880238973, 0.1324660822900412, 0.10515241073061003, 0.03419107175394852, 0.10810937478733341, 0.030559377859677404, 0.16575088999747303, 0.10282765922416374, 0.11818900408120409, 0.009927298359990544, 0.07994763052677145, 0.06752109970877263, 0.15128058435355177, 0.021490239451779292, 0.19538458579496817, 0.1855009091519671, 0.1197270859333567, 0.047834031570543896, 0.02551459792914639, 0.08152950063326206, 0.17518100929637484, 0.06968195903934253, 0.06736889872885857, 0.11218509200201603, 0.1275727512737259, 0.053233590023432004, 0.05166414789821036, 0.13348475269051732, 0.19476401329869034, 0.07209324101046329, 0.09344015137889938, 0.009479933332347762, 0.051999638579474684, 0.14133553242896432, 0.12594114827928685, 0.028609756342773685, 0.04432387406709532, 0.04527552966766203, 0.056691664223667886, 0.002440728384874828, 0.011248858149159562, 0.14063052279470464, 0.11527855802353276, 0.013953153258528188, 0.15046420885860654, 0.18702085012439856, 0.11402736815129268, 0.0017254945064788542, 0.07411472372909801, 0.11559388441532585, 0.10893561836452229, 0.15017707070132247, 0.198060728501197, 0.04447346273248423], - [0.15352324557245492, 0.09508947248635916, 0.0648467773137381, 0.10052248994615477, 0.08546962500750059, 0.08628523522382116, 0.12276133012550565, 0.1396017126485001, 0.05698177213314873, 0.09831425914354645, 0.04827832594018572, 0.1260221339994952, 0.07070114721768485, 0.012936149187027587, 0.1685714013686324, 0.09403465842703182, 0.04352623918178691, 0.030024944562363123, 0.15840386366444553, 0.04141388086399268, 0.09661266683324013, 0.011558136784825031, 0.12268551658326957, 0.14723406319463364, 0.13229520035155487, 0.04969233010940552, 0.09079373635463328, 0.01608535246877302, 0.08986694538383312, 0.14487653419367338, 0.07364115922533956, 0.11852592211670533, 0.09408662375438188, 0.03059295057071266, 0.09673240964485387, 0.027343440505776938, 0.1483079799672769, 0.09200651908735905, 0.10575130214923645, 0.008882592222129873, 0.07153428610112707, 0.06041546988453471, 0.1353604669880599, 0.019228699177151067, 0.1748231532056124, 0.16597959213878738, 0.107127522889412, 0.04280018403537061, 0.022829551495057773, 0.0729496870082825, 0.1567457141121245, 0.06234892968263987, 0.0602792858804522, 0.10037921592768378, 0.11414754418852645, 0.04763151620423726, 0.04622723541111018, 0.11943739203007579, 0.17426788708699534, 0.06450645872078792, 0.0836069121502298, 0.008482305963885847, 0.046527420497518554, 0.12646198951003412, 0.1126876440684275, 0.025598988763302813, 0.039659420394756825, 0.04051092785723106, 0.05072567756422609, 0.0021838766380988884, 0.010065076749004063, 0.1258311720542961, 0.10314713890387746, 0.012484783484285916, 0.13463000333533406, 0.16733958106731892, 0.10202761886684918, 0.0015439108936574257, 0.06631520930151812, 0.1034292817038221, 0.11038256588952834, 0.057104008819336624, 0.13955216270266796, 0.1098610568880544, 0.08770166753227544, 0.14775058882543593, 0.03005532430797646, 0.057401379369977516, 0.02755102955172378, 0.05922224994122391, 0.17215444540682492, 0.11921375673164347, 0.014339320851720466, 0.07226503986645506, 0.0717760634504068, 0.17528349052139683, 0.14331799583358729, 0.055100951418902915, 0.14579838397697775, 0.0716513592338211, 0.1554316797606585, 0.029621643272853243, 0.09658002282375533, 0.07404757373098435], - [0.17846031137802032, 0.11053503204293935, 0.07537995974563472, 0.11685054461552731, 0.09935261487813324, 0.1003007061761313, 0.1427016808932576, 0.16227747801487458, 0.06623742717159986, 0.11428362678390792, 0.056120264054923916, 0.14649214319442222, 0.08218526582214918, 0.015037391916391805, 0.19595276705818235, 0.10930888257761537, 0.050596287021758744, 0.03490195205115243, 0.1841336973279205, 0.048140814420656146, 0.11230564167550687, 0.013435546401317802, 0.14261355281660268, 0.17114956543023846, 0.15378415536045742, 0.057763947546553146, 0.1055415315159862, 0.018698126133919378, 0.10446420016714315, 0.16840909861672573, 0.08560282943855643, 0.13777830769824043, 0.10936928872956436, 0.03556222032998324, 0.11244483453432241, 0.031784886312244846, 0.17239792049806787, 0.10695130879960922, 0.12292868249243113, 0.0103254081679582, 0.0831537330012127, 0.07022886682365666, 0.15734731894762363, 0.02235205248399433, 0.20322000255288147, 0.19293996544324854, 0.12452844532248876, 0.04975229738993509, 0.026537797929146605, 0.0847990401055136, 0.18220621146533902, 0.0724763820863788, 0.07007056219895538, 0.11668399833223729, 0.13268874171440578, 0.055368391812715356, 0.05373601108320975, 0.13883782936185077, 0.20257454352772494, 0.07498436257180507, 0.09718733811319212, 0.009860102669626628, 0.0540849557905192, 0.1470034452521622, 0.1309917073073869, 0.029757080034537288, 0.046101373680117005, 0.04709119308060735, 0.058965143546946014, 0.0025386077749533845, 0.011699965851902326, 0.14627016294592948, 0.11990152017630731, 0.014512710044560078, 0.15649820472762588, 0.1945208598983612, 0.11860015442119298, 0.0017946912064986773, 0.07708691186744215, 0.12022949195506588], - [0.24768051036976024, 0.15340874919881428, 0.10461792180729243, 0.1621738878738882, 0.13788895788409475, 0.13920478959340893, 0.1980520199776914, 0.225220769065586, 0.09192923424127934, 0.15861132814448145, 0.07788788182581427, 0.2033127058413462, 0.11406283238286104, 0.020870012361419343, 0.2719578430552649, 0.15170700765742606, 0.07022129511933332, 0.04843952826362164, 0.2555544578976192, 0.06681340738035137, 0.15586613310716685, 0.018646851863471762, 0.1979297092698637, 0.23753411269988997, 0.21343310337377225, 0.08016910818336964, 0.1464783972931314, 0.025950651929534232, 0.1449831966165307, 0.23373068876892722, 0.11880598168141776, 0.19121899600576953, 0.15179084381364852, 0.04935589775227154, 0.1560593153225572, 0.04411343229804097, 0.2392666728301238, 0.1484349911958273, 0.17060958026859915, 0.01433037040599356], - [0.24802588780879425, 0.153622669627372, 0.10476380599437246, 0.16240003082711635, 0.1380812367802985, 0.1393989033476937, 0.19832819309827035, 0.22553482757717827, 0.0920574247212134, 0.15883250329562493, 0.07799649237864552, 0.2035962147115505, 0.11422188700075789, 0.020899114495500196, 0.2723370739572822, 0.1519185550969481, 0.07031921502040975, 0.04850707463695044, 0.25591081514216235, 0.06690657516129511, 0.15608348022827995, 0.018672853917218492, 0.19820571183459643, 0.23786534152126568, 0.21373072460581133, 0.08028089978632086, 0.14668265371062417, 0.025986838748155147, 0.14518536805535576, 0.23405661391576318, 0.11897165037143213, 0.19148564083396585, 0.1574713038353601, 0.21708766594943277, 0.28630563284911986, 0.06428837755455744], - [0.37258942960245, 0.23077503463910054, 0.15737827636974977, 0.24396056148760667, 0.20742838461456795, 0.20940780958141045, 0.29793256257804646, 0.33880291087698405, 0.13829049729675522, 0.23860135056090637, 0.1171678846232154, 0.3058462895900371, 0.17158639407244533, 0.03139506612744243, 0.40911017773906017, 0.2282150798437472], - [0.24768051036976024, 0.15340874919881428, 0.10461792180729243, 0.1621738878738882, 0.13788895788409475, 0.13920478959340893, 0.1980520199776914, 0.225220769065586, 0.09192923424127934, 0.15861132814448145, 0.07788788182581427, 0.2033127058413462, 0.11406283238286104, 0.020870012361419343, 0.2719578430552649, 0.15170700765742606, 0.07022129511933332, 0.04843952826362164, 0.2555544578976192, 0.06681340738035137, 0.15586613310716685, 0.018646851863471762, 0.1979297092698637, 0.23753411269988997, 0.21343310337377225, 0.08016910818336964, 0.1464783972931314, 0.025950651929534232, 0.1449831966165307, 0.23373068876892722, 0.11880598168141776, 0.19121899600576953, 0.15179084381364852, 0.04935589775227154, 0.1560593153225572, 0.04411343229804097, 0.2392666728301238, 0.1484349911958273, 0.17060958026859915, 0.01433037040599356], - [0.24768051036976024, 0.15340874919881428, 0.10461792180729243, 0.1621738878738882, 0.13788895788409475, 0.13920478959340893, 0.1980520199776914, 0.225220769065586, 0.09192923424127934, 0.15861132814448145, 0.07788788182581427, 0.2033127058413462, 0.11406283238286104, 0.020870012361419343, 0.2719578430552649, 0.15170700765742606, 0.07022129511933332, 0.04843952826362164, 0.2555544578976192, 0.06681340738035137, 0.15586613310716685, 0.018646851863471762, 0.1979297092698637, 0.23753411269988997, 0.21343310337377225, 0.08016910818336964, 0.1464783972931314, 0.025950651929534232, 0.1449831966165307, 0.23373068876892722, 0.11880598168141776, 0.19121899600576953, 0.15179084381364852, 0.04935589775227154, 0.1560593153225572, 0.04411343229804097, 0.2392666728301238, 0.1484349911958273, 0.17060958026859915, 0.01433037040599356], - [0.387733284839387, 0.24015485982792192, 0.1637748986177967, 0.253876310924278, 0.2158592878529835, 0.21791916632378672, 0.3100419978963423, 0.35257351688061767, 0.2461713430135757, 0.3393682593390343, 0.44757514819657734, 0.1005005728492324], - [0.16353440643700792, 0.10129020125571776, 0.06907539765598648, 0.10707750259980159, 0.0910430491609086, 0.09191184484141025, 0.13076652451317197, 0.14870505851042468, 0.06069752009721213, 0.1047252743607885, 0.05142652727905344, 0.13423996349664308, 0.07531152759015192, 0.013779707893699597, 0.17956384365300332, 0.10016660338980309, 0.04636455972831437, 0.03198285359980099, 0.16873328677427074, 0.0441144557626597, 0.10291272221322205, 0.012311836110395775, 0.1306857672142806, 0.1568351101623881, 0.14092209282890691, 0.05293273783140711, 0.09671434268855209, 0.017134268875714943, 0.09572711622173373, 0.1543238480770115, 0.07844325605769907, 0.12625492803046978, 0.10022195734569302, 0.03258789894704945, 0.10304027338340047, 0.029126490235301297, 0.15797905641835802, 0.09800621027247283, 0.11264728258206483, 0.009461820854890907, 0.07619899497188476, 0.06435512726649247, 0.14418724370624061, 0.020482591380646117, 0.18622326856315144, 0.17680302406232687, 0.11411324587011096, 0.04559115895133764, 0.024318253167761508, 0.0777066933426362, 0.16696701026147626, 0.06641466684484068, 0.06421006278332052, 0.1069248857665583, 0.12159103864374035, 0.05073753945931583, 0.04924168633871106, 0.12722583436268306, 0.18563179386637813, 0.0687128870870491, 0.08905886988994213, 0.009035432164352614, 0.049561446318667116, 0.1347085017272271, 0.1200359392924501, 0.027268283817115106, 0.04224558795450571, 0.04315262171954351, 0.05403346926811662, 0.0023262859537098515, 0.010721414504714139, 0.13403654903491943, 0.10987330337776338, 0.013298908898025385, 0.14340914694684173, 0.17825169707180502, 0.10868078009526573, 0.0016445884181541684, 0.07063958523304881, 0.1101738445443299, 0.11758054831650003, 0.060827727766064016, 0.14865227744166581, 0.11702503201869387, 0.09342064187053477, 0.15738531812684184, 0.03201521439082036, 0.06114448967602477, 0.10382777552410098, 0.1431354723068435, 0.18877393058117947, 0.04238816261102419], - [0.18931478384099465, 0.11725809249396936, 0.07996478698818024, 0.12395773281339016, 0.10539552836400544, 0.10640128531778455, 0.15138120999255955, 0.17214766373220333, 0.07026617913163342, 0.12123468761259337, 0.05953366088302137, 0.15540221917752278, 0.08718401146951676, 0.015952009599231567, 0.2078711812851488, 0.11595736507064407, 0.05367369958461762, 0.03702478975393335, 0.19533324153872214, 0.051068878035693224, 0.11913639572715305, 0.014252735205439095, 0.15128772171130855, 0.18155937717307144, 0.16313775262089256, 0.061277317960149645, 0.11196087281767074, 0.01983540026317905, 0.11081801505923433, 0.17865222723918714, 0.09080944119283771, 0.14615838299541906, 0.1160214452995229, 0.03772521745978412, 0.11928405469835733, 0.0337181350584281, 0.18288366080789226, 0.11345639683447971, 0.13040556062135805, 0.010953429366412056, 0.08821138362439966, 0.0745003896914418, 0.16691763812644678, 0.02371156898547879, 0.21558043106834748, 0.2046751323592965, 0.13210262565520578, 0.052778376061538665, 0.028151903578888155, 0.08995676306701976, 0.19328852040933758, 0.07688460533499909, 0.07433245652145608, 0.12378105670329538, 0.1407592548832129, 0.058736057595709795, 0.05700439074739889, 0.14728234783203958, 0.2148957133578259, 0.07954512844968857, 0.1030985532015983, 0.010459822641440727, 0.05737455928138075, 0.1559446201057239, 0.13895900193366503, 0.03156699173602045, 0.04890539260876352, 0.04995541568895709, 0.06255157417661084, 0.002693013244577135, 0.012411591625591608, 0.15516673744807902], - [0.15582045376539008, 0.09651232095756643, 0.06581709648315832, 0.10202663406854806, 0.08674852920264194, 0.08757634360644034, 0.12459823978884935, 0.1416906093289221, 0.05783440518753825, 0.09978536093497073, 0.04900072706893626, 0.12790783591802443, 0.07175906684433664, 0.013129716146784482, 0.17109377902469772, 0.09544172344153798, 0.04417753360227171, 0.03047421560521984, 0.1607741018133701, 0.042033567518396465, 0.09805830725702788, 0.011731084187142908, 0.12452129182889228, 0.14943716471837143, 0.13427476779100272, 0.0504358893497519, 0.09215230661051434, 0.016326041775071437, 0.09121164782573381, 0.147044359398728, 0.07474307101517241, 0.12029945627009313, 0.09549446633957638, 0.031050720834981428, 0.09817984181142858, 0.027752587507058002, 0.15052715078657608, 0.09338323652622518, 0.10733368634652816, 0.009015504756326845, 0.07260467220125497, 0.06131948225009717, 0.13738590080822852, 0.019516423196562774, 0.17743907744797185, 0.168463187880263, 0.10873049983503855, 0.04344061430414566, 0.02317115600283071, 0.07404125211975868, 0.15909114093868224, 0.06328187290927392, 0.061181260489395074, 0.10188121620373095, 0.11585556353592591, 0.04834423895093465, 0.04691894553961334, 0.12122456474448282, 0.17687550273822134, 0.06547168561472232, 0.08485794408914797, 0.00860922891084781, 0.04722362237342663, 0.12835427310079645, 0.11437381855119912, 0.02598203308013339, 0.04025285460153236, 0.04111710339130102, 0.05148469905089557, 0.0022165545513796675, 0.01021568310626363, 0.12771401655964718, 0.10469055633023704, 0.012671596541814639, 0.13664450703816816, 0.16984352667631633, 0.10355428462415937, 0.0015670128333073261, 0.067307501000118, 0.10497692090616872, 0.11203424888888858, 0.057958470933006, 0.14164031795438256, 0.11150493641279158, 0.0890139703593684, 0.14996141925632728, 0.030505049930856305, 0.05826029111642219, 0.027963282761809472, 0.06010840784689968, 0.17473043708133734, 0.12099758313300277, 0.014553883833494794, 0.07334636042494769, 0.07285006732780068, 0.17790630291056034, 0.0989301973089577, 0.13638374168904252, 0.17986942419707855, 0.040388703981232836], - [0.1490765359911958, 0.09233526241995971, 0.06296852894216698, 0.0976109157574458, 0.08299404810701023, 0.08378603465806785, 0.11920562114578914, 0.13555823199591513, 0.0553313289630816, 0.09546664504785775, 0.04687997291732666, 0.12237197777320692, 0.06865333050063585, 0.012561461312757724, 0.16368883089666822, 0.09131100042306806, 0.042265527528094815, 0.029155289884568912, 0.153815789880318, 0.040214352413767675, 0.09381433834769744, 0.011223362220940966, 0.11913200349775391, 0.1429695160437834, 0.12846334848596738, 0.04825302129601608, 0.08816394973267236, 0.015619449792770343, 0.08726400271162271, 0.1406802714694426, 0.07150818680750592, 0.11509288921319505, 0.0913614606055903, 0.029706843936407743, 0.0939306128799265, 0.026551453999575543, 0.14401232745525105, 0.08934160493420577, 0.10268827852213556, 0.008625313216639324, 0.06946233801138785, 0.05866557169947423, 0.13143983149579208, 0.018671751331583056, 0.16975950445661273, 0.161172091881058, 0.1040246378463513, 0.04156050213755719, 0.022168307101803907, 0.07083674267232855, 0.15220566764447255, 0.06054302998342982, 0.058533332184146566, 0.09747179158578337, 0.11084132839998145, 0.046251897641031985, 0.044888291006624594, 0.11597795894213936, 0.1692203212911706, 0.06263806747503713, 0.08118528762078707, 0.008236621012006807, 0.04517978141038145, 0.12279909313025451, 0.10942371341935776, 0.0248575292652322, 0.038510708849485854, 0.0393375529042932, 0.049256438455844605, 0.002120621948981863, 0.00977354778184982, 0.12218654692727692, 0.10015954331772974, 0.012123169149384955, 0.13073052528871054, 0.16249268953840867, 0.09907244951333158, 0.0014991924320470194, 0.06439442866999417, 0.10043351401912919, 0.1071854004601844, 0.055450025136289674, 0.13551011723482043, 0.10667899665704653, 0.08516144084638168, 0.14347108081661994, 0.029184789698902848, 0.0557387825256351, 0.026753030352160315, 0.057506912662784994, 0.16716809419341475, 0.11576080110723733, 0.01392399094397694, 0.0701719259281324, 0.06969711242341488, 0.1702065083755876, 0.13916687524684004, 0.05350498510320062, 0.1415754204215561, 0.06957602019036072, 0.15092969351716987, 0.028763669977259567, 0.09378263985254962, 0.07190282975849477, 0.09464849295042106, 0.13048104587817877, 0.1720846656652933, 0.03864067866059161], - [0.14423132094112415, 0.08933422540125728, 0.060921955602620925, 0.09443841194968906, 0.08029661481691686, 0.08106286059575217, 0.1153312564391741, 0.13115238246727773, 0.053532976284372855, 0.09236383331232718, 0.04535630221478635, 0.11839470164137629, 0.06642199243011034, 0.01215319463954323, 0.15836869395012684, 0.08834325348324733, 0.04089183334666819, 0.028207698445053192, 0.1488165418423116, 0.0389073245555702, 0.09076522910288898, 0.010858585811402444, 0.11526003147710948, 0.13832278846703247, 0.12428809350483766, 0.0466847244246111, 0.08529848674563507, 0.015111793824602163, 0.08442778937693121, 0.1361079478368881, 0.06918406154782372, 0.11135219457426855, 0.08839207363278813, 0.028741326148019417, 0.0908777245352768, 0.02568849120221335, 0.1393317069153209, 0.08643786635491431, 0.09935075267171747, 0.008344977366795651, 0.06720470596146004, 0.056758851040656824, 0.12716783627194342, 0.018064890902733784, 0.16424206134984198, 0.15593375279542385, 0.10064367827736079, 0.04020972235785182, 0.021447803271404914, 0.06853444037229196, 0.14725875103768507, 0.058575289063624865, 0.056630909511498614, 0.09430380952603941, 0.10723881597934645, 0.04474864034400212, 0.04342935300735328, 0.11220849818557717, 0.163720402460575, 0.060602234637766365, 0.07854664180835778, 0.007968918252321884, 0.0437113695279008, 0.11880793509714194, 0.10586727565020065, 0.024049621608251144, 0.03725905200848255, 0.038059022368970546, 0.047655528994591224, 0.002051698497585555, 0.009455892555355895, 0.11821529758108007, 0.09690420522267214, 0.011729147640724243, 0.12648158359965736, 0.15721142901244226, 0.0958524436268398, 0.001450466388834312, 0.06230151141203584, 0.09716927145794031, 0.10370171127996149, 0.05364781465071019, 0.13110583150938676, 0.10321176637367188, 0.08239356398278831, 0.1388080516188944, 0.02823623947037694, 0.05392718698398778, 0.02588351601554489, 0.05563785019185841, 0.16173487587711605, 0.1119983983118956, 0.01347143997725202, 0.06789123118741493, 0.06743184984661066, 0.16467453695890372, 0.1346437393023796, 0.05176599138864854, 0.1369740030812226, 0.06731469329603086, 0.14602424801785077, 0.027828806782710006, 0.09073456085723504, 0.06956587800031083, 0.049289988943616116, 0.15151295985733645, 0.12735852037121487, 0.003333862247204956, 0.05712354925607144, 0.08951490067034465, 0.08782182415229184, 0.0578016188069583, 0.09157227240732324, 0.12624021265090699, 0.16649165126886764, 0.03738479760227176], - [0.1694589116999309, 0.10495973076633594, 0.07157785304667531, 0.11095669378356957, 0.09434134604936262, 0.09524161635770365, 0.1355039187996205, 0.1540923278989471, 0.06289646272400928, 0.10851924929627423, 0.053289601467273046, 0.13910319312249428, 0.07803990476341967, 0.014278917532309872, 0.18606906148410648, 0.10379542732894517, 0.04804424955083078, 0.0331415246623844, 0.17484613646324135, 0.04571262908307061, 0.10664103222246049, 0.012757867862499155, 0.13542023583479298, 0.16251691410696706, 0.1460274018511314, 0.05485037883855437, 0.10021809853261156, 0.017755007155458, 0.09919510694134144, 0.15991467431380685, 0.08128508912194579, 0.13082887672960547, 0.10385278664144561, 0.03376848952138687, 0.10677320430144628, 0.030181681301506596, 0.1637023031134973, 0.10155676774358248, 0.11672825510064294, 0.009804602589163004, 0.07895952320919036, 0.06668657725609006, 0.14941084223083015, 0.021224632294707106, 0.19296974325749094, 0.18320822324566463, 0.118247327134454, 0.047242830101371744, 0.02519925198639844, 0.08052184229937957, 0.17301587149245923, 0.06882072959230966, 0.06653625739386522, 0.11079854796562234, 0.12599602450612882, 0.052575653077750396, 0.0510256083660385, 0.13183495694235145, 0.19235684068489467, 0.07120220948743744, 0.0922852841648866, 0.009362766739239825, 0.05135695257298015, 0.13958870550104785, 0.12438458719824694, 0.028256155999520978, 0.043776056151534036, 0.044715949829245226, 0.05599098744442927, 0.0024105623679280823, 0.011109828649743763, 0.13889240938555025, 0.11385378050363983, 0.013780700207108917, 0.14860455667344946, 0.1847093786107272, 0.11261805462777208, 0.0017041683741461791, 0.07319870782750477, 0.11416520964027846, 0.12184024260650132, 0.06303138754099037, 0.15403763468383044, 0.12126460112952524, 0.09680507390833237, 0.16308705494091372, 0.03317505781633879, 0.06335962506420917] - ] + [ + 0.24768051036976024, + 0.15340874919881428, + 0.10461792180729243, + 0.1621738878738882, + 0.13788895788409475, + 0.13920478959340893, + 0.1980520199776914, + 0.225220769065586, + 0.09192923424127934, + 0.15861132814448145, + 0.07788788182581427, + 0.2033127058413462, + 0.11406283238286104, + 0.020870012361419343, + 0.2719578430552649, + 0.15170700765742606, + 0.07022129511933332, + 0.04843952826362164, + 0.2555544578976192, + 0.06681340738035137, + 0.15586613310716685, + 0.018646851863471762, + 0.1979297092698637, + 0.23753411269988997, + 0.21343310337377225, + 0.08016910818336964, + 0.1464783972931314, + 0.025950651929534232, + 0.1449831966165307, + 0.23373068876892722, + 0.11880598168141776, + 0.19121899600576953, + 0.15179084381364852, + 0.04935589775227154, + 0.1560593153225572, + 0.04411343229804097, + 0.2392666728301238, + 0.1484349911958273, + 0.17060958026859915, + 0.01433037040599356, + ], + [ + 0.49490048799897596, + 0.3065322528949179, + 0.20904131890947963, + 0.32404623250194, + 0.27552152748971576, + 0.2781507442742417, + 0.3957357855481444, + 0.45002276663457547, + ], + [ + 0.2774747194904695, + 0.17186273392192533, + 0.11720271596589263, + 0.18168225662692275, + 0.15447602176127323, + 0.15595013869479196, + 0.2218762736147053, + 0.2523132305670958, + 0.10298766925985375, + 0.17769114622380935, + 0.08725724171457977, + 0.22776978268478074, + 0.1277837823108223, + 0.023380526861408162, + 0.30467244314999586, + 0.16995628493998063, + 0.07866841899027918, + 0.05426646003407173, + 0.2862958470725858, + 0.07485058652127569, + 0.17461572368939868, + 0.02088993591975766, + 0.22173924979601844, + 0.2661077821279658, + 0.17616832761102516, + 0.24286311298519137, + 0.32029952947731805, + 0.07192152273314319, + ], + [ + 0.2703013619564934, + 0.1674196883015804, + 0.11417275710290055, + 0.17698535383607492, + 0.15048246250457872, + 0.15191847013635482, + 0.2161402633508973, + 0.2457903551976426, + 0.10032520193833194, + 0.1730974227854145, + 0.08500144200281991, + 0.22188141170224845, + 0.12448027862860386, + 0.022776086648557087, + 0.29679596211605436, + 0.16556252539583352, + 0.07663466003347703, + 0.05286354765112583, + 0.278894443170582, + 0.07291552728513738, + 0.17010150697308607, + 0.020349883191748984, + 0.21600678191201325, + 0.2592282859804155, + 0.23292611292832396, + 0.08749101451887183, + 0.15985638202387917, + 0.02832074493766232, + 0.1582246235190211, + 0.255077492415341, + 0.12965662340215453, + 0.20868317404203518, + ], + [ + 0.19457563274485226, + 0.1205165654713542, + 0.08218692016467483, + 0.12740238140112917, + 0.10832435377645168, + 0.10935805960596295, + 0.15558792674492308, + 0.17693145731489499, + 0.07221879869975649, + 0.12460366577951727, + 0.061188035614062594, + 0.15972067533731096, + 0.08960675892678109, + 0.016395298340405255, + 0.21364769199403277, + 0.11917969226849504, + 0.0551652324585789, + 0.03805366779842952, + 0.2007613367396708, + 0.052488025793646274, + 0.12244706467838061, + 0.014648802986629832, + 0.15549184052751536, + 0.1866047118849567, + 0.167671170717676, + 0.06298014699696033, + 0.11507214190657873, + 0.02038660414496235, + 0.11389752539236134, + 0.18361677546291374, + 0.09333293534087271, + 0.15021996314975533, + 0.11924555321621164, + 0.0387735596171921, + 0.12259882692942942, + 0.03465512481835747, + 0.18796579590043078, + 0.11660922488526533, + 0.13402938722767327, + 0.011257813079646883, + 0.09066268061997902, + 0.07657067329789471, + 0.17155609506972255, + 0.02437048731808387, + 0.2215711733203188, + 0.2103628283958812, + 0.13577361182582945, + 0.05424502888292601, + 0.028934213909226063, + 0.0924565622310047, + 0.1986597950667768, + 0.0790211436628239, + 0.07639807345045613, + 0.12722079565692512, + 0.1446707992261107, + 0.06036826781167918, + 0.0585884798528245, + 0.15137516172871096, + 0.22086742806031712, + 0.08175559977855866, + 0.10596354820935999, + 0.010750489568562414, + 0.05896893496182565, + 0.16027814898868079, + ], + [ + 0.387733284839387, + 0.24015485982792192, + 0.1637748986177967, + 0.253876310924278, + 0.2158592878529835, + 0.21791916632378672, + 0.3100419978963423, + 0.35257351688061767, + 0.2461713430135757, + 0.3393682593390343, + 0.44757514819657734, + 0.1005005728492324, + ], + [ + 0.16353440643700792, + 0.10129020125571776, + 0.06907539765598648, + 0.10707750259980159, + 0.0910430491609086, + 0.09191184484141025, + 0.13076652451317197, + 0.14870505851042468, + 0.06069752009721213, + 0.1047252743607885, + 0.05142652727905344, + 0.13423996349664308, + 0.07531152759015192, + 0.013779707893699597, + 0.17956384365300332, + 0.10016660338980309, + 0.04636455972831437, + 0.03198285359980099, + 0.16873328677427074, + 0.0441144557626597, + 0.10291272221322205, + 0.012311836110395775, + 0.1306857672142806, + 0.1568351101623881, + 0.14092209282890691, + 0.05293273783140711, + 0.09671434268855209, + 0.017134268875714943, + 0.09572711622173373, + 0.1543238480770115, + 0.07844325605769907, + 0.12625492803046978, + 0.10022195734569302, + 0.03258789894704945, + 0.10304027338340047, + 0.029126490235301297, + 0.15797905641835802, + 0.09800621027247283, + 0.11264728258206483, + 0.009461820854890907, + 0.07619899497188476, + 0.06435512726649247, + 0.14418724370624061, + 0.020482591380646117, + 0.18622326856315144, + 0.17680302406232687, + 0.11411324587011096, + 0.04559115895133764, + 0.024318253167761508, + 0.0777066933426362, + 0.16696701026147626, + 0.06641466684484068, + 0.06421006278332052, + 0.1069248857665583, + 0.12159103864374035, + 0.05073753945931583, + 0.04924168633871106, + 0.12722583436268306, + 0.18563179386637813, + 0.0687128870870491, + 0.08905886988994213, + 0.009035432164352614, + 0.049561446318667116, + 0.1347085017272271, + 0.1200359392924501, + 0.027268283817115106, + 0.04224558795450571, + 0.04315262171954351, + 0.05403346926811662, + 0.0023262859537098515, + 0.010721414504714139, + 0.13403654903491943, + 0.10987330337776338, + 0.013298908898025385, + 0.14340914694684173, + 0.17825169707180502, + 0.10868078009526573, + 0.0016445884181541684, + 0.07063958523304881, + 0.1101738445443299, + 0.11758054831650003, + 0.060827727766064016, + 0.14865227744166581, + 0.11702503201869387, + 0.09342064187053477, + 0.15738531812684184, + 0.03201521439082036, + 0.06114448967602477, + 0.10382777552410098, + 0.1431354723068435, + 0.18877393058117947, + 0.04238816261102419, + ], + [ + 0.18931478384099465, + 0.11725809249396936, + 0.07996478698818024, + 0.12395773281339016, + 0.10539552836400544, + 0.10640128531778455, + 0.15138120999255955, + 0.17214766373220333, + 0.07026617913163342, + 0.12123468761259337, + 0.05953366088302137, + 0.15540221917752278, + 0.08718401146951676, + 0.015952009599231567, + 0.2078711812851488, + 0.11595736507064407, + 0.05367369958461762, + 0.03702478975393335, + 0.19533324153872214, + 0.051068878035693224, + 0.11913639572715305, + 0.014252735205439095, + 0.15128772171130855, + 0.18155937717307144, + 0.16313775262089256, + 0.061277317960149645, + 0.11196087281767074, + 0.01983540026317905, + 0.11081801505923433, + 0.17865222723918714, + 0.09080944119283771, + 0.14615838299541906, + 0.1160214452995229, + 0.03772521745978412, + 0.11928405469835733, + 0.0337181350584281, + 0.18288366080789226, + 0.11345639683447971, + 0.13040556062135805, + 0.010953429366412056, + 0.08821138362439966, + 0.0745003896914418, + 0.16691763812644678, + 0.02371156898547879, + 0.21558043106834748, + 0.2046751323592965, + 0.13210262565520578, + 0.052778376061538665, + 0.028151903578888155, + 0.08995676306701976, + 0.19328852040933758, + 0.07688460533499909, + 0.07433245652145608, + 0.12378105670329538, + 0.1407592548832129, + 0.058736057595709795, + 0.05700439074739889, + 0.14728234783203958, + 0.2148957133578259, + 0.07954512844968857, + 0.1030985532015983, + 0.010459822641440727, + 0.05737455928138075, + 0.1559446201057239, + 0.13895900193366503, + 0.03156699173602045, + 0.04890539260876352, + 0.04995541568895709, + 0.06255157417661084, + 0.002693013244577135, + 0.012411591625591608, + 0.15516673744807902, + ], + [ + 0.2208827351133444, + 0.13681070045747248, + 0.09329879317581574, + 0.14462749557513332, + 0.12297007186353966, + 0.12414353725437031, + 0.17662379572008607, + 0.20085302392695362, + 0.08198295726125182, + 0.14145038674302837, + 0.06946080797470483, + 0.18131530204975832, + 0.1017218123213999, + 0.018611982853869447, + 0.24253338351044798, + 0.13529307872148416, + 0.06262370707329344, + 0.04319861693798904, + 0.22790476144676877, + 0.059584535506577115, + 0.1390022078881141, + 0.016629357048352854, + 0.17651471841061875, + 0.21183412621988404, + 0.19034072388880155, + 0.07149521720826639, + 0.13063017748479328, + 0.023142922984180615, + 0.12929674993937262, + 0.20844221347143077, + 0.1059517769179363, + 0.17053007029227615, + 0.13536784423072898, + 0.04401583989479429, + 0.13917448876740884, + 0.039340582618640645, + 0.21337923212968313, + 0.13237507784892918, + 0.15215048882937396, + 0.012779896996084542, + 0.10292049721512919, + 0.08692321596963569, + 0.19475089953352745, + 0.027665436925096435, + 0.2515281389291008, + 0.23880439830403508, + 0.15413053686754696, + 0.06157908971918815, + ], + [ + 0.1715795373556408, + 0.1062732072642473, + 0.07247358541051933, + 0.11234521687243985, + 0.0955219430260548, + 0.09643347940647069, + 0.13719962830095694, + 0.15602065459839623, + 0.0636835553069129, + 0.10987726996268543, + 0.053956472834027505, + 0.14084394430027286, + 0.07901650388441198, + 0.014457605324831525, + 0.1883975482043314, + 0.10509433361797467, + 0.04864548006260954, + 0.03355626099441541, + 0.17703417838482685, + 0.046284681464683716, + 0.10797554869382073, + 0.0129175210883459, + 0.1371148981191942, + 0.164550666915154, + 0.14785480326481754, + 0.05553678192838664, + 0.1014722377736982, + 0.01797719507885178, + 0.10043644436402703, + 0.1619158624347057, + 0.08230229880238973, + 0.1324660822900412, + 0.10515241073061003, + 0.03419107175394852, + 0.10810937478733341, + 0.030559377859677404, + 0.16575088999747303, + 0.10282765922416374, + 0.11818900408120409, + 0.009927298359990544, + 0.07994763052677145, + 0.06752109970877263, + 0.15128058435355177, + 0.021490239451779292, + 0.19538458579496817, + 0.1855009091519671, + 0.1197270859333567, + 0.047834031570543896, + 0.02551459792914639, + 0.08152950063326206, + 0.17518100929637484, + 0.06968195903934253, + 0.06736889872885857, + 0.11218509200201603, + 0.1275727512737259, + 0.053233590023432004, + 0.05166414789821036, + 0.13348475269051732, + 0.19476401329869034, + 0.07209324101046329, + 0.09344015137889938, + 0.009479933332347762, + 0.051999638579474684, + 0.14133553242896432, + 0.12594114827928685, + 0.028609756342773685, + 0.04432387406709532, + 0.04527552966766203, + 0.056691664223667886, + 0.002440728384874828, + 0.011248858149159562, + 0.14063052279470464, + 0.11527855802353276, + 0.013953153258528188, + 0.15046420885860654, + 0.18702085012439856, + 0.11402736815129268, + 0.0017254945064788542, + 0.07411472372909801, + 0.11559388441532585, + 0.10893561836452229, + 0.15017707070132247, + 0.198060728501197, + 0.04447346273248423, + ], + [ + 0.15352324557245492, + 0.09508947248635916, + 0.0648467773137381, + 0.10052248994615477, + 0.08546962500750059, + 0.08628523522382116, + 0.12276133012550565, + 0.1396017126485001, + 0.05698177213314873, + 0.09831425914354645, + 0.04827832594018572, + 0.1260221339994952, + 0.07070114721768485, + 0.012936149187027587, + 0.1685714013686324, + 0.09403465842703182, + 0.04352623918178691, + 0.030024944562363123, + 0.15840386366444553, + 0.04141388086399268, + 0.09661266683324013, + 0.011558136784825031, + 0.12268551658326957, + 0.14723406319463364, + 0.13229520035155487, + 0.04969233010940552, + 0.09079373635463328, + 0.01608535246877302, + 0.08986694538383312, + 0.14487653419367338, + 0.07364115922533956, + 0.11852592211670533, + 0.09408662375438188, + 0.03059295057071266, + 0.09673240964485387, + 0.027343440505776938, + 0.1483079799672769, + 0.09200651908735905, + 0.10575130214923645, + 0.008882592222129873, + 0.07153428610112707, + 0.06041546988453471, + 0.1353604669880599, + 0.019228699177151067, + 0.1748231532056124, + 0.16597959213878738, + 0.107127522889412, + 0.04280018403537061, + 0.022829551495057773, + 0.0729496870082825, + 0.1567457141121245, + 0.06234892968263987, + 0.0602792858804522, + 0.10037921592768378, + 0.11414754418852645, + 0.04763151620423726, + 0.04622723541111018, + 0.11943739203007579, + 0.17426788708699534, + 0.06450645872078792, + 0.0836069121502298, + 0.008482305963885847, + 0.046527420497518554, + 0.12646198951003412, + 0.1126876440684275, + 0.025598988763302813, + 0.039659420394756825, + 0.04051092785723106, + 0.05072567756422609, + 0.0021838766380988884, + 0.010065076749004063, + 0.1258311720542961, + 0.10314713890387746, + 0.012484783484285916, + 0.13463000333533406, + 0.16733958106731892, + 0.10202761886684918, + 0.0015439108936574257, + 0.06631520930151812, + 0.1034292817038221, + 0.11038256588952834, + 0.057104008819336624, + 0.13955216270266796, + 0.1098610568880544, + 0.08770166753227544, + 0.14775058882543593, + 0.03005532430797646, + 0.057401379369977516, + 0.02755102955172378, + 0.05922224994122391, + 0.17215444540682492, + 0.11921375673164347, + 0.014339320851720466, + 0.07226503986645506, + 0.0717760634504068, + 0.17528349052139683, + 0.14331799583358729, + 0.055100951418902915, + 0.14579838397697775, + 0.0716513592338211, + 0.1554316797606585, + 0.029621643272853243, + 0.09658002282375533, + 0.07404757373098435, + ], + [ + 0.17846031137802032, + 0.11053503204293935, + 0.07537995974563472, + 0.11685054461552731, + 0.09935261487813324, + 0.1003007061761313, + 0.1427016808932576, + 0.16227747801487458, + 0.06623742717159986, + 0.11428362678390792, + 0.056120264054923916, + 0.14649214319442222, + 0.08218526582214918, + 0.015037391916391805, + 0.19595276705818235, + 0.10930888257761537, + 0.050596287021758744, + 0.03490195205115243, + 0.1841336973279205, + 0.048140814420656146, + 0.11230564167550687, + 0.013435546401317802, + 0.14261355281660268, + 0.17114956543023846, + 0.15378415536045742, + 0.057763947546553146, + 0.1055415315159862, + 0.018698126133919378, + 0.10446420016714315, + 0.16840909861672573, + 0.08560282943855643, + 0.13777830769824043, + 0.10936928872956436, + 0.03556222032998324, + 0.11244483453432241, + 0.031784886312244846, + 0.17239792049806787, + 0.10695130879960922, + 0.12292868249243113, + 0.0103254081679582, + 0.0831537330012127, + 0.07022886682365666, + 0.15734731894762363, + 0.02235205248399433, + 0.20322000255288147, + 0.19293996544324854, + 0.12452844532248876, + 0.04975229738993509, + 0.026537797929146605, + 0.0847990401055136, + 0.18220621146533902, + 0.0724763820863788, + 0.07007056219895538, + 0.11668399833223729, + 0.13268874171440578, + 0.055368391812715356, + 0.05373601108320975, + 0.13883782936185077, + 0.20257454352772494, + 0.07498436257180507, + 0.09718733811319212, + 0.009860102669626628, + 0.0540849557905192, + 0.1470034452521622, + 0.1309917073073869, + 0.029757080034537288, + 0.046101373680117005, + 0.04709119308060735, + 0.058965143546946014, + 0.0025386077749533845, + 0.011699965851902326, + 0.14627016294592948, + 0.11990152017630731, + 0.014512710044560078, + 0.15649820472762588, + 0.1945208598983612, + 0.11860015442119298, + 0.0017946912064986773, + 0.07708691186744215, + 0.12022949195506588, + ], + [ + 0.24768051036976024, + 0.15340874919881428, + 0.10461792180729243, + 0.1621738878738882, + 0.13788895788409475, + 0.13920478959340893, + 0.1980520199776914, + 0.225220769065586, + 0.09192923424127934, + 0.15861132814448145, + 0.07788788182581427, + 0.2033127058413462, + 0.11406283238286104, + 0.020870012361419343, + 0.2719578430552649, + 0.15170700765742606, + 0.07022129511933332, + 0.04843952826362164, + 0.2555544578976192, + 0.06681340738035137, + 0.15586613310716685, + 0.018646851863471762, + 0.1979297092698637, + 0.23753411269988997, + 0.21343310337377225, + 0.08016910818336964, + 0.1464783972931314, + 0.025950651929534232, + 0.1449831966165307, + 0.23373068876892722, + 0.11880598168141776, + 0.19121899600576953, + 0.15179084381364852, + 0.04935589775227154, + 0.1560593153225572, + 0.04411343229804097, + 0.2392666728301238, + 0.1484349911958273, + 0.17060958026859915, + 0.01433037040599356, + ], + [ + 0.24802588780879425, + 0.153622669627372, + 0.10476380599437246, + 0.16240003082711635, + 0.1380812367802985, + 0.1393989033476937, + 0.19832819309827035, + 0.22553482757717827, + 0.0920574247212134, + 0.15883250329562493, + 0.07799649237864552, + 0.2035962147115505, + 0.11422188700075789, + 0.020899114495500196, + 0.2723370739572822, + 0.1519185550969481, + 0.07031921502040975, + 0.04850707463695044, + 0.25591081514216235, + 0.06690657516129511, + 0.15608348022827995, + 0.018672853917218492, + 0.19820571183459643, + 0.23786534152126568, + 0.21373072460581133, + 0.08028089978632086, + 0.14668265371062417, + 0.025986838748155147, + 0.14518536805535576, + 0.23405661391576318, + 0.11897165037143213, + 0.19148564083396585, + 0.1574713038353601, + 0.21708766594943277, + 0.28630563284911986, + 0.06428837755455744, + ], + [ + 0.37258942960245, + 0.23077503463910054, + 0.15737827636974977, + 0.24396056148760667, + 0.20742838461456795, + 0.20940780958141045, + 0.29793256257804646, + 0.33880291087698405, + 0.13829049729675522, + 0.23860135056090637, + 0.1171678846232154, + 0.3058462895900371, + 0.17158639407244533, + 0.03139506612744243, + 0.40911017773906017, + 0.2282150798437472, + ], + [ + 0.24768051036976024, + 0.15340874919881428, + 0.10461792180729243, + 0.1621738878738882, + 0.13788895788409475, + 0.13920478959340893, + 0.1980520199776914, + 0.225220769065586, + 0.09192923424127934, + 0.15861132814448145, + 0.07788788182581427, + 0.2033127058413462, + 0.11406283238286104, + 0.020870012361419343, + 0.2719578430552649, + 0.15170700765742606, + 0.07022129511933332, + 0.04843952826362164, + 0.2555544578976192, + 0.06681340738035137, + 0.15586613310716685, + 0.018646851863471762, + 0.1979297092698637, + 0.23753411269988997, + 0.21343310337377225, + 0.08016910818336964, + 0.1464783972931314, + 0.025950651929534232, + 0.1449831966165307, + 0.23373068876892722, + 0.11880598168141776, + 0.19121899600576953, + 0.15179084381364852, + 0.04935589775227154, + 0.1560593153225572, + 0.04411343229804097, + 0.2392666728301238, + 0.1484349911958273, + 0.17060958026859915, + 0.01433037040599356, + ], + [ + 0.24768051036976024, + 0.15340874919881428, + 0.10461792180729243, + 0.1621738878738882, + 0.13788895788409475, + 0.13920478959340893, + 0.1980520199776914, + 0.225220769065586, + 0.09192923424127934, + 0.15861132814448145, + 0.07788788182581427, + 0.2033127058413462, + 0.11406283238286104, + 0.020870012361419343, + 0.2719578430552649, + 0.15170700765742606, + 0.07022129511933332, + 0.04843952826362164, + 0.2555544578976192, + 0.06681340738035137, + 0.15586613310716685, + 0.018646851863471762, + 0.1979297092698637, + 0.23753411269988997, + 0.21343310337377225, + 0.08016910818336964, + 0.1464783972931314, + 0.025950651929534232, + 0.1449831966165307, + 0.23373068876892722, + 0.11880598168141776, + 0.19121899600576953, + 0.15179084381364852, + 0.04935589775227154, + 0.1560593153225572, + 0.04411343229804097, + 0.2392666728301238, + 0.1484349911958273, + 0.17060958026859915, + 0.01433037040599356, + ], + [ + 0.387733284839387, + 0.24015485982792192, + 0.1637748986177967, + 0.253876310924278, + 0.2158592878529835, + 0.21791916632378672, + 0.3100419978963423, + 0.35257351688061767, + 0.2461713430135757, + 0.3393682593390343, + 0.44757514819657734, + 0.1005005728492324, + ], + [ + 0.16353440643700792, + 0.10129020125571776, + 0.06907539765598648, + 0.10707750259980159, + 0.0910430491609086, + 0.09191184484141025, + 0.13076652451317197, + 0.14870505851042468, + 0.06069752009721213, + 0.1047252743607885, + 0.05142652727905344, + 0.13423996349664308, + 0.07531152759015192, + 0.013779707893699597, + 0.17956384365300332, + 0.10016660338980309, + 0.04636455972831437, + 0.03198285359980099, + 0.16873328677427074, + 0.0441144557626597, + 0.10291272221322205, + 0.012311836110395775, + 0.1306857672142806, + 0.1568351101623881, + 0.14092209282890691, + 0.05293273783140711, + 0.09671434268855209, + 0.017134268875714943, + 0.09572711622173373, + 0.1543238480770115, + 0.07844325605769907, + 0.12625492803046978, + 0.10022195734569302, + 0.03258789894704945, + 0.10304027338340047, + 0.029126490235301297, + 0.15797905641835802, + 0.09800621027247283, + 0.11264728258206483, + 0.009461820854890907, + 0.07619899497188476, + 0.06435512726649247, + 0.14418724370624061, + 0.020482591380646117, + 0.18622326856315144, + 0.17680302406232687, + 0.11411324587011096, + 0.04559115895133764, + 0.024318253167761508, + 0.0777066933426362, + 0.16696701026147626, + 0.06641466684484068, + 0.06421006278332052, + 0.1069248857665583, + 0.12159103864374035, + 0.05073753945931583, + 0.04924168633871106, + 0.12722583436268306, + 0.18563179386637813, + 0.0687128870870491, + 0.08905886988994213, + 0.009035432164352614, + 0.049561446318667116, + 0.1347085017272271, + 0.1200359392924501, + 0.027268283817115106, + 0.04224558795450571, + 0.04315262171954351, + 0.05403346926811662, + 0.0023262859537098515, + 0.010721414504714139, + 0.13403654903491943, + 0.10987330337776338, + 0.013298908898025385, + 0.14340914694684173, + 0.17825169707180502, + 0.10868078009526573, + 0.0016445884181541684, + 0.07063958523304881, + 0.1101738445443299, + 0.11758054831650003, + 0.060827727766064016, + 0.14865227744166581, + 0.11702503201869387, + 0.09342064187053477, + 0.15738531812684184, + 0.03201521439082036, + 0.06114448967602477, + 0.10382777552410098, + 0.1431354723068435, + 0.18877393058117947, + 0.04238816261102419, + ], + [ + 0.18931478384099465, + 0.11725809249396936, + 0.07996478698818024, + 0.12395773281339016, + 0.10539552836400544, + 0.10640128531778455, + 0.15138120999255955, + 0.17214766373220333, + 0.07026617913163342, + 0.12123468761259337, + 0.05953366088302137, + 0.15540221917752278, + 0.08718401146951676, + 0.015952009599231567, + 0.2078711812851488, + 0.11595736507064407, + 0.05367369958461762, + 0.03702478975393335, + 0.19533324153872214, + 0.051068878035693224, + 0.11913639572715305, + 0.014252735205439095, + 0.15128772171130855, + 0.18155937717307144, + 0.16313775262089256, + 0.061277317960149645, + 0.11196087281767074, + 0.01983540026317905, + 0.11081801505923433, + 0.17865222723918714, + 0.09080944119283771, + 0.14615838299541906, + 0.1160214452995229, + 0.03772521745978412, + 0.11928405469835733, + 0.0337181350584281, + 0.18288366080789226, + 0.11345639683447971, + 0.13040556062135805, + 0.010953429366412056, + 0.08821138362439966, + 0.0745003896914418, + 0.16691763812644678, + 0.02371156898547879, + 0.21558043106834748, + 0.2046751323592965, + 0.13210262565520578, + 0.052778376061538665, + 0.028151903578888155, + 0.08995676306701976, + 0.19328852040933758, + 0.07688460533499909, + 0.07433245652145608, + 0.12378105670329538, + 0.1407592548832129, + 0.058736057595709795, + 0.05700439074739889, + 0.14728234783203958, + 0.2148957133578259, + 0.07954512844968857, + 0.1030985532015983, + 0.010459822641440727, + 0.05737455928138075, + 0.1559446201057239, + 0.13895900193366503, + 0.03156699173602045, + 0.04890539260876352, + 0.04995541568895709, + 0.06255157417661084, + 0.002693013244577135, + 0.012411591625591608, + 0.15516673744807902, + ], + [ + 0.15582045376539008, + 0.09651232095756643, + 0.06581709648315832, + 0.10202663406854806, + 0.08674852920264194, + 0.08757634360644034, + 0.12459823978884935, + 0.1416906093289221, + 0.05783440518753825, + 0.09978536093497073, + 0.04900072706893626, + 0.12790783591802443, + 0.07175906684433664, + 0.013129716146784482, + 0.17109377902469772, + 0.09544172344153798, + 0.04417753360227171, + 0.03047421560521984, + 0.1607741018133701, + 0.042033567518396465, + 0.09805830725702788, + 0.011731084187142908, + 0.12452129182889228, + 0.14943716471837143, + 0.13427476779100272, + 0.0504358893497519, + 0.09215230661051434, + 0.016326041775071437, + 0.09121164782573381, + 0.147044359398728, + 0.07474307101517241, + 0.12029945627009313, + 0.09549446633957638, + 0.031050720834981428, + 0.09817984181142858, + 0.027752587507058002, + 0.15052715078657608, + 0.09338323652622518, + 0.10733368634652816, + 0.009015504756326845, + 0.07260467220125497, + 0.06131948225009717, + 0.13738590080822852, + 0.019516423196562774, + 0.17743907744797185, + 0.168463187880263, + 0.10873049983503855, + 0.04344061430414566, + 0.02317115600283071, + 0.07404125211975868, + 0.15909114093868224, + 0.06328187290927392, + 0.061181260489395074, + 0.10188121620373095, + 0.11585556353592591, + 0.04834423895093465, + 0.04691894553961334, + 0.12122456474448282, + 0.17687550273822134, + 0.06547168561472232, + 0.08485794408914797, + 0.00860922891084781, + 0.04722362237342663, + 0.12835427310079645, + 0.11437381855119912, + 0.02598203308013339, + 0.04025285460153236, + 0.04111710339130102, + 0.05148469905089557, + 0.0022165545513796675, + 0.01021568310626363, + 0.12771401655964718, + 0.10469055633023704, + 0.012671596541814639, + 0.13664450703816816, + 0.16984352667631633, + 0.10355428462415937, + 0.0015670128333073261, + 0.067307501000118, + 0.10497692090616872, + 0.11203424888888858, + 0.057958470933006, + 0.14164031795438256, + 0.11150493641279158, + 0.0890139703593684, + 0.14996141925632728, + 0.030505049930856305, + 0.05826029111642219, + 0.027963282761809472, + 0.06010840784689968, + 0.17473043708133734, + 0.12099758313300277, + 0.014553883833494794, + 0.07334636042494769, + 0.07285006732780068, + 0.17790630291056034, + 0.0989301973089577, + 0.13638374168904252, + 0.17986942419707855, + 0.040388703981232836, + ], + [ + 0.1490765359911958, + 0.09233526241995971, + 0.06296852894216698, + 0.0976109157574458, + 0.08299404810701023, + 0.08378603465806785, + 0.11920562114578914, + 0.13555823199591513, + 0.0553313289630816, + 0.09546664504785775, + 0.04687997291732666, + 0.12237197777320692, + 0.06865333050063585, + 0.012561461312757724, + 0.16368883089666822, + 0.09131100042306806, + 0.042265527528094815, + 0.029155289884568912, + 0.153815789880318, + 0.040214352413767675, + 0.09381433834769744, + 0.011223362220940966, + 0.11913200349775391, + 0.1429695160437834, + 0.12846334848596738, + 0.04825302129601608, + 0.08816394973267236, + 0.015619449792770343, + 0.08726400271162271, + 0.1406802714694426, + 0.07150818680750592, + 0.11509288921319505, + 0.0913614606055903, + 0.029706843936407743, + 0.0939306128799265, + 0.026551453999575543, + 0.14401232745525105, + 0.08934160493420577, + 0.10268827852213556, + 0.008625313216639324, + 0.06946233801138785, + 0.05866557169947423, + 0.13143983149579208, + 0.018671751331583056, + 0.16975950445661273, + 0.161172091881058, + 0.1040246378463513, + 0.04156050213755719, + 0.022168307101803907, + 0.07083674267232855, + 0.15220566764447255, + 0.06054302998342982, + 0.058533332184146566, + 0.09747179158578337, + 0.11084132839998145, + 0.046251897641031985, + 0.044888291006624594, + 0.11597795894213936, + 0.1692203212911706, + 0.06263806747503713, + 0.08118528762078707, + 0.008236621012006807, + 0.04517978141038145, + 0.12279909313025451, + 0.10942371341935776, + 0.0248575292652322, + 0.038510708849485854, + 0.0393375529042932, + 0.049256438455844605, + 0.002120621948981863, + 0.00977354778184982, + 0.12218654692727692, + 0.10015954331772974, + 0.012123169149384955, + 0.13073052528871054, + 0.16249268953840867, + 0.09907244951333158, + 0.0014991924320470194, + 0.06439442866999417, + 0.10043351401912919, + 0.1071854004601844, + 0.055450025136289674, + 0.13551011723482043, + 0.10667899665704653, + 0.08516144084638168, + 0.14347108081661994, + 0.029184789698902848, + 0.0557387825256351, + 0.026753030352160315, + 0.057506912662784994, + 0.16716809419341475, + 0.11576080110723733, + 0.01392399094397694, + 0.0701719259281324, + 0.06969711242341488, + 0.1702065083755876, + 0.13916687524684004, + 0.05350498510320062, + 0.1415754204215561, + 0.06957602019036072, + 0.15092969351716987, + 0.028763669977259567, + 0.09378263985254962, + 0.07190282975849477, + 0.09464849295042106, + 0.13048104587817877, + 0.1720846656652933, + 0.03864067866059161, + ], + [ + 0.14423132094112415, + 0.08933422540125728, + 0.060921955602620925, + 0.09443841194968906, + 0.08029661481691686, + 0.08106286059575217, + 0.1153312564391741, + 0.13115238246727773, + 0.053532976284372855, + 0.09236383331232718, + 0.04535630221478635, + 0.11839470164137629, + 0.06642199243011034, + 0.01215319463954323, + 0.15836869395012684, + 0.08834325348324733, + 0.04089183334666819, + 0.028207698445053192, + 0.1488165418423116, + 0.0389073245555702, + 0.09076522910288898, + 0.010858585811402444, + 0.11526003147710948, + 0.13832278846703247, + 0.12428809350483766, + 0.0466847244246111, + 0.08529848674563507, + 0.015111793824602163, + 0.08442778937693121, + 0.1361079478368881, + 0.06918406154782372, + 0.11135219457426855, + 0.08839207363278813, + 0.028741326148019417, + 0.0908777245352768, + 0.02568849120221335, + 0.1393317069153209, + 0.08643786635491431, + 0.09935075267171747, + 0.008344977366795651, + 0.06720470596146004, + 0.056758851040656824, + 0.12716783627194342, + 0.018064890902733784, + 0.16424206134984198, + 0.15593375279542385, + 0.10064367827736079, + 0.04020972235785182, + 0.021447803271404914, + 0.06853444037229196, + 0.14725875103768507, + 0.058575289063624865, + 0.056630909511498614, + 0.09430380952603941, + 0.10723881597934645, + 0.04474864034400212, + 0.04342935300735328, + 0.11220849818557717, + 0.163720402460575, + 0.060602234637766365, + 0.07854664180835778, + 0.007968918252321884, + 0.0437113695279008, + 0.11880793509714194, + 0.10586727565020065, + 0.024049621608251144, + 0.03725905200848255, + 0.038059022368970546, + 0.047655528994591224, + 0.002051698497585555, + 0.009455892555355895, + 0.11821529758108007, + 0.09690420522267214, + 0.011729147640724243, + 0.12648158359965736, + 0.15721142901244226, + 0.0958524436268398, + 0.001450466388834312, + 0.06230151141203584, + 0.09716927145794031, + 0.10370171127996149, + 0.05364781465071019, + 0.13110583150938676, + 0.10321176637367188, + 0.08239356398278831, + 0.1388080516188944, + 0.02823623947037694, + 0.05392718698398778, + 0.02588351601554489, + 0.05563785019185841, + 0.16173487587711605, + 0.1119983983118956, + 0.01347143997725202, + 0.06789123118741493, + 0.06743184984661066, + 0.16467453695890372, + 0.1346437393023796, + 0.05176599138864854, + 0.1369740030812226, + 0.06731469329603086, + 0.14602424801785077, + 0.027828806782710006, + 0.09073456085723504, + 0.06956587800031083, + 0.049289988943616116, + 0.15151295985733645, + 0.12735852037121487, + 0.003333862247204956, + 0.05712354925607144, + 0.08951490067034465, + 0.08782182415229184, + 0.0578016188069583, + 0.09157227240732324, + 0.12624021265090699, + 0.16649165126886764, + 0.03738479760227176, + ], + [ + 0.1694589116999309, + 0.10495973076633594, + 0.07157785304667531, + 0.11095669378356957, + 0.09434134604936262, + 0.09524161635770365, + 0.1355039187996205, + 0.1540923278989471, + 0.06289646272400928, + 0.10851924929627423, + 0.053289601467273046, + 0.13910319312249428, + 0.07803990476341967, + 0.014278917532309872, + 0.18606906148410648, + 0.10379542732894517, + 0.04804424955083078, + 0.0331415246623844, + 0.17484613646324135, + 0.04571262908307061, + 0.10664103222246049, + 0.012757867862499155, + 0.13542023583479298, + 0.16251691410696706, + 0.1460274018511314, + 0.05485037883855437, + 0.10021809853261156, + 0.017755007155458, + 0.09919510694134144, + 0.15991467431380685, + 0.08128508912194579, + 0.13082887672960547, + 0.10385278664144561, + 0.03376848952138687, + 0.10677320430144628, + 0.030181681301506596, + 0.1637023031134973, + 0.10155676774358248, + 0.11672825510064294, + 0.009804602589163004, + 0.07895952320919036, + 0.06668657725609006, + 0.14941084223083015, + 0.021224632294707106, + 0.19296974325749094, + 0.18320822324566463, + 0.118247327134454, + 0.047242830101371744, + 0.02519925198639844, + 0.08052184229937957, + 0.17301587149245923, + 0.06882072959230966, + 0.06653625739386522, + 0.11079854796562234, + 0.12599602450612882, + 0.052575653077750396, + 0.0510256083660385, + 0.13183495694235145, + 0.19235684068489467, + 0.07120220948743744, + 0.0922852841648866, + 0.009362766739239825, + 0.05135695257298015, + 0.13958870550104785, + 0.12438458719824694, + 0.028256155999520978, + 0.043776056151534036, + 0.044715949829245226, + 0.05599098744442927, + 0.0024105623679280823, + 0.011109828649743763, + 0.13889240938555025, + 0.11385378050363983, + 0.013780700207108917, + 0.14860455667344946, + 0.1847093786107272, + 0.11261805462777208, + 0.0017041683741461791, + 0.07319870782750477, + 0.11416520964027846, + 0.12184024260650132, + 0.06303138754099037, + 0.15403763468383044, + 0.12126460112952524, + 0.09680507390833237, + 0.16308705494091372, + 0.03317505781633879, + 0.06335962506420917, + ], +] # Xs are tangent vectors in a chart Xs = [ - [-0.597609995187605, -0.4256244780566225, 0.039001131483688445, 0.2861310539156201, -0.5445479395430848, 0.5398107502679328, -0.370911828798264, 0.9784991722126772, -0.858313200235999, 0.6327050201672981], + [ + -0.597609995187605, + -0.4256244780566225, + 0.039001131483688445, + 0.2861310539156201, + -0.5445479395430848, + 0.5398107502679328, + -0.370911828798264, + 0.9784991722126772, + -0.858313200235999, + 0.6327050201672981, + ], [-0.5103976757921316, -0.7856231887301031], - [0.06161321757315563, -0.2461307077230097, 0.04558383266520161, 0.6251649963255619, 0.5702228612959974, -0.6849942773520477, 0.47667344530694655], - [0.20291047527778772, -0.33259407228555404, 0.2518919563557016, 0.7589380540013582, 0.5699565849101806, -0.0840258727078147, 0.17702183701764684, -0.020864846013727956], - [-0.5689099191621423, 0.544600536529926, -0.34916078856459043, 0.9822571022455582, 0.030233304809939243, 0.5950623927405945, 0.10709287674567114, -0.45335793482945186, -0.42415769187544816, 0.44897078165811233, -0.059509496330804046, -0.988472595808626, 0.7941397305966094, -0.1645857296563873, 0.6909105365607005, 0.8511592194074467], + [ + 0.06161321757315563, + -0.2461307077230097, + 0.04558383266520161, + 0.6251649963255619, + 0.5702228612959974, + -0.6849942773520477, + 0.47667344530694655, + ], + [ + 0.20291047527778772, + -0.33259407228555404, + 0.2518919563557016, + 0.7589380540013582, + 0.5699565849101806, + -0.0840258727078147, + 0.17702183701764684, + -0.020864846013727956, + ], + [ + -0.5689099191621423, + 0.544600536529926, + -0.34916078856459043, + 0.9822571022455582, + 0.030233304809939243, + 0.5950623927405945, + 0.10709287674567114, + -0.45335793482945186, + -0.42415769187544816, + 0.44897078165811233, + -0.059509496330804046, + -0.988472595808626, + 0.7941397305966094, + -0.1645857296563873, + 0.6909105365607005, + 0.8511592194074467, + ], [-0.9098421775458598, -0.20952423053057156, 0.9924786336664817], - [-0.33715222274078416, -0.26704690491931915, -0.5195355208430397, 0.645753717662719, 0.10444433627227578, 0.33684638019021196, 0.06539241093725567, 0.09555909109964422, 0.7542247481144044, -0.20290163218931467, -0.2664420819862636, 0.339548396803274, 0.9402884626822843, -0.6574225234652968, 0.07702642759782674, -0.5460026086958019, -0.6357161050460245, -0.5843960906310703, -0.2548940878123618, 0.6267033715997288, 0.08231062546698587, 0.15159625893365325, -0.12967230344148017], - [0.42221703960978085, 0.6412610989675429, -0.3378728652151137, -0.7259095427151108, 0.3792220940510249, 0.09853495773970455, -0.03328822790230723, 0.10717331421952858, 0.9602549746343043, 0.36453406652382325, 0.05098955982227471, -0.8550440747345822, -0.13618136406595704, -0.6238820462729322, 0.15657227739200308, -0.7875237399365813, 0.3339506933166785, -0.7658809531191957], - [0.8929561594617814, 0.9142838995513609, -0.9454002503436634, 0.599611685359211, -0.08033334402177683, 0.352934685220305, 0.9826231085574035, -0.13566440227650745, -0.15023573234217635, 0.8858256604892685, -0.9499508153272389, 0.6730026466902008], - [-0.34597205746030824, 0.9028413427061659, 0.32181983134495096, 0.9413815779327186, 0.16359943156565016, 0.7838434998605843, -0.35087705212133735, -0.2339200570289206, -0.9229212375554967, 0.9129319387405792, -0.9083283912242541, 0.13034732808854765, 0.9882693345252747, 0.19949043337639316, 0.5191850007789172, 0.6832919121607344, 0.08923979072216182, -0.1641363924011765, 0.060902972183083826, -0.13189846296393637, 0.8496859744073246], - [0.09276610111152617, 0.09805875319182467, 0.40149199598583674, 0.4121056057132706, -0.5187299383130162, 0.9808043473462107, 0.9121302771494377, -0.05119856203718953, 0.6638686937978975, 0.8072960740642445, 0.588215689842168, 0.5571754021224098, -0.8228465883832383, 0.09319381915262914, -0.2212392016482081, 0.4600044998096078, -0.7708333499135387, -0.7406857285885389, -0.8937974999435008, 0.19396510657575705, 0.5206418037886062, 0.4451978368270184, 0.8422191864577384, -0.018333885981625553, 0.6610697223081674, -0.14582004740489873], - [0.22774235157623135, -0.9570617965471404, -0.7677114506774323, 0.7761020139166568, 0.5705454599965643, -0.38571286832595675, -0.789873188052665, 0.9318173591345504, 0.2627790302374746, -0.23646863157711917, -0.5637044935797642, 0.20520758669977424, 0.7064722394615206, -0.584610567954003, 0.6716584109355441, 0.25481219283479906, -0.9870528012093185, 0.4129387951226837, 0.2284244974693428, -0.7618228616844276], - [-0.3508209068712791, 0.5477811869201115, 0.9576443316471701, 0.3815048454137753, -0.3581096313769696, -0.3297365896057076, 0.46016273166688904, -0.8346220116109249, -0.3150517800054915, 0.5838284430955387], - [0.6225357146388626, 0.7513896391924713, 0.15368488777021372, 0.9474331253267687, -0.7931484910144164, 0.5669848314865438, 0.5833361007240527, -0.15116391703821175, 0.12146654441996918], + [ + -0.33715222274078416, + -0.26704690491931915, + -0.5195355208430397, + 0.645753717662719, + 0.10444433627227578, + 0.33684638019021196, + 0.06539241093725567, + 0.09555909109964422, + 0.7542247481144044, + -0.20290163218931467, + -0.2664420819862636, + 0.339548396803274, + 0.9402884626822843, + -0.6574225234652968, + 0.07702642759782674, + -0.5460026086958019, + -0.6357161050460245, + -0.5843960906310703, + -0.2548940878123618, + 0.6267033715997288, + 0.08231062546698587, + 0.15159625893365325, + -0.12967230344148017, + ], + [ + 0.42221703960978085, + 0.6412610989675429, + -0.3378728652151137, + -0.7259095427151108, + 0.3792220940510249, + 0.09853495773970455, + -0.03328822790230723, + 0.10717331421952858, + 0.9602549746343043, + 0.36453406652382325, + 0.05098955982227471, + -0.8550440747345822, + -0.13618136406595704, + -0.6238820462729322, + 0.15657227739200308, + -0.7875237399365813, + 0.3339506933166785, + -0.7658809531191957, + ], + [ + 0.8929561594617814, + 0.9142838995513609, + -0.9454002503436634, + 0.599611685359211, + -0.08033334402177683, + 0.352934685220305, + 0.9826231085574035, + -0.13566440227650745, + -0.15023573234217635, + 0.8858256604892685, + -0.9499508153272389, + 0.6730026466902008, + ], + [ + -0.34597205746030824, + 0.9028413427061659, + 0.32181983134495096, + 0.9413815779327186, + 0.16359943156565016, + 0.7838434998605843, + -0.35087705212133735, + -0.2339200570289206, + -0.9229212375554967, + 0.9129319387405792, + -0.9083283912242541, + 0.13034732808854765, + 0.9882693345252747, + 0.19949043337639316, + 0.5191850007789172, + 0.6832919121607344, + 0.08923979072216182, + -0.1641363924011765, + 0.060902972183083826, + -0.13189846296393637, + 0.8496859744073246, + ], + [ + 0.09276610111152617, + 0.09805875319182467, + 0.40149199598583674, + 0.4121056057132706, + -0.5187299383130162, + 0.9808043473462107, + 0.9121302771494377, + -0.05119856203718953, + 0.6638686937978975, + 0.8072960740642445, + 0.588215689842168, + 0.5571754021224098, + -0.8228465883832383, + 0.09319381915262914, + -0.2212392016482081, + 0.4600044998096078, + -0.7708333499135387, + -0.7406857285885389, + -0.8937974999435008, + 0.19396510657575705, + 0.5206418037886062, + 0.4451978368270184, + 0.8422191864577384, + -0.018333885981625553, + 0.6610697223081674, + -0.14582004740489873, + ], + [ + 0.22774235157623135, + -0.9570617965471404, + -0.7677114506774323, + 0.7761020139166568, + 0.5705454599965643, + -0.38571286832595675, + -0.789873188052665, + 0.9318173591345504, + 0.2627790302374746, + -0.23646863157711917, + -0.5637044935797642, + 0.20520758669977424, + 0.7064722394615206, + -0.584610567954003, + 0.6716584109355441, + 0.25481219283479906, + -0.9870528012093185, + 0.4129387951226837, + 0.2284244974693428, + -0.7618228616844276, + ], + [ + -0.3508209068712791, + 0.5477811869201115, + 0.9576443316471701, + 0.3815048454137753, + -0.3581096313769696, + -0.3297365896057076, + 0.46016273166688904, + -0.8346220116109249, + -0.3150517800054915, + 0.5838284430955387, + ], + [ + 0.6225357146388626, + 0.7513896391924713, + 0.15368488777021372, + 0.9474331253267687, + -0.7931484910144164, + 0.5669848314865438, + 0.5833361007240527, + -0.15116391703821175, + 0.12146654441996918, + ], [-0.6912699112418559, -0.2315737570979124, 0.6276350160464672, 0.706838194684831], - [0.30756479319371266, -0.43184860921312285, 0.37624726262849206, 0.8139529250407125, -0.585675532332042, -0.5857479127690419, -0.45612298630613823, 0.2559126942459271, -0.7348456829025003, -0.8876636700373159], - [0.9692875025266756, -0.23787854062334635, -0.24748080007875295, 0.7036144791890337, 0.882878776380204, 0.6653207722292824, -0.8471461307631554, 0.054870797521041625, 0.3479947908450005, -0.40254986389467895], + [ + 0.30756479319371266, + -0.43184860921312285, + 0.37624726262849206, + 0.8139529250407125, + -0.585675532332042, + -0.5857479127690419, + -0.45612298630613823, + 0.2559126942459271, + -0.7348456829025003, + -0.8876636700373159, + ], + [ + 0.9692875025266756, + -0.23787854062334635, + -0.24748080007875295, + 0.7036144791890337, + 0.882878776380204, + 0.6653207722292824, + -0.8471461307631554, + 0.054870797521041625, + 0.3479947908450005, + -0.40254986389467895, + ], [-0.5561604381577363, -0.6690805833024565, -0.49296974074635713], - [0.5526596524494152, 0.9690315932495712, -0.8680156139856099, 0.39561955960098705, -0.7189141230781315, 0.1091438241240188, -0.1514792667377174, -0.8842187642857129, -0.90929587555064, 0.0553477365473245, -0.38102440387803127, -0.21972849843690567, -0.1366925641984078, 0.234658614104986, 0.6618349090074298, 0.3456641681297574, -0.13000537043751015, 0.015349401356097525, 0.4014083014273322, -0.05782560373055445, -0.3626979339434868, -0.46909114377791794, 0.037734998042463275], - [-0.23849715068438293, 0.7921459122177519, 0.7585522723532372, 0.8898425015365772, 0.6681429223463302, -0.7046659515927074, -0.2533112691118138, -0.9895684050716598, 0.7064520294805683, -0.06906516907342031, 0.8213751152386364, -0.6183596959717537, 0.5207021021865952, 0.7449011143255648, 0.9149814958723772, -0.8454584370536609, 0.8033846014701953, 0.7737784202696005], - [0.4835975048151546, -0.5987307405530511, 0.277769205131432, -0.5497708234569545, -0.9238315028510387, 0.5332814495117155, -0.5911554383083086, -0.9275056197495566, 0.5302218322249228, -0.7802927767456045, 0.20312945269109162, -0.2622275493784205, -0.17603338014279468, 0.45721842042830585, -0.07856217105142416, 0.458134032752032, 0.7601845863976819, -0.0687601004445304, 0.5084467209402248, -0.5503154953218936, 0.8116513645055918, -0.10424664785069293, -0.4650749134336116, 0.17127951460844226, -0.21534156550417394], - [-0.6945216072262328, 0.06573632900997772, -0.106647523045865, 0.13865277008666044, -0.7820633695316517, -0.10880551946361727, 0.2658232882927578, -0.08490107870171215, 0.8401971948812119, -0.5389907554930264, 0.9847445142919777, 0.6022812602894703, 0.45645830164530143, -0.24553265752254427, 0.06468186895698413, 0.692893319789019, -0.19092820288195367, 0.45737634128864624, 0.10728439355457109, 0.5890201396380044, -0.9502112271317584, -0.2302405122715243, 0.8242967867244597, -0.7636718337376485, -0.2653389884306485, 0.500710013837995, -0.24084472766713083], - [-0.8374018409716684, 0.4276765409684762, -0.6486173821583863, 0.08856823496937882, 0.557143175184845, -0.1985822093439542, -0.1801379487124286, 0.043017831672796714, -0.1929487463516646, -0.5763738177808153, -0.49637049997464744, 0.12581361013858916, 0.3855284958072094, 0.15109520635764673, 0.41672543545469565, -0.7485533043159125, 0.1884036602694128, 0.6381773143883831, 0.20656419313369856, 0.5496422308632847, 0.685510222422288, 0.17777973619459675, -0.2579184029541337, -0.2079419738929984, 0.6082747209746782, 0.5014782256507726, -0.7783280743075152, -0.5276060845071164, -0.9311912948488923], - [0.6670456246431664, 0.07506905805544695, 0.8002014930850021, -0.761108481031973, -0.3309405791117992, -0.4968484241950417, 0.5855902060858931, 0.9782616605547247, 0.5179425134945737, 0.9992716621826399, 0.04240304791255256, 0.269024423156097, 0.3525829475191862, -0.43198618097746966, 0.3216754129865127, -0.7577084174756146, -0.4026041614694662, 0.1403933118873224, 0.7634052300441858, -0.5740345150905044, 0.912328468664054, -0.6498208158571068] - ] + [ + 0.5526596524494152, + 0.9690315932495712, + -0.8680156139856099, + 0.39561955960098705, + -0.7189141230781315, + 0.1091438241240188, + -0.1514792667377174, + -0.8842187642857129, + -0.90929587555064, + 0.0553477365473245, + -0.38102440387803127, + -0.21972849843690567, + -0.1366925641984078, + 0.234658614104986, + 0.6618349090074298, + 0.3456641681297574, + -0.13000537043751015, + 0.015349401356097525, + 0.4014083014273322, + -0.05782560373055445, + -0.3626979339434868, + -0.46909114377791794, + 0.037734998042463275, + ], + [ + -0.23849715068438293, + 0.7921459122177519, + 0.7585522723532372, + 0.8898425015365772, + 0.6681429223463302, + -0.7046659515927074, + -0.2533112691118138, + -0.9895684050716598, + 0.7064520294805683, + -0.06906516907342031, + 0.8213751152386364, + -0.6183596959717537, + 0.5207021021865952, + 0.7449011143255648, + 0.9149814958723772, + -0.8454584370536609, + 0.8033846014701953, + 0.7737784202696005, + ], + [ + 0.4835975048151546, + -0.5987307405530511, + 0.277769205131432, + -0.5497708234569545, + -0.9238315028510387, + 0.5332814495117155, + -0.5911554383083086, + -0.9275056197495566, + 0.5302218322249228, + -0.7802927767456045, + 0.20312945269109162, + -0.2622275493784205, + -0.17603338014279468, + 0.45721842042830585, + -0.07856217105142416, + 0.458134032752032, + 0.7601845863976819, + -0.0687601004445304, + 0.5084467209402248, + -0.5503154953218936, + 0.8116513645055918, + -0.10424664785069293, + -0.4650749134336116, + 0.17127951460844226, + -0.21534156550417394, + ], + [ + -0.6945216072262328, + 0.06573632900997772, + -0.106647523045865, + 0.13865277008666044, + -0.7820633695316517, + -0.10880551946361727, + 0.2658232882927578, + -0.08490107870171215, + 0.8401971948812119, + -0.5389907554930264, + 0.9847445142919777, + 0.6022812602894703, + 0.45645830164530143, + -0.24553265752254427, + 0.06468186895698413, + 0.692893319789019, + -0.19092820288195367, + 0.45737634128864624, + 0.10728439355457109, + 0.5890201396380044, + -0.9502112271317584, + -0.2302405122715243, + 0.8242967867244597, + -0.7636718337376485, + -0.2653389884306485, + 0.500710013837995, + -0.24084472766713083, + ], + [ + -0.8374018409716684, + 0.4276765409684762, + -0.6486173821583863, + 0.08856823496937882, + 0.557143175184845, + -0.1985822093439542, + -0.1801379487124286, + 0.043017831672796714, + -0.1929487463516646, + -0.5763738177808153, + -0.49637049997464744, + 0.12581361013858916, + 0.3855284958072094, + 0.15109520635764673, + 0.41672543545469565, + -0.7485533043159125, + 0.1884036602694128, + 0.6381773143883831, + 0.20656419313369856, + 0.5496422308632847, + 0.685510222422288, + 0.17777973619459675, + -0.2579184029541337, + -0.2079419738929984, + 0.6082747209746782, + 0.5014782256507726, + -0.7783280743075152, + -0.5276060845071164, + -0.9311912948488923, + ], + [ + 0.6670456246431664, + 0.07506905805544695, + 0.8002014930850021, + -0.761108481031973, + -0.3309405791117992, + -0.4968484241950417, + 0.5855902060858931, + 0.9782616605547247, + 0.5179425134945737, + 0.9992716621826399, + 0.04240304791255256, + 0.269024423156097, + 0.3525829475191862, + -0.43198618097746966, + 0.3216754129865127, + -0.7577084174756146, + -0.4026041614694662, + 0.1403933118873224, + 0.7634052300441858, + -0.5740345150905044, + 0.912328468664054, + -0.6498208158571068, + ], +] for (M, p, q, v, u, dy, X) in zip(Ms, ps, qs, vs, us, dys, Xs) V = typeof(M).parameters[2] @@ -239,20 +4036,25 @@ for (M, p, q, v, u, dy, X) in zip(Ms, ps, qs, vs, us, dys, Xs) @test(is_point(M, exp(M, p, v))) @test(isapprox(p, exp(M, p, 0.0 * v); atol=1e-5)) - geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), -1.0, 1e-3) + geodesic_speed = + finite_difference(t -> distance(M, p, exp(M, p, t * v)), -1.0, 1e-3) @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) - geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), -0.811, 1e-3) + geodesic_speed = + finite_difference(t -> distance(M, p, exp(M, p, t * v)), -0.811, 1e-3) @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) - geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), -0.479, 1e-3) + geodesic_speed = + finite_difference(t -> distance(M, p, exp(M, p, t * v)), -0.479, 1e-3) @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) - geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.181, 1e-3) + geodesic_speed = + finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.181, 1e-3) @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) - geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.703, 1e-3) + geodesic_speed = + finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.703, 1e-3) @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) - geodesic_speed = finite_difference(t -> distance(M, p, exp(M, p, t * v)), 1.0, 1e-3) + geodesic_speed = + finite_difference(t -> distance(M, p, exp(M, p, t * v)), 1.0, 1e-3) @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) - # Geodesics are (locally) length-minizing. So let B_a be a one-parameter # family of curves such that B_0 is a geodesic. Then the derivative of # length(B_a) at a = 0 should be 0, and the second derivative should be @@ -313,7 +4115,9 @@ for (M, p, q, v, u, dy, X) in zip(Ms, ps, qs, vs, us, dys, Xs) # curvature contains the same information as the Riemann tensor, this # should be fine. - sectional_curvature(M, p, u, v,) = inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) + sectional_curvature(M, p, u, v) = + inner(M, p, riemann_tensor(M, p, u, v, v), u) / + (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) # Orthonormalize u_ = u / norm(M, p, u) @@ -339,7 +4143,6 @@ for (M, p, q, v, u, dy, X) in zip(Ms, ps, qs, vs, us, dys, Xs) @testset "get_vector()" begin @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) end - end end From 53a040e19b1d97f4f71a1185183aca4977da9e79 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Tue, 17 Dec 2024 18:34:46 +0100 Subject: [PATCH 10/35] fix Ronny's comments --- src/Manifolds.jl | 6 +- src/manifolds/Segre.jl | 236 +- .../{SegreWarped.jl => SegreWarpedMetric.jl} | 140 +- test/manifolds/segre.jl | 2655 +---------------- 4 files changed, 276 insertions(+), 2761 deletions(-) rename src/manifolds/{SegreWarped.jl => SegreWarpedMetric.jl} (67%) diff --git a/src/Manifolds.jl b/src/Manifolds.jl index fcce06a411..1ae7287bb4 100644 --- a/src/Manifolds.jl +++ b/src/Manifolds.jl @@ -453,7 +453,7 @@ include("manifolds/MultinomialSymmetricPositiveDefinite.jl") include("manifolds/PositiveNumbers.jl") include("manifolds/ProjectiveSpace.jl") include("manifolds/Segre.jl") -include("manifolds/SegreWarped.jl") +include("manifolds/SegreWarpedMetric.jl") include("manifolds/SkewHermitian.jl") include("manifolds/Spectrahedron.jl") include("manifolds/Stiefel.jl") @@ -739,8 +739,8 @@ export AbstractMetric, ProductMetric, RealSymplecticMetric, RiemannianMetric, - WarpedMetric, - StiefelSubmersionMetric + StiefelSubmersionMetric, + WarpedMetric export AbstractAtlas, RetractionAtlas # Vector transport types export AbstractVectorTransportMethod, ParallelTransport, ProjectionTransport diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 1c8cdab793..68f7a4dbc3 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -7,27 +7,25 @@ The Segre manifold ```` is the set of rank-one tensors in ``𝔽^{n_1} \otimes \dots \otimes 𝔽^{n_d}``. -When ``𝔽 = ℝ``, the Segre manifold is represented as +When ``𝔽 = ℝ``, the Segre manifold is a normal Riemannian covering of ````math - \mathcal{S} \sim ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}. + \mathcal{P} = ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} ```` -This is a local diffeomorphism, and the metric is a locally a [warped product](https://en.wikipedia.org/wiki/Warped_product) of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. The tuple ``(n_1, \dots, n_d)`` is called the _valence_ of the manifold. +with the [warped product metric](https://en.wikipedia.org/wiki/Warped_product) [`inner`](@ref inner(::Segre, ::Any)). The tuple ``(n_1, \dots, n_d)`` is called the _valence_ of the manifold. The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). # Constructor - Segre(valence::NTuple{V, Int}; field::AbstractNumbers=ℝ) + Segre(n::Int...; field::AbstractNumbers=ℝ) -Generate a valence `V` Segre manifold. +Generate a valence `(n, ...)` Segre manifold. Segre(n) is ``\mathbb{R} \setminus \{ 0 \}``. """ struct Segre{𝔽,V} <: AbstractManifold{𝔽} end -function Segre(valence::NTuple{V,Int}; field::AbstractNumbers=ℝ) where {V} - return Segre{field,valence}() +function Segre(n::Int...; field::AbstractNumbers=ℝ) + return Segre{field,(n...,)}() end -valence(::Segre{𝔽,V}) where {𝔽,V} = V -ndims(::Segre{𝔽,V}) where {𝔽,V} = length(V) manifold_dimension(::Segre{𝔽,V}) where {𝔽,V} = (1 + sum(V .- 1)) """ @@ -81,19 +79,17 @@ end Check whether `p` is a valid point on `M`, i.e. `p[1]` is a singleton containing a positive number and `p[i + 1]` is a point on `Sphere(V[i])`. The tolerance can be set using the `kwargs...`. """ -function check_point(M::Segre{ℝ,V}, p; kwargs...) where {V} +function check_point(M::Segre{ℝ,V}, p; atol=1.4901161193847656e-8, kwargs...) where {V} if p[1][1] <= 0.0 return DomainError(p[1][1], "$(p) has non-positive modulus.") end for (x, n) in zip(p[2:end], V) - e = check_point(Sphere(n - 1)::AbstractSphere, x; rtol=1e-10, atol=1e-10, kwargs...) + e = check_point(Sphere(n - 1)::AbstractSphere, x; atol=atol, kwargs...) if !isnothing(e) return e end end - - return nothing end """ @@ -101,55 +97,47 @@ end Check whether `v` is a tangent vector to `p` on `M`, i.e. after `check_point(M, p)`, `v` has to be of same dimension as `p` and orthogonal to `p`. The tolerance can be set using the `kwargs...`. """ -function check_vector(M::Segre{ℝ,V}, p, v, kwargs...) where {V} - e = check_point(M, p, kwargs...) - if !isnothing(e) - return e - end - +function check_vector(M::Segre{ℝ,V}, p, v; atol=1.4901161193847656e-8, kwargs...) where {V} for (x, xdot, n) in zip(p[2:end], v[2:end], V) - # check_vector(::AbstractSphere, ...) uses isapprox to compare the dot product to 0, which by default sets atol=0 - e = check_vector( - Sphere(n - 1)::AbstractSphere, - x, - xdot; - rtol=1e-10, - atol=1e-10, - kwargs..., - ) + e = check_vector(Sphere(n - 1)::AbstractSphere, x, xdot; atol=atol, kwargs...) if !isnothing(e) return e end end - - return nothing end -""" +@doc raw""" function get_coordinates(M::Segre{𝔽, V}, p, v; kwargs...) -""" -function get_coordinates(M::Segre{𝔽,V}, p, v; kwargs...) where {𝔽,V} - @assert(is_point(M, p)) - @assert(is_vector(M, p, v)) - coords = [ +Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}``. +""" +get_coordinates(M::Segre{𝔽,V}, p, v, ::DefaultOrthonormalBasis; kwargs...) where {𝔽,V} + +function get_coordinates_orthonormal!( + M::Segre{ℝ,V}, + X, + p, + v, + ::RealNumbers; + kwargs..., +) where {V} + return X = vcat( v[1], [ get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end]) ]..., - ] - - return vcat(coords...) + ) end -""" +@doc raw""" function get_vector( M::Segre{𝔽, V}, p, X; kwargs...) + +Get tangent vector `v` from coordinates in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}``. """ -function get_vector(M::Segre{𝔽,V}, p, X; kwargs...) where {𝔽,V} - @assert(is_point(M, p)) +get_vector(M::Segre{𝔽,V}, p, X; kwargs...) where {𝔽,V} +function get_vector_orthonormal!(M::Segre{ℝ,V}, v, p, X, ::RealNumbers; kwargs...) where {V} X_ = deepcopy(X) - v = eltype(p)[[] for _ in p] # Initialize v[1] = [X_[1]] X_ = X_[2:end] for (i, n) in enumerate(V) @@ -163,10 +151,7 @@ function get_vector(M::Segre{𝔽,V}, p, X; kwargs...) where {𝔽,V} X_ = X_[n:end] end - @assert(length(X_) == 0) - check_vector(M, p, v) - - return v + return v # TODO: Why do I have to return v here? end @doc raw""" @@ -183,41 +168,52 @@ function inner(M::Segre{ℝ,V}, p, u, v) where {V} end @doc raw""" - function norm(M::Segre{𝔽, V}, p, v) + function rand(M::Segre{ℝ, V}; vector_at=nothing) -Norm of tangent vector ``v`` at ``p``. -""" -function norm(M::Segre{𝔽,V}, p, v) where {𝔽,V} - return sqrt(inner(M, p, v, v)) -end +If `vector_at` is `nothing`, return a random point on +````math + ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} +```` +from a log-normal distribution on ℝ^{+} and a uniform distribution on ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. +If `vector_at` is not `nothing`, return a random tangent vector from a normal distribution on the tangent space. """ - function rand(M::Segre{ℝ, V}; vector_at=nothing) -""" -function rand(M::Segre{ℝ,V}; vector_at=nothing) where {V} +function rand(M::Segre{ℝ,V}; vector_at=nothing, kwargs...) where {V} if isnothing(vector_at) - lambda = abs.(rand(Euclidean(1))) - xs = [rand(Sphere(n - 1)) for n in V] - return [lambda, xs...] + return [ + rand(PositiveArrays(1); kwargs...), + [rand(Sphere(n - 1); kwargs...) for n in V]..., + ] else - @assert(is_point(M, vector_at)) - - lambdadot = rand(Euclidean(1); vector_at=vector_at[1]) - xdots = [rand(Sphere(n - 1); vector_at=vector_at[i + 1]) for (i, n) in enumerate(V)] - return [lambdadot, xdots...] + return [ + rand(PositiveArrays(1); vector_at=vector_at[1], kwargs...), + [ + rand(Sphere(n - 1); vector_at=xdot, kwargs...) for + (xdot, n) in zip(vector_at[2:end], V) + ]..., + ] end end @doc raw""" - function embed(M::Segre{𝔽, V}, v) + function get_embedding(M::Segre{𝔽,V}) + +``\mathcal{S}`` is embedded in ``𝔽^{n_1 \times \dots \times n_d}``. +""" +function get_embedding(M::Segre{𝔽,V}) where {𝔽,V} + return Euclidean(prod(V)) +end + +@doc raw""" + function embed!(M::Segre{𝔽, V}, q, p) Embed ``p \doteq (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: ````math (\lambda, x_1, \dots, x_d) \mapsto \lambda x_1 \otimes \dots \otimes x_d. ```` """ -function embed(M::Segre{𝔽,V}, p) where {𝔽,V} - return kronecker(p...)[:] +function embed!(M::Segre{𝔽,V}, q, p) where {𝔽,V} + return q = kron(p...) end @doc raw""" @@ -228,48 +224,55 @@ Embed tangent vector ``v = (\nu, u_1, \dots, u_d)`` at ``p \doteq (\lambda, x_1, (\nu, u_1, \dots, u_d) \mapsto \nu x_1 \otimes \dots \otimes x_d + \lambda u_1 \otimes x_2 \otimes \dots \otimes x_d + \dots + \lambda x_1 \otimes \dots \otimes x_{d - 1} \otimes u_d. ```` """ -function embed_vector(M::Segre{𝔽,V}, p, v) where {𝔽,V} +function embed_vector!(M::Segre{𝔽,V}, u, p, v) where {𝔽,V} # Product rule - return sum([ - kronecker([i == j ? xdot : x for (j, (x, xdot)) in enumerate(zip(p, v))]...)[:] for + return u = sum([ + kron([i == j ? xdot : x for (j, (x, xdot)) in enumerate(zip(p, v))]...) for (i, _) in enumerate(p) ]) end @doc raw""" - function m(M::Segre{ℝ, V}, p, q) + function spherical_angle_sum(M::Segre{ℝ, V}, p, q) Let ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}``. -Then +Then this is ````math - m(p, q) = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} + \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2}, ```` -is the distance between ``(x_1, \dots, x_d)`` and ``(y_1, \dots, y_d)`` on ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. +where ``\sphericalangle(x_i, y_i)`` is the distance between ``x_i`` and ``y_i`` on the sphere ``S^{n_i - 1}``. """ -function m(M::Segre{ℝ,V}, p, q) where {V} +function spherical_angle_sum(M::Segre{ℝ,V}, p, q) where {V} return sqrt( sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), ) end -""" +@doc raw""" function connected_by_geodesic(M::Segre{ℝ, V}, p, q) -Check if two points, `p` and `q`, can be connected by a geodesic. +``\mathcal{S}`` is not a complete manifold, i.e. not every pair `p` and `q` of points are connected by a geodesic in ``\mathcal{S}``. +`connected_by_geodesic(M, p, q)` returns `true` if two points, `p` and `q`, are connected by a geodesic, and otherwise returns `false`. """ function connected_by_geodesic(M::Segre{ℝ,V}, p, q) where {V} - q_ = closest_representation(M, p, q) + closest_representative!(M, q, p) - return m(M, p, q_) < pi + return spherical_angle_sum(M, p, q) < pi end -""" - function closest_representation(M::Segre{ℝ, V}, p, q) +@doc raw""" + function closest_representative!(M::Segre{ℝ, V}, p, q) -Find the representation of `q` that is closest to `p`. +``\mathcal{S}`` is a ``2^d``-sheeted Riemannian covering of +````math + \mathcal{P} = ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} +```` +with the metric [`inner`](@ref inner(::Segre, ::Any)). +Every equivalence class ``q \in \mathcal{S}`` has ``2^d`` representatives in ``\mathcal{P}``. +`closest_representative!(M, q, p)` changes representative of `q` to the one that is closest to `p` in ``\mathcal{P}``. """ -function closest_representation(M::Segre{ℝ,V}, p, q) where {V} +function closest_representative!(M::Segre{ℝ,V}, q, p) where {V} # Find closest representation by flipping an even number of signs. ds = [distance(Sphere(n - 1), x, y) for (n, x, y) in zip(V, p[2:end], q[2:end])] @@ -293,15 +296,12 @@ function closest_representation(M::Segre{ℝ,V}, p, q) where {V} q2 = deepcopy(q) q2[flips2] = -q2[flips2] - m(M, p, q1) < m(M, p, q2) ? flips = flips1 : flips = flips2 + spherical_angle_sum(M, p, q1) < spherical_angle_sum(M, p, q2) ? flips = flips1 : + flips = flips2 end end - q_ = deepcopy(q) - q_[flips] = -q[flips] - @assert(iseven(sum(flips))) # Should not be necessary but you never know... - - return q_ + return q[flips] = -q[flips] end @doc raw""" @@ -334,23 +334,23 @@ For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven: exp(M::Segre{ℝ,V}, p, v) where {V} function exp!(M::Segre{ℝ,V}, q, p, v) where {V} - m_ = sqrt( + m = sqrt( sum([ norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) ]), ) - q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * m_)^2) + q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * m)^2) - f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * m_)) - if m_ == 0 + f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * m)) + if m == 0 for (x, y) in zip(p[2:end], q[2:end]) y .= x end else for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) a = norm(Sphere(n - 1), x, xdot) - y .= x * cos(a * f / m_) .+ xdot * (f / m_) * sinc(a * f / (m_ * pi)) + y .= x * cos(a * f / m) .+ xdot * (f / m) * sinc(a * f / (m * pi)) end end @@ -382,25 +382,22 @@ where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \oper For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -function log(M::Segre{ℝ,V}, p, q) where {V} - q_ = closest_representation(M, p, q) - if connected_by_geodesic(M, p, q_) - v = zeros.(size.(p)) # Initialize - log!(M, v, p, q_) - return v - else - return Nothing - end -end +log(M::Segre{ℝ,V}, p, q) where {V} function log!(M::Segre{ℝ,V}, v, p, q) where {V} - m_ = m(M, p, q) + closest_representative!(M, q, p) - v[1][1] = q[1][1] * cos(m_) - p[1][1] + if !connected_by_geodesic(M, p, q) + v = nan.(size.(p)) + else + m = spherical_angle_sum(M, p, q) + + v[1][1] = q[1][1] * cos(m) - p[1][1] - for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) - a = distance(Sphere(n - 1), x, y) - xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(m_ / pi) / sinc(a / pi) + for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + a = distance(Sphere(n - 1), x, y) + xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(m / pi) / sinc(a / pi) + end end return 0 @@ -421,8 +418,10 @@ and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimi ```` """ function distance(M::Segre{ℝ,V}, p, q) where {V} - q_ = closest_representation(M, p, q) - return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m(M, p, q_) / 2)^2) + closest_representative!(M, q, p) + m = spherical_angle_sum(M, p, q) + + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(m)) but more stable for small m end @@ -439,20 +438,17 @@ If ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``u``, ``v``, ``w ``R_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ function riemann_tensor(M::Segre{ℝ,V}, p, u, v, w) where {V} - u_ = deepcopy(u) - u_[1][1] = 0.0 - v_ = deepcopy(v) - v_[1][1] = 0.0 - w_ = deepcopy(w) - w_[1][1] = 0.0 - return [ [0.0], [ riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for - (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end]) + (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u[2:end], v[2:end], w[2:end]) ]..., - ] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) + ] + + (1 / p[1][1]^2) * ( + inner(M, p, [[0.0], u[2:end]...], [[0.0], w[2:end]...]) * [[0.0], v[2:end]...] - + inner(M, p, [[0.0], v[2:end]...], [[0.0], w[2:end]...]) * [[0.0], u[2:end]...] + ) end @doc raw""" diff --git a/src/manifolds/SegreWarped.jl b/src/manifolds/SegreWarpedMetric.jl similarity index 67% rename from src/manifolds/SegreWarped.jl rename to src/manifolds/SegreWarpedMetric.jl index bb7acd00b8..d438a4c113 100644 --- a/src/manifolds/SegreWarped.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -1,33 +1,41 @@ @doc raw""" WarpedMetric{A} <: AbstractMetric -is the ``A``-warped metric on the Segre manifold ``\mathcal{S}``. We denote it ``\mathcal{S}_A``. It is a generalization of the metric -````math - \langle (\nu, u_1, \dots, u_d), (\xi, v_1, \dots, v_d) \rangle_{(\lambda, x_1, \dots, x_d)} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle + \dots + \langle u_d, v_d \rangle), -```` -on the Segre that is induced from its Euclidean embedding, to the metric +The ``A``-warped metric on the Segre manifold ``\mathcal{S}`` is a generalization of the Euclidean metric on ``\mathcal{S}``. +We this manifold by ``\mathcal{S}_A``. + +Similarly to ``\mathcal{S}``, when ``𝔽 = ℝ``, ``\mathcal{S}_A`` is a normal Riemannian covering of the product manifold ````math - \langle (\nu, u_1, \dots, u_d), (\xi, v_1, \dots, v_d) \rangle_{(\lambda, x_1, \dots, x_d)} = \nu \xi + (A \lambda)^2 (\langle u_1, v_1 \rangle + \dots + \langle u_d, v_d \rangle). + ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} ```` -``A`` is called the _warping factor_ and ``A = 1`` corresponds to the usual Segre manifold. +with a [warped product metric](https://en.wikipedia.org/wiki/Warped_product), but the warping function now depends on the _warping factor_ ``A``. +``A = 1`` corresponds to the usual Segre manifold. The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ struct WarpedMetric{A} <: AbstractMetric end -valence(::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}) where {V,A,𝔽} = V -ndims(::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}) where {V,A,𝔽} = length(V) +@doc raw""" + function get_coordinates(M::Segre{𝔽, V}, p, v; kwargs...) +Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each sphere tangent space ``T_{x_i} S^{n_i - 1}``. """ - function get_coordinates(M::MetricManifold{𝔽, Segre{𝔽, V}, WarpedMetric{A}}, p, v; kwargs...) -""" -function get_coordinates( +get_coordinates( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, v; kwargs..., -) where {V,A,𝔽} - return get_coordinates(M.manifold, p, v; kwargs...) +) where {𝔽,V,A} + +function get_coordinates_orthonormal!( + M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, + X, + p, + v, + ::RealNumbers; + kwargs..., +) where {𝔽,V,A} + return get_coordinates_orthonormal!(M.manifold, X, p, v, RealNumbers(); kwargs...) end """ @@ -55,52 +63,28 @@ function inner(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v) whe return u[1][1] * v[1][1] + (A * p[1][1])^2 * dot(u[2:end], v[2:end]) end -@doc raw""" - function norm(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, v) - -Norm of tangent vector ``v`` at ``p``. -""" -function norm(M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, v) where {V,A,𝔽} - return sqrt(inner(M, p, v, v)) -end - -@doc raw""" - function m(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) - -When ``p``, ``q \in ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1}``, this is the distance between the ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` parts of ``p`` and ``q``. -""" -function m(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} - return sqrt( - sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), - ) +function spherical_angle_sum( + M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, + p, + q, +) where {V,A} + return spherical_angle_sum(M.manifold, p, q) end -""" - function connected_by_geodesic(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) - -Check if two points, `p` and `q`, can be connected by a geodesic. -""" function connected_by_geodesic( M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q, ) where {V,A} - q_ = closest_representation(M.manifold, p, q) - - return A * m(M, p, q) < pi + return connected_by_geodesic(M.manifold, p, q) end -""" - function closest_representation(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) - -Find the representation of ``q`` that is closest to ``p``. -""" -function closest_representation( +function closest_representative!( M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, - p, q, + p, ) where {V,A} - return closest_representation(M.manifold, p, q) + return closest_representative!(M.manifold, q, p) end @doc raw""" @@ -133,16 +117,16 @@ For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven: exp(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, v) where {V,A} function exp!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) where {V,A} - m_ = sqrt( + m = sqrt( sum([ norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) ]), ) - q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * A * m_)^2) + q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * A * m)^2) - f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * A * m_)) - if m_ == 0 + f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * A * m)) + if m == 0 for (x, y) in zip(p[2:end], q[2:end]) y .= x end @@ -150,8 +134,8 @@ function exp!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) wher for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) a = norm(Sphere(n - 1), x, xdot) y .= - x * cos(a * f / (A * m_)) .+ - xdot * (f / (A * m_)) * sinc(a * f / (A * m_ * pi)) + x * cos(a * f / (A * m)) .+ + xdot * (f / (A * m)) * sinc(a * f / (A * m * pi)) end end @@ -183,25 +167,23 @@ where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \oper For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -function log(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} - q_ = closest_representation(M, p, q) - if connected_by_geodesic(M, p, q) - v = zeros.(size.(p)) # Initialize - log!(M, v, p, q_) - return v - else - return Nothing - end -end +log(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} function log!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, v, p, q) where {V,A} - m_ = m(M, p, q) + closest_representative!(M, q, p) + + if !connected_by_geodesic(M, p, q) + v = nan.(size.(p)) + else + m = spherical_angle_sum(M, p, q) - v[1][1] = q[1][1] * cos(A * m_) - p[1][1] + v[1][1] = q[1][1] * cos(A * m) - p[1][1] - for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) - a = distance(Sphere(n - 1), x, y) - xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(A * m_ / pi) / sinc(a / pi) + for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + a = distance(Sphere(n - 1), x, y) + xdot .= + (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(A * m / pi) / sinc(a / pi) + end end return 0 @@ -222,8 +204,9 @@ and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimi ```` """ function distance(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} - q_ = closest_representation(M, p, q) - return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m(M, p, q_) / 2)^2) + closest_representative!(M, q, p) + m = spherical_angle_sum(M, p, q) + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m / 2)^2) # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(A * m)) but more stable for small m end @@ -245,20 +228,17 @@ function riemann_tensor( v, w, ) where {V,A} - # Can we avoid the deep-copies here? That looks a bit inefficient - u_ = deepcopy(u) - u_[1][1] = 0.0 - v_ = deepcopy(v) - v_[1][1] = 0.0 - w_ = deepcopy(w) - w_[1][1] = 0.0 return [ [0.0], [ riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for - (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u_[2:end], v_[2:end], w_[2:end]) + (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u[2:end], v[2:end], w[2:end]) ]..., - ] + (1 / p[1][1]^2) * (inner(M, p, u_, w_) * v_ - inner(M, p, v_, w_) * u_) + ] + + (1 / p[1][1]^2) * ( + inner(M, p, [[0.0], u[2:end]...], [[0.0], w[2:end]...]) * [[0.0], v[2:end]...] - + inner(M, p, [[0.0], v[2:end]...], [[0.0], w[2:end]...]) * [[0.0], u[2:end]...] + ) end @doc raw""" diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index 4e423afdda..ec56cd91aa 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1,63 +1,20 @@ -using Manifolds, Test - -# Approximate derivative of f at x -# https://en.wikipedia.org/wiki/Finite_difference_coefficient -function finite_difference(f::Function, x::Float64, h::Float64; order=1::Int64) #={{{=# - if order == 1 - return ( - (1 / 12) * f(x - 2 * h) + - (-2 / 3) * f(x - 1 * h) + - (2 / 3) * f(x + 1 * h) + - (-1 / 12) * f(x + 2 * h) - ) / h - elseif order == 2 - return ( - (-1 / 12) * f(x - 2 * h) + - (4 / 3) * f(x - 1 * h) + - (-5 / 2) * f(x) + - (4 / 3) * f(x + 1 * h) + - (-1 / 12) * f(x + 2 * h) - ) / h^2 - elseif order == 3 - return ( - (1 / 8) * f(x - 3 * h) + - (-1) * f(x - 2 * h) + - (13 / 8) * f(x - 1 * h) + - (-13 / 8) * f(x + 1 * h) + - (1) * f(x + 2 * h) + - (-1 / 8) * f(x + 3 * h) - ) / h^3 - end -end #=}}}=# +using Manifolds, Test, LinearAlgebra, FiniteDifferences, Random # Manifolds to test Ms = [ - Segre{ℝ,(10,)}(), - Segre{ℝ,(2,)}(), - Segre{ℝ,(7,)}(), - Segre{ℝ,(7, 2)}(), - Segre{ℝ,(9, 8)}(), - Segre{ℝ,(2, 2)}(), - Segre{ℝ,(7, 9, 9)}(), - Segre{ℝ,(10, 7, 3)}(), - Segre{ℝ,(5, 6, 3)}(), - Segre{ℝ,(9, 3, 6, 6)}(), - Segre{ℝ,(5, 4, 10, 10)}(), - Segre{ℝ,(10, 6, 3, 4)}(), - MetricManifold(Segre{ℝ,(10,)}(), WarpedMetric{1.2025837056880606}()), - MetricManifold(Segre{ℝ,(9,)}(), WarpedMetric{1.1157384770946328}()), - MetricManifold(Segre{ℝ,(4,)}(), WarpedMetric{1.108519951945247}()), - MetricManifold(Segre{ℝ,(2, 9)}(), WarpedMetric{1.1302422072971439}()), - MetricManifold(Segre{ℝ,(4, 7)}(), WarpedMetric{1.4990018903833313}()), - MetricManifold(Segre{ℝ,(2, 2)}(), WarpedMetric{1.1978398577942357}()), - MetricManifold(Segre{ℝ,(9, 6, 10)}(), WarpedMetric{1.4545138169484464}()), - MetricManifold(Segre{ℝ,(9, 9, 2)}(), WarpedMetric{0.886048645869852}()), - MetricManifold(Segre{ℝ,(10, 10, 7)}(), WarpedMetric{1.2810851738110494}()), - MetricManifold(Segre{ℝ,(9, 3, 8, 10)}(), WarpedMetric{1.396673190458706}()), - MetricManifold(Segre{ℝ,(10, 9, 7, 6)}(), WarpedMetric{1.294280190668267}()), - MetricManifold(Segre{ℝ,(7, 2, 8, 8)}(), WarpedMetric{1.2374529454448573}()), + Segre(10), + Segre(7, 2), + Segre(7, 9, 9), + Segre(9, 3, 6, 6), + MetricManifold(Segre(10), WarpedMetric{1.2025837056880606}()), + MetricManifold(Segre(2, 9), WarpedMetric{1.1302422072971439}()), + MetricManifold(Segre(9, 6, 10), WarpedMetric{1.4545138169484464}()), + MetricManifold(Segre(9, 3, 8, 10), WarpedMetric{1.396673190458706}()), ] +# Vs[i] is the valence of Ms[i] +Vs = [(10,), (7, 2), (7, 9, 9), (9, 3, 6, 6), (10), (2, 9), (9, 6, 10), (9, 3, 8, 10)] + # ps[i] is a point on Ms[i] ps = [ [ @@ -75,19 +32,6 @@ ps = [ -0.030292993087650443, ], ], - [[0.3298310216639224], [0.2514005595224343, -0.96788313275509]], - [ - [0.42312947328046224], - [ - 0.33560958022362747, - -0.7750899034491946, - 0.23449838016304786, - 0.36554747855051023, - -0.28711573724812484, - -0.014134328816621394, - 0.12390389837644036, - ], - ], [ [1.5024828708442504], [ @@ -101,35 +45,6 @@ ps = [ ], [0.13573491868289245, 0.9907451901726038], ], - [ - [0.3013653757380563], - [ - 0.5977968840579448, - -0.22702223761000456, - 0.5118227538696087, - -0.11912796582968001, - 0.06221848112591997, - 0.1884433539067577, - -0.10700788275590943, - -0.3518682598612047, - 0.37456880426014166, - ], - [ - 0.013604873029341946, - -0.16528022578112536, - 0.20155485791540892, - -0.3541277493897382, - 0.676862752046083, - -0.2658785210172399, - 0.5147053312531512, - -0.112740319727795, - ], - ], - [ - [2.851092491176718], - [0.3804764585148756, -0.9247906057675856], - [0.43841826755186564, -0.8987710624384948], - ], [ [0.5567549635823631], [ @@ -164,50 +79,6 @@ ps = [ 0.09108177932795573, ], ], - [ - [0.36252817849574176], - [ - -0.4152409797128937, - 0.3949651690781115, - 0.059637140694856684, - -0.29809447149493, - -0.45495068818315665, - 0.15339000916151824, - 0.5145387514659299, - 0.0726835092343826, - 0.15840576161081632, - 0.23135797656647117, - ], - [ - -0.539717469908245, - 0.4395297187977435, - 0.21328340065082524, - 0.45891791025442036, - -0.08479985319672712, - -0.07573386931397807, - -0.4964842269000107, - ], - [0.3787170228715312, 0.8302726053139932, 0.40892642058497286], - ], - [ - [0.2755990738257318], - [ - 0.21794010543619222, - -0.832205317244186, - -0.08165195766640711, - -0.32019564073885964, - 0.3882578136419659, - ], - [ - 0.8072220207586441, - 0.1839997459775723, - 0.25829762282479984, - -0.16088661411000194, - 0.4709383701765526, - -0.012312173701218641, - ], - [-0.5999408691302599, 0.19608311412450938, -0.7756431949694802], - ], [ [0.13874530878036045], [ @@ -239,66 +110,6 @@ ps = [ -0.014682951172671068, ], ], - [ - [0.21051807193802943], - [ - 0.23403384696597218, - 0.42054682357471496, - -0.5698122696955275, - 0.5838315012795727, - -0.32066069773765116, - ], - [0.5766960203474961, -0.6743800959552224, 0.13162023644111331, 0.4419381174485529], - [ - -0.21057589355060127, - 0.08811991196707877, - 0.3405460927874034, - -0.3897589394700625, - 0.7083087794882124, - -0.1136094071563721, - 0.08025571453602402, - 0.38379031842997346, - -0.10397276906281434, - 0.029227598658195648, - ], - [ - -0.5554668166067296, - -0.20795381463643023, - 0.2553028805249397, - 0.10256974403643938, - -0.08894446390830917, - 0.04610645378979823, - 0.27966690408533734, - -0.07380638485934377, - -0.33321238127988634, - 0.6064514324865661, - ], - ], - [ - [0.4828275813633084], - [ - 0.23384095547788736, - 0.3512388738563172, - 0.20430444349630456, - 0.6579221192887889, - 0.09844835569247844, - 0.363573528638023, - 0.2687104582601494, - -0.14301608669058016, - -0.09631021994329247, - -0.3217692977748192, - ], - [ - -0.5116624664211036, - 0.07668016024356412, - 0.5061460483419392, - 0.3214705004283764, - -0.46018395871455636, - 0.40127956928413683, - ], - [-0.38096699727867506, 0.2861444037357305, -0.8791959549470149], - [0.692923641553941, -0.3060961599674285, 0.22172696315719087, 0.6140025420451529], - ], [ [1.1838757652294163], [ @@ -314,24 +125,6 @@ ps = [ 0.16638557775398255, ], ], - [ - [0.3032739397640297297], - [ - -0.48082028355309697, - 0.3388907360614881, - 0.454066186534629, - -0.17812152265340722, - -0.2993680565146906, - -0.4376744632861303, - -0.07894707721342749, - -0.15363745968032946, - 0.3241053320409901, - ], - ], - [ - [1.1617468533361055], - [-0.02260630098657834, 0.2972001146356296, 0.7596474220087696, -0.5780111082424827], - ], [ [1.2844162220009774], [-0.30842015389728145, 0.951250234517699], @@ -347,29 +140,6 @@ ps = [ -0.4044368794841003, ], ], - [ - [0.18104388996897572], - [ - 0.5520877166363866, - -0.052976780373050814, - -0.8311689032169315, - -0.03938106404973989, - ], - [ - 0.034274688844047635, - 0.16403282417490214, - 0.2354752745921137, - 0.49694577571607884, - -0.1464762658164691, - -0.0454250584931338, - -0.8037387865251501, - ], - ], - [ - [1.6905902450546004], - [-0.12543067772892338, -0.99210238639188], - [0.8762083930519261, -0.48193241429204725], - ], [ [0.5007028223906543], [ @@ -404,68 +174,6 @@ ps = [ -0.4067248155023813, ], ], - [ - [0.42070460277285854], - [ - -0.11765364391216213, - -0.02107059901087521, - 0.01919962552849528, - 0.0075532937836861914, - -0.407416349154066, - 0.2526422092654315, - 0.18892381530643113, - -0.039220900801933495, - -0.8474911902514953, - ], - [ - -0.32443831265566164, - -0.2349409435382715, - -0.24293165040461917, - 0.17482035071905289, - 0.4202882276170908, - 0.29174253040759934, - -0.12773231584125186, - 0.17922569173029038, - 0.6631525474037887, - ], - [0.2845093749411345, -0.9586732579824081], - ], - [ - [0.10062440822372039], - [ - 0.07996808517600432, - -0.26307264663569147, - -0.4495698788298603, - 0.6111308460433761, - -0.11895028828957643, - 0.20924569495870432, - 0.3301577806915321, - -0.004487812699664358, - 0.3268240075329048, - -0.27392104072489637, - ], - [ - 0.12284217101173843, - 0.35404646594484673, - -0.035991021401721314, - 0.5860476109030441, - -0.4404194916015131, - 0.2346021425142989, - -0.16531437985938108, - 0.29739181674429876, - 0.0961161858068593, - 0.3752295207239467, - ], - [ - 0.37225889195343176, - -0.40269820383703075, - 0.5891470410337922, - -0.5231944785778554, - 0.017605742011659636, - 0.24075511508976774, - 0.14197812515009833, - ], - ], [ [0.18481028402754704], [ @@ -503,85 +211,10 @@ ps = [ -0.19203856057632393, ], ], - [ - [0.4228588017696557], - [ - -0.141865030134013, - 0.44059694416524103, - -0.4181744594149625, - -0.3452888941246838, - -0.3554076392829921, - 0.06722507728789844, - -0.08166976238961376, - -0.07165859365772556, - -0.13418586367363106, - 0.5753345078159252, - ], - [ - 0.45050543565810647, - 0.3522148480832122, - 0.20063517590059027, - -0.2069225940646595, - 0.5565420673454308, - -0.2904080923745975, - 0.3836714803715129, - 0.18159571033346678, - 0.12514543453657165, - ], - [ - 0.14887119923616898, - 0.10387753894769929, - -0.13940282319720718, - -0.6456183547647123, - -0.468455996706801, - 0.3389787430786487, - -0.4432076338534407, - ], - [ - -0.08150071800245477, - -0.5444374572967173, - 0.6051990477077818, - 0.2041079018657187, - -0.4187164733526199, - 0.3371884933536173, - ], - ], - [ - [0.17800461834682948], - [ - 0.40442214560226664, - -0.18410967602595124, - -0.37808224287777675, - 0.5298695372118921, - 0.20342335952859486, - 0.47237240617396475, - 0.3381149112046999, - ], - [-0.0671758988249334, -0.997741148102584], - [ - 0.5860119193049029, - -0.1655879827363143, - 0.42146580605026046, - -0.05072788682343524, - 0.01966945374695293, - -0.18509497429620517, - -0.2917989581694971, - 0.5737335943846366, - ], - [ - -0.45925413330012654, - -0.054244623817065345, - -0.11041902728376159, - 0.03752800032819433, - 0.24065851466537416, - -0.17318765966122213, - -0.5175866433893724, - -0.6455509506489918, - ], - ], ] # qs[i] is a point on Ms[i] that is connected to ps[i] by a geodesic and uses the closest representation to ps[i] +# TODO: test m = 0 qs = [ [ [0.2285468999681258], @@ -598,19 +231,6 @@ qs = [ 0.38335320681028, ], ], - [[0.5], [0.2514005595224343, -0.96788313275509]], # m = 0 - [ - [0.7626963166735549], - [ - -0.04331677552451647, - -0.008943154324947739, - -0.8741092621910937, - 0.26370232932220805, - 0.2684875896184496, - 0.30167858701939854, - -0.03663605553981364, - ], - ], [ [0.9263875479802128], [ @@ -624,35 +244,6 @@ qs = [ ], [-0.8467814852966212, 0.5319408953623024], ], - [ - [0.5053216839247762], - [ - -0.59015897645163, - 0.41560724598915816, - 0.3244409818454344, - 0.2767905184327968, - 0.2788412597376433, - 0.1764703807465072, - 0.301994778424145, - 0.2876603862925981, - 0.11943395810822663, - ], - [ - -0.03534714586479288, - 0.15957987916099206, - -0.28718149774238777, - -0.19635088853199553, - 0.684165557894705, - -0.5666526357569592, - 0.2510512156243137, - 0.007316029468452894, - ], - ], - [ - [0.18066790739255756], - [-0.992558358800348, -0.12176988287569214], - [-0.7201988141976301, -0.6937677334874601], - ], [ [0.05929877942048794], [ @@ -687,50 +278,6 @@ qs = [ -0.13023121083469708, ], ], - [ - [0.4428343667970336], - [ - -0.127255572630727, - 0.22668672002145898, - 0.3495203443639004, - -0.2800785570522293, - 0.3076023585481211, - 0.2954405117453133, - 0.6120999631203197, - 0.09785748462223727, - 0.40179977381828863, - -0.06496817376226975, - ], - [ - 0.08909415980355775, - 0.880431882384782, - -0.3060967538577087, - 0.013454468756813096, - -0.29939494476539896, - -0.16687570624161663, - 0.07443689564200096, - ], - [0.14631014012300886, 0.5274221714215308, 0.8369105065598011], - ], - [ - [0.9747973672469175], - [ - 0.5036745603591766, - 0.08655987562606954, - 0.45670653353901913, - 0.16988849841032172, - 0.7080793497266027, - ], - [ - -0.04773379921570165, - 0.14480351638724792, - 0.46223423790321516, - 0.1869203226531565, - -0.4654696219322667, - -0.7151865207075913, - ], - [-0.6614475098892549, 0.6975530383411345, -0.27551216009888874], - ], [ [0.5944460845919239], [ @@ -762,66 +309,6 @@ qs = [ -0.34832193537003325, ], ], - [ - [0.35664035777449904], - [ - 0.13343426198137742, - -0.25425996956084335, - -0.922195129235849, - 0.08550784318326136, - 0.2445234507695054, - ], - [0.4047997839831198, -0.5275627401918468, -0.1815584055185977, 0.7244661727327466], - [ - -0.48114822474834057, - 0.07687937224998155, - 0.18315655165440772, - 0.4530633997597068, - 0.3699870416956907, - 0.2678528031163627, - -0.09413476091065198, - 0.11453703309553476, - 0.49851411436369913, - 0.21128473391689526, - ], - [ - -0.3768156565668107, - 0.14736306468252625, - -0.06614007558247408, - -0.48760209381974895, - -0.3574364962985913, - 0.5633803923618522, - 0.024688951851943863, - -0.3699931126715858, - -0.003533128694901466, - 0.10718456273036511, - ], - ], - [ - [0.11597881520641286], - [ - 0.004793068006686758, - 0.5431793112729557, - -0.2543049740455072, - 0.24843954495843448, - 0.3105833349418175, - 0.22857210987819054, - 0.244361879116985, - -0.4284169847117112, - 0.3591924409584363, - 0.2399161670796564, - ], - [ - 0.16123153683830393, - 0.11403720071692096, - 0.07121418589008548, - 0.7353846315348165, - 0.6113006204016374, - 0.20359136354078292, - ], - [-0.12820954768918336, -0.7223351856222379, -0.6795544065734709], - [-0.5181411756487838, -0.5982091832712966, 0.13154159318612907, 0.5969692658832942], - ], [ [0.9068920036691095], [ @@ -837,29 +324,6 @@ qs = [ 0.19832899484009994, ], ], - [ - [0.26091111882856616], - [ - -0.2735468559596818, - 0.7908310184653957, - -0.3965289688792057, - -0.20393895097120848, - 0.009693462487979644, - 0.22432025309225306, - 0.14645403468888063, - 0.07594795417367314, - 0.15264889046998872, - ], - ], - [ - [0.7507973403445075], - [ - -0.3623234540901233, - -0.8628926515811954, - 0.04303829727534214, - -0.3496937108828457, - ], - ], [ [1.8900272913460916], [-0.24462417095922365, 0.9696179737311559], @@ -875,24 +339,6 @@ qs = [ -0.25037156781949155, ], ], - [ - [0.0038033069402429436], - [-0.6935787317124584, 0.4529983876547129, -0.5165298785674818, 0.2166515364483497], - [ - -0.4548679332583842, - 0.38597993504553063, - 0.20134736150306345, - 0.16454891197012098, - -0.6254798836839162, - 0.4249626997707289, - -0.06840444087211281, - ], - ], - [ - [0.05069728715399965], - [0.9989195510484316, 0.046472901062876736], - [0.9990218321402392, 0.0442196665202251], - ], [ [1.3388920951283048], [ @@ -927,68 +373,6 @@ qs = [ -0.17468256196490237, ], ], - [ - [1.1931486977771844], - [ - 0.22644039039058186, - -0.11411958485037178, - 0.30437736829730944, - -0.62733810852234, - -0.6264916698299722, - 0.07060731738622097, - 0.2251625848885129, - -0.02341401611326633, - -0.02791368478545802, - ], - [ - 0.6571431019356029, - 0.006127671303832962, - -0.03377055193505131, - -0.2634138473656534, - 0.0015253787707612755, - -0.3506356042585966, - 0.27828523163579455, - 0.4040591774006482, - 0.3659835342176074, - ], - [0.5769596212360408, -0.8167726706147582], - ], - [ - [0.09396735191763278], - [ - 0.08808204191629705, - -0.269420904705849, - -0.6118443181714507, - 0.2480461224526081, - 0.1084861630557538, - 0.2683009932904934, - 0.38655863782557004, - 0.32133983398494953, - 0.33119696155689554, - -0.19401189178526185, - ], - [ - -0.5120308222265519, - 0.7045182787166198, - -0.09497155095499868, - -0.018552062467794783, - -0.10973828476807547, - -0.3071753378516766, - -0.055696702155718036, - -0.19520860631422926, - 0.2906599716297778, - 0.004872010410999308, - ], - [ - -0.071497555279541, - -0.7200146974217542, - 0.13219105850125198, - 0.5589884484433559, - 0.2558843206526261, - -0.11634032369835579, - 0.2598317093251373, - ], - ], [ [0.5595013700016621], [ @@ -1026,85 +410,10 @@ qs = [ -0.17050835599699163, ], ], - [ - [0.0879788405568045], - [ - 0.4752198883185735, - 0.4601150437982469, - 0.004558213453811248, - -0.3747084951936111, - -0.06469017263215665, - 0.006333332718496339, - -0.19475186049495816, - -0.4040009330690733, - 0.3550915844479287, - 0.30095342923066604, - ], - [ - 0.3443393165370433, - 0.3660193874394325, - -0.08495542638537015, - 0.09676362754304287, - 0.5155711330857424, - -0.004321193772576179, - -0.6430158188019451, - 0.16550949028930745, - 0.15551404574943303, - ], - [ - 0.4892943761703814, - 0.06614536658571389, - -0.2830598467537517, - -0.19219480553946047, - -0.5053021840588248, - -0.4208210443148484, - -0.4546794862909613, - ], - [ - -0.045503401271809414, - -0.49376674883678284, - -0.011090272673863474, - 0.6509068904350033, - -0.5051014195999987, - 0.2742145509818364, - ], - ], - [ - [1.4349423523410283], - [ - 0.06370019368643771, - 0.31519275409207537, - -0.717868367412602, - 0.2601814359189934, - 0.03539231049664084, - -0.46547257907453504, - 0.309271891789521, - ], - [0.6968005890360706, -0.7172649016360588], - [ - 0.39039913946740623, - -0.5538051672666193, - -0.10251421913304977, - -0.18753950466778713, - 0.5673704705466129, - 0.37985274492764076, - 0.06722234077506756, - -0.1564989325835006, - ], - [ - -0.7130313109989243, - 0.24441120802232372, - 0.5661277861967524, - -0.06364217193543024, - 0.2700793817903238, - -0.14762085346258608, - 0.0921868105034791, - 0.06375984394161507, - ], - ], ] # vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representation to ps[i] for t in [-1, 1] +# TODO test m = 0 vs = [ [ [0.6940789907123062], @@ -1121,19 +430,6 @@ vs = [ -1.1548635082931478, ], ], - [[0.2389420207891795], [0.0, 0.0]], # m = 0 - [ - [0.46132409636616317], - [ - 0.7034437676859567, - 0.6114140712984324, - -0.08829607209219353, - 0.03327833095019875, - -0.6185892330923073, - 0.1326136814054642, - 0.5700109876145869, - ], - ], [ [0.45470843046349313], [ @@ -1147,35 +443,6 @@ vs = [ ], [-0.5045110500803344, 0.06911945375717096], ], - [ - [-0.19135891857701476], - [ - -0.0069569775655274405, - 0.4648330993586129, - -0.5249300916156493, - -0.6942918549175187, - 0.03839836910376858, - 0.48996587981873707, - 0.19149786106059058, - 0.25496379149224513, - 0.8306443019906313, - ], - [ - -0.14991071399697806, - -0.0899250894563053, - 0.48363972474877626, - -0.06740963522851286, - -0.17392353118572687, - -0.8626165876780832, - -0.4781319504914857, - -0.002601732145143469, - ], - ], - [ - [0.032475437742255364], - [-0.0793840052835045, -0.032660090840698486], - [-0.16688671771785502, -0.08140692187036919], - ], [ [-0.14362437882603868], [ @@ -1210,50 +477,6 @@ vs = [ 0.23241083119724726, ], ], - [ - [0.167542758489263], - [ - -0.7172648711179583, - -0.12978356499468247, - -0.14709754758453525, - 0.7429222145447074, - -0.301380485416464, - 0.10648701938150486, - -0.5862695196566239, - -0.6731434017042006, - -0.1027873036321029, - 0.8518198213004147, - ], - [ - 0.36528861191780526, - -0.05502523773982651, - 0.3349143864166638, - 0.5976408658825734, - 0.22224119027517705, - 0.5079433605241578, - 0.13504430515015828, - ], - [-0.09838274427397142, 0.1575018337179488, -0.22867252665062765], - ], - [ - [0.0005576618010449276], - [ - -0.5529387542450745, - -0.18931262357519596, - -0.4740879804055004, - 0.7218017303773806, - 0.4001673857383268, - ], - [ - 0.04653671285987987, - -0.3342761936754844, - 0.10416238554693465, - -0.3780599114751379, - -0.13425764881025848, - 0.045590813877080076, - ], - [-0.3467728705815678, 1.0951463617116348, 0.5450739839349461], - ], [ [-0.10835780918855986], [ @@ -1285,66 +508,6 @@ vs = [ 0.3909668100967531, ], ], - [ - [-0.13373401585247496], - [ - -0.0462149976885849, - -0.22586363815314267, - -0.24082866649963608, - -0.17798976955515672, - -0.22606766311009552, - ], - [-1.1531492828944132, -1.048323182821658, 0.3469323589434465, -0.19825175056321256], - [ - -0.33544764292008533, - 0.5454762716081148, - -0.44056401394680517, - 0.6346538879978276, - 0.4071906233657455, - 0.20386210363713045, - 0.1131664536677318, - 0.13733952167695518, - 0.3499954521074497, - -0.40947620073175056, - ], - [ - 0.5235561961524053, - -0.33651887371172584, - 0.165664680004435, - 0.3177740663156395, - -0.5050069337944564, - 0.007676908750572816, - -0.15745475915753057, - -0.13379200089703605, - 0.7775600848786371, - 0.6495661761313964, - ], - ], - [ - [0.14255661510910747], - [ - -0.01620371146007782, - -0.2176640728621523, - -0.26783759524037853, - 0.1887922975530844, - -0.03868441552368684, - 0.24619823528128237, - 0.16400437859951833, - 0.8207953853819989, - -0.683215714398723, - 0.2095762101658616, - ], - [ - -0.587587477362466, - 0.9611453504625634, - -0.4956705989932666, - -0.8797827478845143, - 0.2660001180346881, - 0.7021729654279507, - ], - [0.6165274130606305, 0.1402548199881536, -0.22150177598219462], - [0.42439566636895776, 0.04342532989904936, 0.1811774237827697, -0.5227232167013833], - ], [ [-0.25050034943799143], [ @@ -1360,24 +523,6 @@ vs = [ -0.41159169074078095, ], ], - [ - [1.5189255716984038], - [ - 0.14389418968383233, - -0.7434685056546961, - 0.17177099801922532, - -0.0699519450185816, - -0.48084553564682225, - -0.2504085373789058, - 0.5705781638468338, - -0.7229621177887824, - -0.2742605768830553, - ], - ], - [ - [-0.2000130047239455], - [0.28376287916446385, -0.011498145899119377, 0.276592098504903, 0.3464992149574739], - ], [ [0.7638265778356526], [0.043718096583251764, 0.014174547965435269], @@ -1393,29 +538,6 @@ vs = [ 0.039882538236865134, ], ], - [ - [0.13319966661993943], - [ - -0.27617394286645647, - -0.22020251242074337, - -0.2045923981917276, - 0.7425959288733582, - ], - [ - -0.7440711602827321, - -0.42811046699670163, - -0.07153818588627878, - -0.1126683907082826, - -0.31430569035654404, - 1.0115723034951567, - -0.20961404535149197, - ], - ], - [ - [0.4767148797604099], - [0.3384876432473121, -0.04279471058404047], - [-0.27439746807899096, -0.49888606251189316], - ], [ [-0.2827629165886028], [ @@ -1450,68 +572,6 @@ vs = [ 0.28418328300445966, ], ], - [ - [-0.05589178950257751], - [ - -0.1019705158920252, - -0.4021433820745908, - 0.48255194721701017, - 0.008131662295720925, - 0.07202859076099435, - -0.18565046869387167, - 0.3240465427833554, - -0.4904527437336233, - 0.04012334309767329, - ], - [ - -0.47219983715545033, - -0.3425847967691243, - -0.26741555241645554, - 0.5136974943331476, - -1.3528826516837709, - -0.5084770566734448, - 0.5426586250054705, - -0.31969383279201147, - 0.6862705068300334, - ], - [0.09849573584104232, 0.029230981468574946], - ], - [ - [-0.05719286771089035], - [ - 0.4242973237170861, - -0.5219356456168175, - 0.3310684379655346, - 0.12413567167651018, - -0.5923469397738462, - -0.37146828706242285, - -0.5751410323943549, - -0.055651487469272024, - 0.5472629066920902, - 0.29283912917169935, - ], - [ - 0.1875320328414897, - 0.6808265997858123, - -0.2995863467195515, - -0.13554874838930378, - 0.6373044353809255, - 0.8178243633205413, - -0.9612380226211692, - 0.07781549715708687, - -0.3845106658570097, - -0.6707841245616247, - ], - [ - -0.2707020905807271, - -0.5625117726096117, - 0.10488366055899745, - -0.28409682013973964, - -0.25019752929639916, - -0.8986902851125926, - -0.8128844484365579, - ], - ], [ [-0.13762858893746074], [ @@ -1549,82 +609,6 @@ vs = [ -0.8637091370051597, ], ], - [ - [0.08588821780925351], - [ - -0.19846651453049668, - -0.12131137905689643, - -0.012056169732668959, - 0.387028828005472, - -0.1673202197809444, - 0.15365077102586527, - -0.5066602440919681, - -0.5263849388489793, - -1.0529289245626894, - -0.2368951143092367, - ], - [ - -0.5124015057222998, - 0.10937701513453171, - 1.100622688156337, - -0.3529295809332267, - -0.14952258183921502, - 0.28769664553265084, - -0.29663286648941295, - 0.8048977491005426, - 0.26266525195090656, - ], - [ - 0.5229761285972861, - 0.058988804914361245, - 0.16088566715699476, - 0.0876297447684608, - -0.12424872326482747, - -0.18192414077364386, - 0.0034228886467715103, - ], - [ - -0.4422179502033592, - 0.06409501421449978, - -0.03443123742857476, - -0.40737856180759047, - -0.49232052745173593, - -0.3063601971060485, - ], - ], - [ - [0.0020120000622140064], - [ - -0.4605158014626578, - 0.04861856501815409, - 0.12440850145559806, - 0.41986549071776175, - 0.45760378449565353, - 0.3823068642538414, - -0.7509927996480504, - ], - [0.7945555246182702, -0.05349582066856984], - [ - -0.2002746258874713, - 0.06644197619406682, - 0.3105130297384215, - -0.019792549607544785, - -0.0029621125749771035, - 0.5952370789475336, - -0.15048879670202958, - 0.10947909205995154, - ], - [ - 0.47460069009979067, - 0.34348555903411404, - 0.8553181291195778, - 0.36336966197832254, - -0.4154570058919746, - 0.7084181186043732, - -0.8911752856098722, - -0.12208726470275424, - ], - ], ] # us[i] is a tangent vector to Ms[i] at ps[i] @@ -1644,19 +628,6 @@ us = [ -0.33394550809020124, ], ], - [[1.3683817863110515], [1.309120423677036, 0.34003444822705764]], - [ - [-0.12929062734170355], - [ - 0.15850990687718194, - 0.17487391887026144, - 1.0186159795799787, - -0.34163759242980707, - 0.14845978504467341, - -0.13138435258479628, - 0.07372358714600029, - ], - ], [ [-0.2603225446842325], [ @@ -1670,35 +641,6 @@ us = [ ], [1.3205385203894777, -0.18091754616690692], ], - [ - [-0.3096239639876968], - [ - 0.8763931296077601, - 0.9630409930052396, - -0.024742767752841448, - -0.5119584268098544, - -0.65137269579901, - -0.5585309447674137, - 0.36820697176827755, - 0.788214538036487, - 0.2908132604789067, - ], - [ - 0.2655385329237167, - -0.33415351180043346, - -0.5131255776726478, - 0.27265294689102404, - -0.0733048224201999, - -0.5967809983817592, - 0.11338960014259027, - 0.23310946516775605, - ], - ], - [ - [-0.5123951975200387], - [-0.7694459734927109, -0.31656471982654616], - [-1.1392866599419809, -0.5557411721084375], - ], [ [-0.14766117733667908], [ @@ -1733,50 +675,6 @@ us = [ 0.3462072647694016, ], ], - [ - [-0.0360207524796129], - [ - 0.20350245773360448, - 0.37364752980981, - -0.13027127184216153, - -0.08190812987077147, - 0.4553806555417341, - -0.5133558357167839, - -0.01992655851146799, - 0.7876406853642887, - 0.14590589840824297, - 0.5882183495667237, - ], - [ - 0.1421766874190634, - 0.16985174267090664, - 0.2674424928046712, - 0.19679295366232205, - 0.020504602587278625, - -0.7983181858070574, - 0.41087597326194303, - ], - [0.08272242498791532, 0.043641892904065484, -0.1652205757255303], - ], - [ - [0.07334723852895442], - [ - -0.335402461448991, - -0.04149991778158621, - 0.8259416067042924, - -0.36669745774013474, - -0.0293979473512328, - ], - [ - 0.25357991790389556, - -0.6762696649693698, - -0.1500007754391727, - -0.21823190285300317, - -0.1554963524472741, - 0.2760192231713663, - ], - [-0.6373006596520467, -0.671494722883091, 0.3231820209261418], - ], [ [-0.8237610837914967], [ @@ -1808,71 +706,6 @@ us = [ -0.3979129485173604, ], ], - [ - [-0.17314190690191722], - [ - -1.1339790699243253, - -0.6846816962035396, - 0.2090090635616599, - 0.6968343188160526, - -0.8282658301524312, - ], - [0.26096836011459945, 0.5854265047018472, 0.7062605498807286, 0.34245153599846784], - [ - -0.4642499534514001, - 0.3677311750533016, - -0.5795938822926545, - -0.2327468766014096, - 0.008116599138855707, - 0.25047446112097677, - 0.1664040210464276, - -0.13265399018639917, - -0.38415949773048125, - -0.10878478149940779, - ], - [ - 0.36290342984947627, - -0.5552686774454564, - -0.03722341001087248, - -0.08247270899765498, - 0.42071065664777474, - 0.029450006187029542, - -0.6467198752580883, - 0.3282922917661867, - 0.13054924199752604, - 0.6409942919440069, - ], - ], - [ - [0.15795465249466936], - [ - 0.5351607860771331, - -0.41785689120228914, - -0.030904801558696852, - 0.20801945515978773, - 0.39257256533026225, - -0.08950160299890557, - 0.6172225568521781, - 0.8206592397973528, - 0.5312616693613874, - 0.34916321649313975, - ], - [ - -0.48125632002442126, - -0.3885025059033661, - -0.39789961820933506, - -0.8112377504395194, - -0.13593743657921403, - 0.45648408250913297, - ], - [-0.6908584605178826, -0.25115275205263854, 0.217617378343041], - [ - -0.05159880494311214, - -0.08968056529390697, - -0.31839202789900106, - 0.12849987939389101, - ], - ], [ [-0.11566741406383592], [ @@ -1888,29 +721,6 @@ us = [ -0.4702399492568731, ], ], - [ - [0.996024398644524], - [ - -0.7416787110144638, - 0.14070197751838798, - -0.13795012958209601, - -0.4757150483429905, - -0.1360189820310271, - 0.3238908388104348, - 0.5189337739664109, - 0.6803924956106052, - -0.5549192083475457, - ], - ], - [ - [-0.5889817889278641], - [ - 0.08753868748426015, - 0.07610237172143071, - -0.1871044108743123, - -0.21019436123666874, - ], - ], [ [-0.44426957903450753], [0.02248238255936011, 0.0072893752214958085], @@ -1926,24 +736,6 @@ us = [ 0.6543369295727094, ], ], - [ - [-0.8389592975128012], - [-0.3425282245979182, 0.7830546276591328, -0.3052977538552278, 0.5882182554997865], - [ - 0.03745255029472473, - -0.18373865390118915, - 0.31498165370594844, - 0.46034942779621935, - 0.11932816285894, - 0.030905964762235363, - 0.31751727602532254, - ], - ], - [ - [-0.4656394904731537], - [-0.49930548339416325, 0.06312677606155825], - [0.1221872729023376, 0.22215047352319392], - ], [ [0.26115469823295706], [ @@ -1978,68 +770,6 @@ us = [ 0.2491580414140638, ], ], - [ - [0.9549180463751705], - [ - 0.3895017091001908, - 0.49171007245983317, - -0.7574299513534506, - -0.34411683885229793, - 0.0513658453673059, - 0.06981342473422567, - -0.1439873053399203, - -0.18295666103878877, - -0.11403644383556799, - ], - [ - -0.15850209669311577, - 0.2414976982465587, - -0.09000199478941477, - -0.47413124486427444, - 0.09572564708049942, - -0.36176114242096513, - -0.1257338263899131, - -0.06322697714974733, - 0.19138488813360416, - ], - [-0.19020791605007967, -0.056448779449793374], - ], - [ - [-0.5581377638463701], - [ - -0.25985100085298074, - -0.12823304129983562, - 0.6940528086313831, - 0.3949636485406578, - 0.6535818467393291, - 0.5759145253409661, - 0.2526448903910712, - -0.5437798878532403, - -0.36348766005250244, - -0.17477846468203878, - ], - [ - 0.11703814560342424, - 0.5421400308047751, - 0.5209685317484212, - 0.004412884829451791, - -0.10761650749037417, - 0.4539634764966858, - 0.15393382881531487, - 0.37298468621560743, - 0.20920463087073315, - -1.1982965330635182, - ], - [ - -0.2361677344675108, - -0.08561184124338428, - 0.33089548131311, - 0.09448935004937808, - -0.5233825679847084, - -0.09673390251592129, - -0.4195453536456808, - ], - ], [ [0.1798820030601053], [ @@ -2077,82 +807,6 @@ us = [ -0.5591798774189761, ], ], - [ - [0.02775921877564232], - [ - -0.32610417589316576, - -0.9533681500385859, - -0.7953634329826215, - -1.0380444511104359, - 1.8624955384484987, - 0.44685665513406264, - -0.8501002862266008, - -1.070462937138491, - -0.02354710201871483, - 0.28743720819281715, - ], - [ - 0.2653138406460859, - -0.2282890286319614, - 0.02811495791663485, - 0.03337784871438022, - 0.1768829048441087, - -0.2345694568284544, - -0.46257070907000497, - -0.2368037688836088, - 0.12834132594241648, - ], - [ - -0.5490049782150824, - -0.15079368647293154, - 0.4956415766510821, - -0.04311702187664941, - -0.13959940872666987, - 0.1745102984539435, - -0.031814296573279166, - ], - [ - 1.060646643382475, - -0.07879165090994764, - -0.13387349603704785, - -0.2653272097959495, - -0.9301322737127853, - -0.6249913037816839, - ], - ], - [ - [0.16969505385956252], - [ - 0.0930186150799604, - 0.1546667070131112, - 0.5068773816789583, - 0.21700722366006517, - -0.408452920217741, - 0.26880615167829464, - 0.06987247642683876, - ], - [-0.0984469609988096, 0.006628235293547613], - [ - 0.016225795251541872, - -0.7366173566083619, - 1.1134825891599547, - -0.7078026064080831, - -0.024735556978746676, - -0.65431320330066, - 0.7988331267058175, - -0.913679346443505, - ], - [ - -0.41346861893716785, - -0.30448423297022137, - 0.7646027070405849, - -0.3087443669597033, - 0.3795212472780163, - -0.002675858285340116, - 0.4202373636203284, - -0.023732041788181002, - ], - ], ] # When testing that exp(Ms[i], ps[i], t * vs[i]) is an extremum of the length functional, we parametrize curves in Ms[i] and take a derivative along dys[i] @@ -2199,46 +853,6 @@ dys = [ 0.17060958026859915, 0.01433037040599356, ], - [ - 0.49490048799897596, - 0.3065322528949179, - 0.20904131890947963, - 0.32404623250194, - 0.27552152748971576, - 0.2781507442742417, - 0.3957357855481444, - 0.45002276663457547, - ], - [ - 0.2774747194904695, - 0.17186273392192533, - 0.11720271596589263, - 0.18168225662692275, - 0.15447602176127323, - 0.15595013869479196, - 0.2218762736147053, - 0.2523132305670958, - 0.10298766925985375, - 0.17769114622380935, - 0.08725724171457977, - 0.22776978268478074, - 0.1277837823108223, - 0.023380526861408162, - 0.30467244314999586, - 0.16995628493998063, - 0.07866841899027918, - 0.05426646003407173, - 0.2862958470725858, - 0.07485058652127569, - 0.17461572368939868, - 0.02088993591975766, - 0.22173924979601844, - 0.2661077821279658, - 0.17616832761102516, - 0.24286311298519137, - 0.32029952947731805, - 0.07192152273314319, - ], [ 0.2703013619564934, 0.1674196883015804, @@ -2273,86 +887,6 @@ dys = [ 0.12965662340215453, 0.20868317404203518, ], - [ - 0.19457563274485226, - 0.1205165654713542, - 0.08218692016467483, - 0.12740238140112917, - 0.10832435377645168, - 0.10935805960596295, - 0.15558792674492308, - 0.17693145731489499, - 0.07221879869975649, - 0.12460366577951727, - 0.061188035614062594, - 0.15972067533731096, - 0.08960675892678109, - 0.016395298340405255, - 0.21364769199403277, - 0.11917969226849504, - 0.0551652324585789, - 0.03805366779842952, - 0.2007613367396708, - 0.052488025793646274, - 0.12244706467838061, - 0.014648802986629832, - 0.15549184052751536, - 0.1866047118849567, - 0.167671170717676, - 0.06298014699696033, - 0.11507214190657873, - 0.02038660414496235, - 0.11389752539236134, - 0.18361677546291374, - 0.09333293534087271, - 0.15021996314975533, - 0.11924555321621164, - 0.0387735596171921, - 0.12259882692942942, - 0.03465512481835747, - 0.18796579590043078, - 0.11660922488526533, - 0.13402938722767327, - 0.011257813079646883, - 0.09066268061997902, - 0.07657067329789471, - 0.17155609506972255, - 0.02437048731808387, - 0.2215711733203188, - 0.2103628283958812, - 0.13577361182582945, - 0.05424502888292601, - 0.028934213909226063, - 0.0924565622310047, - 0.1986597950667768, - 0.0790211436628239, - 0.07639807345045613, - 0.12722079565692512, - 0.1446707992261107, - 0.06036826781167918, - 0.0585884798528245, - 0.15137516172871096, - 0.22086742806031712, - 0.08175559977855866, - 0.10596354820935999, - 0.010750489568562414, - 0.05896893496182565, - 0.16027814898868079, - ], - [ - 0.387733284839387, - 0.24015485982792192, - 0.1637748986177967, - 0.253876310924278, - 0.2158592878529835, - 0.21791916632378672, - 0.3100419978963423, - 0.35257351688061767, - 0.2461713430135757, - 0.3393682593390343, - 0.44757514819657734, - 0.1005005728492324, - ], [ 0.16353440643700792, 0.10129020125571776, @@ -2447,130 +981,6 @@ dys = [ 0.18877393058117947, 0.04238816261102419, ], - [ - 0.18931478384099465, - 0.11725809249396936, - 0.07996478698818024, - 0.12395773281339016, - 0.10539552836400544, - 0.10640128531778455, - 0.15138120999255955, - 0.17214766373220333, - 0.07026617913163342, - 0.12123468761259337, - 0.05953366088302137, - 0.15540221917752278, - 0.08718401146951676, - 0.015952009599231567, - 0.2078711812851488, - 0.11595736507064407, - 0.05367369958461762, - 0.03702478975393335, - 0.19533324153872214, - 0.051068878035693224, - 0.11913639572715305, - 0.014252735205439095, - 0.15128772171130855, - 0.18155937717307144, - 0.16313775262089256, - 0.061277317960149645, - 0.11196087281767074, - 0.01983540026317905, - 0.11081801505923433, - 0.17865222723918714, - 0.09080944119283771, - 0.14615838299541906, - 0.1160214452995229, - 0.03772521745978412, - 0.11928405469835733, - 0.0337181350584281, - 0.18288366080789226, - 0.11345639683447971, - 0.13040556062135805, - 0.010953429366412056, - 0.08821138362439966, - 0.0745003896914418, - 0.16691763812644678, - 0.02371156898547879, - 0.21558043106834748, - 0.2046751323592965, - 0.13210262565520578, - 0.052778376061538665, - 0.028151903578888155, - 0.08995676306701976, - 0.19328852040933758, - 0.07688460533499909, - 0.07433245652145608, - 0.12378105670329538, - 0.1407592548832129, - 0.058736057595709795, - 0.05700439074739889, - 0.14728234783203958, - 0.2148957133578259, - 0.07954512844968857, - 0.1030985532015983, - 0.010459822641440727, - 0.05737455928138075, - 0.1559446201057239, - 0.13895900193366503, - 0.03156699173602045, - 0.04890539260876352, - 0.04995541568895709, - 0.06255157417661084, - 0.002693013244577135, - 0.012411591625591608, - 0.15516673744807902, - ], - [ - 0.2208827351133444, - 0.13681070045747248, - 0.09329879317581574, - 0.14462749557513332, - 0.12297007186353966, - 0.12414353725437031, - 0.17662379572008607, - 0.20085302392695362, - 0.08198295726125182, - 0.14145038674302837, - 0.06946080797470483, - 0.18131530204975832, - 0.1017218123213999, - 0.018611982853869447, - 0.24253338351044798, - 0.13529307872148416, - 0.06262370707329344, - 0.04319861693798904, - 0.22790476144676877, - 0.059584535506577115, - 0.1390022078881141, - 0.016629357048352854, - 0.17651471841061875, - 0.21183412621988404, - 0.19034072388880155, - 0.07149521720826639, - 0.13063017748479328, - 0.023142922984180615, - 0.12929674993937262, - 0.20844221347143077, - 0.1059517769179363, - 0.17053007029227615, - 0.13536784423072898, - 0.04401583989479429, - 0.13917448876740884, - 0.039340582618640645, - 0.21337923212968313, - 0.13237507784892918, - 0.15215048882937396, - 0.012779896996084542, - 0.10292049721512919, - 0.08692321596963569, - 0.19475089953352745, - 0.027665436925096435, - 0.2515281389291008, - 0.23880439830403508, - 0.15413053686754696, - 0.06157908971918815, - ], [ 0.1715795373556408, 0.1062732072642473, @@ -2657,194 +1067,6 @@ dys = [ 0.198060728501197, 0.04447346273248423, ], - [ - 0.15352324557245492, - 0.09508947248635916, - 0.0648467773137381, - 0.10052248994615477, - 0.08546962500750059, - 0.08628523522382116, - 0.12276133012550565, - 0.1396017126485001, - 0.05698177213314873, - 0.09831425914354645, - 0.04827832594018572, - 0.1260221339994952, - 0.07070114721768485, - 0.012936149187027587, - 0.1685714013686324, - 0.09403465842703182, - 0.04352623918178691, - 0.030024944562363123, - 0.15840386366444553, - 0.04141388086399268, - 0.09661266683324013, - 0.011558136784825031, - 0.12268551658326957, - 0.14723406319463364, - 0.13229520035155487, - 0.04969233010940552, - 0.09079373635463328, - 0.01608535246877302, - 0.08986694538383312, - 0.14487653419367338, - 0.07364115922533956, - 0.11852592211670533, - 0.09408662375438188, - 0.03059295057071266, - 0.09673240964485387, - 0.027343440505776938, - 0.1483079799672769, - 0.09200651908735905, - 0.10575130214923645, - 0.008882592222129873, - 0.07153428610112707, - 0.06041546988453471, - 0.1353604669880599, - 0.019228699177151067, - 0.1748231532056124, - 0.16597959213878738, - 0.107127522889412, - 0.04280018403537061, - 0.022829551495057773, - 0.0729496870082825, - 0.1567457141121245, - 0.06234892968263987, - 0.0602792858804522, - 0.10037921592768378, - 0.11414754418852645, - 0.04763151620423726, - 0.04622723541111018, - 0.11943739203007579, - 0.17426788708699534, - 0.06450645872078792, - 0.0836069121502298, - 0.008482305963885847, - 0.046527420497518554, - 0.12646198951003412, - 0.1126876440684275, - 0.025598988763302813, - 0.039659420394756825, - 0.04051092785723106, - 0.05072567756422609, - 0.0021838766380988884, - 0.010065076749004063, - 0.1258311720542961, - 0.10314713890387746, - 0.012484783484285916, - 0.13463000333533406, - 0.16733958106731892, - 0.10202761886684918, - 0.0015439108936574257, - 0.06631520930151812, - 0.1034292817038221, - 0.11038256588952834, - 0.057104008819336624, - 0.13955216270266796, - 0.1098610568880544, - 0.08770166753227544, - 0.14775058882543593, - 0.03005532430797646, - 0.057401379369977516, - 0.02755102955172378, - 0.05922224994122391, - 0.17215444540682492, - 0.11921375673164347, - 0.014339320851720466, - 0.07226503986645506, - 0.0717760634504068, - 0.17528349052139683, - 0.14331799583358729, - 0.055100951418902915, - 0.14579838397697775, - 0.0716513592338211, - 0.1554316797606585, - 0.029621643272853243, - 0.09658002282375533, - 0.07404757373098435, - ], - [ - 0.17846031137802032, - 0.11053503204293935, - 0.07537995974563472, - 0.11685054461552731, - 0.09935261487813324, - 0.1003007061761313, - 0.1427016808932576, - 0.16227747801487458, - 0.06623742717159986, - 0.11428362678390792, - 0.056120264054923916, - 0.14649214319442222, - 0.08218526582214918, - 0.015037391916391805, - 0.19595276705818235, - 0.10930888257761537, - 0.050596287021758744, - 0.03490195205115243, - 0.1841336973279205, - 0.048140814420656146, - 0.11230564167550687, - 0.013435546401317802, - 0.14261355281660268, - 0.17114956543023846, - 0.15378415536045742, - 0.057763947546553146, - 0.1055415315159862, - 0.018698126133919378, - 0.10446420016714315, - 0.16840909861672573, - 0.08560282943855643, - 0.13777830769824043, - 0.10936928872956436, - 0.03556222032998324, - 0.11244483453432241, - 0.031784886312244846, - 0.17239792049806787, - 0.10695130879960922, - 0.12292868249243113, - 0.0103254081679582, - 0.0831537330012127, - 0.07022886682365666, - 0.15734731894762363, - 0.02235205248399433, - 0.20322000255288147, - 0.19293996544324854, - 0.12452844532248876, - 0.04975229738993509, - 0.026537797929146605, - 0.0847990401055136, - 0.18220621146533902, - 0.0724763820863788, - 0.07007056219895538, - 0.11668399833223729, - 0.13268874171440578, - 0.055368391812715356, - 0.05373601108320975, - 0.13883782936185077, - 0.20257454352772494, - 0.07498436257180507, - 0.09718733811319212, - 0.009860102669626628, - 0.0540849557905192, - 0.1470034452521622, - 0.1309917073073869, - 0.029757080034537288, - 0.046101373680117005, - 0.04709119308060735, - 0.058965143546946014, - 0.0025386077749533845, - 0.011699965851902326, - 0.14627016294592948, - 0.11990152017630731, - 0.014512710044560078, - 0.15649820472762588, - 0.1945208598983612, - 0.11860015442119298, - 0.0017946912064986773, - 0.07708691186744215, - 0.12022949195506588, - ], [ 0.24768051036976024, 0.15340874919881428, @@ -2887,62 +1109,6 @@ dys = [ 0.17060958026859915, 0.01433037040599356, ], - [ - 0.24802588780879425, - 0.153622669627372, - 0.10476380599437246, - 0.16240003082711635, - 0.1380812367802985, - 0.1393989033476937, - 0.19832819309827035, - 0.22553482757717827, - 0.0920574247212134, - 0.15883250329562493, - 0.07799649237864552, - 0.2035962147115505, - 0.11422188700075789, - 0.020899114495500196, - 0.2723370739572822, - 0.1519185550969481, - 0.07031921502040975, - 0.04850707463695044, - 0.25591081514216235, - 0.06690657516129511, - 0.15608348022827995, - 0.018672853917218492, - 0.19820571183459643, - 0.23786534152126568, - 0.21373072460581133, - 0.08028089978632086, - 0.14668265371062417, - 0.025986838748155147, - 0.14518536805535576, - 0.23405661391576318, - 0.11897165037143213, - 0.19148564083396585, - 0.1574713038353601, - 0.21708766594943277, - 0.28630563284911986, - 0.06428837755455744, - ], - [ - 0.37258942960245, - 0.23077503463910054, - 0.15737827636974977, - 0.24396056148760667, - 0.20742838461456795, - 0.20940780958141045, - 0.29793256257804646, - 0.33880291087698405, - 0.13829049729675522, - 0.23860135056090637, - 0.1171678846232154, - 0.3058462895900371, - 0.17158639407244533, - 0.03139506612744243, - 0.40911017773906017, - 0.2282150798437472, - ], [ 0.24768051036976024, 0.15340874919881428, @@ -2985,62 +1151,6 @@ dys = [ 0.17060958026859915, 0.01433037040599356, ], - [ - 0.24768051036976024, - 0.15340874919881428, - 0.10461792180729243, - 0.1621738878738882, - 0.13788895788409475, - 0.13920478959340893, - 0.1980520199776914, - 0.225220769065586, - 0.09192923424127934, - 0.15861132814448145, - 0.07788788182581427, - 0.2033127058413462, - 0.11406283238286104, - 0.020870012361419343, - 0.2719578430552649, - 0.15170700765742606, - 0.07022129511933332, - 0.04843952826362164, - 0.2555544578976192, - 0.06681340738035137, - 0.15586613310716685, - 0.018646851863471762, - 0.1979297092698637, - 0.23753411269988997, - 0.21343310337377225, - 0.08016910818336964, - 0.1464783972931314, - 0.025950651929534232, - 0.1449831966165307, - 0.23373068876892722, - 0.11880598168141776, - 0.19121899600576953, - 0.15179084381364852, - 0.04935589775227154, - 0.1560593153225572, - 0.04411343229804097, - 0.2392666728301238, - 0.1484349911958273, - 0.17060958026859915, - 0.01433037040599356, - ], - [ - 0.387733284839387, - 0.24015485982792192, - 0.1637748986177967, - 0.253876310924278, - 0.2158592878529835, - 0.21791916632378672, - 0.3100419978963423, - 0.35257351688061767, - 0.2461713430135757, - 0.3393682593390343, - 0.44757514819657734, - 0.1005005728492324, - ], [ 0.16353440643700792, 0.10129020125571776, @@ -3135,182 +1245,6 @@ dys = [ 0.18877393058117947, 0.04238816261102419, ], - [ - 0.18931478384099465, - 0.11725809249396936, - 0.07996478698818024, - 0.12395773281339016, - 0.10539552836400544, - 0.10640128531778455, - 0.15138120999255955, - 0.17214766373220333, - 0.07026617913163342, - 0.12123468761259337, - 0.05953366088302137, - 0.15540221917752278, - 0.08718401146951676, - 0.015952009599231567, - 0.2078711812851488, - 0.11595736507064407, - 0.05367369958461762, - 0.03702478975393335, - 0.19533324153872214, - 0.051068878035693224, - 0.11913639572715305, - 0.014252735205439095, - 0.15128772171130855, - 0.18155937717307144, - 0.16313775262089256, - 0.061277317960149645, - 0.11196087281767074, - 0.01983540026317905, - 0.11081801505923433, - 0.17865222723918714, - 0.09080944119283771, - 0.14615838299541906, - 0.1160214452995229, - 0.03772521745978412, - 0.11928405469835733, - 0.0337181350584281, - 0.18288366080789226, - 0.11345639683447971, - 0.13040556062135805, - 0.010953429366412056, - 0.08821138362439966, - 0.0745003896914418, - 0.16691763812644678, - 0.02371156898547879, - 0.21558043106834748, - 0.2046751323592965, - 0.13210262565520578, - 0.052778376061538665, - 0.028151903578888155, - 0.08995676306701976, - 0.19328852040933758, - 0.07688460533499909, - 0.07433245652145608, - 0.12378105670329538, - 0.1407592548832129, - 0.058736057595709795, - 0.05700439074739889, - 0.14728234783203958, - 0.2148957133578259, - 0.07954512844968857, - 0.1030985532015983, - 0.010459822641440727, - 0.05737455928138075, - 0.1559446201057239, - 0.13895900193366503, - 0.03156699173602045, - 0.04890539260876352, - 0.04995541568895709, - 0.06255157417661084, - 0.002693013244577135, - 0.012411591625591608, - 0.15516673744807902, - ], - [ - 0.15582045376539008, - 0.09651232095756643, - 0.06581709648315832, - 0.10202663406854806, - 0.08674852920264194, - 0.08757634360644034, - 0.12459823978884935, - 0.1416906093289221, - 0.05783440518753825, - 0.09978536093497073, - 0.04900072706893626, - 0.12790783591802443, - 0.07175906684433664, - 0.013129716146784482, - 0.17109377902469772, - 0.09544172344153798, - 0.04417753360227171, - 0.03047421560521984, - 0.1607741018133701, - 0.042033567518396465, - 0.09805830725702788, - 0.011731084187142908, - 0.12452129182889228, - 0.14943716471837143, - 0.13427476779100272, - 0.0504358893497519, - 0.09215230661051434, - 0.016326041775071437, - 0.09121164782573381, - 0.147044359398728, - 0.07474307101517241, - 0.12029945627009313, - 0.09549446633957638, - 0.031050720834981428, - 0.09817984181142858, - 0.027752587507058002, - 0.15052715078657608, - 0.09338323652622518, - 0.10733368634652816, - 0.009015504756326845, - 0.07260467220125497, - 0.06131948225009717, - 0.13738590080822852, - 0.019516423196562774, - 0.17743907744797185, - 0.168463187880263, - 0.10873049983503855, - 0.04344061430414566, - 0.02317115600283071, - 0.07404125211975868, - 0.15909114093868224, - 0.06328187290927392, - 0.061181260489395074, - 0.10188121620373095, - 0.11585556353592591, - 0.04834423895093465, - 0.04691894553961334, - 0.12122456474448282, - 0.17687550273822134, - 0.06547168561472232, - 0.08485794408914797, - 0.00860922891084781, - 0.04722362237342663, - 0.12835427310079645, - 0.11437381855119912, - 0.02598203308013339, - 0.04025285460153236, - 0.04111710339130102, - 0.05148469905089557, - 0.0022165545513796675, - 0.01021568310626363, - 0.12771401655964718, - 0.10469055633023704, - 0.012671596541814639, - 0.13664450703816816, - 0.16984352667631633, - 0.10355428462415937, - 0.0015670128333073261, - 0.067307501000118, - 0.10497692090616872, - 0.11203424888888858, - 0.057958470933006, - 0.14164031795438256, - 0.11150493641279158, - 0.0890139703593684, - 0.14996141925632728, - 0.030505049930856305, - 0.05826029111642219, - 0.027963282761809472, - 0.06010840784689968, - 0.17473043708133734, - 0.12099758313300277, - 0.014553883833494794, - 0.07334636042494769, - 0.07285006732780068, - 0.17790630291056034, - 0.0989301973089577, - 0.13638374168904252, - 0.17986942419707855, - 0.040388703981232836, - ], [ 0.1490765359911958, 0.09233526241995971, @@ -3421,214 +1355,6 @@ dys = [ 0.1720846656652933, 0.03864067866059161, ], - [ - 0.14423132094112415, - 0.08933422540125728, - 0.060921955602620925, - 0.09443841194968906, - 0.08029661481691686, - 0.08106286059575217, - 0.1153312564391741, - 0.13115238246727773, - 0.053532976284372855, - 0.09236383331232718, - 0.04535630221478635, - 0.11839470164137629, - 0.06642199243011034, - 0.01215319463954323, - 0.15836869395012684, - 0.08834325348324733, - 0.04089183334666819, - 0.028207698445053192, - 0.1488165418423116, - 0.0389073245555702, - 0.09076522910288898, - 0.010858585811402444, - 0.11526003147710948, - 0.13832278846703247, - 0.12428809350483766, - 0.0466847244246111, - 0.08529848674563507, - 0.015111793824602163, - 0.08442778937693121, - 0.1361079478368881, - 0.06918406154782372, - 0.11135219457426855, - 0.08839207363278813, - 0.028741326148019417, - 0.0908777245352768, - 0.02568849120221335, - 0.1393317069153209, - 0.08643786635491431, - 0.09935075267171747, - 0.008344977366795651, - 0.06720470596146004, - 0.056758851040656824, - 0.12716783627194342, - 0.018064890902733784, - 0.16424206134984198, - 0.15593375279542385, - 0.10064367827736079, - 0.04020972235785182, - 0.021447803271404914, - 0.06853444037229196, - 0.14725875103768507, - 0.058575289063624865, - 0.056630909511498614, - 0.09430380952603941, - 0.10723881597934645, - 0.04474864034400212, - 0.04342935300735328, - 0.11220849818557717, - 0.163720402460575, - 0.060602234637766365, - 0.07854664180835778, - 0.007968918252321884, - 0.0437113695279008, - 0.11880793509714194, - 0.10586727565020065, - 0.024049621608251144, - 0.03725905200848255, - 0.038059022368970546, - 0.047655528994591224, - 0.002051698497585555, - 0.009455892555355895, - 0.11821529758108007, - 0.09690420522267214, - 0.011729147640724243, - 0.12648158359965736, - 0.15721142901244226, - 0.0958524436268398, - 0.001450466388834312, - 0.06230151141203584, - 0.09716927145794031, - 0.10370171127996149, - 0.05364781465071019, - 0.13110583150938676, - 0.10321176637367188, - 0.08239356398278831, - 0.1388080516188944, - 0.02823623947037694, - 0.05392718698398778, - 0.02588351601554489, - 0.05563785019185841, - 0.16173487587711605, - 0.1119983983118956, - 0.01347143997725202, - 0.06789123118741493, - 0.06743184984661066, - 0.16467453695890372, - 0.1346437393023796, - 0.05176599138864854, - 0.1369740030812226, - 0.06731469329603086, - 0.14602424801785077, - 0.027828806782710006, - 0.09073456085723504, - 0.06956587800031083, - 0.049289988943616116, - 0.15151295985733645, - 0.12735852037121487, - 0.003333862247204956, - 0.05712354925607144, - 0.08951490067034465, - 0.08782182415229184, - 0.0578016188069583, - 0.09157227240732324, - 0.12624021265090699, - 0.16649165126886764, - 0.03738479760227176, - ], - [ - 0.1694589116999309, - 0.10495973076633594, - 0.07157785304667531, - 0.11095669378356957, - 0.09434134604936262, - 0.09524161635770365, - 0.1355039187996205, - 0.1540923278989471, - 0.06289646272400928, - 0.10851924929627423, - 0.053289601467273046, - 0.13910319312249428, - 0.07803990476341967, - 0.014278917532309872, - 0.18606906148410648, - 0.10379542732894517, - 0.04804424955083078, - 0.0331415246623844, - 0.17484613646324135, - 0.04571262908307061, - 0.10664103222246049, - 0.012757867862499155, - 0.13542023583479298, - 0.16251691410696706, - 0.1460274018511314, - 0.05485037883855437, - 0.10021809853261156, - 0.017755007155458, - 0.09919510694134144, - 0.15991467431380685, - 0.08128508912194579, - 0.13082887672960547, - 0.10385278664144561, - 0.03376848952138687, - 0.10677320430144628, - 0.030181681301506596, - 0.1637023031134973, - 0.10155676774358248, - 0.11672825510064294, - 0.009804602589163004, - 0.07895952320919036, - 0.06668657725609006, - 0.14941084223083015, - 0.021224632294707106, - 0.19296974325749094, - 0.18320822324566463, - 0.118247327134454, - 0.047242830101371744, - 0.02519925198639844, - 0.08052184229937957, - 0.17301587149245923, - 0.06882072959230966, - 0.06653625739386522, - 0.11079854796562234, - 0.12599602450612882, - 0.052575653077750396, - 0.0510256083660385, - 0.13183495694235145, - 0.19235684068489467, - 0.07120220948743744, - 0.0922852841648866, - 0.009362766739239825, - 0.05135695257298015, - 0.13958870550104785, - 0.12438458719824694, - 0.028256155999520978, - 0.043776056151534036, - 0.044715949829245226, - 0.05599098744442927, - 0.0024105623679280823, - 0.011109828649743763, - 0.13889240938555025, - 0.11385378050363983, - 0.013780700207108917, - 0.14860455667344946, - 0.1847093786107272, - 0.11261805462777208, - 0.0017041683741461791, - 0.07319870782750477, - 0.11416520964027846, - 0.12184024260650132, - 0.06303138754099037, - 0.15403763468383044, - 0.12126460112952524, - 0.09680507390833237, - 0.16308705494091372, - 0.03317505781633879, - 0.06335962506420917, - ], ] # Xs are tangent vectors in a chart @@ -3645,16 +1371,6 @@ Xs = [ -0.858313200235999, 0.6327050201672981, ], - [-0.5103976757921316, -0.7856231887301031], - [ - 0.06161321757315563, - -0.2461307077230097, - 0.04558383266520161, - 0.6251649963255619, - 0.5702228612959974, - -0.6849942773520477, - 0.47667344530694655, - ], [ 0.20291047527778772, -0.33259407228555404, @@ -3665,25 +1381,6 @@ Xs = [ 0.17702183701764684, -0.020864846013727956, ], - [ - -0.5689099191621423, - 0.544600536529926, - -0.34916078856459043, - 0.9822571022455582, - 0.030233304809939243, - 0.5950623927405945, - 0.10709287674567114, - -0.45335793482945186, - -0.42415769187544816, - 0.44897078165811233, - -0.059509496330804046, - -0.988472595808626, - 0.7941397305966094, - -0.1645857296563873, - 0.6909105365607005, - 0.8511592194074467, - ], - [-0.9098421775458598, -0.20952423053057156, 0.9924786336664817], [ -0.33715222274078416, -0.26704690491931915, @@ -3709,40 +1406,6 @@ Xs = [ 0.15159625893365325, -0.12967230344148017, ], - [ - 0.42221703960978085, - 0.6412610989675429, - -0.3378728652151137, - -0.7259095427151108, - 0.3792220940510249, - 0.09853495773970455, - -0.03328822790230723, - 0.10717331421952858, - 0.9602549746343043, - 0.36453406652382325, - 0.05098955982227471, - -0.8550440747345822, - -0.13618136406595704, - -0.6238820462729322, - 0.15657227739200308, - -0.7875237399365813, - 0.3339506933166785, - -0.7658809531191957, - ], - [ - 0.8929561594617814, - 0.9142838995513609, - -0.9454002503436634, - 0.599611685359211, - -0.08033334402177683, - 0.352934685220305, - 0.9826231085574035, - -0.13566440227650745, - -0.15023573234217635, - 0.8858256604892685, - -0.9499508153272389, - 0.6730026466902008, - ], [ -0.34597205746030824, 0.9028413427061659, @@ -3766,56 +1429,6 @@ Xs = [ -0.13189846296393637, 0.8496859744073246, ], - [ - 0.09276610111152617, - 0.09805875319182467, - 0.40149199598583674, - 0.4121056057132706, - -0.5187299383130162, - 0.9808043473462107, - 0.9121302771494377, - -0.05119856203718953, - 0.6638686937978975, - 0.8072960740642445, - 0.588215689842168, - 0.5571754021224098, - -0.8228465883832383, - 0.09319381915262914, - -0.2212392016482081, - 0.4600044998096078, - -0.7708333499135387, - -0.7406857285885389, - -0.8937974999435008, - 0.19396510657575705, - 0.5206418037886062, - 0.4451978368270184, - 0.8422191864577384, - -0.018333885981625553, - 0.6610697223081674, - -0.14582004740489873, - ], - [ - 0.22774235157623135, - -0.9570617965471404, - -0.7677114506774323, - 0.7761020139166568, - 0.5705454599965643, - -0.38571286832595675, - -0.789873188052665, - 0.9318173591345504, - 0.2627790302374746, - -0.23646863157711917, - -0.5637044935797642, - 0.20520758669977424, - 0.7064722394615206, - -0.584610567954003, - 0.6716584109355441, - 0.25481219283479906, - -0.9870528012093185, - 0.4129387951226837, - 0.2284244974693428, - -0.7618228616844276, - ], [ -0.3508209068712791, 0.5477811869201115, @@ -3828,18 +1441,6 @@ Xs = [ -0.3150517800054915, 0.5838284430955387, ], - [ - 0.6225357146388626, - 0.7513896391924713, - 0.15368488777021372, - 0.9474331253267687, - -0.7931484910144164, - 0.5669848314865438, - 0.5833361007240527, - -0.15116391703821175, - 0.12146654441996918, - ], - [-0.6912699112418559, -0.2315737570979124, 0.6276350160464672, 0.706838194684831], [ 0.30756479319371266, -0.43184860921312285, @@ -3852,19 +1453,6 @@ Xs = [ -0.7348456829025003, -0.8876636700373159, ], - [ - 0.9692875025266756, - -0.23787854062334635, - -0.24748080007875295, - 0.7036144791890337, - 0.882878776380204, - 0.6653207722292824, - -0.8471461307631554, - 0.054870797521041625, - 0.3479947908450005, - -0.40254986389467895, - ], - [-0.5561604381577363, -0.6690805833024565, -0.49296974074635713], [ 0.5526596524494152, 0.9690315932495712, @@ -3890,53 +1478,6 @@ Xs = [ -0.46909114377791794, 0.037734998042463275, ], - [ - -0.23849715068438293, - 0.7921459122177519, - 0.7585522723532372, - 0.8898425015365772, - 0.6681429223463302, - -0.7046659515927074, - -0.2533112691118138, - -0.9895684050716598, - 0.7064520294805683, - -0.06906516907342031, - 0.8213751152386364, - -0.6183596959717537, - 0.5207021021865952, - 0.7449011143255648, - 0.9149814958723772, - -0.8454584370536609, - 0.8033846014701953, - 0.7737784202696005, - ], - [ - 0.4835975048151546, - -0.5987307405530511, - 0.277769205131432, - -0.5497708234569545, - -0.9238315028510387, - 0.5332814495117155, - -0.5911554383083086, - -0.9275056197495566, - 0.5302218322249228, - -0.7802927767456045, - 0.20312945269109162, - -0.2622275493784205, - -0.17603338014279468, - 0.45721842042830585, - -0.07856217105142416, - 0.458134032752032, - 0.7601845863976819, - -0.0687601004445304, - 0.5084467209402248, - -0.5503154953218936, - 0.8116513645055918, - -0.10424664785069293, - -0.4650749134336116, - 0.17127951460844226, - -0.21534156550417394, - ], [ -0.6945216072262328, 0.06573632900997772, @@ -3966,93 +1507,87 @@ Xs = [ 0.500710013837995, -0.24084472766713083, ], - [ - -0.8374018409716684, - 0.4276765409684762, - -0.6486173821583863, - 0.08856823496937882, - 0.557143175184845, - -0.1985822093439542, - -0.1801379487124286, - 0.043017831672796714, - -0.1929487463516646, - -0.5763738177808153, - -0.49637049997464744, - 0.12581361013858916, - 0.3855284958072094, - 0.15109520635764673, - 0.41672543545469565, - -0.7485533043159125, - 0.1884036602694128, - 0.6381773143883831, - 0.20656419313369856, - 0.5496422308632847, - 0.685510222422288, - 0.17777973619459675, - -0.2579184029541337, - -0.2079419738929984, - 0.6082747209746782, - 0.5014782256507726, - -0.7783280743075152, - -0.5276060845071164, - -0.9311912948488923, - ], - [ - 0.6670456246431664, - 0.07506905805544695, - 0.8002014930850021, - -0.761108481031973, - -0.3309405791117992, - -0.4968484241950417, - 0.5855902060858931, - 0.9782616605547247, - 0.5179425134945737, - 0.9992716621826399, - 0.04240304791255256, - 0.269024423156097, - 0.3525829475191862, - -0.43198618097746966, - 0.3216754129865127, - -0.7577084174756146, - -0.4026041614694662, - 0.1403933118873224, - 0.7634052300441858, - -0.5740345150905044, - 0.912328468664054, - -0.6498208158571068, - ], ] -for (M, p, q, v, u, dy, X) in zip(Ms, ps, qs, vs, us, dys, Xs) - V = typeof(M).parameters[2] - +for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @testset "Manifold $M" begin + @testset "is_point()" begin + @test(is_point(M, p)) + @test(is_point(M, q)) + @test_throws DomainError is_point(M, [[-1.0], p[2:end]...], true) + @test_throws DomainError is_point(M, [p[1], 2 * p[2:end]...], true) + end + + @testset "is_vector()" begin + @test(is_vector(M, p, v)) + @test(is_vector(M, p, u)) + @test_throws DomainError is_vector(M, p, p, false, true) + end + + Random.seed!(1) @testset "rand()" begin @test(is_point(M, rand(M))) @test(is_vector(M, p, rand(M, vector_at=p))) end + @testset "get_embedding()" begin + @test(get_embedding(M) == Euclidean(prod(V))) + end + + @testset "embed!()" begin + p_ = zeros(prod(V)) + p__ = zeros(prod(V)) + embed!(M, p_, p) + embed!(M, p__, [p[1], [-x for x in p[2:end]]...]) + @test(is_point(get_embedding(M), p_)) + @test(p_ == (-1)^length(V) * p__) + end + + # ManifoldsBase doesn't export embed_vector! right now + # @testset "embed_vector!()" begin + # p_ = zeros(prod(V)) + # v_ = zeros(prod(V)) + # embed!(M, p_, p) + # embed_vector!(M, v_, p, v) + # @test(is_vector(get_embedding(M), p_, v_)) + # end + + @testset "get_coordinates()" begin + @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) + end + + @testset "get_vector()" begin + @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) + end + @testset "exp()" begin - @test(is_point(M, exp(M, p, v))) - @test(isapprox(p, exp(M, p, 0.0 * v); atol=1e-5)) + # Zero vector + p_ = exp(M, p, zeros.(size.(v))) + @test(is_point(M, p_)) + @test(isapprox(p, p_; atol=1e-5)) - geodesic_speed = - finite_difference(t -> distance(M, p, exp(M, p, t * v)), -1.0, 1e-3) + # Tangent vector in the scaling direction + p_ = exp(M, p, [v[1], zeros.(size.(v[2:end]))...]) + @test(is_point(M, p_)) + @test(isapprox([p[1] + v[1], p[2:end]...], p_; atol=1e-5)) + + # Generic tangent vector + p_ = exp(M, p, v) + @test(is_point(M, p)) + + geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -1.0) @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) geodesic_speed = - finite_difference(t -> distance(M, p, exp(M, p, t * v)), -0.811, 1e-3) + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.811) @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) geodesic_speed = - finite_difference(t -> distance(M, p, exp(M, p, t * v)), -0.479, 1e-3) + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.479) @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) - geodesic_speed = - finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.181, 1e-3) + geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.181) @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) - geodesic_speed = - finite_difference(t -> distance(M, p, exp(M, p, t * v)), 0.703, 1e-3) + geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.703) @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) - geodesic_speed = - finite_difference(t -> distance(M, p, exp(M, p, t * v)), 1.0, 1e-3) + geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 1.0) @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) # Geodesics are (locally) length-minizing. So let B_a be a one-parameter @@ -4098,14 +1633,28 @@ for (M, p, q, v, u, dy, X) in zip(Ms, ps, qs, vs, us, dys, Xs) # dy = rand(4 * n); dy = dy / norm(dy) f = a -> curve_length(a * dy) - @test(isapprox(finite_difference(f, 0.0, 1e-3), 0.0; atol=1e-5)) - @test(finite_difference(f, 0.0, 1e-3; order=2) >= 0.0) + @test(isapprox(central_fdm(3, 1)(f, 0.0), 0.0; atol=1e-5)) + @test(central_fdm(3, 2)(f, 0.0) >= 0.0) end @testset "log()" begin - @test(is_vector(M, p, log(M, p, q))) - @test(isapprox(0.0 * v, log(M, p, p); atol=1e-5)) - @test(isapprox(q, exp(M, p, log(M, p, q)), atol=1e-10)) + # Same point + v_ = log(M, p, p) + @test(is_vector(M, p, v_)) + @test(isapprox(zeros.(size.(v)), v_; atol=1e-5)) + + # Scaled point + v_ = log(M, p, [q[1], p[2:end]...]) + @test(is_vector(M, p, v_)) + @test(isapprox(v_, [q[1] - p[1], zeros.(size.(q[2:end]))...]; atol=1e-5)) + + # Generic tangent vector + v_ = log(M, p, q) + @test(is_vector(M, p, v_)) + end + + @testset "norm()" begin + @test(isapprox(norm(M, p, log(M, p, q)), distance(M, p, q))) end @testset "riemann_tensor()" begin @@ -4135,15 +1684,5 @@ for (M, p, q, v, u, dy, X) in zip(Ms, ps, qs, vs, us, dys, Xs) @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) end - - @testset "get_coordinates()" begin - @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) - end - - @testset "get_vector()" begin - @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) - end end end - -# TODO: Test that distance and inner are compatible From 85919d2e9f2966b1f7681cf02e53e7ad52c23296 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Tue, 17 Dec 2024 19:12:23 +0100 Subject: [PATCH 11/35] Add test that get_coordinates(::Segre,...) and get_vector(::Segre,...) uses an ONB by default. Also fix a bug that was discovered by adding this test. --- src/manifolds/Segre.jl | 17 +++++------ src/manifolds/SegreWarpedMetric.jl | 46 ++++++++++++++++++++++++------ test/manifolds/segre.jl | 9 ++++-- 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 68f7a4dbc3..3b97c58876 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -123,7 +123,7 @@ function get_coordinates_orthonormal!( ) where {V} return X = vcat( v[1], - [ + p[1][1] * [ get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end]) ]..., ) @@ -141,13 +141,14 @@ function get_vector_orthonormal!(M::Segre{ℝ,V}, v, p, X, ::RealNumbers; kwargs v[1] = [X_[1]] X_ = X_[2:end] for (i, n) in enumerate(V) - v[i + 1] = get_vector( - Sphere(n - 1), - p[i + 1], - X_[1:(n - 1)], - DefaultOrthonormalBasis(); - kwargs..., - ) + v[i + 1] = + get_vector( + Sphere(n - 1), + p[i + 1], + X_[1:(n - 1)], + DefaultOrthonormalBasis(); + kwargs..., + ) / p[1][1] X_ = X_[n:end] end diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index d438a4c113..a3808a9c47 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -18,7 +18,7 @@ struct WarpedMetric{A} <: AbstractMetric end @doc raw""" function get_coordinates(M::Segre{𝔽, V}, p, v; kwargs...) -Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each sphere tangent space ``T_{x_i} S^{n_i - 1}``. +Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S}_A = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each sphere tangent space ``T_{x_i} S^{n_i - 1}``. """ get_coordinates( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, @@ -35,19 +35,47 @@ function get_coordinates_orthonormal!( ::RealNumbers; kwargs..., ) where {𝔽,V,A} - return get_coordinates_orthonormal!(M.manifold, X, p, v, RealNumbers(); kwargs...) + return X = vcat( + v[1], + A * + p[1][1] * + [ + get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + ]..., + ) end +@doc raw""" + function get_vector( M::Segre{𝔽, V}, p, X; kwargs...) + +Get tangent vector `v` from coordinates in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S}_A = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}``. """ - function get_vector(M::MetricManifold{𝔽, Segre{𝔽, V}, WarpedMetric{A}}, p, X; kwargs...) -""" -function get_vector( - M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, +get_vector(M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, X; kwargs...) where {V,A,𝔽} + +function get_vector_orthonormal!( + M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, + v, p, - X; + X, + ::RealNumbers; kwargs..., -) where {V,A,𝔽} - return get_vector(M.manifold, p, X; kwargs...) +) where {V,A} + X_ = deepcopy(X) + v[1] = [X_[1]] + X_ = X_[2:end] + for (i, n) in enumerate(V) + v[i + 1] = + get_vector( + Sphere(n - 1), + p[i + 1], + X_[1:(n - 1)], + DefaultOrthonormalBasis(); + kwargs..., + ) / (A * p[1][1]) + X_ = X_[n:end] + end + + return v # TODO: Why do I have to return v here? end @doc raw""" diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index ec56cd91aa..f3057954e8 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1554,10 +1554,13 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @testset "get_coordinates()" begin @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) - end - - @testset "get_vector()" begin @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) + @test( + isapprox( + dot(X, get_coordinates(M, p, v)), + inner(M, p, v, get_vector(M, p, X)), + ) + ) end @testset "exp()" begin From acfc7525a7a44dffddea20c8e75d02ace6fb886a Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Wed, 18 Dec 2024 09:27:43 +0100 Subject: [PATCH 12/35] Remove todos for Segre. --- src/manifolds/Segre.jl | 2 +- src/manifolds/SegreWarpedMetric.jl | 2 +- test/manifolds/segre.jl | 11 ++++------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 3b97c58876..94f80d901f 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -152,7 +152,7 @@ function get_vector_orthonormal!(M::Segre{ℝ,V}, v, p, X, ::RealNumbers; kwargs X_ = X_[n:end] end - return v # TODO: Why do I have to return v here? + return v end @doc raw""" diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index a3808a9c47..828258e117 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -75,7 +75,7 @@ function get_vector_orthonormal!( X_ = X_[n:end] end - return v # TODO: Why do I have to return v here? + return v end @doc raw""" diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index f3057954e8..be8c3e652c 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1,4 +1,4 @@ -using Manifolds, Test, LinearAlgebra, FiniteDifferences, Random +using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences # Manifolds to test Ms = [ @@ -213,8 +213,7 @@ ps = [ ], ] -# qs[i] is a point on Ms[i] that is connected to ps[i] by a geodesic and uses the closest representation to ps[i] -# TODO: test m = 0 +# qs[i] is a point on Ms[i] that is connected to ps[i] by a geodesic and uses the closest representative to ps[i] qs = [ [ [0.2285468999681258], @@ -412,8 +411,7 @@ qs = [ ], ] -# vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representation to ps[i] for t in [-1, 1] -# TODO test m = 0 +# vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representative to ps[i] for t in [-1, 1] vs = [ [ [0.6940789907123062], @@ -1357,7 +1355,7 @@ dys = [ ], ] -# Xs are tangent vectors in a chart +# Xs[i] is coordinates for a tangent vector at ps[i] Xs = [ [ -0.597609995187605, @@ -1661,7 +1659,6 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) end @testset "riemann_tensor()" begin - # Test Riemann tensor by testing that sectional curvature is difference # between circumference and 2 pi r for small circles. Since the sectional # curvature contains the same information as the Riemann tensor, this From e6bf4a6bc9070fb11d91c013dc19e11b4ef52a60 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Wed, 18 Dec 2024 09:42:40 +0100 Subject: [PATCH 13/35] Fix inconsistencies in docstrings for Segre. --- src/manifolds/Segre.jl | 10 +++++----- src/manifolds/SegreWarpedMetric.jl | 13 +++++++------ test/manifolds/segre.jl | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 94f80d901f..cdc524b3da 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -107,9 +107,9 @@ function check_vector(M::Segre{ℝ,V}, p, v; atol=1.4901161193847656e-8, kwargs. end @doc raw""" - function get_coordinates(M::Segre{𝔽, V}, p, v; kwargs...) + function get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) -Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}``. +Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathbb{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. """ get_coordinates(M::Segre{𝔽,V}, p, v, ::DefaultOrthonormalBasis; kwargs...) where {𝔽,V} @@ -130,11 +130,11 @@ function get_coordinates_orthonormal!( end @doc raw""" - function get_vector( M::Segre{𝔽, V}, p, X; kwargs...) + function get_vector( M::Segre{𝔽, V}, p, X, DefaultOrthonormalBasis; kwargs...) -Get tangent vector `v` from coordinates in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}``. +Get tangent vector `v` from coordinates in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathbb{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. """ -get_vector(M::Segre{𝔽,V}, p, X; kwargs...) where {𝔽,V} +get_vector(M::Segre{𝔽,V}, p, X, ::DefaultOrthonormalBasis; kwargs...) where {𝔽,V} function get_vector_orthonormal!(M::Segre{ℝ,V}, v, p, X, ::RealNumbers; kwargs...) where {V} X_ = deepcopy(X) diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index 828258e117..a3d4acde49 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -16,14 +16,15 @@ The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024]( struct WarpedMetric{A} <: AbstractMetric end @doc raw""" - function get_coordinates(M::Segre{𝔽, V}, p, v; kwargs...) + function get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) -Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S}_A = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each sphere tangent space ``T_{x_i} S^{n_i - 1}``. +Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S}_A = \mathbb{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. """ get_coordinates( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, - v; + v, + ::DefaultOrthonormalBasis; kwargs..., ) where {𝔽,V,A} @@ -46,11 +47,11 @@ function get_coordinates_orthonormal!( end @doc raw""" - function get_vector( M::Segre{𝔽, V}, p, X; kwargs...) + function get_vector( M::Segre{𝔽, V}, p, X, ::DefaultOrthonormalBasis; kwargs...) -Get tangent vector `v` from coordinates in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S}_A = \mathrm{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}``. +Get tangent vector `v` from coordinates in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S}_A = \mathbb{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. """ -get_vector(M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, X; kwargs...) where {V,A,𝔽} +get_vector(M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, X, ::DefaultOrthonormalBasis; kwargs...) where {V,A,𝔽} function get_vector_orthonormal!( M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index be8c3e652c..b9047eb5d2 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1538,7 +1538,7 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) embed!(M, p_, p) embed!(M, p__, [p[1], [-x for x in p[2:end]]...]) @test(is_point(get_embedding(M), p_)) - @test(p_ == (-1)^length(V) * p__) + @test(isapprox(p_, (-1)^length(V) * p__)) end # ManifoldsBase doesn't export embed_vector! right now From 7079eef64e5fe71c75d02b7fba0d57b8f6c7d3f7 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Wed, 18 Dec 2024 09:44:45 +0100 Subject: [PATCH 14/35] formatting --- src/manifolds/SegreWarpedMetric.jl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index a3d4acde49..0c01f58510 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -51,7 +51,13 @@ end Get tangent vector `v` from coordinates in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S}_A = \mathbb{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. """ -get_vector(M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, X, ::DefaultOrthonormalBasis; kwargs...) where {V,A,𝔽} +get_vector( + M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, + p, + X, + ::DefaultOrthonormalBasis; + kwargs..., +) where {V,A,𝔽} function get_vector_orthonormal!( M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, From 1a2ce374b2b79452b96c6e770fe51a535dab472d Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Wed, 18 Dec 2024 15:40:49 +0100 Subject: [PATCH 15/35] Fix codecov. --- src/manifolds/Segre.jl | 53 ++++++++++++++---------------- src/manifolds/SegreWarpedMetric.jl | 21 ++++-------- test/manifolds/segre.jl | 25 +++++++++----- 3 files changed, 47 insertions(+), 52 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index cdc524b3da..e965353e3b 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -217,22 +217,23 @@ function embed!(M::Segre{𝔽,V}, q, p) where {𝔽,V} return q = kron(p...) end -@doc raw""" - function embed_vector(M::Segre{𝔽, V}, p, v) - -Embed tangent vector ``v = (\nu, u_1, \dots, u_d)`` at ``p \doteq (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: -````math - (\nu, u_1, \dots, u_d) \mapsto \nu x_1 \otimes \dots \otimes x_d + \lambda u_1 \otimes x_2 \otimes \dots \otimes x_d + \dots + \lambda x_1 \otimes \dots \otimes x_{d - 1} \otimes u_d. -```` -""" -function embed_vector!(M::Segre{𝔽,V}, u, p, v) where {𝔽,V} - - # Product rule - return u = sum([ - kron([i == j ? xdot : x for (j, (x, xdot)) in enumerate(zip(p, v))]...) for - (i, _) in enumerate(p) - ]) -end +# ManifoldsBase doesn't export embed_vector! right now +# @doc raw""" +# function embed_vector(M::Segre{𝔽, V}, p, v) + +# Embed tangent vector ``v = (\nu, u_1, \dots, u_d)`` at ``p \doteq (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: +# ````math +# (\nu, u_1, \dots, u_d) \mapsto \nu x_1 \otimes \dots \otimes x_d + \lambda u_1 \otimes x_2 \otimes \dots \otimes x_d + \dots + \lambda x_1 \otimes \dots \otimes x_{d - 1} \otimes u_d. +# ```` +# """ +# function embed_vector!(M::Segre{𝔽,V}, u, p, v) where {𝔽,V} + +# # Product rule +# return u = sum([ +# kron([i == j ? xdot : x for (j, (x, xdot)) in enumerate(zip(p, v))]...) for +# (i, _) in enumerate(p) +# ]) +# end @doc raw""" function spherical_angle_sum(M::Segre{ℝ, V}, p, q) @@ -355,7 +356,7 @@ function exp!(M::Segre{ℝ,V}, q, p, v) where {V} end end - return 0 + return q end @doc raw""" @@ -387,21 +388,15 @@ log(M::Segre{ℝ,V}, p, q) where {V} function log!(M::Segre{ℝ,V}, v, p, q) where {V} closest_representative!(M, q, p) + m = spherical_angle_sum(M, p, q) - if !connected_by_geodesic(M, p, q) - v = nan.(size.(p)) - else - m = spherical_angle_sum(M, p, q) - - v[1][1] = q[1][1] * cos(m) - p[1][1] - - for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) - a = distance(Sphere(n - 1), x, y) - xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(m / pi) / sinc(a / pi) - end + v[1][1] = q[1][1] * cos(m) - p[1][1] + for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + a = distance(Sphere(n - 1), x, y) + xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(m / pi) / sinc(a / pi) end - return 0 + return v end @doc raw""" diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index 0c01f58510..33a48a023b 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -174,7 +174,7 @@ function exp!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) wher end end - return 0 + return q end @doc raw""" @@ -206,22 +206,15 @@ log(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} function log!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, v, p, q) where {V,A} closest_representative!(M, q, p) + m = spherical_angle_sum(M, p, q) - if !connected_by_geodesic(M, p, q) - v = nan.(size.(p)) - else - m = spherical_angle_sum(M, p, q) - - v[1][1] = q[1][1] * cos(A * m) - p[1][1] - - for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) - a = distance(Sphere(n - 1), x, y) - xdot .= - (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(A * m / pi) / sinc(a / pi) - end + v[1][1] = q[1][1] * cos(A * m) - p[1][1] + for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + a = distance(Sphere(n - 1), x, y) + xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(A * m / pi) / sinc(a / pi) end - return 0 + return v end @doc raw""" diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index b9047eb5d2..bf1dbedfea 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1512,6 +1512,7 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @testset "is_point()" begin @test(is_point(M, p)) @test(is_point(M, q)) + @test_throws DomainError is_point(M, [[1.0, 0.0], p[2:end]...], true) @test_throws DomainError is_point(M, [[-1.0], p[2:end]...], true) @test_throws DomainError is_point(M, [p[1], 2 * p[2:end]...], true) end @@ -1519,6 +1520,8 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @testset "is_vector()" begin @test(is_vector(M, p, v)) @test(is_vector(M, p, u)) + @test_throws DomainError is_vector(M, [[1.0, 0.0], p[2:end]...], v, false, true) + @test_throws DomainError is_vector(M, p, [[1.0, 0.0], v[2:end]...], false, true) @test_throws DomainError is_vector(M, p, p, false, true) end @@ -1658,15 +1661,9 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @test(isapprox(norm(M, p, log(M, p, q)), distance(M, p, q))) end - @testset "riemann_tensor()" begin - # Test Riemann tensor by testing that sectional curvature is difference - # between circumference and 2 pi r for small circles. Since the sectional - # curvature contains the same information as the Riemann tensor, this - # should be fine. - - sectional_curvature(M, p, u, v) = - inner(M, p, riemann_tensor(M, p, u, v, v), u) / - (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) + @testset "sectional_curvature()" begin + # Test that sectional curvature is difference between circumference + # and 2 pi r for small circles. # Orthonormalize u_ = u / norm(M, p, u) @@ -1684,5 +1681,15 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) end + + @testset "riemann_tensor()" begin + @test( + isapprox( + sectional_curvature(M, p, u, v), + inner(M, p, riemann_tensor(M, p, u, v, v), u) / + (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2), + ) + ) + end end end From da09f54136f170b799900df312b80abe9bf71516 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Wed, 18 Dec 2024 20:04:40 +0100 Subject: [PATCH 16/35] =?UTF-8?q?A=20bit=20of=20markdown=20formatting,=20u?= =?UTF-8?q?se=20UTF8=20symbols=20where=20useful=20(in=20VS=20code=20->=20T?= =?UTF-8?q?AB=20turns=20\lambda=20into=20=CE=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project.toml | 1 - src/manifolds/Segre.jl | 134 ++++++++++++++++++----------- src/manifolds/SegreWarpedMetric.jl | 71 ++++++++------- test/manifolds/segre.jl | 26 +++--- 4 files changed, 137 insertions(+), 95 deletions(-) diff --git a/Project.toml b/Project.toml index 3ca84ee2d6..e33a7dc7c8 100644 --- a/Project.toml +++ b/Project.toml @@ -3,7 +3,6 @@ uuid = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e" authors = ["Seth Axen ", "Mateusz Baran ", "Ronny Bergmann ", "Antoine Levitt "] version = "0.10.9" - [deps] Einsum = "b7d42ee7-0b51-5a75-98ca-779d3107e4c0" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index e965353e3b..2da13eacef 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -2,15 +2,19 @@ Segre{𝔽,V} <: AbstractManifold{𝔽} The Segre manifold + ````math \mathcal{S} = \operatorname{Seg}(𝔽^{n_1} \times \dots \times 𝔽^{n_d}) ```` + is the set of rank-one tensors in ``𝔽^{n_1} \otimes \dots \otimes 𝔽^{n_d}``. When ``𝔽 = ℝ``, the Segre manifold is a normal Riemannian covering of + ````math \mathcal{P} = ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} ```` + with the [warped product metric](https://en.wikipedia.org/wiki/Warped_product) [`inner`](@ref inner(::Segre, ::Any)). The tuple ``(n_1, \dots, n_d)`` is called the _valence_ of the manifold. The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). @@ -18,7 +22,8 @@ The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024]( # Constructor Segre(n::Int...; field::AbstractNumbers=ℝ) -Generate a valence `(n, ...)` Segre manifold. Segre(n) is ``\mathbb{R} \setminus \{ 0 \}``. +Generate a valence `(n, ...)` Segre manifold. +`Segre(n)` is the same as ``\mathbb{R} \setminus \{ 0 \}``. """ struct Segre{𝔽,V} <: AbstractManifold{𝔽} end @@ -106,10 +111,28 @@ function check_vector(M::Segre{ℝ,V}, p, v; atol=1.4901161193847656e-8, kwargs. end end + +@doc raw""" + function embed(M::Segre{𝔽, V}, p) + function embed!(M::Segre{𝔽, V}, q, p) + +Embed ``p ≐ (Ξ», x_1, …, x_d)`` in ``𝔽^{n_1 Γ—β‹―Γ— n_d}`` using the Kronecker product: +````math + (Ξ», x_1, …, x_d) ↦ Ξ» x_1 βŠ—β‹―βŠ— x_d. +```` +""" +embed(::Segre{𝔽,V}, p) + +function embed!(M::Segre{𝔽,V}, q, p) where {𝔽,V} + return q = kron(p...) +end + @doc raw""" function get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) -Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathbb{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. +Get coordinates of `v` in the tangent space +``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} ×…× T_{x_d} S^{n_d - 1}`` +using a `DefaultOrthonormalBasis` on each factor. """ get_coordinates(M::Segre{𝔽,V}, p, v, ::DefaultOrthonormalBasis; kwargs...) where {𝔽,V} @@ -132,7 +155,9 @@ end @doc raw""" function get_vector( M::Segre{𝔽, V}, p, X, DefaultOrthonormalBasis; kwargs...) -Get tangent vector `v` from coordinates in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S} = \mathbb{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. +Get tangent vector `v` from coordinates in the tangent space +``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` +using `DefaultOrthonormalBasis` on each factor. """ get_vector(M::Segre{𝔽,V}, p, X, ::DefaultOrthonormalBasis; kwargs...) where {𝔽,V} @@ -158,13 +183,16 @@ end @doc raw""" function inner(M::Segre{ℝ, V}, p, u, v,) -Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v = (\xi, v_1, \dots, v_d)`` at ``p \doteq (\lambda, x_1, \dots, x_d)``. This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric: +Inner product between two tangent vectors ``u = (Ξ½, u_1, …, u_d)`` and ``v = (ΞΎ, v_1, …, v_d)`` at ``p ≐ (Ξ», x_1, \dots, x_d)``. +This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric: + ````math \langle u, v \rangle_{p} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle_{x_1} + \dots + \langle u_d, v_d \rangle_{x_d}), ```` -where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. + +where ``Ξ½, ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} S^{n_i - 1} βŠ‚ ℝ^{n_i}``. """ -function inner(M::Segre{ℝ,V}, p, u, v) where {V} +function inner(::Segre{ℝ,V}, p, u, v) where {V} return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) end @@ -172,10 +200,12 @@ end function rand(M::Segre{ℝ, V}; vector_at=nothing) If `vector_at` is `nothing`, return a random point on + ````math - ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} + ℝ^{+} Γ— S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1} ```` -from a log-normal distribution on ℝ^{+} and a uniform distribution on ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. + +from a log-normal distribution on ℝ^{+} and a uniform distribution on ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}``. If `vector_at` is not `nothing`, return a random tangent vector from a normal distribution on the tangent space. """ @@ -199,24 +229,12 @@ end @doc raw""" function get_embedding(M::Segre{𝔽,V}) -``\mathcal{S}`` is embedded in ``𝔽^{n_1 \times \dots \times n_d}``. +``\mathcal{S}`` is embedded in ``𝔽^{n_1 Γ—β‹―Γ— n_d}``. """ -function get_embedding(M::Segre{𝔽,V}) where {𝔽,V} +function get_embedding(::Segre{𝔽,V}) where {𝔽,V} return Euclidean(prod(V)) end -@doc raw""" - function embed!(M::Segre{𝔽, V}, q, p) - -Embed ``p \doteq (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: -````math - (\lambda, x_1, \dots, x_d) \mapsto \lambda x_1 \otimes \dots \otimes x_d. -```` -""" -function embed!(M::Segre{𝔽,V}, q, p) where {𝔽,V} - return q = kron(p...) -end - # ManifoldsBase doesn't export embed_vector! right now # @doc raw""" # function embed_vector(M::Segre{𝔽, V}, p, v) @@ -238,12 +256,15 @@ end @doc raw""" function spherical_angle_sum(M::Segre{ℝ, V}, p, q) -Let ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}``. +Let ``p ≐ (Ξ», x_1, …, x_d)``, ``q ≐ (ΞΌ, y_1, …, y_d) ∈ \mathcal{S}``. Then this is + ````math - \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2}, + \sqrt{\sphericalangle(x_1, y_1)^2 + … + \sphericalangle(x_d, y_d)^2}, ```` + where ``\sphericalangle(x_i, y_i)`` is the distance between ``x_i`` and ``y_i`` on the sphere ``S^{n_i - 1}``. + """ function spherical_angle_sum(M::Segre{ℝ,V}, p, q) where {V} return sqrt( @@ -259,14 +280,13 @@ end """ function connected_by_geodesic(M::Segre{ℝ,V}, p, q) where {V} closest_representative!(M, q, p) - return spherical_angle_sum(M, p, q) < pi end @doc raw""" function closest_representative!(M::Segre{ℝ, V}, p, q) -``\mathcal{S}`` is a ``2^d``-sheeted Riemannian covering of +``\mathcal{S}`` is a ``2^d``-sheeted Riemannian covering of ````math \mathcal{P} = ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} ```` @@ -311,31 +331,34 @@ end Exponential map on the Segre manifold. -Let ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``v = (\nu, u_1, \dots, u_d) \in T_p \mathcal{S}``. +Let ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}`` and ``v = (Ξ½, u_1, …, u_d) ∈ T_p \mathcal{S}``. Then + ````math - \operatorname{exp}_p(v) \doteq + \operatorname{exp}_p(v) ≐ \left( - \sqrt{t^2 + 2 \lambda \nu t + \lambda^2},\\ + \sqrt{t^2 + 2 Ξ» Ξ½ t + Ξ»^2},\\ x_1 \cos\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{m} \mathclose{\Big)},\\ - \dots,\\ + …,\\ x_d \cos\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{m} \mathclose{\Big)} \right), ```` + where + ````math - g = \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{\lambda} + P \mathclose{\Big)} - \tan^{-1}(P),\\ - m = \sqrt{\lVert u_1 \rVert_{x_1}^2 + \dots + \lVert u_d \rVert_{x_d}^2},\\ - P = \frac{\nu}{\lambda m},\\ + g = \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{Ξ»} + P \mathclose{\Big)} - \tan^{-1}(P),\\ + m = \sqrt{\lVert u_1 \rVert_{x_1}^2 + … + \lVert u_d \rVert_{x_d}^2},\\ + P = \frac{\nu}{Ξ» m},\\ t = \lVert v \rVert_{p}. ```` -If ``m = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. +If ``m = 0`` and ``Ξ½ t < Ξ»``, then ``\operatorname{exp}_p(v) = p + v``. For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ exp(M::Segre{ℝ,V}, p, v) where {V} -function exp!(M::Segre{ℝ,V}, q, p, v) where {V} +function exp!(::Segre{ℝ,V}, q, p, v) where {V} m = sqrt( sum([ norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) @@ -364,20 +387,24 @@ end Logarithmic map on the Segre manifold. -Let ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}``. +Let ``p ≐ (Ξ», x_1, …, x_d)``, ``q ≐ (ΞΌ, y_1, …, y_d) ∈ \mathcal{S}``. Assume ``p`` and ``q`` are connected by a geodesic. + Let + ````math - m = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} + m = \sqrt{\sphericalangle(x_1, y_1)^2 + … + \sphericalangle(x_d, y_d)^2} ```` -and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimizes ``m``. Then + +and assume ``(ΞΌ, y_1, …, y_d)`` is the representation of ``q`` that minimizes ``m``. Then + ````math \operatorname{log}_p(q) = c \left( - \frac{\lambda m \mathopen{\Big(} \operatorname{cos}(m) - \frac{\lambda}{\mu} \mathclose{\Big)}}{\operatorname{sin}(m)}, - \frac{\sphericalangle(x_1, y_1) (y_1 - \langle x_1, y_1 \rangle x_1)}{\sin(\sphericalangle(x_1, y_1))}, + \frac{Ξ» m \mathopen{\Big(} \operatorname{cos}(m) - \frac{Ξ»}{ΞΌ} \mathclose{\Big)}}{\operatorname{sin}(m)}, + \frac{\sphericalangle(x_1, y_1) (y_1 - ⟨x_1, y_1⟩ x_1)}{\sin(\sphericalangle(x_1, y_1))}, \dots, - \frac{\sphericalangle(x_d, y_d) (y_d - \langle x_d, y_d \rangle x_d)}{\sin(\sphericalangle(x_d, y_d))} + \frac{\sphericalangle(x_d, y_d) (y_d - ⟨x_d, y_d⟩ x_d)}{\sin(\sphericalangle(x_d, y_d))} \right), ```` where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \operatorname{dist}(p, q)``. @@ -404,13 +431,16 @@ end Riemannian distance between two points `p` and `q` on the Segre manifold. -Assume ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}`` are connected by a geodesic. Let +Assume ``p ≐ (Ξ», x_1, …, x_d)``, ``q ≐ (ΞΌ, y_1, …, y_d) ∈ \mathcal{S}`` are connected by a geodesic. Let + ````math - m = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} + m = \sqrt{\sphericalangle(x_1, y_1)^2 + … + \sphericalangle(x_d, y_d)^2} ```` -and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimizes ``m``. Then + +and assume ``(ΞΌ, y_1, …, y_d)`` is the representation of ``q`` that minimizes ``m``. Then + ````math - \operatorname{dist}_{\mathcal{S}}(p, q) = \sqrt{\lambda^2 - 2 \lambda \mu \cos(m) + \mu^2}. + \operatorname{dist}_{\mathcal{S}}(p, q) = \sqrt{Ξ»^2 - 2 λμ\cos(m) + ΞΌ^2}. ```` """ function distance(M::Segre{ℝ,V}, p, q) where {V} @@ -426,11 +456,13 @@ end Riemann tensor of the Segre manifold at ``p``. -``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. -If ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}`` and ``u``, ``v``, ``w \in T_p (S^{n_1 - 1} \times \dots \times S^{n_d - 1}) \subset T_p \mathcal{S}`` then +``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}``. +If ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}`` and ``u``, ``v``, ``w ∈ T_p (S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}) βŠ‚ T_p \mathcal{S}``, then + ````math - R_{\mathcal{S}}(u, v) w = R_{S^{n_1 - 1} \times \dots \times S^{n_d - 1}}(u, v) w + \lambda^{-2}(\langle u, w \rangle_p v - \langle v, w \rangle_p u). + R_{\mathcal{S}}(u, v) w = R_{S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}}(u, v) w + Ξ»^{-2}(⟨u,w⟩_p v - ⟨v,w⟩_p u). ```` + ``R_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ function riemann_tensor(M::Segre{ℝ,V}, p, u, v, w) where {V} @@ -452,11 +484,13 @@ end Sectional curvature of the Segre manifold at ``p``. -``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` -If ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i - 1}``, and ``v_j \in T_{x_j} S^{n_j - 1}``, then +``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}`` +If ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}``, ``u_i ∈ T_{x_i} S^{n_i - 1}``, and ``v_j ∈ T_{x_j} S^{n_j - 1}``, then + ````math K_{\mathcal{S}}(u_i, v_j) = \frac{\delta_{i j} - 1}{\lambda^2}. ```` + ``K_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ function sectional_curvature(M::Segre{ℝ,V}, p, u, v) where {V} diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index 33a48a023b..72f4bf4505 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -5,9 +5,11 @@ The ``A``-warped metric on the Segre manifold ``\mathcal{S}`` is a generalizatio We this manifold by ``\mathcal{S}_A``. Similarly to ``\mathcal{S}``, when ``𝔽 = ℝ``, ``\mathcal{S}_A`` is a normal Riemannian covering of the product manifold + ````math - ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} + ℝ^{+} Γ— S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1} ```` + with a [warped product metric](https://en.wikipedia.org/wiki/Warped_product), but the warping function now depends on the _warping factor_ ``A``. ``A = 1`` corresponds to the usual Segre manifold. @@ -18,7 +20,7 @@ struct WarpedMetric{A} <: AbstractMetric end @doc raw""" function get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) -Get coordinates of `v` in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S}_A = \mathbb{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. +Get coordinates of `v` in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. """ get_coordinates( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, @@ -49,7 +51,7 @@ end @doc raw""" function get_vector( M::Segre{𝔽, V}, p, X, ::DefaultOrthonormalBasis; kwargs...) -Get tangent vector `v` from coordinates in the tangent space ``T_{(\lambda, x_1, \dots, x_d)} \mathcal{S}_A = \mathbb{R} \times T_{x_1} S^{n_1 - 1} \times \dots \times T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. +Get tangent vector `v` from coordinates in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. """ get_vector( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, @@ -88,11 +90,11 @@ end @doc raw""" function inner( M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, u, v) -Inner product between two tangent vectors ``u = (\nu, u_1, \dots, u_d)`` and ``v = (\xi, v_1, \dots, v_d)`` at ``p = (\lambda, x_1, \dots, x_d``: +Inner product between two tangent vectors ``u = (Ξ½, u_1,…, u_d)`` and ``v = (ΞΎ, v_1,…, v_d)`` at ``p = (Ξ», x_1,…, x_d``: ````math - \langle u, v \rangle_{p} = \nu \xi + (A \lambda)^2 (\langle u_1, v_1 \rangle_{x_1} + \dots + \langle u_d, v_d \rangle_{x_d}), + ⟨ u, v ⟩_{p} = Ξ½ ΞΎ + (A Ξ»)^2 (⟨ u_1, v_1 ⟩_{x_1} +… + ⟨ u_d, v_d ⟩_{x_d}), ```` -where ``\nu``, ``\xi \in T_{\lambda} ℝ^{+} = ℝ`` and ``u_i``, ``v_i \in T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. +where ``Ξ½``, ``ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ function inner(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v) where {V,A} return u[1][1] * v[1][1] + (A * p[1][1])^2 * dot(u[2:end], v[2:end]) @@ -127,31 +129,31 @@ end Exponential map on the warped Segre manifold. -Let ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``v = (\nu, u_1, \dots, u_d) \in T_p \mathcal{S}_A``. +Let ``p ≐ (Ξ», x_1,…, x_d) ∈ \mathcal{S}_A`` and ``v = (Ξ½, u_1,…, u_d) ∈ T_p \mathcal{S}_A``. Then ````math - \operatorname{exp}_p(v) \doteq + \operatorname{exp}_p(v) ≐ \left( - \sqrt{t^2 + 2 \lambda \nu t + \lambda^2},\\ + \sqrt{t^2 + 2 Ξ» Ξ½ t + Ξ»^2},\\ x_1 \cos\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)},\\ - \dots,\\ + …,\\ x_d \cos\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} \right), ```` where ````math - g = \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{\lambda} + P \mathclose{\Big)} - \tan^{-1}(P),\\ - m = \sqrt{\lVert u_1 \rVert_{x_1}^2 + \dots + \lVert u_d \rVert_{x_d}^2},\\ - P = \frac{\nu}{\lambda A m},\\ + g = \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{Ξ»} + P \mathclose{\Big)} - \tan^{-1}(P),\\ + m = \sqrt{\lVert u_1 \rVert_{x_1}^2 +… + \lVert u_d \rVert_{x_d}^2},\\ + P = \frac{Ξ½}{Ξ» A m},\\ t = \lVert v \rVert_{p}. ```` -If ``m = 0`` and ``\nu t < \lambda``, then ``\operatorname{exp}_p(v) = p + v``. +If ``m = 0`` and ``Ξ½ t < Ξ»``, then ``\operatorname{exp}_p(v) = p + v``. For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ exp(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, v) where {V,A} -function exp!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) where {V,A} +function exp!(::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) where {V,A} m = sqrt( sum([ norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) @@ -182,22 +184,26 @@ end Logarithmic map on the warped Segre manifold. -Let ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}_A``. +Let ``p ≐ (Ξ», x_1,…, x_d)``, ``q ≐ (ΞΌ, y_1,…, y_d) ∈ \mathcal{S}_A``. Assume ``p`` and ``q`` are connected by a geodesic. Let + ````math - m = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} + m = \sqrt{\sphericalangle(x_1, y_1)^2 +… + \sphericalangle(x_d, y_d)^2} ```` -and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimizes ``m``. Then + +and assume ``(ΞΌ, y_1,…, y_d)`` is the representation of ``q`` that minimizes ``m``. Then + ````math \operatorname{log}_p(q) = c \left( - \frac{\lambda A m \mathopen{\Big(} \cos(A m) - \frac{\lambda}{\mu} \mathclose{\Big)}}{\sin(A m)}, - \frac{\sphericalangle(x_1, y_1) (y_1 - \langle x_1, y_1 \rangle x_1)}{\sin(\sphericalangle(x_1, y_1))}, - \dots, - \frac{\sphericalangle(x_d, y_d) (y_d - \langle x_d, y_d \rangle x_d)}{\sin(\sphericalangle(x_d, y_d))} + \frac{Ξ» A m \mathopen{\Big(} \cos(A m) - \frac{Ξ»}{ΞΌ} \mathclose{\Big)}}{\sin(A m)}, + \frac{\sphericalangle(x_1, y_1) (y_1 - ⟨ x_1, y_1 ⟩ x_1)}{\sin(\sphericalangle(x_1, y_1))}, + …, + \frac{\sphericalangle(x_d, y_d) (y_d - ⟨ x_d, y_d ⟩ x_d)}{\sin(\sphericalangle(x_d, y_d))} \right), ```` + where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \operatorname{dist}(p, q)``. For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). @@ -222,13 +228,16 @@ end Riemannian distance between two points `p` and `q` on the warped Segre manifold. -Assume ``p \doteq (\lambda, x_1, \dots, x_d)``, ``q \doteq (\mu, y_1, \dots, y_d) \in \mathcal{S}_A`` are connected by a geodesic. Let +Assume ``p ≐ (Ξ», x_1,…, x_d)``, ``q ≐ (ΞΌ, y_1,…, y_d) ∈ \mathcal{S}_A`` are connected by a geodesic. Let + ````math - m = \sqrt{\sphericalangle(x_1, y_1)^2 + \dots + \sphericalangle(x_d, y_d)^2} + m = \sqrt{\sphericalangle(x_1, y_1)^2 +… + \sphericalangle(x_d, y_d)^2} ```` -and assume ``(\mu, y_1, \dots, y_d)`` is the representation of ``q`` that minimizes ``m``. Then + +and assume ``(ΞΌ, y_1,…, y_d)`` is the representation of ``q`` that minimizes ``m``. Then + ````math - \operatorname{dist}_{\mathcal{S}_A}(p, q) = \sqrt{\lambda^2 - 2 \lambda \mu \cos(A m) + \mu^2}. + \operatorname{dist}_{\mathcal{S}_A}(p, q) = \sqrt{Ξ»^2 - 2 Ξ» ΞΌ \cos(A m) + ΞΌ^2}. ```` """ function distance(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} @@ -243,9 +252,9 @@ end Riemann tensor of the warped Segre manifold at ``p``. -``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}``. If ``p \doteq (\lambda, x_1, \dots, x_d) \in \mathcal{S}_A`` and ``u``, ``v``, ``w \in T_{(x_1, \dots, x_d)} (S^{n_1 - 1} \times \dots \times S^{n_d - 1}) \subset T_p \mathcal{S}_A`` then +``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}``. If ``p ≐ (Ξ», x_1,…, x_d) ∈ \mathcal{S}_A`` and ``u``, ``v``, ``w ∈ T_{(x_1,…, x_d)} (S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}) \subset T_p \mathcal{S}_A`` then ````math - R_{\mathcal{S}_A}(u, v) w = R_{S^{n_1 - 1} \times \dots \times S^{n_d - 1}}(u, v) w + \lambda^{-2}(\langle u, w \rangle_{p} v - \langle v, w \rangle_{p} u). + R_{\mathcal{S}_A}(u, v) w = R_{S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}}(u, v) w + Ξ»^{-2}(⟨ u, w ⟩_{p} v - ⟨ v, w ⟩_{p} u). ```` ``R_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ @@ -274,10 +283,10 @@ end Sectional curvature of the warped Segre manifold at ``p``. -``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} \times \dots \times S^{n_d - 1}`` -If ``p = (\lambda, x_1, \dots, x_d) \in \mathcal{S}``, ``u_i \in T_{x_i} S^{n_i - 1}``, and ``v_j \in T_{x_j} S^{n_j - 1}``, then +``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}`` +If ``p = (Ξ», x_1,…, x_d) ∈ \mathcal{S}``, ``u_i ∈ T_{x_i} S^{n_i - 1}``, and ``v_j ∈ T_{x_j} S^{n_j - 1}``, then ````math - K_{\mathcal{S}_A}(u_i, v_j) = -(1 - \delta_{i j}) \lambda^2. + K_{\mathcal{S}_A}(u_i, v_j) = -(1 - \delta_{i j}) Ξ»^2. ```` ``K_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index bf1dbedfea..a27ba15201 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1509,7 +1509,7 @@ Xs = [ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @testset "Manifold $M" begin - @testset "is_point()" begin + @testset "is_point" begin @test(is_point(M, p)) @test(is_point(M, q)) @test_throws DomainError is_point(M, [[1.0, 0.0], p[2:end]...], true) @@ -1517,7 +1517,7 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @test_throws DomainError is_point(M, [p[1], 2 * p[2:end]...], true) end - @testset "is_vector()" begin + @testset "is_vector" begin @test(is_vector(M, p, v)) @test(is_vector(M, p, u)) @test_throws DomainError is_vector(M, [[1.0, 0.0], p[2:end]...], v, false, true) @@ -1526,16 +1526,16 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) end Random.seed!(1) - @testset "rand()" begin + @testset "rand" begin @test(is_point(M, rand(M))) @test(is_vector(M, p, rand(M, vector_at=p))) end - @testset "get_embedding()" begin + @testset "get_embedding" begin @test(get_embedding(M) == Euclidean(prod(V))) end - @testset "embed!()" begin + @testset "embed!" begin p_ = zeros(prod(V)) p__ = zeros(prod(V)) embed!(M, p_, p) @@ -1545,7 +1545,7 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) end # ManifoldsBase doesn't export embed_vector! right now - # @testset "embed_vector!()" begin + # @testset "embed_vector!" begin # p_ = zeros(prod(V)) # v_ = zeros(prod(V)) # embed!(M, p_, p) @@ -1553,7 +1553,7 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) # @test(is_vector(get_embedding(M), p_, v_)) # end - @testset "get_coordinates()" begin + @testset "get_coordinates" begin @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) @test( @@ -1564,7 +1564,7 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) ) end - @testset "exp()" begin + @testset "exp" begin # Zero vector p_ = exp(M, p, zeros.(size.(v))) @test(is_point(M, p_)) @@ -1575,7 +1575,7 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @test(is_point(M, p_)) @test(isapprox([p[1] + v[1], p[2:end]...], p_; atol=1e-5)) - # Generic tangent vector + # Generic tangent vector p_ = exp(M, p, v) @test(is_point(M, p)) @@ -1641,7 +1641,7 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @test(central_fdm(3, 2)(f, 0.0) >= 0.0) end - @testset "log()" begin + @testset "log" begin # Same point v_ = log(M, p, p) @test(is_vector(M, p, v_)) @@ -1657,11 +1657,11 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @test(is_vector(M, p, v_)) end - @testset "norm()" begin + @testset "norm" begin @test(isapprox(norm(M, p, log(M, p, q)), distance(M, p, q))) end - @testset "sectional_curvature()" begin + @testset "sectional_curvature" begin # Test that sectional curvature is difference between circumference # and 2 pi r for small circles. @@ -1682,7 +1682,7 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) end - @testset "riemann_tensor()" begin + @testset "riemann_tensor" begin @test( isapprox( sectional_curvature(M, p, u, v), From 92ea877c16991cbf8fc72941bfa7a63388ac3dd9 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Wed, 18 Dec 2024 20:10:44 +0100 Subject: [PATCH 17/35] Fix a typo. --- src/manifolds/Segre.jl | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 2da13eacef..bb3e19dd32 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -111,7 +111,6 @@ function check_vector(M::Segre{ℝ,V}, p, v; atol=1.4901161193847656e-8, kwargs. end end - @doc raw""" function embed(M::Segre{𝔽, V}, p) function embed!(M::Segre{𝔽, V}, q, p) @@ -121,9 +120,9 @@ Embed ``p ≐ (Ξ», x_1, …, x_d)`` in ``𝔽^{n_1 Γ—β‹―Γ— n_d}`` using the Kron (Ξ», x_1, …, x_d) ↦ Ξ» x_1 βŠ—β‹―βŠ— x_d. ```` """ -embed(::Segre{𝔽,V}, p) +embed(::Segre, p) -function embed!(M::Segre{𝔽,V}, q, p) where {𝔽,V} +function embed!(M::Segre, q, p) return q = kron(p...) end @@ -134,16 +133,9 @@ Get coordinates of `v` in the tangent space ``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} ×…× T_{x_d} S^{n_d - 1}`` using a `DefaultOrthonormalBasis` on each factor. """ -get_coordinates(M::Segre{𝔽,V}, p, v, ::DefaultOrthonormalBasis; kwargs...) where {𝔽,V} - -function get_coordinates_orthonormal!( - M::Segre{ℝ,V}, - X, - p, - v, - ::RealNumbers; - kwargs..., -) where {V} +get_coordinates(M::Segre, p, v, ::DefaultOrthonormalBasis; kwargs...) + +function get_coordinates_orthonormal!(M::Segre{ℝ}, X, p, v, ::RealNumbers; kwargs...) return X = vcat( v[1], p[1][1] * [ @@ -159,7 +151,7 @@ Get tangent vector `v` from coordinates in the tangent space ``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. """ -get_vector(M::Segre{𝔽,V}, p, X, ::DefaultOrthonormalBasis; kwargs...) where {𝔽,V} +get_vector(M::Segre, p, X, ::DefaultOrthonormalBasis; kwargs...) function get_vector_orthonormal!(M::Segre{ℝ,V}, v, p, X, ::RealNumbers; kwargs...) where {V} X_ = deepcopy(X) @@ -176,7 +168,6 @@ function get_vector_orthonormal!(M::Segre{ℝ,V}, v, p, X, ::RealNumbers; kwargs ) / p[1][1] X_ = X_[n:end] end - return v end @@ -192,7 +183,7 @@ This inner product is obtained by embedding the Segre manifold in the space of t where ``Ξ½, ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} S^{n_i - 1} βŠ‚ ℝ^{n_i}``. """ -function inner(::Segre{ℝ,V}, p, u, v) where {V} +function inner(::Segre{ℝ}, p, u, v) return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) end @@ -266,7 +257,7 @@ Then this is where ``\sphericalangle(x_i, y_i)`` is the distance between ``x_i`` and ``y_i`` on the sphere ``S^{n_i - 1}``. """ -function spherical_angle_sum(M::Segre{ℝ,V}, p, q) where {V} +function spherical_angle_sum(::Segre{ℝ,V}, p, q) where {V} return sqrt( sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), ) From 07dca08da9af61e33e710320b0ade089b73f845e Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Wed, 18 Dec 2024 20:14:36 +0100 Subject: [PATCH 18/35] Sponsor a nice show function. --- src/manifolds/Segre.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index bb3e19dd32..e8fc479634 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -488,3 +488,7 @@ function sectional_curvature(M::Segre{ℝ,V}, p, u, v) where {V} return inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) end + +function Base.show(io::IO, M::Segre{𝔽,V}) where {𝔽,V} + return print(io, "Segre($(join(V, ", ")); field=$(𝔽))") +end From 4620c18121c0e67eaa2b9df703938ab0df2572a8 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Wed, 18 Dec 2024 21:04:14 +0100 Subject: [PATCH 19/35] Ooops. Deleted a parameter too much. --- src/manifolds/Segre.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index e8fc479634..df6ce276c3 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -135,7 +135,14 @@ using a `DefaultOrthonormalBasis` on each factor. """ get_coordinates(M::Segre, p, v, ::DefaultOrthonormalBasis; kwargs...) -function get_coordinates_orthonormal!(M::Segre{ℝ}, X, p, v, ::RealNumbers; kwargs...) +function get_coordinates_orthonormal!( + M::Segre{ℝ,V}, + X, + p, + v, + ::RealNumbers; + kwargs..., +) where {V} return X = vcat( v[1], p[1][1] * [ From f3a7f5081adb0011d7cd838bae7de07ba90af744 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Thu, 19 Dec 2024 08:18:49 +0100 Subject: [PATCH 20/35] reduce magic numbers in testing and replace them by a bit more structured points and tangents. --- test/manifolds/segre.jl | 989 +++------------------------------------- 1 file changed, 55 insertions(+), 934 deletions(-) diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index a27ba15201..d190f44f1b 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -13,798 +13,59 @@ Ms = [ ] # Vs[i] is the valence of Ms[i] -Vs = [(10,), (7, 2), (7, 9, 9), (9, 3, 6, 6), (10), (2, 9), (9, 6, 10), (9, 3, 8, 10)] +Vs = [(10,), (7, 2), (7, 9, 9), (9, 3, 6, 6), (10,), (2, 9), (9, 6, 10), (9, 3, 8, 10)] + +# n β‰₯ k, for same n,k X is in TpM and can be scaled by l +unit_p(n, k) = 1 / sqrt(k) .* [ones(k)..., zeros(n - k)...] +unit_X(n, k; l=1.0) = l / sqrt(n - k) .* [zeros(k)..., ones(n - k)...] # ps[i] is a point on Ms[i] ps = [ - [ - [0.4679314536763416], - [ - -0.317396495862958, - 0.09740239786995583, - -0.03435690079466174, - -0.507098294482249, - -0.3456993992812562, - 0.03370180478069075, - 0.12197903860091835, - -0.19063489706041362, - -0.6772451984545433, - -0.030292993087650443, - ], - ], - [ - [1.5024828708442504], - [ - -0.20674979086955983, - 0.006156775886150006, - -0.3570727686996312, - -0.02472149296318015, - -0.8820637035264094, - -0.19877726490312608, - 0.10749756092041758, - ], - [0.13573491868289245, 0.9907451901726038], - ], - [ - [0.5567549635823631], - [ - 0.20108807178297264, - 0.11422009200726954, - -0.4229195164047098, - 0.8118482504243884, - -0.2985123290622806, - -0.10304198468607091, - 0.0939765805139303, - ], - [ - 0.04424901152619659, - -0.7169306819079923, - -0.031129292324036512, - 0.6372250118096429, - -0.02583896509973039, - 0.014153747195613426, - 0.16225623748001994, - -0.11092394734951527, - 0.19372269982536366, - ], - [ - 0.42796852361059873, - 0.1000612228302854, - -0.6494403216595616, - 0.012394320858700462, - -0.44765471097923526, - 0.28788160552521874, - 0.26926315361113184, - 0.14434420119149496, - 0.09108177932795573, - ], - ], - [ - [0.13874530878036045], - [ - 0.22313639103335817, - -0.582683687448744, - 0.019810748294280565, - -0.532091804219692, - 0.4183784535017075, - 0.14178309829111962, - -0.20220724006960822, - 0.29098277220121593, - 0.08046116169937856, - ], - [0.9267624891781729, -0.13156790592635095, 0.35185391113703934], - [ - -0.20128032438008028, - -0.8385905159101716, - 0.32092863797763976, - -0.004535145988646948, - 0.2201729511393691, - -0.3236669445683654, - ], - [ - -0.4807744861170881, - -0.7965214809133648, - 0.05085093394774735, - -0.18228152610151416, - -0.3136581939724126, - -0.014682951172671068, - ], - ], - [ - [1.1838757652294163], - [ - 0.210872386528422, - 0.07121151449265378, - -0.5646662541775129, - 0.3616416663029674, - 0.06637879222702027, - 0.07584789624963773, - -0.5828313418578935, - 0.2675952004007925, - 0.22734623628568493, - 0.16638557775398255, - ], - ], - [ - [1.2844162220009774], - [-0.30842015389728145, 0.951250234517699], - [ - 0.30279327531038325, - 0.08852690888227953, - 0.05590206678861999, - -0.11020418544430191, - 0.34622673649276936, - 0.039237251633264296, - 0.2036788352046126, - 0.7474907644209177, - -0.4044368794841003, - ], - ], - [ - [0.5007028223906543], - [ - -0.06769241297456885, - -0.5449485746545011, - 0.398606571568952, - 0.6501033139153659, - -0.04258821690222594, - -0.13267612920115782, - 0.28917066939208946, - -0.0862022715614269, - 0.08037444499516286, - ], - [ - -0.435703924552393, - 0.003588856443541161, - -0.6651813230937048, - 0.2132673584452006, - -0.23794057413100464, - -0.5153487505082289, - ], - [ - 0.10026563183607826, - -0.41453578717039885, - 0.22729656824470607, - -0.4898014879827773, - 0.3079502543279662, - 0.32626734055020185, - 0.22241280421779944, - -0.20185051232763798, - 0.26385177592505493, - -0.4067248155023813, - ], - ], - [ - [0.18481028402754704], - [ - 0.3100324954044331, - 0.20571167887073383, - 0.2759549800636245, - -0.5098047663273968, - -0.40513901097801985, - -0.006849531735112356, - 0.32426009440794523, - 0.0980343539650855, - 0.496558786543343, - ], - [0.7400543367573574, -0.6634600702609377, -0.11018309224186618], - [ - -0.3047981091301781, - -0.2991724005041669, - -0.180567141067543, - -0.46275630707119686, - 0.5780573143957574, - 0.04795327307127396, - 0.27896164368216786, - -0.3956977653578857, - ], - [ - -0.5375940335785957, - -0.33527871549213856, - -0.34423023822843113, - -0.057618837476544824, - 0.2307053118861316, - -0.5816558302641435, - 0.1347923363882464, - 0.005386448290725161, - 0.17361223551501662, - -0.19203856057632393, - ], - ], + [[0.5], unit_p(10, 4)], + [[0.6], unit_p(7, 3), unit_p(2, 1)], + [[0.7], unit_p(7, 3), unit_p(9, 5), unit_p(9, 4)], + [[0.8], unit_p(9, 3), unit_p(3, 1), unit_p(6, 4), unit_p(6, 3)], + [[0.9], unit_p(10, 4)], + [[1.0], unit_p(2, 1), unit_p(9, 5)], + [[1.1], unit_p(9, 3), unit_p(6, 5), unit_p(10, 4)], + [[1.2], unit_p(9, 3), unit_p(3, 1), unit_p(8, 4), unit_p(10, 4)], ] # qs[i] is a point on Ms[i] that is connected to ps[i] by a geodesic and uses the closest representative to ps[i] +# (tricked by only switching only one entry to zero) qs = [ - [ - [0.2285468999681258], - [ - 0.0072000169737206285, - 0.46919050788513217, - -0.0578728225972693, - 0.14417171957969074, - 0.5393873747379379, - 0.3535952408499787, - -0.19179220675967715, - 0.0603486044844522, - -0.3902812557079805, - 0.38335320681028, - ], - ], - [ - [0.9263875479802128], - [ - -0.2876490379709154, - 0.5934703502895091, - 0.00669105544965959, - -0.5238009412763243, - 0.48771046854635186, - 0.22195505041284128, - 0.05927252688380565, - ], - [-0.8467814852966212, 0.5319408953623024], - ], - [ - [0.05929877942048794], - [ - -0.2492472329981639, - 0.19078207722614024, - -0.6950020535594956, - 0.6155692112895002, - 0.12163736596071065, - 0.07617216946811589, - -0.13757492254479187, - ], - [ - -0.3446138929389734, - -0.44528715923871226, - 0.09867730315307487, - 0.3856741902911293, - -0.03976898819561624, - -0.09854548801276108, - 0.5786967392957476, - 0.419483004838766, - -0.048271382271637374, - ], - [ - -0.13898349823957276, - 0.37007148419755803, - -0.5672020653516858, - 0.2664429979574558, - 0.26019214805889984, - -0.183973837333837, - -0.537331406376888, - -0.2092584392846679, - -0.13023121083469708, - ], - ], - [ - [0.5944460845919239], - [ - 0.18440528974038717, - -0.3234774292705488, - -0.07521274368923382, - -0.5055464117085976, - 0.17461559395815557, - 0.20174607290008786, - -0.5921554567742019, - 0.22060599004214254, - 0.3600218594053353, - ], - [0.9391716922907767, -0.20920363981570536, -0.27237909150215467], - [ - 0.594536709760007, - -0.6154768837189905, - 0.2868298100684849, - 0.08944875927641796, - 0.42003473849671874, - 0.031823015747801525, - ], - [ - 0.04047760394645142, - 0.5651446411453817, - 0.4996377449872775, - 0.5242952935259201, - -0.18199312205158755, - -0.34832193537003325, - ], - ], - [ - [0.9068920036691095], - [ - 0.028598193298964708, - 0.4294897666239807, - 0.5582305652867099, - 0.20015138065027618, - -0.36032666340358765, - -0.06085371828646839, - 0.3481371808459643, - 0.3824819666832563, - 0.15057862863095645, - 0.19832899484009994, - ], - ], - [ - [1.8900272913460916], - [-0.24462417095922365, 0.9696179737311559], - [ - 0.0029148214868594184, - 0.046733730849394826, - 0.3464166332779196, - -0.41612585782053313, - 0.4403234930433767, - -0.07014699792539351, - -0.6626027503215617, - 0.06409791188610743, - -0.25037156781949155, - ], - ], - [ - [1.3388920951283048], - [ - -0.2894849285247092, - -0.375237468281043, - 0.10659685105991663, - 0.5326935539788507, - -0.2687936085300003, - -0.28583226069914086, - -0.06940771783985483, - 0.566949781731537, - 0.0083926101085135, - ], - [ - -0.2692873331242094, - -0.352948146454535, - -0.36201078692503574, - 0.26291906209331745, - -0.430264386434885, - -0.6462246148490923, - ], - [ - -0.2899662461053266, - 0.561676369276759, - 0.29953621040966766, - 0.026981212635263388, - -0.1879070254370779, - -0.10235375900374745, - -0.04777542564881818, - -0.6562458092558364, - 0.02736625708068412, - -0.17468256196490237, - ], - ], - [ - [0.5595013700016621], - [ - -0.16410496932023275, - 0.2124425044194968, - 0.019103430387761126, - -0.49321855967754313, - 0.2187406652190155, - -0.2438450092656317, - -0.29126737061752705, - -0.6546701444600094, - 0.2521323190300214, - ], - [0.5091077043894671, -0.7810695653023092, -0.36157942348777083], - [ - 0.09792086442785906, - -0.46300382891140285, - -0.34321497128243517, - -0.4715033116632154, - 0.23250354333074766, - 0.3343541579831825, - 0.33398745563364823, - -0.39815681352786747, - ], - [ - 0.1472380561455175, - -0.2928950599225513, - -0.06829513714619305, - 0.2630794095929546, - -0.07520704498840525, - -0.097452294891074, - 0.1546325256973868, - -0.7547590605905541, - 0.42527618176727117, - -0.17050835599699163, - ], - ], -] - -# vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representative to ps[i] for t in [-1, 1] -vs = [ - [ - [0.6940789907123062], - [ - 0.14913995456500687, - -0.030547142938236793, - 0.31162623436384285, - -0.20563967625033036, - 0.19319043822673818, - 0.317062500120066, - -0.8754858218076765, - -0.3259209038205042, - -0.033243255319008624, - -1.1548635082931478, - ], - ], - [ - [0.45470843046349313], - [ - 0.433513329547113, - -0.7320515075884788, - -0.38765391945909755, - 0.19640702045402264, - 0.14944186690806377, - -0.9671407596317976, - -0.9289295848779034, - ], - [-0.5045110500803344, 0.06911945375717096], - ], - [ - [-0.14362437882603868], - [ - 0.21703580244995338, - -0.07582942569056315, - -0.4131524696769127, - 0.07113227925464494, - 0.9216831076067749, - -0.3117658924120991, - -0.2601938828890881, - ], - [ - -0.40993096871840384, - 0.06033520676657045, - 0.3353505686920585, - 0.32669207217743906, - -0.26949939576113957, - 0.4622586254534011, - -0.23046667729151138, - 0.39890816877066293, - -0.352075854880814, - ], - [ - 0.27574595870419494, - -0.20132897843112602, - 0.7181884086912088, - 0.20902304397906357, - -0.9797911979282492, - -0.22738728408774556, - -0.08434852248139064, - -0.03906999050989374, - 0.23241083119724726, - ], - ], - [ - [-0.10835780918855986], - [ - -0.2879956140065193, - 0.43075721925722893, - -0.3291055923326802, - 0.017387780693294552, - 0.060086501392198954, - -0.22944578876172467, - -0.2678362137267055, - 0.821848362075142, - 0.5607641072034037, - ], - [0.1257205818761756, 0.5344739830694265, -0.1312860116480018], - [ - -0.32028258895073813, - 0.05581149125388041, - -0.38726569273936556, - -0.4124721885803405, - 0.09543462429188473, - -0.2587175245909177, - ], - [ - 0.23313088537058163, - 0.398484868218528, - 0.17079789329674128, - -0.5464610930958373, - -1.0423151616550292, - 0.3909668100967531, - ], - ], - [ - [-0.25050034943799143], - [ - 0.3488629827096742, - -0.01790447096652751, - 0.41078746198742494, - 0.2674738658616262, - -0.3676063246452534, - 0.27995679376647054, - -0.6476807696598814, - -0.05608263854802896, - -1.002407614041255, - -0.41159169074078095, - ], - ], - [ - [0.7638265778356526], - [0.043718096583251764, 0.014174547965435269], - [ - 0.1589574325807131, - 0.8748133883099838, - -0.3528071207217161, - -0.2644899757823254, - 0.24010835273681236, - -0.1673897092037622, - -0.6222042985569745, - -0.09191448012128656, - 0.039882538236865134, - ], - ], - [ - [-0.2827629165886028], - [ - -0.5431768324825607, - -0.2133080279346807, - -0.10499961310795408, - 0.09083087776121102, - 0.37394345246532357, - 0.41219715056530515, - -0.17844896356814216, - 0.6017127772767268, - 0.04825845645947814, - ], - [ - 0.1686105642978755, - 0.27823583527578005, - -0.06479699938479212, - 0.4075789329243761, - -0.1242362543997863, - 0.16905085277591742, - ], - [ - 0.4498529143568951, - -0.38162629109703405, - -0.6140545422956211, - 0.15825503736095084, - -0.2582602332898444, - 0.7274993022330352, - -0.2411292264007391, - -0.5521909388447415, - -0.32703914771404785, - 0.28418328300445966, - ], - ], - [ - [-0.13762858893746074], - [ - -0.44703815295307797, - 0.5944800147380626, - 1.4927738811624347, - 0.2690676585035225, - 0.1392293231358478, - -0.40920070507884104, - -0.7332317211680289, - -0.3830957876846897, - 0.1418909392355959, - ], - [-0.28919223043248377, -0.334256240757651, 0.07031663871919733], - [ - 1.4923062450401439, - -0.07045305045420008, - 1.1439824974086474, - -0.48836659931427834, - 0.9029762904802794, - -0.4051626818191545, - 0.7052172856721804, - 0.7200604408974567, - ], - [ - -0.4660428754709174, - 0.3303812040550049, - 0.0416448317248993, - 0.0923448025024135, - -0.11839363942123281, - 0.12128945856537898, - -0.3046909560916853, - -0.9180764335769804, - -0.8185102432606277, - -0.8637091370051597, - ], - ], + [[0.1], unit_p(10, 3)], + [[0.2], unit_p(7, 2), unit_p(2, 2)], + [[0.3], unit_p(7, 2), unit_p(9, 4), unit_p(9, 3)], + [[0.4], unit_p(9, 3), unit_p(3, 1), unit_p(6, 3), unit_p(6, 2)], + [[0.5], unit_p(10, 3)], + [[0.6], unit_p(2, 2), unit_p(9, 5)], + [[0.7], unit_p(9, 2), unit_p(6, 4), unit_p(10, 3)], + [[0.8], unit_p(9, 2), unit_p(3, 2), unit_p(8, 3), unit_p(10, 3)], ] # us[i] is a tangent vector to Ms[i] at ps[i] us = [ - [ - [-0.37772914799158225], - [ - -0.59695867308892, - 0.3750933177933997, - 0.34564315403507745, - 0.046043813336741984, - -0.0545409875155681, - 0.2577121584084208, - -0.3308621558840682, - 0.15972331014082508, - 0.23275600794660842, - -0.33394550809020124, - ], - ], - [ - [-0.2603225446842325], - [ - 0.3602679784109386, - 0.17337068990715637, - -0.19313197776041668, - -0.25410123672991486, - 0.08222041883237792, - -0.21642611657517966, - 0.2574667569083157, - ], - [1.3205385203894777, -0.18091754616690692], - ], - [ - [-0.14766117733667908], - [ - -1.0051180880053472, - 0.9460677967957836, - 0.5835821685582908, - 0.6948551934342009, - 0.6374252884087097, - -0.009680426176410788, - -0.36146835559128143, - ], - [ - 0.4688516869504158, - -0.28425151202447, - -0.3187195701047898, - -0.35633492041750464, - 0.554715750802327, - -0.10721116773599117, - 0.28645702408100504, - -0.1610220090851739, - -0.28845747034499986, - ], - [ - 0.09417372769886223, - 0.1989812337413881, - -0.08400464069697863, - -0.6790036003882072, - -0.22919842842946442, - 0.3185935243022103, - -0.9397877219225759, - -0.548382602086301, - 0.3462072647694016, - ], - ], - [ - [-0.8237610837914967], - [ - 0.3004390493463726, - 0.4405860908850111, - -0.7157767786794753, - -0.26422248721975317, - 0.43563297876352225, - -0.05301527548401603, - 0.2653406121711885, - -0.16921344490396534, - -0.10660913986306259, - ], - [0.2301095438238535, 0.13543635311552182, -0.5554515952958057], - [ - -0.047141475305190236, - 0.26349478946841576, - 0.7660038342835548, - -0.44707592462720674, - -0.008237239351391848, - 0.10681017970047482, - ], - [ - -0.10101942119876328, - -0.09752768648570287, - -0.03101236164578546, - -0.017267002331470507, - 0.426143631920239, - -0.3979129485173604, - ], - ], - [ - [-0.11566741406383592], - [ - -0.6189044291634334, - -0.4887938523139652, - 0.377907148579411, - 0.4086524760594208, - 0.07938663795474155, - -0.6960459002055371, - -0.5157245121702985, - -0.0949098978719522, - 0.35850803987739277, - -0.4702399492568731, - ], - ], - [ - [-0.44426957903450753], - [0.02248238255936011, 0.0072893752214958085], - [ - -0.11483810063446695, - 0.7180538788465062, - 1.2336105712455359, - 0.5094984474406282, - 0.44539460730056, - -0.22600080346686421, - 0.23177494146123226, - 0.04078051728077603, - 0.6543369295727094, - ], - ], - [ - [0.26115469823295706], - [ - 0.9332535998779934, - 0.8409422500428906, - 1.1570765490059969, - 0.009748111907376684, - 0.1823249755535606, - 0.42856570496684815, - 0.5854663071660117, - 0.3272130825134361, - -0.2809222008539077, - ], - [ - -0.3442363693316475, - -0.5817781819508783, - 0.35114374833485607, - 1.1229502716222781, - 0.45619247794084083, - 0.08783351766172355, - ], - [ - 0.06361430009419232, - 0.6926810562240848, - -0.4297785211478541, - -0.46202875308860125, - -0.36949007474336926, - 0.8488609929914562, - 0.030242445794160633, - -0.14503901054294097, - 0.2058457533515663, - 0.2491580414140638, - ], - ], - [ - [0.1798820030601053], - [ - -0.1533759903297747, - 0.2964688376499158, - -0.14860837418627715, - -0.5551072496477686, - 0.19870817329497556, - -0.3760368493600557, - 0.4044751294601737, - -0.32878881969363477, - -0.5566640994443255, - ], - [0.5598006445911394, 0.4954191143909883, 0.7768169558982286], - [ - 0.035077508613607256, - -0.18338072549214748, - -0.11985026451776065, - 0.7471592115103867, - 0.34655767438419205, - 0.22412820486882898, - 0.6981705844979219, - 0.3181720496138494, - ], - [ - 0.18466074016625922, - 0.5419495972646897, - 0.5887579351606795, - -0.5653359894384714, - 0.16017679421854783, - -0.49769950032627924, - -0.6930225262597705, - 0.3904417023562996, - 0.6252695138324811, - -0.5591798774189761, - ], - ], + [[0.5], unit_X(10, 4)], + [[0.6], unit_X(7, 3), unit_X(2, 1)], + [[0.7], unit_X(7, 3), unit_X(9, 5), unit_X(9, 4)], + [[0.8], unit_X(9, 3), unit_X(3, 1), unit_X(6, 4), unit_X(6, 3)], + [[0.9], unit_X(10, 4)], + [[1.0], unit_X(2, 1), unit_X(9, 5)], + [[1.1], unit_X(9, 3), unit_X(6, 5), unit_X(10, 4)], + [[1.2], unit_X(9, 3), unit_X(3, 1), unit_X(8, 4), unit_X(10, 4)], +] + +# vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representative to ps[i] for t in [-1, 1] +vs = [ + [[0.5], unit_X(10, 5)], + [[0.6], unit_X(7, 4), unit_X(2, 1)], + [[0.7], unit_X(7, 4), unit_X(9, 6), unit_X(9, 5)], + [[0.8], unit_X(9, 4), unit_X(3, 1), unit_X(6, 5), unit_X(6, 4)], + [[0.9], unit_X(10, 5)], + [[1.0], unit_X(2, 1), unit_X(9, 6)], + [[1.1], unit_X(9, 4), unit_X(6, 5), unit_X(10, 5)], + [[1.2], unit_X(9, 4), unit_X(3, 1), unit_X(8, 5), unit_X(10, 5)], ] # When testing that exp(Ms[i], ps[i], t * vs[i]) is an extremum of the length functional, we parametrize curves in Ms[i] and take a derivative along dys[i] @@ -1357,154 +618,14 @@ dys = [ # Xs[i] is coordinates for a tangent vector at ps[i] Xs = [ - [ - -0.597609995187605, - -0.4256244780566225, - 0.039001131483688445, - 0.2861310539156201, - -0.5445479395430848, - 0.5398107502679328, - -0.370911828798264, - 0.9784991722126772, - -0.858313200235999, - 0.6327050201672981, - ], - [ - 0.20291047527778772, - -0.33259407228555404, - 0.2518919563557016, - 0.7589380540013582, - 0.5699565849101806, - -0.0840258727078147, - 0.17702183701764684, - -0.020864846013727956, - ], - [ - -0.33715222274078416, - -0.26704690491931915, - -0.5195355208430397, - 0.645753717662719, - 0.10444433627227578, - 0.33684638019021196, - 0.06539241093725567, - 0.09555909109964422, - 0.7542247481144044, - -0.20290163218931467, - -0.2664420819862636, - 0.339548396803274, - 0.9402884626822843, - -0.6574225234652968, - 0.07702642759782674, - -0.5460026086958019, - -0.6357161050460245, - -0.5843960906310703, - -0.2548940878123618, - 0.6267033715997288, - 0.08231062546698587, - 0.15159625893365325, - -0.12967230344148017, - ], - [ - -0.34597205746030824, - 0.9028413427061659, - 0.32181983134495096, - 0.9413815779327186, - 0.16359943156565016, - 0.7838434998605843, - -0.35087705212133735, - -0.2339200570289206, - -0.9229212375554967, - 0.9129319387405792, - -0.9083283912242541, - 0.13034732808854765, - 0.9882693345252747, - 0.19949043337639316, - 0.5191850007789172, - 0.6832919121607344, - 0.08923979072216182, - -0.1641363924011765, - 0.060902972183083826, - -0.13189846296393637, - 0.8496859744073246, - ], - [ - -0.3508209068712791, - 0.5477811869201115, - 0.9576443316471701, - 0.3815048454137753, - -0.3581096313769696, - -0.3297365896057076, - 0.46016273166688904, - -0.8346220116109249, - -0.3150517800054915, - 0.5838284430955387, - ], - [ - 0.30756479319371266, - -0.43184860921312285, - 0.37624726262849206, - 0.8139529250407125, - -0.585675532332042, - -0.5857479127690419, - -0.45612298630613823, - 0.2559126942459271, - -0.7348456829025003, - -0.8876636700373159, - ], - [ - 0.5526596524494152, - 0.9690315932495712, - -0.8680156139856099, - 0.39561955960098705, - -0.7189141230781315, - 0.1091438241240188, - -0.1514792667377174, - -0.8842187642857129, - -0.90929587555064, - 0.0553477365473245, - -0.38102440387803127, - -0.21972849843690567, - -0.1366925641984078, - 0.234658614104986, - 0.6618349090074298, - 0.3456641681297574, - -0.13000537043751015, - 0.015349401356097525, - 0.4014083014273322, - -0.05782560373055445, - -0.3626979339434868, - -0.46909114377791794, - 0.037734998042463275, - ], - [ - -0.6945216072262328, - 0.06573632900997772, - -0.106647523045865, - 0.13865277008666044, - -0.7820633695316517, - -0.10880551946361727, - 0.2658232882927578, - -0.08490107870171215, - 0.8401971948812119, - -0.5389907554930264, - 0.9847445142919777, - 0.6022812602894703, - 0.45645830164530143, - -0.24553265752254427, - 0.06468186895698413, - 0.692893319789019, - -0.19092820288195367, - 0.45737634128864624, - 0.10728439355457109, - 0.5890201396380044, - -0.9502112271317584, - -0.2302405122715243, - 0.8242967867244597, - -0.7636718337376485, - -0.2653389884306485, - 0.500710013837995, - -0.24084472766713083, - ], + [-0.5, -0.4, 0.0, 0.2, -0.5, 0.5, -0.3, 0.9, -0.8, 0.6], + [0.2, -0.3, 0.2, 0.7, 0.5, 0.0, 0.1, 0.0], + [-0.3, -0.2, -0.5, 0.6, 0.1, 0.3, 0.0, zeros(16)...], + [-0.3, 0.9, 0.3, 0.9, 0.1, zeros(16)...], + [-0.3, 0.5, 0.9, 0.3, -0.3, -0.3, 0.4, -0.8, -0.3, 0.5], + [0.3, -0.4, 0.3, 0.8, -0.5, -0.5, -0.4, 0.2, -0.7, -0.8], + [0.5, 0.9, -0.8, 0.3, -0.7, 0.1, -0.1, zeros(16)...], + [-0.6, 0.0, -0.1, 0.1, -0.7, -0.1, 0.2, -0.0, 0.8, -0.5, 0.9, zeros(16)...], ] for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @@ -1512,14 +633,14 @@ for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @testset "is_point" begin @test(is_point(M, p)) @test(is_point(M, q)) - @test_throws DomainError is_point(M, [[1.0, 0.0], p[2:end]...], true) - @test_throws DomainError is_point(M, [[-1.0], p[2:end]...], true) - @test_throws DomainError is_point(M, [p[1], 2 * p[2:end]...], true) + @test_throws DomainError is_point(M, [[1.0, 0.0], p[2:end]...]; error=:error) + @test_throws DomainError is_point(M, [[-1.0], p[2:end]...]; error=:error) + @test_throws DomainError is_point(M, [p[1], 2 * p[2:end]...]; error=:error) end @testset "is_vector" begin - @test(is_vector(M, p, v)) - @test(is_vector(M, p, u)) + @test(is_vector(M, p, v; error=:error)) + @test(is_vector(M, p, u; error=:error)) @test_throws DomainError is_vector(M, [[1.0, 0.0], p[2:end]...], v, false, true) @test_throws DomainError is_vector(M, p, [[1.0, 0.0], v[2:end]...], false, true) @test_throws DomainError is_vector(M, p, p, false, true) From c958bd24e305bbcf9b35920862c0b8b7adabcdb1 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Thu, 19 Dec 2024 08:47:01 +0100 Subject: [PATCH 21/35] Add Simon to the about page, adapt menu, wrap Segre test in a testset. --- docs/make.jl | 2 +- docs/src/manifolds/segre.md | 2 +- docs/src/misc/about.md | 1 + test/manifolds/segre.jl | 1613 ++++++++++++++++++----------------- 4 files changed, 822 insertions(+), 796 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index f63e0e30b8..58d7d3319d 100755 --- a/docs/make.jl +++ b/docs/make.jl @@ -201,7 +201,7 @@ makedocs(; "Projective space" => "manifolds/projectivespace.md", "Orthogonal and Unitary Matrices" => "manifolds/generalunitary.md", "Rotations" => "manifolds/rotations.md", - "Segre-Veronese" => "manifolds/segre.md", + "Segre" => "manifolds/segre.md", "Shape spaces" => "manifolds/shapespace.md", "Skew-Hermitian matrices" => "manifolds/skewhermitian.md", "Spectrahedron" => "manifolds/spectrahedron.md", diff --git a/docs/src/manifolds/segre.md b/docs/src/manifolds/segre.md index bfaef2ab84..339b934157 100644 --- a/docs/src/manifolds/segre.md +++ b/docs/src/manifolds/segre.md @@ -10,7 +10,7 @@ Pages = ["manifolds/Segre.jl"] Order = [:function] ``` -## A warped metric +## [A warped metric](@id segre-warped-metric-sec) ```@docs WarpedMetric diff --git a/docs/src/misc/about.md b/docs/src/misc/about.md index f70a1b9adc..613f0aa687 100644 --- a/docs/src/misc/about.md +++ b/docs/src/misc/about.md @@ -17,6 +17,7 @@ - [Nick Dewaele](https://github.com/Nikdwal) contributed the [Tucker manifold](../manifolds/tucker.md) - [RenΓ©e Dornig](https://github.com/r-dornig) contributed the [centered matrices](../manifolds/centeredmatrices.md) and the [essential manifold](../manifolds/essentialmanifold.md) - [David Hong](https://github.com/dahong67) contributed uniform distributions on the Stiefel and Grassmann manifolds. +- [Simon Jacobsson](https://github.com/sjacobsson) contributed the [Segre manifold](../manifolds/segre.md) including its [warped metric](@ref segre-warped-metric-sec) thereon. - [Johannes Voll KolstΓΈ](https://github.com/johannvk) contributed the [symplectic manifold](../manifolds/symplectic.md), the [symplectic Stiefel manifold](../manifolds/symplecticstiefel.md) - [Manuel Weiß](https://github.com/manuelweisser) contributed [symmetric matrices](../manifolds/symmetric.md) diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index d190f44f1b..1216bb0547 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -1,816 +1,841 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences -# Manifolds to test -Ms = [ - Segre(10), - Segre(7, 2), - Segre(7, 9, 9), - Segre(9, 3, 6, 6), - MetricManifold(Segre(10), WarpedMetric{1.2025837056880606}()), - MetricManifold(Segre(2, 9), WarpedMetric{1.1302422072971439}()), - MetricManifold(Segre(9, 6, 10), WarpedMetric{1.4545138169484464}()), - MetricManifold(Segre(9, 3, 8, 10), WarpedMetric{1.396673190458706}()), -] - -# Vs[i] is the valence of Ms[i] -Vs = [(10,), (7, 2), (7, 9, 9), (9, 3, 6, 6), (10,), (2, 9), (9, 6, 10), (9, 3, 8, 10)] - -# n β‰₯ k, for same n,k X is in TpM and can be scaled by l -unit_p(n, k) = 1 / sqrt(k) .* [ones(k)..., zeros(n - k)...] -unit_X(n, k; l=1.0) = l / sqrt(n - k) .* [zeros(k)..., ones(n - k)...] - -# ps[i] is a point on Ms[i] -ps = [ - [[0.5], unit_p(10, 4)], - [[0.6], unit_p(7, 3), unit_p(2, 1)], - [[0.7], unit_p(7, 3), unit_p(9, 5), unit_p(9, 4)], - [[0.8], unit_p(9, 3), unit_p(3, 1), unit_p(6, 4), unit_p(6, 3)], - [[0.9], unit_p(10, 4)], - [[1.0], unit_p(2, 1), unit_p(9, 5)], - [[1.1], unit_p(9, 3), unit_p(6, 5), unit_p(10, 4)], - [[1.2], unit_p(9, 3), unit_p(3, 1), unit_p(8, 4), unit_p(10, 4)], -] - -# qs[i] is a point on Ms[i] that is connected to ps[i] by a geodesic and uses the closest representative to ps[i] -# (tricked by only switching only one entry to zero) -qs = [ - [[0.1], unit_p(10, 3)], - [[0.2], unit_p(7, 2), unit_p(2, 2)], - [[0.3], unit_p(7, 2), unit_p(9, 4), unit_p(9, 3)], - [[0.4], unit_p(9, 3), unit_p(3, 1), unit_p(6, 3), unit_p(6, 2)], - [[0.5], unit_p(10, 3)], - [[0.6], unit_p(2, 2), unit_p(9, 5)], - [[0.7], unit_p(9, 2), unit_p(6, 4), unit_p(10, 3)], - [[0.8], unit_p(9, 2), unit_p(3, 2), unit_p(8, 3), unit_p(10, 3)], -] - -# us[i] is a tangent vector to Ms[i] at ps[i] -us = [ - [[0.5], unit_X(10, 4)], - [[0.6], unit_X(7, 3), unit_X(2, 1)], - [[0.7], unit_X(7, 3), unit_X(9, 5), unit_X(9, 4)], - [[0.8], unit_X(9, 3), unit_X(3, 1), unit_X(6, 4), unit_X(6, 3)], - [[0.9], unit_X(10, 4)], - [[1.0], unit_X(2, 1), unit_X(9, 5)], - [[1.1], unit_X(9, 3), unit_X(6, 5), unit_X(10, 4)], - [[1.2], unit_X(9, 3), unit_X(3, 1), unit_X(8, 4), unit_X(10, 4)], -] - -# vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representative to ps[i] for t in [-1, 1] -vs = [ - [[0.5], unit_X(10, 5)], - [[0.6], unit_X(7, 4), unit_X(2, 1)], - [[0.7], unit_X(7, 4), unit_X(9, 6), unit_X(9, 5)], - [[0.8], unit_X(9, 4), unit_X(3, 1), unit_X(6, 5), unit_X(6, 4)], - [[0.9], unit_X(10, 5)], - [[1.0], unit_X(2, 1), unit_X(9, 6)], - [[1.1], unit_X(9, 4), unit_X(6, 5), unit_X(10, 5)], - [[1.2], unit_X(9, 4), unit_X(3, 1), unit_X(8, 5), unit_X(10, 5)], -] - -# When testing that exp(Ms[i], ps[i], t * vs[i]) is an extremum of the length functional, we parametrize curves in Ms[i] and take a derivative along dys[i] -dys = [ - [ - 0.24768051036976024, - 0.15340874919881428, - 0.10461792180729243, - 0.1621738878738882, - 0.13788895788409475, - 0.13920478959340893, - 0.1980520199776914, - 0.225220769065586, - 0.09192923424127934, - 0.15861132814448145, - 0.07788788182581427, - 0.2033127058413462, - 0.11406283238286104, - 0.020870012361419343, - 0.2719578430552649, - 0.15170700765742606, - 0.07022129511933332, - 0.04843952826362164, - 0.2555544578976192, - 0.06681340738035137, - 0.15586613310716685, - 0.018646851863471762, - 0.1979297092698637, - 0.23753411269988997, - 0.21343310337377225, - 0.08016910818336964, - 0.1464783972931314, - 0.025950651929534232, - 0.1449831966165307, - 0.23373068876892722, - 0.11880598168141776, - 0.19121899600576953, - 0.15179084381364852, - 0.04935589775227154, - 0.1560593153225572, - 0.04411343229804097, - 0.2392666728301238, - 0.1484349911958273, - 0.17060958026859915, - 0.01433037040599356, - ], - [ - 0.2703013619564934, - 0.1674196883015804, - 0.11417275710290055, - 0.17698535383607492, - 0.15048246250457872, - 0.15191847013635482, - 0.2161402633508973, - 0.2457903551976426, - 0.10032520193833194, - 0.1730974227854145, - 0.08500144200281991, - 0.22188141170224845, - 0.12448027862860386, - 0.022776086648557087, - 0.29679596211605436, - 0.16556252539583352, - 0.07663466003347703, - 0.05286354765112583, - 0.278894443170582, - 0.07291552728513738, - 0.17010150697308607, - 0.020349883191748984, - 0.21600678191201325, - 0.2592282859804155, - 0.23292611292832396, - 0.08749101451887183, - 0.15985638202387917, - 0.02832074493766232, - 0.1582246235190211, - 0.255077492415341, - 0.12965662340215453, - 0.20868317404203518, - ], - [ - 0.16353440643700792, - 0.10129020125571776, - 0.06907539765598648, - 0.10707750259980159, - 0.0910430491609086, - 0.09191184484141025, - 0.13076652451317197, - 0.14870505851042468, - 0.06069752009721213, - 0.1047252743607885, - 0.05142652727905344, - 0.13423996349664308, - 0.07531152759015192, - 0.013779707893699597, - 0.17956384365300332, - 0.10016660338980309, - 0.04636455972831437, - 0.03198285359980099, - 0.16873328677427074, - 0.0441144557626597, - 0.10291272221322205, - 0.012311836110395775, - 0.1306857672142806, - 0.1568351101623881, - 0.14092209282890691, - 0.05293273783140711, - 0.09671434268855209, - 0.017134268875714943, - 0.09572711622173373, - 0.1543238480770115, - 0.07844325605769907, - 0.12625492803046978, - 0.10022195734569302, - 0.03258789894704945, - 0.10304027338340047, - 0.029126490235301297, - 0.15797905641835802, - 0.09800621027247283, - 0.11264728258206483, - 0.009461820854890907, - 0.07619899497188476, - 0.06435512726649247, - 0.14418724370624061, - 0.020482591380646117, - 0.18622326856315144, - 0.17680302406232687, - 0.11411324587011096, - 0.04559115895133764, - 0.024318253167761508, - 0.0777066933426362, - 0.16696701026147626, - 0.06641466684484068, - 0.06421006278332052, - 0.1069248857665583, - 0.12159103864374035, - 0.05073753945931583, - 0.04924168633871106, - 0.12722583436268306, - 0.18563179386637813, - 0.0687128870870491, - 0.08905886988994213, - 0.009035432164352614, - 0.049561446318667116, - 0.1347085017272271, - 0.1200359392924501, - 0.027268283817115106, - 0.04224558795450571, - 0.04315262171954351, - 0.05403346926811662, - 0.0023262859537098515, - 0.010721414504714139, - 0.13403654903491943, - 0.10987330337776338, - 0.013298908898025385, - 0.14340914694684173, - 0.17825169707180502, - 0.10868078009526573, - 0.0016445884181541684, - 0.07063958523304881, - 0.1101738445443299, - 0.11758054831650003, - 0.060827727766064016, - 0.14865227744166581, - 0.11702503201869387, - 0.09342064187053477, - 0.15738531812684184, - 0.03201521439082036, - 0.06114448967602477, - 0.10382777552410098, - 0.1431354723068435, - 0.18877393058117947, - 0.04238816261102419, - ], - [ - 0.1715795373556408, - 0.1062732072642473, - 0.07247358541051933, - 0.11234521687243985, - 0.0955219430260548, - 0.09643347940647069, - 0.13719962830095694, - 0.15602065459839623, - 0.0636835553069129, - 0.10987726996268543, - 0.053956472834027505, - 0.14084394430027286, - 0.07901650388441198, - 0.014457605324831525, - 0.1883975482043314, - 0.10509433361797467, - 0.04864548006260954, - 0.03355626099441541, - 0.17703417838482685, - 0.046284681464683716, - 0.10797554869382073, - 0.0129175210883459, - 0.1371148981191942, - 0.164550666915154, - 0.14785480326481754, - 0.05553678192838664, - 0.1014722377736982, - 0.01797719507885178, - 0.10043644436402703, - 0.1619158624347057, - 0.08230229880238973, - 0.1324660822900412, - 0.10515241073061003, - 0.03419107175394852, - 0.10810937478733341, - 0.030559377859677404, - 0.16575088999747303, - 0.10282765922416374, - 0.11818900408120409, - 0.009927298359990544, - 0.07994763052677145, - 0.06752109970877263, - 0.15128058435355177, - 0.021490239451779292, - 0.19538458579496817, - 0.1855009091519671, - 0.1197270859333567, - 0.047834031570543896, - 0.02551459792914639, - 0.08152950063326206, - 0.17518100929637484, - 0.06968195903934253, - 0.06736889872885857, - 0.11218509200201603, - 0.1275727512737259, - 0.053233590023432004, - 0.05166414789821036, - 0.13348475269051732, - 0.19476401329869034, - 0.07209324101046329, - 0.09344015137889938, - 0.009479933332347762, - 0.051999638579474684, - 0.14133553242896432, - 0.12594114827928685, - 0.028609756342773685, - 0.04432387406709532, - 0.04527552966766203, - 0.056691664223667886, - 0.002440728384874828, - 0.011248858149159562, - 0.14063052279470464, - 0.11527855802353276, - 0.013953153258528188, - 0.15046420885860654, - 0.18702085012439856, - 0.11402736815129268, - 0.0017254945064788542, - 0.07411472372909801, - 0.11559388441532585, - 0.10893561836452229, - 0.15017707070132247, - 0.198060728501197, - 0.04447346273248423, - ], - [ - 0.24768051036976024, - 0.15340874919881428, - 0.10461792180729243, - 0.1621738878738882, - 0.13788895788409475, - 0.13920478959340893, - 0.1980520199776914, - 0.225220769065586, - 0.09192923424127934, - 0.15861132814448145, - 0.07788788182581427, - 0.2033127058413462, - 0.11406283238286104, - 0.020870012361419343, - 0.2719578430552649, - 0.15170700765742606, - 0.07022129511933332, - 0.04843952826362164, - 0.2555544578976192, - 0.06681340738035137, - 0.15586613310716685, - 0.018646851863471762, - 0.1979297092698637, - 0.23753411269988997, - 0.21343310337377225, - 0.08016910818336964, - 0.1464783972931314, - 0.025950651929534232, - 0.1449831966165307, - 0.23373068876892722, - 0.11880598168141776, - 0.19121899600576953, - 0.15179084381364852, - 0.04935589775227154, - 0.1560593153225572, - 0.04411343229804097, - 0.2392666728301238, - 0.1484349911958273, - 0.17060958026859915, - 0.01433037040599356, - ], - [ - 0.24768051036976024, - 0.15340874919881428, - 0.10461792180729243, - 0.1621738878738882, - 0.13788895788409475, - 0.13920478959340893, - 0.1980520199776914, - 0.225220769065586, - 0.09192923424127934, - 0.15861132814448145, - 0.07788788182581427, - 0.2033127058413462, - 0.11406283238286104, - 0.020870012361419343, - 0.2719578430552649, - 0.15170700765742606, - 0.07022129511933332, - 0.04843952826362164, - 0.2555544578976192, - 0.06681340738035137, - 0.15586613310716685, - 0.018646851863471762, - 0.1979297092698637, - 0.23753411269988997, - 0.21343310337377225, - 0.08016910818336964, - 0.1464783972931314, - 0.025950651929534232, - 0.1449831966165307, - 0.23373068876892722, - 0.11880598168141776, - 0.19121899600576953, - 0.15179084381364852, - 0.04935589775227154, - 0.1560593153225572, - 0.04411343229804097, - 0.2392666728301238, - 0.1484349911958273, - 0.17060958026859915, - 0.01433037040599356, - ], - [ - 0.16353440643700792, - 0.10129020125571776, - 0.06907539765598648, - 0.10707750259980159, - 0.0910430491609086, - 0.09191184484141025, - 0.13076652451317197, - 0.14870505851042468, - 0.06069752009721213, - 0.1047252743607885, - 0.05142652727905344, - 0.13423996349664308, - 0.07531152759015192, - 0.013779707893699597, - 0.17956384365300332, - 0.10016660338980309, - 0.04636455972831437, - 0.03198285359980099, - 0.16873328677427074, - 0.0441144557626597, - 0.10291272221322205, - 0.012311836110395775, - 0.1306857672142806, - 0.1568351101623881, - 0.14092209282890691, - 0.05293273783140711, - 0.09671434268855209, - 0.017134268875714943, - 0.09572711622173373, - 0.1543238480770115, - 0.07844325605769907, - 0.12625492803046978, - 0.10022195734569302, - 0.03258789894704945, - 0.10304027338340047, - 0.029126490235301297, - 0.15797905641835802, - 0.09800621027247283, - 0.11264728258206483, - 0.009461820854890907, - 0.07619899497188476, - 0.06435512726649247, - 0.14418724370624061, - 0.020482591380646117, - 0.18622326856315144, - 0.17680302406232687, - 0.11411324587011096, - 0.04559115895133764, - 0.024318253167761508, - 0.0777066933426362, - 0.16696701026147626, - 0.06641466684484068, - 0.06421006278332052, - 0.1069248857665583, - 0.12159103864374035, - 0.05073753945931583, - 0.04924168633871106, - 0.12722583436268306, - 0.18563179386637813, - 0.0687128870870491, - 0.08905886988994213, - 0.009035432164352614, - 0.049561446318667116, - 0.1347085017272271, - 0.1200359392924501, - 0.027268283817115106, - 0.04224558795450571, - 0.04315262171954351, - 0.05403346926811662, - 0.0023262859537098515, - 0.010721414504714139, - 0.13403654903491943, - 0.10987330337776338, - 0.013298908898025385, - 0.14340914694684173, - 0.17825169707180502, - 0.10868078009526573, - 0.0016445884181541684, - 0.07063958523304881, - 0.1101738445443299, - 0.11758054831650003, - 0.060827727766064016, - 0.14865227744166581, - 0.11702503201869387, - 0.09342064187053477, - 0.15738531812684184, - 0.03201521439082036, - 0.06114448967602477, - 0.10382777552410098, - 0.1431354723068435, - 0.18877393058117947, - 0.04238816261102419, - ], - [ - 0.1490765359911958, - 0.09233526241995971, - 0.06296852894216698, - 0.0976109157574458, - 0.08299404810701023, - 0.08378603465806785, - 0.11920562114578914, - 0.13555823199591513, - 0.0553313289630816, - 0.09546664504785775, - 0.04687997291732666, - 0.12237197777320692, - 0.06865333050063585, - 0.012561461312757724, - 0.16368883089666822, - 0.09131100042306806, - 0.042265527528094815, - 0.029155289884568912, - 0.153815789880318, - 0.040214352413767675, - 0.09381433834769744, - 0.011223362220940966, - 0.11913200349775391, - 0.1429695160437834, - 0.12846334848596738, - 0.04825302129601608, - 0.08816394973267236, - 0.015619449792770343, - 0.08726400271162271, - 0.1406802714694426, - 0.07150818680750592, - 0.11509288921319505, - 0.0913614606055903, - 0.029706843936407743, - 0.0939306128799265, - 0.026551453999575543, - 0.14401232745525105, - 0.08934160493420577, - 0.10268827852213556, - 0.008625313216639324, - 0.06946233801138785, - 0.05866557169947423, - 0.13143983149579208, - 0.018671751331583056, - 0.16975950445661273, - 0.161172091881058, - 0.1040246378463513, - 0.04156050213755719, - 0.022168307101803907, - 0.07083674267232855, - 0.15220566764447255, - 0.06054302998342982, - 0.058533332184146566, - 0.09747179158578337, - 0.11084132839998145, - 0.046251897641031985, - 0.044888291006624594, - 0.11597795894213936, - 0.1692203212911706, - 0.06263806747503713, - 0.08118528762078707, - 0.008236621012006807, - 0.04517978141038145, - 0.12279909313025451, - 0.10942371341935776, - 0.0248575292652322, - 0.038510708849485854, - 0.0393375529042932, - 0.049256438455844605, - 0.002120621948981863, - 0.00977354778184982, - 0.12218654692727692, - 0.10015954331772974, - 0.012123169149384955, - 0.13073052528871054, - 0.16249268953840867, - 0.09907244951333158, - 0.0014991924320470194, - 0.06439442866999417, - 0.10043351401912919, - 0.1071854004601844, - 0.055450025136289674, - 0.13551011723482043, - 0.10667899665704653, - 0.08516144084638168, - 0.14347108081661994, - 0.029184789698902848, - 0.0557387825256351, - 0.026753030352160315, - 0.057506912662784994, - 0.16716809419341475, - 0.11576080110723733, - 0.01392399094397694, - 0.0701719259281324, - 0.06969711242341488, - 0.1702065083755876, - 0.13916687524684004, - 0.05350498510320062, - 0.1415754204215561, - 0.06957602019036072, - 0.15092969351716987, - 0.028763669977259567, - 0.09378263985254962, - 0.07190282975849477, - 0.09464849295042106, - 0.13048104587817877, - 0.1720846656652933, - 0.03864067866059161, - ], -] - -# Xs[i] is coordinates for a tangent vector at ps[i] -Xs = [ - [-0.5, -0.4, 0.0, 0.2, -0.5, 0.5, -0.3, 0.9, -0.8, 0.6], - [0.2, -0.3, 0.2, 0.7, 0.5, 0.0, 0.1, 0.0], - [-0.3, -0.2, -0.5, 0.6, 0.1, 0.3, 0.0, zeros(16)...], - [-0.3, 0.9, 0.3, 0.9, 0.1, zeros(16)...], - [-0.3, 0.5, 0.9, 0.3, -0.3, -0.3, 0.4, -0.8, -0.3, 0.5], - [0.3, -0.4, 0.3, 0.8, -0.5, -0.5, -0.4, 0.2, -0.7, -0.8], - [0.5, 0.9, -0.8, 0.3, -0.7, 0.1, -0.1, zeros(16)...], - [-0.6, 0.0, -0.1, 0.1, -0.7, -0.1, 0.2, -0.0, 0.8, -0.5, 0.9, zeros(16)...], -] - -for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) - @testset "Manifold $M" begin - @testset "is_point" begin - @test(is_point(M, p)) - @test(is_point(M, q)) - @test_throws DomainError is_point(M, [[1.0, 0.0], p[2:end]...]; error=:error) - @test_throws DomainError is_point(M, [[-1.0], p[2:end]...]; error=:error) - @test_throws DomainError is_point(M, [p[1], 2 * p[2:end]...]; error=:error) - end +@testset "Segre Manifold" begin + # Manifolds to test + Ms = [ + Segre(10), + Segre(7, 2), + Segre(7, 9, 9), + Segre(9, 3, 6, 6), + MetricManifold(Segre(10), WarpedMetric{1.2025837056880606}()), + MetricManifold(Segre(2, 9), WarpedMetric{1.1302422072971439}()), + MetricManifold(Segre(9, 6, 10), WarpedMetric{1.4545138169484464}()), + MetricManifold(Segre(9, 3, 8, 10), WarpedMetric{1.396673190458706}()), + ] + + # Vs[i] is the valence of Ms[i] + Vs = [(10,), (7, 2), (7, 9, 9), (9, 3, 6, 6), (10,), (2, 9), (9, 6, 10), (9, 3, 8, 10)] + + # n β‰₯ k, for same n,k X is in TpM and can be scaled by l + unit_p(n, k) = 1 / sqrt(k) .* [ones(k)..., zeros(n - k)...] + unit_X(n, k; l=1.0) = l / sqrt(n - k) .* [zeros(k)..., ones(n - k)...] + + # ps[i] is a point on Ms[i] + ps = [ + [[0.5], unit_p(10, 4)], + [[0.6], unit_p(7, 3), unit_p(2, 1)], + [[0.7], unit_p(7, 3), unit_p(9, 5), unit_p(9, 4)], + [[0.8], unit_p(9, 3), unit_p(3, 1), unit_p(6, 4), unit_p(6, 3)], + [[0.9], unit_p(10, 4)], + [[1.0], unit_p(2, 1), unit_p(9, 5)], + [[1.1], unit_p(9, 3), unit_p(6, 5), unit_p(10, 4)], + [[1.2], unit_p(9, 3), unit_p(3, 1), unit_p(8, 4), unit_p(10, 4)], + ] + + # qs[i] is a point on Ms[i] that is connected to ps[i] by a geodesic and uses the closest representative to ps[i] + # (tricked by only switching only one entry to zero) + qs = [ + [[0.1], unit_p(10, 3)], + [[0.2], unit_p(7, 2), unit_p(2, 2)], + [[0.3], unit_p(7, 2), unit_p(9, 4), unit_p(9, 3)], + [[0.4], unit_p(9, 3), unit_p(3, 1), unit_p(6, 3), unit_p(6, 2)], + [[0.5], unit_p(10, 3)], + [[0.6], unit_p(2, 2), unit_p(9, 5)], + [[0.7], unit_p(9, 2), unit_p(6, 4), unit_p(10, 3)], + [[0.8], unit_p(9, 2), unit_p(3, 2), unit_p(8, 3), unit_p(10, 3)], + ] + + # us[i] is a tangent vector to Ms[i] at ps[i] + us = [ + [[0.5], unit_X(10, 4)], + [[0.6], unit_X(7, 3), unit_X(2, 1)], + [[0.7], unit_X(7, 3), unit_X(9, 5), unit_X(9, 4)], + [[0.8], unit_X(9, 3), unit_X(3, 1), unit_X(6, 4), unit_X(6, 3)], + [[0.9], unit_X(10, 4)], + [[1.0], unit_X(2, 1), unit_X(9, 5)], + [[1.1], unit_X(9, 3), unit_X(6, 5), unit_X(10, 4)], + [[1.2], unit_X(9, 3), unit_X(3, 1), unit_X(8, 4), unit_X(10, 4)], + ] + + # vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representative to ps[i] for t in [-1, 1] + vs = [ + [[0.5], unit_X(10, 5)], + [[0.6], unit_X(7, 4), unit_X(2, 1)], + [[0.7], unit_X(7, 4), unit_X(9, 6), unit_X(9, 5)], + [[0.8], unit_X(9, 4), unit_X(3, 1), unit_X(6, 5), unit_X(6, 4)], + [[0.9], unit_X(10, 5)], + [[1.0], unit_X(2, 1), unit_X(9, 6)], + [[1.1], unit_X(9, 4), unit_X(6, 5), unit_X(10, 5)], + [[1.2], unit_X(9, 4), unit_X(3, 1), unit_X(8, 5), unit_X(10, 5)], + ] + + # When testing that exp(Ms[i], ps[i], t * vs[i]) is an extremum of the length functional, we parametrize curves in Ms[i] and take a derivative along dys[i] + dys = [ + [ + 0.24768051036976024, + 0.15340874919881428, + 0.10461792180729243, + 0.1621738878738882, + 0.13788895788409475, + 0.13920478959340893, + 0.1980520199776914, + 0.225220769065586, + 0.09192923424127934, + 0.15861132814448145, + 0.07788788182581427, + 0.2033127058413462, + 0.11406283238286104, + 0.020870012361419343, + 0.2719578430552649, + 0.15170700765742606, + 0.07022129511933332, + 0.04843952826362164, + 0.2555544578976192, + 0.06681340738035137, + 0.15586613310716685, + 0.018646851863471762, + 0.1979297092698637, + 0.23753411269988997, + 0.21343310337377225, + 0.08016910818336964, + 0.1464783972931314, + 0.025950651929534232, + 0.1449831966165307, + 0.23373068876892722, + 0.11880598168141776, + 0.19121899600576953, + 0.15179084381364852, + 0.04935589775227154, + 0.1560593153225572, + 0.04411343229804097, + 0.2392666728301238, + 0.1484349911958273, + 0.17060958026859915, + 0.01433037040599356, + ], + [ + 0.2703013619564934, + 0.1674196883015804, + 0.11417275710290055, + 0.17698535383607492, + 0.15048246250457872, + 0.15191847013635482, + 0.2161402633508973, + 0.2457903551976426, + 0.10032520193833194, + 0.1730974227854145, + 0.08500144200281991, + 0.22188141170224845, + 0.12448027862860386, + 0.022776086648557087, + 0.29679596211605436, + 0.16556252539583352, + 0.07663466003347703, + 0.05286354765112583, + 0.278894443170582, + 0.07291552728513738, + 0.17010150697308607, + 0.020349883191748984, + 0.21600678191201325, + 0.2592282859804155, + 0.23292611292832396, + 0.08749101451887183, + 0.15985638202387917, + 0.02832074493766232, + 0.1582246235190211, + 0.255077492415341, + 0.12965662340215453, + 0.20868317404203518, + ], + [ + 0.16353440643700792, + 0.10129020125571776, + 0.06907539765598648, + 0.10707750259980159, + 0.0910430491609086, + 0.09191184484141025, + 0.13076652451317197, + 0.14870505851042468, + 0.06069752009721213, + 0.1047252743607885, + 0.05142652727905344, + 0.13423996349664308, + 0.07531152759015192, + 0.013779707893699597, + 0.17956384365300332, + 0.10016660338980309, + 0.04636455972831437, + 0.03198285359980099, + 0.16873328677427074, + 0.0441144557626597, + 0.10291272221322205, + 0.012311836110395775, + 0.1306857672142806, + 0.1568351101623881, + 0.14092209282890691, + 0.05293273783140711, + 0.09671434268855209, + 0.017134268875714943, + 0.09572711622173373, + 0.1543238480770115, + 0.07844325605769907, + 0.12625492803046978, + 0.10022195734569302, + 0.03258789894704945, + 0.10304027338340047, + 0.029126490235301297, + 0.15797905641835802, + 0.09800621027247283, + 0.11264728258206483, + 0.009461820854890907, + 0.07619899497188476, + 0.06435512726649247, + 0.14418724370624061, + 0.020482591380646117, + 0.18622326856315144, + 0.17680302406232687, + 0.11411324587011096, + 0.04559115895133764, + 0.024318253167761508, + 0.0777066933426362, + 0.16696701026147626, + 0.06641466684484068, + 0.06421006278332052, + 0.1069248857665583, + 0.12159103864374035, + 0.05073753945931583, + 0.04924168633871106, + 0.12722583436268306, + 0.18563179386637813, + 0.0687128870870491, + 0.08905886988994213, + 0.009035432164352614, + 0.049561446318667116, + 0.1347085017272271, + 0.1200359392924501, + 0.027268283817115106, + 0.04224558795450571, + 0.04315262171954351, + 0.05403346926811662, + 0.0023262859537098515, + 0.010721414504714139, + 0.13403654903491943, + 0.10987330337776338, + 0.013298908898025385, + 0.14340914694684173, + 0.17825169707180502, + 0.10868078009526573, + 0.0016445884181541684, + 0.07063958523304881, + 0.1101738445443299, + 0.11758054831650003, + 0.060827727766064016, + 0.14865227744166581, + 0.11702503201869387, + 0.09342064187053477, + 0.15738531812684184, + 0.03201521439082036, + 0.06114448967602477, + 0.10382777552410098, + 0.1431354723068435, + 0.18877393058117947, + 0.04238816261102419, + ], + [ + 0.1715795373556408, + 0.1062732072642473, + 0.07247358541051933, + 0.11234521687243985, + 0.0955219430260548, + 0.09643347940647069, + 0.13719962830095694, + 0.15602065459839623, + 0.0636835553069129, + 0.10987726996268543, + 0.053956472834027505, + 0.14084394430027286, + 0.07901650388441198, + 0.014457605324831525, + 0.1883975482043314, + 0.10509433361797467, + 0.04864548006260954, + 0.03355626099441541, + 0.17703417838482685, + 0.046284681464683716, + 0.10797554869382073, + 0.0129175210883459, + 0.1371148981191942, + 0.164550666915154, + 0.14785480326481754, + 0.05553678192838664, + 0.1014722377736982, + 0.01797719507885178, + 0.10043644436402703, + 0.1619158624347057, + 0.08230229880238973, + 0.1324660822900412, + 0.10515241073061003, + 0.03419107175394852, + 0.10810937478733341, + 0.030559377859677404, + 0.16575088999747303, + 0.10282765922416374, + 0.11818900408120409, + 0.009927298359990544, + 0.07994763052677145, + 0.06752109970877263, + 0.15128058435355177, + 0.021490239451779292, + 0.19538458579496817, + 0.1855009091519671, + 0.1197270859333567, + 0.047834031570543896, + 0.02551459792914639, + 0.08152950063326206, + 0.17518100929637484, + 0.06968195903934253, + 0.06736889872885857, + 0.11218509200201603, + 0.1275727512737259, + 0.053233590023432004, + 0.05166414789821036, + 0.13348475269051732, + 0.19476401329869034, + 0.07209324101046329, + 0.09344015137889938, + 0.009479933332347762, + 0.051999638579474684, + 0.14133553242896432, + 0.12594114827928685, + 0.028609756342773685, + 0.04432387406709532, + 0.04527552966766203, + 0.056691664223667886, + 0.002440728384874828, + 0.011248858149159562, + 0.14063052279470464, + 0.11527855802353276, + 0.013953153258528188, + 0.15046420885860654, + 0.18702085012439856, + 0.11402736815129268, + 0.0017254945064788542, + 0.07411472372909801, + 0.11559388441532585, + 0.10893561836452229, + 0.15017707070132247, + 0.198060728501197, + 0.04447346273248423, + ], + [ + 0.24768051036976024, + 0.15340874919881428, + 0.10461792180729243, + 0.1621738878738882, + 0.13788895788409475, + 0.13920478959340893, + 0.1980520199776914, + 0.225220769065586, + 0.09192923424127934, + 0.15861132814448145, + 0.07788788182581427, + 0.2033127058413462, + 0.11406283238286104, + 0.020870012361419343, + 0.2719578430552649, + 0.15170700765742606, + 0.07022129511933332, + 0.04843952826362164, + 0.2555544578976192, + 0.06681340738035137, + 0.15586613310716685, + 0.018646851863471762, + 0.1979297092698637, + 0.23753411269988997, + 0.21343310337377225, + 0.08016910818336964, + 0.1464783972931314, + 0.025950651929534232, + 0.1449831966165307, + 0.23373068876892722, + 0.11880598168141776, + 0.19121899600576953, + 0.15179084381364852, + 0.04935589775227154, + 0.1560593153225572, + 0.04411343229804097, + 0.2392666728301238, + 0.1484349911958273, + 0.17060958026859915, + 0.01433037040599356, + ], + [ + 0.24768051036976024, + 0.15340874919881428, + 0.10461792180729243, + 0.1621738878738882, + 0.13788895788409475, + 0.13920478959340893, + 0.1980520199776914, + 0.225220769065586, + 0.09192923424127934, + 0.15861132814448145, + 0.07788788182581427, + 0.2033127058413462, + 0.11406283238286104, + 0.020870012361419343, + 0.2719578430552649, + 0.15170700765742606, + 0.07022129511933332, + 0.04843952826362164, + 0.2555544578976192, + 0.06681340738035137, + 0.15586613310716685, + 0.018646851863471762, + 0.1979297092698637, + 0.23753411269988997, + 0.21343310337377225, + 0.08016910818336964, + 0.1464783972931314, + 0.025950651929534232, + 0.1449831966165307, + 0.23373068876892722, + 0.11880598168141776, + 0.19121899600576953, + 0.15179084381364852, + 0.04935589775227154, + 0.1560593153225572, + 0.04411343229804097, + 0.2392666728301238, + 0.1484349911958273, + 0.17060958026859915, + 0.01433037040599356, + ], + [ + 0.16353440643700792, + 0.10129020125571776, + 0.06907539765598648, + 0.10707750259980159, + 0.0910430491609086, + 0.09191184484141025, + 0.13076652451317197, + 0.14870505851042468, + 0.06069752009721213, + 0.1047252743607885, + 0.05142652727905344, + 0.13423996349664308, + 0.07531152759015192, + 0.013779707893699597, + 0.17956384365300332, + 0.10016660338980309, + 0.04636455972831437, + 0.03198285359980099, + 0.16873328677427074, + 0.0441144557626597, + 0.10291272221322205, + 0.012311836110395775, + 0.1306857672142806, + 0.1568351101623881, + 0.14092209282890691, + 0.05293273783140711, + 0.09671434268855209, + 0.017134268875714943, + 0.09572711622173373, + 0.1543238480770115, + 0.07844325605769907, + 0.12625492803046978, + 0.10022195734569302, + 0.03258789894704945, + 0.10304027338340047, + 0.029126490235301297, + 0.15797905641835802, + 0.09800621027247283, + 0.11264728258206483, + 0.009461820854890907, + 0.07619899497188476, + 0.06435512726649247, + 0.14418724370624061, + 0.020482591380646117, + 0.18622326856315144, + 0.17680302406232687, + 0.11411324587011096, + 0.04559115895133764, + 0.024318253167761508, + 0.0777066933426362, + 0.16696701026147626, + 0.06641466684484068, + 0.06421006278332052, + 0.1069248857665583, + 0.12159103864374035, + 0.05073753945931583, + 0.04924168633871106, + 0.12722583436268306, + 0.18563179386637813, + 0.0687128870870491, + 0.08905886988994213, + 0.009035432164352614, + 0.049561446318667116, + 0.1347085017272271, + 0.1200359392924501, + 0.027268283817115106, + 0.04224558795450571, + 0.04315262171954351, + 0.05403346926811662, + 0.0023262859537098515, + 0.010721414504714139, + 0.13403654903491943, + 0.10987330337776338, + 0.013298908898025385, + 0.14340914694684173, + 0.17825169707180502, + 0.10868078009526573, + 0.0016445884181541684, + 0.07063958523304881, + 0.1101738445443299, + 0.11758054831650003, + 0.060827727766064016, + 0.14865227744166581, + 0.11702503201869387, + 0.09342064187053477, + 0.15738531812684184, + 0.03201521439082036, + 0.06114448967602477, + 0.10382777552410098, + 0.1431354723068435, + 0.18877393058117947, + 0.04238816261102419, + ], + [ + 0.1490765359911958, + 0.09233526241995971, + 0.06296852894216698, + 0.0976109157574458, + 0.08299404810701023, + 0.08378603465806785, + 0.11920562114578914, + 0.13555823199591513, + 0.0553313289630816, + 0.09546664504785775, + 0.04687997291732666, + 0.12237197777320692, + 0.06865333050063585, + 0.012561461312757724, + 0.16368883089666822, + 0.09131100042306806, + 0.042265527528094815, + 0.029155289884568912, + 0.153815789880318, + 0.040214352413767675, + 0.09381433834769744, + 0.011223362220940966, + 0.11913200349775391, + 0.1429695160437834, + 0.12846334848596738, + 0.04825302129601608, + 0.08816394973267236, + 0.015619449792770343, + 0.08726400271162271, + 0.1406802714694426, + 0.07150818680750592, + 0.11509288921319505, + 0.0913614606055903, + 0.029706843936407743, + 0.0939306128799265, + 0.026551453999575543, + 0.14401232745525105, + 0.08934160493420577, + 0.10268827852213556, + 0.008625313216639324, + 0.06946233801138785, + 0.05866557169947423, + 0.13143983149579208, + 0.018671751331583056, + 0.16975950445661273, + 0.161172091881058, + 0.1040246378463513, + 0.04156050213755719, + 0.022168307101803907, + 0.07083674267232855, + 0.15220566764447255, + 0.06054302998342982, + 0.058533332184146566, + 0.09747179158578337, + 0.11084132839998145, + 0.046251897641031985, + 0.044888291006624594, + 0.11597795894213936, + 0.1692203212911706, + 0.06263806747503713, + 0.08118528762078707, + 0.008236621012006807, + 0.04517978141038145, + 0.12279909313025451, + 0.10942371341935776, + 0.0248575292652322, + 0.038510708849485854, + 0.0393375529042932, + 0.049256438455844605, + 0.002120621948981863, + 0.00977354778184982, + 0.12218654692727692, + 0.10015954331772974, + 0.012123169149384955, + 0.13073052528871054, + 0.16249268953840867, + 0.09907244951333158, + 0.0014991924320470194, + 0.06439442866999417, + 0.10043351401912919, + 0.1071854004601844, + 0.055450025136289674, + 0.13551011723482043, + 0.10667899665704653, + 0.08516144084638168, + 0.14347108081661994, + 0.029184789698902848, + 0.0557387825256351, + 0.026753030352160315, + 0.057506912662784994, + 0.16716809419341475, + 0.11576080110723733, + 0.01392399094397694, + 0.0701719259281324, + 0.06969711242341488, + 0.1702065083755876, + 0.13916687524684004, + 0.05350498510320062, + 0.1415754204215561, + 0.06957602019036072, + 0.15092969351716987, + 0.028763669977259567, + 0.09378263985254962, + 0.07190282975849477, + 0.09464849295042106, + 0.13048104587817877, + 0.1720846656652933, + 0.03864067866059161, + ], + ] + + # Xs[i] is coordinates for a tangent vector at ps[i] + Xs = [ + [-0.5, -0.4, 0.0, 0.2, -0.5, 0.5, -0.3, 0.9, -0.8, 0.6], + [0.2, -0.3, 0.2, 0.7, 0.5, 0.0, 0.1, 0.0], + [-0.3, -0.2, -0.5, 0.6, 0.1, 0.3, 0.0, zeros(16)...], + [-0.3, 0.9, 0.3, 0.9, 0.1, zeros(16)...], + [-0.3, 0.5, 0.9, 0.3, -0.3, -0.3, 0.4, -0.8, -0.3, 0.5], + [0.3, -0.4, 0.3, 0.8, -0.5, -0.5, -0.4, 0.2, -0.7, -0.8], + [0.5, 0.9, -0.8, 0.3, -0.7, 0.1, -0.1, zeros(16)...], + [-0.6, 0.0, -0.1, 0.1, -0.7, -0.1, 0.2, -0.0, 0.8, -0.5, 0.9, zeros(16)...], + ] + + for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) + @testset "Manifold $M" begin + @testset "is_point" begin + @test(is_point(M, p)) + @test(is_point(M, q)) + @test_throws DomainError is_point( + M, + [[1.0, 0.0], p[2:end]...]; + error=:error, + ) + @test_throws DomainError is_point(M, [[-1.0], p[2:end]...]; error=:error) + @test_throws DomainError is_point(M, [p[1], 2 * p[2:end]...]; error=:error) + end - @testset "is_vector" begin - @test(is_vector(M, p, v; error=:error)) - @test(is_vector(M, p, u; error=:error)) - @test_throws DomainError is_vector(M, [[1.0, 0.0], p[2:end]...], v, false, true) - @test_throws DomainError is_vector(M, p, [[1.0, 0.0], v[2:end]...], false, true) - @test_throws DomainError is_vector(M, p, p, false, true) - end + @testset "is_vector" begin + @test(is_vector(M, p, v; error=:error)) + @test(is_vector(M, p, u; error=:error)) + @test_throws DomainError is_vector( + M, + [[1.0, 0.0], p[2:end]...], + v, + false, + true, + ) + @test_throws DomainError is_vector( + M, + p, + [[1.0, 0.0], v[2:end]...], + false, + true, + ) + @test_throws DomainError is_vector(M, p, p, false, true) + end - Random.seed!(1) - @testset "rand" begin - @test(is_point(M, rand(M))) - @test(is_vector(M, p, rand(M, vector_at=p))) - end + Random.seed!(1) + @testset "rand" begin + @test(is_point(M, rand(M))) + @test(is_vector(M, p, rand(M, vector_at=p))) + end - @testset "get_embedding" begin - @test(get_embedding(M) == Euclidean(prod(V))) - end + @testset "get_embedding" begin + @test(get_embedding(M) == Euclidean(prod(V))) + end - @testset "embed!" begin - p_ = zeros(prod(V)) - p__ = zeros(prod(V)) - embed!(M, p_, p) - embed!(M, p__, [p[1], [-x for x in p[2:end]]...]) - @test(is_point(get_embedding(M), p_)) - @test(isapprox(p_, (-1)^length(V) * p__)) - end + @testset "embed!" begin + p_ = zeros(prod(V)) + p__ = zeros(prod(V)) + embed!(M, p_, p) + embed!(M, p__, [p[1], [-x for x in p[2:end]]...]) + @test(is_point(get_embedding(M), p_)) + @test(isapprox(p_, (-1)^length(V) * p__)) + end - # ManifoldsBase doesn't export embed_vector! right now - # @testset "embed_vector!" begin - # p_ = zeros(prod(V)) - # v_ = zeros(prod(V)) - # embed!(M, p_, p) - # embed_vector!(M, v_, p, v) - # @test(is_vector(get_embedding(M), p_, v_)) - # end - - @testset "get_coordinates" begin - @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) - @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) - @test( - isapprox( - dot(X, get_coordinates(M, p, v)), - inner(M, p, v, get_vector(M, p, X)), + # ManifoldsBase doesn't export embed_vector! right now + # @testset "embed_vector!" begin + # p_ = zeros(prod(V)) + # v_ = zeros(prod(V)) + # embed!(M, p_, p) + # embed_vector!(M, v_, p, v) + # @test(is_vector(get_embedding(M), p_, v_)) + # end + + @testset "get_coordinates" begin + @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) + @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) + @test( + isapprox( + dot(X, get_coordinates(M, p, v)), + inner(M, p, v, get_vector(M, p, X)), + ) ) - ) - end + end - @testset "exp" begin - # Zero vector - p_ = exp(M, p, zeros.(size.(v))) - @test(is_point(M, p_)) - @test(isapprox(p, p_; atol=1e-5)) - - # Tangent vector in the scaling direction - p_ = exp(M, p, [v[1], zeros.(size.(v[2:end]))...]) - @test(is_point(M, p_)) - @test(isapprox([p[1] + v[1], p[2:end]...], p_; atol=1e-5)) - - # Generic tangent vector - p_ = exp(M, p, v) - @test(is_point(M, p)) - - geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -1.0) - @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) - geodesic_speed = - central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.811) - @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) - geodesic_speed = - central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.479) - @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) - geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.181) - @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) - geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.703) - @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) - geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 1.0) - @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) - - # Geodesics are (locally) length-minizing. So let B_a be a one-parameter - # family of curves such that B_0 is a geodesic. Then the derivative of - # length(B_a) at a = 0 should be 0, and the second derivative should be - # nonnegative. - - n = manifold_dimension(M) - x = get_coordinates(M, p, v) - x0 = 0.0 * x - x1 = 0.2 * x - x2 = 0.4 * x - x3 = 0.6 * x - x4 = 0.8 * x - x5 = 1.0 * x - - function curve_length(y::Vector{Float64}) - @assert(length(y) == 4 * n) - - # Control points - y1 = y[1:n] - y2 = y[(n + 1):(2 * n)] - y3 = y[(2 * n + 1):(3 * n)] - y4 = y[(3 * n + 1):(4 * n)] - - # Bezier curve from 0 to v with control points y1, ..., y4 - function b(t) - return ( - (1 - t)^5 * x0 + - 5 * t * (1 - t)^4 * (x1 + y1) + - 10 * t^2 * (1 - t)^3 * (x2 + y2) + - 10 * t^3 * (1 - t)^2 * (x3 + y3) + - 5 * t^4 * (1 - t) * (x4 + y4) + - t^5 * x5 - ) + @testset "exp" begin + # Zero vector + p_ = exp(M, p, zeros.(size.(v))) + @test(is_point(M, p_)) + @test(isapprox(p, p_; atol=1e-5)) + + # Tangent vector in the scaling direction + p_ = exp(M, p, [v[1], zeros.(size.(v[2:end]))...]) + @test(is_point(M, p_)) + @test(isapprox([p[1] + v[1], p[2:end]...], p_; atol=1e-5)) + + # Generic tangent vector + p_ = exp(M, p, v) + @test(is_point(M, p)) + + geodesic_speed = + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -1.0) + @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) + geodesic_speed = + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.811) + @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) + geodesic_speed = + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.479) + @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) + geodesic_speed = + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.181) + @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) + geodesic_speed = + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.703) + @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) + geodesic_speed = + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 1.0) + @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) + + # Geodesics are (locally) length-minizing. So let B_a be a one-parameter + # family of curves such that B_0 is a geodesic. Then the derivative of + # length(B_a) at a = 0 should be 0, and the second derivative should be + # nonnegative. + + n = manifold_dimension(M) + x = get_coordinates(M, p, v) + x0 = 0.0 * x + x1 = 0.2 * x + x2 = 0.4 * x + x3 = 0.6 * x + x4 = 0.8 * x + x5 = 1.0 * x + + function curve_length(y::Vector{Float64}) + @assert(length(y) == 4 * n) + + # Control points + y1 = y[1:n] + y2 = y[(n + 1):(2 * n)] + y3 = y[(2 * n + 1):(3 * n)] + y4 = y[(3 * n + 1):(4 * n)] + + # Bezier curve from 0 to v with control points y1, ..., y4 + function b(t) + return ( + (1 - t)^5 * x0 + + 5 * t * (1 - t)^4 * (x1 + y1) + + 10 * t^2 * (1 - t)^3 * (x2 + y2) + + 10 * t^3 * (1 - t)^2 * (x3 + y3) + + 5 * t^4 * (1 - t) * (x4 + y4) + + t^5 * x5 + ) + end + + # Length of curve on manifold + ps_ = [exp(M, p, get_vector(M, p, b(t))) for t in 0.0:1e-3:1.0] + ds = [ + distance(M, p1, p2) for + (p1, p2) in zip(ps_[1:(end - 1)], ps_[2:end]) + ] + return sum(ds) end - # Length of curve on manifold - ps_ = [exp(M, p, get_vector(M, p, b(t))) for t in 0.0:1e-3:1.0] - ds = [distance(M, p1, p2) for (p1, p2) in zip(ps_[1:(end - 1)], ps_[2:end])] - return sum(ds) + # dy = rand(4 * n); dy = dy / norm(dy) + f = a -> curve_length(a * dy) + @test(isapprox(central_fdm(3, 1)(f, 0.0), 0.0; atol=1e-5)) + @test(central_fdm(3, 2)(f, 0.0) >= 0.0) end - # dy = rand(4 * n); dy = dy / norm(dy) - f = a -> curve_length(a * dy) - @test(isapprox(central_fdm(3, 1)(f, 0.0), 0.0; atol=1e-5)) - @test(central_fdm(3, 2)(f, 0.0) >= 0.0) - end + @testset "log" begin + # Same point + v_ = log(M, p, p) + @test(is_vector(M, p, v_)) + @test(isapprox(zeros.(size.(v)), v_; atol=1e-5)) - @testset "log" begin - # Same point - v_ = log(M, p, p) - @test(is_vector(M, p, v_)) - @test(isapprox(zeros.(size.(v)), v_; atol=1e-5)) + # Scaled point + v_ = log(M, p, [q[1], p[2:end]...]) + @test(is_vector(M, p, v_)) + @test(isapprox(v_, [q[1] - p[1], zeros.(size.(q[2:end]))...]; atol=1e-5)) - # Scaled point - v_ = log(M, p, [q[1], p[2:end]...]) - @test(is_vector(M, p, v_)) - @test(isapprox(v_, [q[1] - p[1], zeros.(size.(q[2:end]))...]; atol=1e-5)) - - # Generic tangent vector - v_ = log(M, p, q) - @test(is_vector(M, p, v_)) - end + # Generic tangent vector + v_ = log(M, p, q) + @test(is_vector(M, p, v_)) + end - @testset "norm" begin - @test(isapprox(norm(M, p, log(M, p, q)), distance(M, p, q))) - end + @testset "norm" begin + @test(isapprox(norm(M, p, log(M, p, q)), distance(M, p, q))) + end - @testset "sectional_curvature" begin - # Test that sectional curvature is difference between circumference - # and 2 pi r for small circles. - - # Orthonormalize - u_ = u / norm(M, p, u) - v_ = v - inner(M, p, u_, v) * u_ - v_ = v_ / norm(M, p, v_) - - r = 1e-2 - ps_ = [ - exp(M, p, r * (cos(theta) * u_ + sin(theta) * v_)) for - theta in 0.0:1e-3:(2 * pi) - ] - ds = [distance(M, p1, p2) for (p1, p2) in zip(ps_, [ps_[2:end]..., ps_[1]])] - C = sum(ds) - K = 3 * (2 * pi * r - C) / (pi * r^3) # https://en.wikipedia.org/wiki/Bertrand%E2%80%93Diguet%E2%80%93Puiseux_theorem - - @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) - end + @testset "sectional_curvature" begin + # Test that sectional curvature is difference between circumference + # and 2 pi r for small circles. + + # Orthonormalize + u_ = u / norm(M, p, u) + v_ = v - inner(M, p, u_, v) * u_ + v_ = v_ / norm(M, p, v_) + + r = 1e-2 + ps_ = [ + exp(M, p, r * (cos(theta) * u_ + sin(theta) * v_)) for + theta in 0.0:1e-3:(2 * pi) + ] + ds = [distance(M, p1, p2) for (p1, p2) in zip(ps_, [ps_[2:end]..., ps_[1]])] + C = sum(ds) + K = 3 * (2 * pi * r - C) / (pi * r^3) # https://en.wikipedia.org/wiki/Bertrand%E2%80%93Diguet%E2%80%93Puiseux_theorem + + @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) + end - @testset "riemann_tensor" begin - @test( - isapprox( - sectional_curvature(M, p, u, v), - inner(M, p, riemann_tensor(M, p, u, v, v), u) / - (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2), + @testset "riemann_tensor" begin + @test( + isapprox( + sectional_curvature(M, p, u, v), + inner(M, p, riemann_tensor(M, p, u, v, v), u) / + (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2), + ) ) - ) + end end end end From 2a1426bd0d552a873edbcd5683782693806f437c Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Thu, 19 Dec 2024 09:02:00 +0100 Subject: [PATCH 22/35] Fix / re-add embed for tangent vectors. Unify test formatting --- src/manifolds/Segre.jl | 35 ++++++++------- test/manifolds/segre.jl | 95 +++++++++++++++++++---------------------- 2 files changed, 61 insertions(+), 69 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index df6ce276c3..573b625988 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -126,6 +126,23 @@ function embed!(M::Segre, q, p) return q = kron(p...) end +@doc raw""" + embed!(M::Segre{𝔽, V}, p, v) + +Embed tangent vector ``v = (Ξ½, u_1, …, u_d)`` at ``p ≐ (Ξ», x_1, …, x_d)`` in ``𝔽^{n_1 Γ—β‹―Γ— n_d}`` using the Kronecker product: + +````math + (Ξ½, u_1, …, u_d) ↦ Ξ½ x_1 βŠ—β‹―βŠ— x_d + Ξ» u_1 βŠ— x_2 βŠ—β‹―βŠ— x_d + … + Ξ» x_1 βŠ—β‹―βŠ— x_{d - 1} βŠ— u_d. +```` +""" +function embed!(::Segre{𝔽,V}, u, p, v) where {𝔽,V} + # Product rule + return u = sum([ + kron([i == j ? xdot : x for (j, (x, xdot)) in enumerate(zip(p, v))]...) for + (i, _) in enumerate(p) + ]) +end + @doc raw""" function get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) @@ -233,24 +250,6 @@ function get_embedding(::Segre{𝔽,V}) where {𝔽,V} return Euclidean(prod(V)) end -# ManifoldsBase doesn't export embed_vector! right now -# @doc raw""" -# function embed_vector(M::Segre{𝔽, V}, p, v) - -# Embed tangent vector ``v = (\nu, u_1, \dots, u_d)`` at ``p \doteq (\lambda, x_1, \dots, x_d)`` in ``𝔽^{n_1 \times \dots \times n_d}`` using the KrΓΆnecker product: -# ````math -# (\nu, u_1, \dots, u_d) \mapsto \nu x_1 \otimes \dots \otimes x_d + \lambda u_1 \otimes x_2 \otimes \dots \otimes x_d + \dots + \lambda x_1 \otimes \dots \otimes x_{d - 1} \otimes u_d. -# ```` -# """ -# function embed_vector!(M::Segre{𝔽,V}, u, p, v) where {𝔽,V} - -# # Product rule -# return u = sum([ -# kron([i == j ? xdot : x for (j, (x, xdot)) in enumerate(zip(p, v))]...) for -# (i, _) in enumerate(p) -# ]) -# end - @doc raw""" function spherical_angle_sum(M::Segre{ℝ, V}, p, q) diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index 1216bb0547..e2e5e309bb 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -632,8 +632,8 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) @testset "Manifold $M" begin @testset "is_point" begin - @test(is_point(M, p)) - @test(is_point(M, q)) + @test is_point(M, p) + @test is_point(M, q) @test_throws DomainError is_point( M, [[1.0, 0.0], p[2:end]...]; @@ -644,8 +644,8 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences end @testset "is_vector" begin - @test(is_vector(M, p, v; error=:error)) - @test(is_vector(M, p, u; error=:error)) + @test is_vector(M, p, v; error=:error) + @test is_vector(M, p, u; error=:error) @test_throws DomainError is_vector( M, [[1.0, 0.0], p[2:end]...], @@ -665,76 +665,71 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences Random.seed!(1) @testset "rand" begin - @test(is_point(M, rand(M))) - @test(is_vector(M, p, rand(M, vector_at=p))) + @test is_point(M, rand(M)) + @test is_vector(M, p, rand(M, vector_at=p)) end @testset "get_embedding" begin - @test(get_embedding(M) == Euclidean(prod(V))) + @test get_embedding(M) == Euclidean(prod(V)) end @testset "embed!" begin + # points p_ = zeros(prod(V)) p__ = zeros(prod(V)) embed!(M, p_, p) embed!(M, p__, [p[1], [-x for x in p[2:end]]...]) - @test(is_point(get_embedding(M), p_)) - @test(isapprox(p_, (-1)^length(V) * p__)) - end + @test is_point(get_embedding(M), p_) + @test isapprox(p_, (-1)^length(V) * p__) - # ManifoldsBase doesn't export embed_vector! right now - # @testset "embed_vector!" begin - # p_ = zeros(prod(V)) - # v_ = zeros(prod(V)) - # embed!(M, p_, p) - # embed_vector!(M, v_, p, v) - # @test(is_vector(get_embedding(M), p_, v_)) - # end + # vectors + v_ = zeros(prod(V)) + embed!(M, v_, p, v) + @test is_vector(get_embedding(M), p_, v_) + end @testset "get_coordinates" begin - @test(isapprox(v, get_vector(M, p, get_coordinates(M, p, v)))) - @test(isapprox(X, get_coordinates(M, p, get_vector(M, p, X)))) - @test( - isapprox( - dot(X, get_coordinates(M, p, v)), - inner(M, p, v, get_vector(M, p, X)), - ) + @test isapprox(v, get_vector(M, p, get_coordinates(M, p, v))) + @test isapprox(X, get_coordinates(M, p, get_vector(M, p, X))) + @test isapprox( + dot(X, get_coordinates(M, p, v)), + inner(M, p, v, get_vector(M, p, X)), ) end @testset "exp" begin # Zero vector p_ = exp(M, p, zeros.(size.(v))) - @test(is_point(M, p_)) - @test(isapprox(p, p_; atol=1e-5)) + @test is_point(M, p_) + @test isapprox(p, p_; atol=1e-5) # Tangent vector in the scaling direction p_ = exp(M, p, [v[1], zeros.(size.(v[2:end]))...]) - @test(is_point(M, p_)) - @test(isapprox([p[1] + v[1], p[2:end]...], p_; atol=1e-5)) + @test is_point(M, p_) + @test isapprox([p[1] + v[1], p[2:end]...], p_; atol=1e-5) # Generic tangent vector p_ = exp(M, p, v) - @test(is_point(M, p)) + @test is_point(M, p) geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -1.0) - @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) + @test isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5) geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.811) - @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) + @test isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5) geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.479) - @test(isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5)) + @test isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5) geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.181) - @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) + @test isapprox(geodesic_speed, norm(M, p, v); atol=1e-5) geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.703) - @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) + @test isapprox(geodesic_speed, norm(M, p, v); atol=1e-5) geodesic_speed = central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 1.0) - @test(isapprox(geodesic_speed, norm(M, p, v); atol=1e-5)) + @test isapprox(geodesic_speed, norm(M, p, v); atol=1e-5) # Geodesics are (locally) length-minizing. So let B_a be a one-parameter # family of curves such that B_0 is a geodesic. Then the derivative of @@ -782,28 +777,28 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences # dy = rand(4 * n); dy = dy / norm(dy) f = a -> curve_length(a * dy) - @test(isapprox(central_fdm(3, 1)(f, 0.0), 0.0; atol=1e-5)) - @test(central_fdm(3, 2)(f, 0.0) >= 0.0) + @test isapprox(central_fdm(3, 1)(f, 0.0), 0.0; atol=1e-5) + @test central_fdm(3, 2)(f, 0.0) >= 0.0 end @testset "log" begin # Same point v_ = log(M, p, p) - @test(is_vector(M, p, v_)) - @test(isapprox(zeros.(size.(v)), v_; atol=1e-5)) + @test is_vector(M, p, v_) + @test isapprox(zeros.(size.(v)), v_; atol=1e-5) # Scaled point v_ = log(M, p, [q[1], p[2:end]...]) - @test(is_vector(M, p, v_)) - @test(isapprox(v_, [q[1] - p[1], zeros.(size.(q[2:end]))...]; atol=1e-5)) + @test is_vector(M, p, v_) + @test isapprox(v_, [q[1] - p[1], zeros.(size.(q[2:end]))...]; atol=1e-5) # Generic tangent vector v_ = log(M, p, q) - @test(is_vector(M, p, v_)) + @test is_vector(M, p, v_) end @testset "norm" begin - @test(isapprox(norm(M, p, log(M, p, q)), distance(M, p, q))) + @test isapprox(norm(M, p, log(M, p, q)), distance(M, p, q)) end @testset "sectional_curvature" begin @@ -824,16 +819,14 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences C = sum(ds) K = 3 * (2 * pi * r - C) / (pi * r^3) # https://en.wikipedia.org/wiki/Bertrand%E2%80%93Diguet%E2%80%93Puiseux_theorem - @test(isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2)) + @test isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2) end @testset "riemann_tensor" begin - @test( - isapprox( - sectional_curvature(M, p, u, v), - inner(M, p, riemann_tensor(M, p, u, v, v), u) / - (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2), - ) + @test isapprox( + sectional_curvature(M, p, u, v), + inner(M, p, riemann_tensor(M, p, u, v, v), u) / + (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2), ) end end From e9561597e361203016ce4f431ea0f5317b5222df Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Thu, 19 Dec 2024 09:17:40 +0100 Subject: [PATCH 23/35] Add link to Segre. --- src/manifolds/Segre.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 573b625988..35fe91b228 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -19,6 +19,8 @@ with the [warped product metric](https://en.wikipedia.org/wiki/Warped_product) [ The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). +The manifold is named after [Beniamino Segre](https://en.wikipedia.org/wiki/Beniamino_Segre)(1903–1977). + # Constructor Segre(n::Int...; field::AbstractNumbers=ℝ) From 25ece444223e9c3992447bfd0ccdb02de88964d0 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Thu, 19 Dec 2024 11:16:37 +0100 Subject: [PATCH 24/35] Move docstring from check_point and check_vector to is_point and is_vector. Explain the warping parameter A a bit more. --- src/manifolds/Segre.jl | 22 ++++++++-------------- src/manifolds/SegreWarpedMetric.jl | 7 ++++++- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 35fe91b228..752b7f6e22 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -19,7 +19,7 @@ with the [warped product metric](https://en.wikipedia.org/wiki/Warped_product) [ The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). -The manifold is named after [Beniamino Segre](https://en.wikipedia.org/wiki/Beniamino_Segre)(1903–1977). +The manifold is named after [Corrado Segre](https://en.wikipedia.org/wiki/Corrado_Segre)(1863–1924). # Constructor Segre(n::Int...; field::AbstractNumbers=ℝ) @@ -35,11 +35,6 @@ end manifold_dimension(::Segre{𝔽,V}) where {𝔽,V} = (1 + sum(V .- 1)) -""" - check_size(M::Segre{𝔽, V}, p) - -Check whether `p` has the right size for `Segre` manifold `M`. -""" function check_size(M::Segre{𝔽,V}, p;) where {𝔽,V} p_size = only.(size.(p)) M_size = [1, V...] @@ -54,11 +49,6 @@ function check_size(M::Segre{𝔽,V}, p;) where {𝔽,V} return nothing end -""" - check_size(M::Segre{𝔽, V}, p, v) - -Check whether `p` and `v` have the right size for `Segre` manifold `M`. -""" function check_size(M::Segre{𝔽,V}, p, v;) where {𝔽,V} p_size = only.(size.(p)) v_size = only.(size.(v)) @@ -82,10 +72,12 @@ function check_size(M::Segre{𝔽,V}, p, v;) where {𝔽,V} end """ - check_point(M::Segre{ℝ, V}, p; kwargs...) + is_point(M::Segre{ℝ, V}, p; kwargs...) Check whether `p` is a valid point on `M`, i.e. `p[1]` is a singleton containing a positive number and `p[i + 1]` is a point on `Sphere(V[i])`. The tolerance can be set using the `kwargs...`. """ +is_point(M::Segre{ℝ,V}, p; kwargs...) where {V} + function check_point(M::Segre{ℝ,V}, p; atol=1.4901161193847656e-8, kwargs...) where {V} if p[1][1] <= 0.0 return DomainError(p[1][1], "$(p) has non-positive modulus.") @@ -100,10 +92,12 @@ function check_point(M::Segre{ℝ,V}, p; atol=1.4901161193847656e-8, kwargs...) end """ - function check_vector(M::Segre{ℝ, V}, p, v, kwargs...) + function is_vector(M::Segre{ℝ, V}, p, v, kwargs...) -Check whether `v` is a tangent vector to `p` on `M`, i.e. after `check_point(M, p)`, `v` has to be of same dimension as `p` and orthogonal to `p`. The tolerance can be set using the `kwargs...`. +Check whether `v` is a tangent vector to `p` on `M`, i.e. `v` has to be of same dimension as `p` and orthogonal to `p`. The tolerance can be set using the `kwargs...`. """ +is_vector(M::Segre{ℝ,V}, p, v; kwargs...) where {V} + function check_vector(M::Segre{ℝ,V}, p, v; atol=1.4901161193847656e-8, kwargs...) where {V} for (x, xdot, n) in zip(p[2:end], v[2:end], V) e = check_vector(Sphere(n - 1)::AbstractSphere, x, xdot; atol=atol, kwargs...) diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index 72f4bf4505..198b9961f1 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -2,7 +2,7 @@ WarpedMetric{A} <: AbstractMetric The ``A``-warped metric on the Segre manifold ``\mathcal{S}`` is a generalization of the Euclidean metric on ``\mathcal{S}``. -We this manifold by ``\mathcal{S}_A``. +We denote this manifold by ``\mathcal{S}_A``. Similarly to ``\mathcal{S}``, when ``𝔽 = ℝ``, ``\mathcal{S}_A`` is a normal Riemannian covering of the product manifold @@ -12,11 +12,16 @@ Similarly to ``\mathcal{S}``, when ``𝔽 = ℝ``, ``\mathcal{S}_A`` is a normal with a [warped product metric](https://en.wikipedia.org/wiki/Warped_product), but the warping function now depends on the _warping factor_ ``A``. ``A = 1`` corresponds to the usual Segre manifold. +The Segre manifold is a cone in the sense that if ``p \in \mathcal{S}``, then ``a p \in \mathcal{S}`` for all ``r \neq 0``. The tangent subspace at ``p`` defined ``\mathrm{d} (r p) / \mathrm{d} r`` is called the _radial_ direction. ``A < 1`` puts less weight on the directions orthogonal to the radial direction compared to ``\mathcal{S}``, while ``A > 1`` puts more weight on those directions. The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ struct WarpedMetric{A} <: AbstractMetric end +function WarpedMetric(A::Real) + return WarpedMetric{A}() +end + @doc raw""" function get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) From 82f2c72c1f7bab9f163b0467e16b1c4f769fda0f Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Thu, 19 Dec 2024 11:18:13 +0100 Subject: [PATCH 25/35] Test coverage for case in closest_representative! where given points are not as close as possible. --- test/manifolds/segre.jl | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index e2e5e309bb..a5ffba9bcb 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -7,10 +7,10 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences Segre(7, 2), Segre(7, 9, 9), Segre(9, 3, 6, 6), - MetricManifold(Segre(10), WarpedMetric{1.2025837056880606}()), - MetricManifold(Segre(2, 9), WarpedMetric{1.1302422072971439}()), - MetricManifold(Segre(9, 6, 10), WarpedMetric{1.4545138169484464}()), - MetricManifold(Segre(9, 3, 8, 10), WarpedMetric{1.396673190458706}()), + MetricManifold(Segre(10), WarpedMetric(1.2025837056880606)), + MetricManifold(Segre(2, 9), WarpedMetric(1.1302422072971439)), + MetricManifold(Segre(9, 6, 10), WarpedMetric(1.4545138169484464)), + MetricManifold(Segre(9, 3, 8, 10), WarpedMetric(1.396673190458706)), ] # Vs[i] is the valence of Ms[i] @@ -831,4 +831,19 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences end end end + + # Test a point that does not use the closest representative + @testset "log" begin + M = Ms[4] + p = ps[4] + q = qs[4] + q_ = [q[1], q[2], q[3], -q[4], -q[5]] + @test isapprox(log(M, p, q), log(M, p, q_)) + + M = Ms[8] + p = ps[8] + q = qs[8] + q_ = [q[1], q[2], q[3], -q[4], -q[5]] + @test isapprox(log(M, p, q), log(M, p, q_)) + end end From 0dab4f41a83f2792f9a00011e7b47403c3437062 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Thu, 19 Dec 2024 11:28:19 +0100 Subject: [PATCH 26/35] Update zenodo metadata. --- .zenodo.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.zenodo.json b/.zenodo.json index 4076fbb329..04322d2cce 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -31,6 +31,12 @@ "name": "Weiß, Manuel", "type": "ProjectMember" }, + { + "affiliation": "KU Leuven", + "name": "Jacobsson, Simon", + "orcid": "0000-0002-1181-972X", + "type": "ProjectMember" + }, { "affiliation": "Georg-August-University GΓΆttingen", "name": "Klingbiel, Lukas", From bd66d56d37a700af5fb4239176b3ba759ceb8a70 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Thu, 19 Dec 2024 11:43:02 +0100 Subject: [PATCH 27/35] Add line about constructor in docstring for WarpedMetric. --- src/manifolds/SegreWarpedMetric.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index 198b9961f1..d928221d05 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -15,6 +15,11 @@ with a [warped product metric](https://en.wikipedia.org/wiki/Warped_product), bu The Segre manifold is a cone in the sense that if ``p \in \mathcal{S}``, then ``a p \in \mathcal{S}`` for all ``r \neq 0``. The tangent subspace at ``p`` defined ``\mathrm{d} (r p) / \mathrm{d} r`` is called the _radial_ direction. ``A < 1`` puts less weight on the directions orthogonal to the radial direction compared to ``\mathcal{S}``, while ``A > 1`` puts more weight on those directions. The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). + +# Constructor + WarpedMetric(A::Real) + +Generate a warped product metric with warping factor `A`. """ struct WarpedMetric{A} <: AbstractMetric end From e0e61a2fd4e5a235f580a9efa8a3078f8d41b858 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Thu, 19 Dec 2024 13:04:42 +0100 Subject: [PATCH 28/35] Actually test coverage for case in closest_representative! where given points are not as close as possible. --- test/manifolds/segre.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index a5ffba9bcb..3f23dfdcd2 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -837,13 +837,13 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences M = Ms[4] p = ps[4] q = qs[4] - q_ = [q[1], q[2], q[3], -q[4], -q[5]] - @test isapprox(log(M, p, q), log(M, p, q_)) + q_ = [q[1], q[2], q[3], q[4], -q[5]] + @test is_vector(M, p, log(M, p, q_)) M = Ms[8] p = ps[8] q = qs[8] - q_ = [q[1], q[2], q[3], -q[4], -q[5]] - @test isapprox(log(M, p, q), log(M, p, q_)) + q_ = [q[1], q[2], q[3], q[4], -q[5]] + @test is_vector(M, p, log(M, p, q_)) end end From d11971c63f175a1aa42dd99204ef901caefb8eb4 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Thu, 19 Dec 2024 18:13:06 +0100 Subject: [PATCH 29/35] Fix documentation unify code: * sort function definitions alphabetically * unify doc strings. --- _quarto.yml | 26 -- docs/src/manifolds/segre.md | 2 +- .../config/vocabularies/Manifolds/accept.txt | 1 + src/manifolds/Segre.jl | 421 +++++++++--------- src/manifolds/SegreWarpedMetric.jl | 242 +++++----- tutorials/_quarto.yml | 2 +- 6 files changed, 340 insertions(+), 354 deletions(-) delete mode 100644 _quarto.yml diff --git a/_quarto.yml b/_quarto.yml deleted file mode 100644 index 44421d48c1..0000000000 --- a/_quarto.yml +++ /dev/null @@ -1,26 +0,0 @@ - -project: - title: "Manifolds.jl" - #execute-dir: project - -crossref: - fig-prefix: Figure - tbl-prefix: Table -bibliography: - - CITATION.bib -# - bib/manopt-bibliography.yaml -# csl: journal-of-the-royal-statistical-society.csl -fig-format: png - -execute: - freeze: auto - eval: true - echo: true - output: true - -format: - commonmark: - variant: -raw_html+tex_math_dollars - wrap: preserve - -jupyter: julia-1.9 diff --git a/docs/src/manifolds/segre.md b/docs/src/manifolds/segre.md index 339b934157..a60c11c2f2 100644 --- a/docs/src/manifolds/segre.md +++ b/docs/src/manifolds/segre.md @@ -18,7 +18,7 @@ WarpedMetric ```@autodocs Modules = [Manifolds] -Pages = ["manifolds/SegreWarped.jl"] +Pages = ["manifolds/SegreWarpedMetric.jl"] Order = [:function] ``` diff --git a/docs/styles/config/vocabularies/Manifolds/accept.txt b/docs/styles/config/vocabularies/Manifolds/accept.txt index bb1628d587..9285310b82 100644 --- a/docs/styles/config/vocabularies/Manifolds/accept.txt +++ b/docs/styles/config/vocabularies/Manifolds/accept.txt @@ -1,6 +1,7 @@ Grassmann [Jj]ulia Riemannian +Segre Stiefel [sS]ymplectic struct \ No newline at end of file diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 752b7f6e22..433266e5eb 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -33,9 +33,7 @@ function Segre(n::Int...; field::AbstractNumbers=ℝ) return Segre{field,(n...,)}() end -manifold_dimension(::Segre{𝔽,V}) where {𝔽,V} = (1 + sum(V .- 1)) - -function check_size(M::Segre{𝔽,V}, p;) where {𝔽,V} +function check_size(M::Segre{𝔽,V}, p) where {𝔽,V} p_size = only.(size.(p)) M_size = [1, V...] @@ -71,47 +69,66 @@ function check_size(M::Segre{𝔽,V}, p, v;) where {𝔽,V} return nothing end -""" - is_point(M::Segre{ℝ, V}, p; kwargs...) +@doc raw""" + closest_representative!(M::Segre{ℝ, V}, p, q) -Check whether `p` is a valid point on `M`, i.e. `p[1]` is a singleton containing a positive number and `p[i + 1]` is a point on `Sphere(V[i])`. The tolerance can be set using the `kwargs...`. +``\mathcal{S}`` is a ``2^d``-sheeted Riemannian covering of +````math + \mathcal{P} = ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} +```` +with the metric [`inner`](@ref inner(::Segre, ::Any)). +Every equivalence class ``q \in \mathcal{S}`` has ``2^d`` representatives in ``\mathcal{P}``. +`closest_representative!(M, q, p)` changes representative of `q` to the one that is closest to `p` in ``\mathcal{P}``. """ -is_point(M::Segre{ℝ,V}, p; kwargs...) where {V} +function closest_representative!(M::Segre{ℝ,V}, q, p) where {V} -function check_point(M::Segre{ℝ,V}, p; atol=1.4901161193847656e-8, kwargs...) where {V} - if p[1][1] <= 0.0 - return DomainError(p[1][1], "$(p) has non-positive modulus.") - end + # Find closest representation by flipping an even number of signs. + ds = [distance(Sphere(n - 1), x, y) for (n, x, y) in zip(V, p[2:end], q[2:end])] + flips = [false, (ds .> (pi / 2))...] + nbr_flips = sum(flips) - for (x, n) in zip(p[2:end], V) - e = check_point(Sphere(n - 1)::AbstractSphere, x; atol=atol, kwargs...) - if !isnothing(e) - return e + # This code is pretty ugly. + if isodd(nbr_flips) + if nbr_flips == length(V) + flips[argmin(ds) + 1] = false + else + is = sortperm(ds; rev=true) + + flips1 = deepcopy(flips) + flips1[is[nbr_flips] + 1] = false + q1 = deepcopy(q) + q1[flips1] = -q1[flips1] + + flips2 = deepcopy(flips) + flips2[is[nbr_flips + 1] + 1] = true + q2 = deepcopy(q) + q2[flips2] = -q2[flips2] + + spherical_angle_sum(M, p, q1) < spherical_angle_sum(M, p, q2) ? flips = flips1 : + flips = flips2 end end + + return q[flips] = -q[flips] end -""" - function is_vector(M::Segre{ℝ, V}, p, v, kwargs...) +@doc raw""" + connected_by_geodesic(M::Segre{ℝ, V}, p, q) -Check whether `v` is a tangent vector to `p` on `M`, i.e. `v` has to be of same dimension as `p` and orthogonal to `p`. The tolerance can be set using the `kwargs...`. +``\mathcal{S}`` is not a complete manifold, i.e. not every pair `p` and `q` of points are connected by a geodesic in ``\mathcal{S}``. +`connected_by_geodesic(M, p, q)` returns `true` if two points, `p` and `q`, are connected by a geodesic, and otherwise returns `false`. """ -is_vector(M::Segre{ℝ,V}, p, v; kwargs...) where {V} - -function check_vector(M::Segre{ℝ,V}, p, v; atol=1.4901161193847656e-8, kwargs...) where {V} - for (x, xdot, n) in zip(p[2:end], v[2:end], V) - e = check_vector(Sphere(n - 1)::AbstractSphere, x, xdot; atol=atol, kwargs...) - if !isnothing(e) - return e - end - end +function connected_by_geodesic(M::Segre{ℝ,V}, p, q) where {V} + closest_representative!(M, q, p) + return spherical_angle_sum(M, p, q) < pi end @doc raw""" - function embed(M::Segre{𝔽, V}, p) - function embed!(M::Segre{𝔽, V}, q, p) + embed(M::Segre{𝔽, V}, p) + embed!(M::Segre{𝔽, V}, q, p) + +Embed ``p ≐ (Ξ», x_1, …, x_d)`` in ``𝔽^{n_1 Γ—β‹―Γ— n_d}`` using the Kronecker product -Embed ``p ≐ (Ξ», x_1, …, x_d)`` in ``𝔽^{n_1 Γ—β‹―Γ— n_d}`` using the Kronecker product: ````math (Ξ», x_1, …, x_d) ↦ Ξ» x_1 βŠ—β‹―βŠ— x_d. ```` @@ -125,7 +142,7 @@ end @doc raw""" embed!(M::Segre{𝔽, V}, p, v) -Embed tangent vector ``v = (Ξ½, u_1, …, u_d)`` at ``p ≐ (Ξ», x_1, …, x_d)`` in ``𝔽^{n_1 Γ—β‹―Γ— n_d}`` using the Kronecker product: +Embed tangent vector ``v = (Ξ½, u_1, …, u_d)`` at ``p ≐ (Ξ», x_1, …, x_d)`` in ``𝔽^{n_1 Γ—β‹―Γ— n_d}`` using the Kronecker product ````math (Ξ½, u_1, …, u_d) ↦ Ξ½ x_1 βŠ—β‹―βŠ— x_d + Ξ» u_1 βŠ— x_2 βŠ—β‹―βŠ— x_d + … + Ξ» x_1 βŠ—β‹―βŠ— x_{d - 1} βŠ— u_d. @@ -139,193 +156,75 @@ function embed!(::Segre{𝔽,V}, u, p, v) where {𝔽,V} ]) end -@doc raw""" - function get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) - -Get coordinates of `v` in the tangent space -``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} ×…× T_{x_d} S^{n_d - 1}`` -using a `DefaultOrthonormalBasis` on each factor. """ -get_coordinates(M::Segre, p, v, ::DefaultOrthonormalBasis; kwargs...) - -function get_coordinates_orthonormal!( - M::Segre{ℝ,V}, - X, - p, - v, - ::RealNumbers; - kwargs..., -) where {V} - return X = vcat( - v[1], - p[1][1] * [ - get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end]) - ]..., - ) -end - -@doc raw""" - function get_vector( M::Segre{𝔽, V}, p, X, DefaultOrthonormalBasis; kwargs...) + is_point(M::Segre{ℝ, V}, p; kwargs...) -Get tangent vector `v` from coordinates in the tangent space -``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` -using `DefaultOrthonormalBasis` on each factor. +Check whether `p` is a valid point on `M`, i.e. `p[1]` is a singleton containing a positive number and `p[i + 1]` is a point on `Sphere(V[i])`. +The tolerance can be set using the `kwargs...`. """ -get_vector(M::Segre, p, X, ::DefaultOrthonormalBasis; kwargs...) +is_point(M::Segre{ℝ,V}, p; kwargs...) where {V} -function get_vector_orthonormal!(M::Segre{ℝ,V}, v, p, X, ::RealNumbers; kwargs...) where {V} - X_ = deepcopy(X) - v[1] = [X_[1]] - X_ = X_[2:end] - for (i, n) in enumerate(V) - v[i + 1] = - get_vector( - Sphere(n - 1), - p[i + 1], - X_[1:(n - 1)], - DefaultOrthonormalBasis(); - kwargs..., - ) / p[1][1] - X_ = X_[n:end] +function check_point(M::Segre{ℝ,V}, p; atol=1.4901161193847656e-8, kwargs...) where {V} + if p[1][1] <= 0.0 + return DomainError(p[1][1], "$(p) has non-positive modulus.") end - return v -end -@doc raw""" - function inner(M::Segre{ℝ, V}, p, u, v,) - -Inner product between two tangent vectors ``u = (Ξ½, u_1, …, u_d)`` and ``v = (ΞΎ, v_1, …, v_d)`` at ``p ≐ (Ξ», x_1, \dots, x_d)``. -This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric: - -````math - \langle u, v \rangle_{p} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle_{x_1} + \dots + \langle u_d, v_d \rangle_{x_d}), -```` - -where ``Ξ½, ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} S^{n_i - 1} βŠ‚ ℝ^{n_i}``. -""" -function inner(::Segre{ℝ}, p, u, v) - return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) + for (x, n) in zip(p[2:end], V) + e = check_point(Sphere(n - 1)::AbstractSphere, x; atol=atol, kwargs...) + if !isnothing(e) + return e + end + end end -@doc raw""" - function rand(M::Segre{ℝ, V}; vector_at=nothing) - -If `vector_at` is `nothing`, return a random point on - -````math - ℝ^{+} Γ— S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1} -```` - -from a log-normal distribution on ℝ^{+} and a uniform distribution on ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}``. +""" + is_vector(M::Segre{ℝ, V}, p, v, kwargs...) -If `vector_at` is not `nothing`, return a random tangent vector from a normal distribution on the tangent space. +Check whether `v` is a tangent vector to `p` on `M`, i.e. `v` has to be of same dimension as `p` and orthogonal to `p`. +The tolerance can be set using the `kwargs...`. """ -function rand(M::Segre{ℝ,V}; vector_at=nothing, kwargs...) where {V} - if isnothing(vector_at) - return [ - rand(PositiveArrays(1); kwargs...), - [rand(Sphere(n - 1); kwargs...) for n in V]..., - ] - else - return [ - rand(PositiveArrays(1); vector_at=vector_at[1], kwargs...), - [ - rand(Sphere(n - 1); vector_at=xdot, kwargs...) for - (xdot, n) in zip(vector_at[2:end], V) - ]..., - ] +is_vector(M::Segre{ℝ,V}, p, v; kwargs...) where {V} + +function check_vector(M::Segre{ℝ,V}, p, v; atol=1.4901161193847656e-8, kwargs...) where {V} + for (x, xdot, n) in zip(p[2:end], v[2:end], V) + e = check_vector(Sphere(n - 1)::AbstractSphere, x, xdot; atol=atol, kwargs...) + if !isnothing(e) + return e + end end end @doc raw""" - function get_embedding(M::Segre{𝔽,V}) - -``\mathcal{S}`` is embedded in ``𝔽^{n_1 Γ—β‹―Γ— n_d}``. -""" -function get_embedding(::Segre{𝔽,V}) where {𝔽,V} - return Euclidean(prod(V)) -end + distance(M::Segre{ℝ, V}, p, q) -@doc raw""" - function spherical_angle_sum(M::Segre{ℝ, V}, p, q) +Riemannian distance between two points `p` and `q` on the Segre manifold. -Let ``p ≐ (Ξ», x_1, …, x_d)``, ``q ≐ (ΞΌ, y_1, …, y_d) ∈ \mathcal{S}``. -Then this is +Assume ``p ≐ (Ξ», x_1, …, x_d)``, ``q ≐ (ΞΌ, y_1, …, y_d) ∈ \mathcal{S}`` are connected by a geodesic. Let ````math - \sqrt{\sphericalangle(x_1, y_1)^2 + … + \sphericalangle(x_d, y_d)^2}, + m = \sqrt{\sphericalangle(x_1, y_1)^2 + … + \sphericalangle(x_d, y_d)^2} ```` -where ``\sphericalangle(x_i, y_i)`` is the distance between ``x_i`` and ``y_i`` on the sphere ``S^{n_i - 1}``. - -""" -function spherical_angle_sum(::Segre{ℝ,V}, p, q) where {V} - return sqrt( - sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), - ) -end - -@doc raw""" - function connected_by_geodesic(M::Segre{ℝ, V}, p, q) - -``\mathcal{S}`` is not a complete manifold, i.e. not every pair `p` and `q` of points are connected by a geodesic in ``\mathcal{S}``. -`connected_by_geodesic(M, p, q)` returns `true` if two points, `p` and `q`, are connected by a geodesic, and otherwise returns `false`. -""" -function connected_by_geodesic(M::Segre{ℝ,V}, p, q) where {V} - closest_representative!(M, q, p) - return spherical_angle_sum(M, p, q) < pi -end - -@doc raw""" - function closest_representative!(M::Segre{ℝ, V}, p, q) +and assume ``(ΞΌ, y_1, …, y_d)`` is the representation of ``q`` that minimizes ``m``. Then -``\mathcal{S}`` is a ``2^d``-sheeted Riemannian covering of ````math - \mathcal{P} = ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} + \operatorname{dist}_{\mathcal{S}}(p, q) = \sqrt{Ξ»^2 - 2 λμ\cos(m) + ΞΌ^2}. ```` -with the metric [`inner`](@ref inner(::Segre, ::Any)). -Every equivalence class ``q \in \mathcal{S}`` has ``2^d`` representatives in ``\mathcal{P}``. -`closest_representative!(M, q, p)` changes representative of `q` to the one that is closest to `p` in ``\mathcal{P}``. """ -function closest_representative!(M::Segre{ℝ,V}, q, p) where {V} - - # Find closest representation by flipping an even number of signs. - ds = [distance(Sphere(n - 1), x, y) for (n, x, y) in zip(V, p[2:end], q[2:end])] - flips = [false, (ds .> (pi / 2))...] - nbr_flips = sum(flips) - - # This code is pretty ugly. - if isodd(nbr_flips) - if nbr_flips == length(V) - flips[argmin(ds) + 1] = false - else - is = sortperm(ds; rev=true) - - flips1 = deepcopy(flips) - flips1[is[nbr_flips] + 1] = false - q1 = deepcopy(q) - q1[flips1] = -q1[flips1] - - flips2 = deepcopy(flips) - flips2[is[nbr_flips + 1] + 1] = true - q2 = deepcopy(q) - q2[flips2] = -q2[flips2] - - spherical_angle_sum(M, p, q1) < spherical_angle_sum(M, p, q2) ? flips = flips1 : - flips = flips2 - end - end - - return q[flips] = -q[flips] +function distance(M::Segre{ℝ,V}, p, q) where {V} + closest_representative!(M, q, p) + m = spherical_angle_sum(M, p, q) + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m / 2)^2) + # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(m)) but more stable for small m end @doc raw""" - function exp(M::Segre{ℝ, V}, p, v) + exp(M::Segre{ℝ, V}, p, v) Exponential map on the Segre manifold. Let ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}`` and ``v = (Ξ½, u_1, …, u_d) ∈ T_p \mathcal{S}``. -Then +The exponential map is given by ````math \operatorname{exp}_p(v) ≐ @@ -340,11 +239,14 @@ Then where ````math - g = \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{Ξ»} + P \mathclose{\Big)} - \tan^{-1}(P),\\ - m = \sqrt{\lVert u_1 \rVert_{x_1}^2 + … + \lVert u_d \rVert_{x_d}^2},\\ - P = \frac{\nu}{Ξ» m},\\ - t = \lVert v \rVert_{p}. + \begin{aligned} + g &= \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{Ξ»} + P \mathclose{\Big)} - \tan^{-1}(P),\\ + m &= \sqrt{\lVert u_1 \rVert_{x_1}^2 + … + \lVert u_d \rVert_{x_d}^2} > 0,\\ + P &= \frac{\nu}{Ξ» m},\\ + t &= \lVert v \rVert_{p}. + \end{aligned} ```` + If ``m = 0`` and ``Ξ½ t < Ξ»``, then ``\operatorname{exp}_p(v) = p + v``. For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). @@ -376,7 +278,84 @@ function exp!(::Segre{ℝ,V}, q, p, v) where {V} end @doc raw""" - function log(M::Segre{ℝ, V}, p, q) + get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) + +Get coordinates of `v` in the tangent space +``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} ×…× T_{x_d} S^{n_d - 1}`` +using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. +""" +get_coordinates(M::Segre, p, v, ::DefaultOrthonormalBasis; kwargs...) + +function get_coordinates_orthonormal!( + M::Segre{ℝ,V}, + X, + p, + v, + ::RealNumbers; + kwargs..., +) where {V} + return X = vcat( + v[1], + p[1][1] * [ + get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + ]..., + ) +end + +@doc raw""" + get_embedding(M::Segre{𝔽,V}) + +Return the embedding of the [`Segre`](@ref) manifold ``\mathcal{S}``, which is ``𝔽^{n_1 Γ—β‹―Γ— n_d}``. +""" +function get_embedding(::Segre{𝔽,V}) where {𝔽,V} + return Euclidean(prod(V)) +end + +@doc raw""" + get_vector( M::Segre{𝔽, V}, p, X, DefaultOrthonormalBasis; kwargs...) + +Get tangent vector `v` from coordinates in the tangent space +``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` +using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. +""" +get_vector(M::Segre, p, X, ::DefaultOrthonormalBasis; kwargs...) + +function get_vector_orthonormal!(M::Segre{ℝ,V}, v, p, X, ::RealNumbers; kwargs...) where {V} + X_ = deepcopy(X) + v[1] = [X_[1]] + X_ = X_[2:end] + for (i, n) in enumerate(V) + v[i + 1] = + get_vector( + Sphere(n - 1), + p[i + 1], + X_[1:(n - 1)], + DefaultOrthonormalBasis(); + kwargs..., + ) / p[1][1] + X_ = X_[n:end] + end + return v +end + +@doc raw""" + inner(M::Segre{ℝ, V}, p, u, v,) + +Inner product between two tangent vectors ``u = (Ξ½, u_1, …, u_d)`` and ``v = (ΞΎ, v_1, …, v_d)`` at ``p ≐ (Ξ», x_1, \dots, x_d)``. +This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric: + +````math + \langle u, v \rangle_{p} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle_{x_1} + \dots + \langle u_d, v_d \rangle_{x_d}), +```` + +where ``Ξ½, ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} S^{n_i - 1} βŠ‚ ℝ^{n_i}``. +""" +function inner(::Segre{ℝ}, p, u, v) + return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) +end + +@doc raw""" + log(M::Segre{ℝ, V}, p, q) Logarithmic map on the Segre manifold. @@ -419,33 +398,59 @@ function log!(M::Segre{ℝ,V}, v, p, q) where {V} return v end -@doc raw""" - function distance(M::Segre{ℝ, V}, p, q) +manifold_dimension(::Segre{𝔽,V}) where {𝔽,V} = (1 + sum(V .- 1)) -Riemannian distance between two points `p` and `q` on the Segre manifold. +@doc raw""" + spherical_angle_sum(M::Segre{ℝ, V}, p, q) -Assume ``p ≐ (Ξ», x_1, …, x_d)``, ``q ≐ (ΞΌ, y_1, …, y_d) ∈ \mathcal{S}`` are connected by a geodesic. Let +Let ``p ≐ (Ξ», x_1, …, x_d)``, ``q ≐ (ΞΌ, y_1, …, y_d) ∈ \mathcal{S}``. +Then this is ````math - m = \sqrt{\sphericalangle(x_1, y_1)^2 + … + \sphericalangle(x_d, y_d)^2} + \sqrt{\sphericalangle(x_1, y_1)^2 + … + \sphericalangle(x_d, y_d)^2}, ```` -and assume ``(ΞΌ, y_1, …, y_d)`` is the representation of ``q`` that minimizes ``m``. Then +where ``\sphericalangle(x_i, y_i)`` is the distance between ``x_i`` and ``y_i`` on the sphere ``S^{n_i - 1}``. + +""" +function spherical_angle_sum(::Segre{ℝ,V}, p, q) where {V} + return sqrt( + sum([distance(Sphere(n - 1), x, y)^2 for (n, x, y) in zip(V, p[2:end], q[2:end])]), + ) +end + +@doc raw""" + rand(M::Segre{ℝ, V}; vector_at=nothing) + +If `vector_at` is `nothing`, return a random point on ````math - \operatorname{dist}_{\mathcal{S}}(p, q) = \sqrt{Ξ»^2 - 2 λμ\cos(m) + ΞΌ^2}. + ℝ^{+} Γ— S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1} ```` -""" -function distance(M::Segre{ℝ,V}, p, q) where {V} - closest_representative!(M, q, p) - m = spherical_angle_sum(M, p, q) - return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(m / 2)^2) - # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(m)) but more stable for small m +from a log-normal distribution on ``ℝ^{+}`` and a uniform distribution on ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}``. + +If `vector_at` is not `nothing`, return a random tangent vector from a normal distribution on the tangent space. +""" +function rand(M::Segre{ℝ,V}; vector_at=nothing, kwargs...) where {V} + if isnothing(vector_at) + return [ + rand(PositiveArrays(1); kwargs...), + [rand(Sphere(n - 1); kwargs...) for n in V]..., + ] + else + return [ + rand(PositiveArrays(1); vector_at=vector_at[1], kwargs...), + [ + rand(Sphere(n - 1); vector_at=xdot, kwargs...) for + (xdot, n) in zip(vector_at[2:end], V) + ]..., + ] + end end @doc raw""" - function riemann_tensor(M::Segre{ℝ, V}, p, u, v, w) + riemann_tensor(M::Segre{ℝ, V}, p, u, v, w) Riemann tensor of the Segre manifold at ``p``. @@ -473,7 +478,7 @@ function riemann_tensor(M::Segre{ℝ,V}, p, u, v, w) where {V} end @doc raw""" - function sectional_curvature(M::Segre{ℝ, V}, p, u, v) + sectional_curvature(M::Segre{ℝ, V}, p, u, v) Sectional curvature of the Segre manifold at ``p``. @@ -491,6 +496,6 @@ function sectional_curvature(M::Segre{ℝ,V}, p, u, v) where {V} (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) end -function Base.show(io::IO, M::Segre{𝔽,V}) where {𝔽,V} +function Base.show(io::IO, ::Segre{𝔽,V}) where {𝔽,V} return print(io, "Segre($(join(V, ", ")); field=$(𝔽))") end diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index d928221d05..793fb038db 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -27,10 +27,111 @@ function WarpedMetric(A::Real) return WarpedMetric{A}() end +function connected_by_geodesic( + M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, + p, + q, +) where {V,A} + return connected_by_geodesic(M.manifold, p, q) +end + +function closest_representative!( + M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, + q, + p, +) where {V,A} + return closest_representative!(M.manifold, q, p) +end + +@doc raw""" + distance(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) + +Riemannian distance between two points `p` and `q` on the warped Segre manifold. + +Assume ``p ≐ (Ξ», x_1,…, x_d)``, ``q ≐ (ΞΌ, y_1,…, y_d) ∈ \mathcal{S}_A`` are connected by a geodesic. Let + +````math + m = \sqrt{\sphericalangle(x_1, y_1)^2 +… + \sphericalangle(x_d, y_d)^2} +```` + +and assume ``(ΞΌ, y_1,…, y_d)`` is the representation of ``q`` that minimizes ``m``. Then + +````math + \operatorname{dist}_{\mathcal{S}_A}(p, q) = \sqrt{Ξ»^2 - 2 Ξ» ΞΌ \cos(A m) + ΞΌ^2}. +```` +""" +function distance(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} + closest_representative!(M, q, p) + m = spherical_angle_sum(M, p, q) + return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m / 2)^2) + # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(A * m)) but more stable for small m +end + +@doc raw""" + exp(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, v) + +Exponential map on the warped Segre manifold. + +Let ``p ≐ (Ξ», x_1,…, x_d) ∈ \mathcal{S}_A`` and ``v = (Ξ½, u_1,…, u_d) ∈ T_p \mathcal{S}_A``. +Then the exponential map is given by + +````math + \operatorname{exp}_p(v) ≐ + \left( + \sqrt{t^2 + 2 Ξ» Ξ½ t + Ξ»^2},\\ + x_1 \cos\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)},\\ + …,\\ + x_d \cos\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} + \right), +```` + +where + +````math + \begin{aligned} + g &= \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{Ξ»} + P \mathclose{\Big)} - \tan^{-1}(P),\\ + m &= \sqrt{\lVert u_1 \rVert_{x_1}^2 +… + \lVert u_d \rVert_{x_d}^2} > 0,\\ + P &= \frac{Ξ½}{Ξ» A m},\\ + t &= \lVert v \rVert_{p}. + \end{aligned} +```` + +If ``m = 0`` and ``Ξ½ t < Ξ»``, then ``\operatorname{exp}_p(v) = p + v``. + +For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). +""" +exp(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, v) where {V,A} + +function exp!(::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) where {V,A} + m = sqrt( + sum([ + norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + ]), + ) + + q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * A * m)^2) + + f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * A * m)) + if m == 0 + for (x, y) in zip(p[2:end], q[2:end]) + y .= x + end + else + for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) + a = norm(Sphere(n - 1), x, xdot) + y .= + x * cos(a * f / (A * m)) .+ + xdot * (f / (A * m)) * sinc(a * f / (A * m * pi)) + end + end + + return q +end + @doc raw""" - function get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) + get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) -Get coordinates of `v` in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. +Get coordinates of `v` in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. """ get_coordinates( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, @@ -59,9 +160,9 @@ function get_coordinates_orthonormal!( end @doc raw""" - function get_vector( M::Segre{𝔽, V}, p, X, ::DefaultOrthonormalBasis; kwargs...) + get_vector( M::Segre{𝔽, V}, p, X, ::DefaultOrthonormalBasis; kwargs...) -Get tangent vector `v` from coordinates in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` using `DefaultOrthonormalBasis` on each factor. +Get tangent vector `v` from coordinates in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. """ get_vector( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, @@ -98,11 +199,11 @@ function get_vector_orthonormal!( end @doc raw""" - function inner( M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, u, v) + inner(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, u, v) Inner product between two tangent vectors ``u = (Ξ½, u_1,…, u_d)`` and ``v = (ΞΎ, v_1,…, v_d)`` at ``p = (Ξ», x_1,…, x_d``: ````math - ⟨ u, v ⟩_{p} = Ξ½ ΞΎ + (A Ξ»)^2 (⟨ u_1, v_1 ⟩_{x_1} +… + ⟨ u_d, v_d ⟩_{x_d}), + ⟨u, v⟩_{p} = Ξ½ ΞΎ + (A Ξ»)^2 (⟨ u_1, v_1 ⟩_{x_1} +… + ⟨u_d, v_d⟩_{x_d}), ```` where ``Ξ½``, ``ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. """ @@ -110,87 +211,8 @@ function inner(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v) whe return u[1][1] * v[1][1] + (A * p[1][1])^2 * dot(u[2:end], v[2:end]) end -function spherical_angle_sum( - M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, - p, - q, -) where {V,A} - return spherical_angle_sum(M.manifold, p, q) -end - -function connected_by_geodesic( - M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, - p, - q, -) where {V,A} - return connected_by_geodesic(M.manifold, p, q) -end - -function closest_representative!( - M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, - q, - p, -) where {V,A} - return closest_representative!(M.manifold, q, p) -end - @doc raw""" - function exp(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, v) - -Exponential map on the warped Segre manifold. - -Let ``p ≐ (Ξ», x_1,…, x_d) ∈ \mathcal{S}_A`` and ``v = (Ξ½, u_1,…, u_d) ∈ T_p \mathcal{S}_A``. -Then -````math - \operatorname{exp}_p(v) ≐ - \left( - \sqrt{t^2 + 2 Ξ» Ξ½ t + Ξ»^2},\\ - x_1 \cos\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)},\\ - …,\\ - x_d \cos\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} - \right), -```` -where -````math - g = \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{Ξ»} + P \mathclose{\Big)} - \tan^{-1}(P),\\ - m = \sqrt{\lVert u_1 \rVert_{x_1}^2 +… + \lVert u_d \rVert_{x_d}^2},\\ - P = \frac{Ξ½}{Ξ» A m},\\ - t = \lVert v \rVert_{p}. -```` -If ``m = 0`` and ``Ξ½ t < Ξ»``, then ``\operatorname{exp}_p(v) = p + v``. - -For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). -""" -exp(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, v) where {V,A} - -function exp!(::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) where {V,A} - m = sqrt( - sum([ - norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) - ]), - ) - - q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * A * m)^2) - - f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * A * m)) - if m == 0 - for (x, y) in zip(p[2:end], q[2:end]) - y .= x - end - else - for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) - a = norm(Sphere(n - 1), x, xdot) - y .= - x * cos(a * f / (A * m)) .+ - xdot * (f / (A * m)) * sinc(a * f / (A * m * pi)) - end - end - - return q -end - -@doc raw""" - function log(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) + log(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) Logarithmic map on the warped Segre manifold. @@ -234,31 +256,7 @@ function log!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, v, p, q) wher end @doc raw""" - function distance(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, q) - -Riemannian distance between two points `p` and `q` on the warped Segre manifold. - -Assume ``p ≐ (Ξ», x_1,…, x_d)``, ``q ≐ (ΞΌ, y_1,…, y_d) ∈ \mathcal{S}_A`` are connected by a geodesic. Let - -````math - m = \sqrt{\sphericalangle(x_1, y_1)^2 +… + \sphericalangle(x_d, y_d)^2} -```` - -and assume ``(ΞΌ, y_1,…, y_d)`` is the representation of ``q`` that minimizes ``m``. Then - -````math - \operatorname{dist}_{\mathcal{S}_A}(p, q) = \sqrt{Ξ»^2 - 2 Ξ» ΞΌ \cos(A m) + ΞΌ^2}. -```` -""" -function distance(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} - closest_representative!(M, q, p) - m = spherical_angle_sum(M, p, q) - return sqrt((p[1][1] - q[1][1])^2 + 4 * p[1][1] * q[1][1] * sin(A * m / 2)^2) - # Equivalent to sqrt(p[1][1]^2 + q[1][1]^2 - 2 * p[1][1] * q[1][1] * cos(A * m)) but more stable for small m -end - -@doc raw""" - function riemann_tensor(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, u, v) + riemann_tensor(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, u, v) Riemann tensor of the warped Segre manifold at ``p``. @@ -271,25 +269,25 @@ Riemann tensor of the warped Segre manifold at ``p``. function riemann_tensor( M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, - u, - v, - w, + X, + Y, + Z, ) where {V,A} return [ [0.0], [ riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for - (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u[2:end], v[2:end], w[2:end]) + (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], X[2:end], Y[2:end], Z[2:end]) ]..., ] + (1 / p[1][1]^2) * ( - inner(M, p, [[0.0], u[2:end]...], [[0.0], w[2:end]...]) * [[0.0], v[2:end]...] - - inner(M, p, [[0.0], v[2:end]...], [[0.0], w[2:end]...]) * [[0.0], u[2:end]...] + inner(M, p, [[0.0], X[2:end]...], [[0.0], Z[2:end]...]) * [[0.0], Y[2:end]...] - + inner(M, p, [[0.0], Y[2:end]...], [[0.0], Z[2:end]...]) * [[0.0], X[2:end]...] ) end @doc raw""" - function sectional_curvature(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, u, v) + sectional_curvature(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, u, v) Sectional curvature of the warped Segre manifold at ``p``. @@ -309,3 +307,11 @@ function sectional_curvature( return inner(M, p, riemann_tensor(M, p, u, v, v), u) / (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) end + +function spherical_angle_sum( + M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, + p, + q, +) where {V,A} + return spherical_angle_sum(M.manifold, p, q) +end diff --git a/tutorials/_quarto.yml b/tutorials/_quarto.yml index 0966a12e28..4ae305952e 100644 --- a/tutorials/_quarto.yml +++ b/tutorials/_quarto.yml @@ -24,4 +24,4 @@ format: variant: -raw_html+tex_math_dollars+pipe_tables+footnotes wrap: preserve -jupyter: julia-1.10 +jupyter: julia-1.11 From 5d8a4badbb7596a95cca9d73df9e6d42092cb35f Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Thu, 19 Dec 2024 18:19:08 +0100 Subject: [PATCH 30/35] bump documenter CI to Julia 1.11 as well. --- .github/workflows/documenter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/documenter.yml b/.github/workflows/documenter.yml index f16edf2929..73427534fe 100644 --- a/.github/workflows/documenter.yml +++ b/.github/workflows/documenter.yml @@ -17,7 +17,7 @@ jobs: version: "1.6.38" - uses: julia-actions/setup-julia@latest with: - version: "1.10" + version: "1.11" - name: Julia Cache uses: julia-actions/cache@v2 - name: Cache Quarto From f41fece46e8e2bc71b172fda35985310a9aea729 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Fri, 20 Dec 2024 08:16:56 +0100 Subject: [PATCH 31/35] add a show method for the warped metric so it prints nicer on REPL --- src/manifolds/SegreWarpedMetric.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index 793fb038db..c61a069f7b 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -308,6 +308,10 @@ function sectional_curvature( (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) end +function show(io::IO, ::WarpedMetric{A}) where {A} + return print(io, "WarpedMetric($A)") +end + function spherical_angle_sum( M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, From 1f29ba8c5e1c545db7acc5441f6f8273b39147ff Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Fri, 20 Dec 2024 15:40:36 +0100 Subject: [PATCH 32/35] Code golf in the segre tests. Also change a bunch of variable names and update the docs a bit. --- src/manifolds/Segre.jl | 183 ++++---- src/manifolds/SegreWarpedMetric.jl | 138 +++--- test/manifolds/segre.jl | 723 ++++------------------------- 3 files changed, 254 insertions(+), 790 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index 433266e5eb..e16439e6d3 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -12,20 +12,18 @@ is the set of rank-one tensors in ``𝔽^{n_1} \otimes \dots \otimes 𝔽^{n_d}` When ``𝔽 = ℝ``, the Segre manifold is a normal Riemannian covering of ````math - \mathcal{P} = ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} + \mathcal{P} = ℝ^{+} \times \mathbb{S}^{n_1 - 1} \times \dots \times \mathbb{S}^{n_d - 1} ```` -with the [warped product metric](https://en.wikipedia.org/wiki/Warped_product) [`inner`](@ref inner(::Segre, ::Any)). The tuple ``(n_1, \dots, n_d)`` is called the _valence_ of the manifold. +equipped with a [warped product metric](https://en.wikipedia.org/wiki/Warped_product). The tuple ``(n_1, \dots, n_d)`` is called the _valence_ of the manifold. -The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). - -The manifold is named after [Corrado Segre](https://en.wikipedia.org/wiki/Corrado_Segre)(1863–1924). +The geometry of the Segre manifold is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). It is named after [Corrado Segre](https://en.wikipedia.org/wiki/Corrado_Segre)(1863–1924). # Constructor Segre(n::Int...; field::AbstractNumbers=ℝ) Generate a valence `(n, ...)` Segre manifold. -`Segre(n)` is the same as ``\mathbb{R} \setminus \{ 0 \}``. +`Segre(n)` is the same as ``\mathbb{R}^{n} \setminus \{ 0 \}``. """ struct Segre{𝔽,V} <: AbstractManifold{𝔽} end @@ -47,9 +45,9 @@ function check_size(M::Segre{𝔽,V}, p) where {𝔽,V} return nothing end -function check_size(M::Segre{𝔽,V}, p, v;) where {𝔽,V} +function check_size(M::Segre{𝔽,V}, p, X;) where {𝔽,V} p_size = only.(size.(p)) - v_size = only.(size.(v)) + X_size = only.(size.(X)) M_size = [1, V...] if p_size != M_size @@ -59,10 +57,10 @@ function check_size(M::Segre{𝔽,V}, p, v;) where {𝔽,V} ) end - if v_size != M_size + if X_size != M_size return DomainError( - v_size, - "The vector $(v) can not belong to the manifold $(M), since its size $(v_size) is not equal to the manifolds representation size ($(M_size)).", + X_size, + "The vector $(X) can not belong to the manifold $(M), since its size $(X_size) is not equal to the manifolds representation size ($(M_size)).", ) end @@ -74,9 +72,9 @@ end ``\mathcal{S}`` is a ``2^d``-sheeted Riemannian covering of ````math - \mathcal{P} = ℝ^{+} \times S^{n_1 - 1} \times \dots \times S^{n_d - 1} + \mathcal{P} = ℝ^{+} \times \mathbb{S}^{n_1 - 1} \times \dots \times \mathbb{S}^{n_d - 1} ```` -with the metric [`inner`](@ref inner(::Segre, ::Any)). +with the metric [`inner`](@ref inner(::Segre, ::Any, ::Any, ::Any)). Every equivalence class ``q \in \mathcal{S}`` has ``2^d`` representatives in ``\mathcal{P}``. `closest_representative!(M, q, p)` changes representative of `q` to the one that is closest to `p` in ``\mathcal{P}``. """ @@ -140,18 +138,18 @@ function embed!(M::Segre, q, p) end @doc raw""" - embed!(M::Segre{𝔽, V}, p, v) + embed!(M::Segre{𝔽, V}, p, X) -Embed tangent vector ``v = (Ξ½, u_1, …, u_d)`` at ``p ≐ (Ξ», x_1, …, x_d)`` in ``𝔽^{n_1 Γ—β‹―Γ— n_d}`` using the Kronecker product +Embed tangent vector ``X = (Ξ½, u_1, …, u_d)`` at ``p ≐ (Ξ», x_1, …, x_d)`` in ``𝔽^{n_1 Γ—β‹―Γ— n_d}`` using the Kronecker product ````math (Ξ½, u_1, …, u_d) ↦ Ξ½ x_1 βŠ—β‹―βŠ— x_d + Ξ» u_1 βŠ— x_2 βŠ—β‹―βŠ— x_d + … + Ξ» x_1 βŠ—β‹―βŠ— x_{d - 1} βŠ— u_d. ```` """ -function embed!(::Segre{𝔽,V}, u, p, v) where {𝔽,V} +function embed!(::Segre{𝔽,V}, u, p, X) where {𝔽,V} # Product rule return u = sum([ - kron([i == j ? xdot : x for (j, (x, xdot)) in enumerate(zip(p, v))]...) for + kron([i == j ? xdot : x for (j, (x, xdot)) in enumerate(zip(p, X))]...) for (i, _) in enumerate(p) ]) end @@ -178,15 +176,15 @@ function check_point(M::Segre{ℝ,V}, p; atol=1.4901161193847656e-8, kwargs...) end """ - is_vector(M::Segre{ℝ, V}, p, v, kwargs...) + is_vector(M::Segre{ℝ, V}, p, X, kwargs...) -Check whether `v` is a tangent vector to `p` on `M`, i.e. `v` has to be of same dimension as `p` and orthogonal to `p`. +Check whether `X` is a tangent vector to `p` on `M`, i.e. `X` has to be of same dimension as `p` and orthogonal to `p`. The tolerance can be set using the `kwargs...`. """ is_vector(M::Segre{ℝ,V}, p, v; kwargs...) where {V} -function check_vector(M::Segre{ℝ,V}, p, v; atol=1.4901161193847656e-8, kwargs...) where {V} - for (x, xdot, n) in zip(p[2:end], v[2:end], V) +function check_vector(M::Segre{ℝ,V}, p, X; atol=1.4901161193847656e-8, kwargs...) where {V} + for (x, xdot, n) in zip(p[2:end], X[2:end], V) e = check_vector(Sphere(n - 1)::AbstractSphere, x, xdot; atol=atol, kwargs...) if !isnothing(e) return e @@ -219,20 +217,20 @@ function distance(M::Segre{ℝ,V}, p, q) where {V} end @doc raw""" - exp(M::Segre{ℝ, V}, p, v) + exp(M::Segre{ℝ, V}, p, X) Exponential map on the Segre manifold. -Let ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}`` and ``v = (Ξ½, u_1, …, u_d) ∈ T_p \mathcal{S}``. +Let ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}`` and ``X = (Ξ½, u_1, …, u_d) ∈ T_p \mathcal{S}``. The exponential map is given by ````math - \operatorname{exp}_p(v) ≐ + \operatorname{exp}_p(X) ≐ \left( - \sqrt{t^2 + 2 Ξ» Ξ½ t + Ξ»^2},\\ - x_1 \cos\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{m} \mathclose{\Big)},\\ + \sqrt{(Ξ» + Ξ½)^2 + (Ξ» m)^2},\\ + x_1 \cos\mathopen{\Big(} \frac{f \lVert u_1 \rVert_{x_1}}{m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{f \lVert u_1 \rVert_{x_1}}{m} \mathclose{\Big)},\\ …,\\ - x_d \cos\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{m} \mathclose{\Big)} + x_d \cos\mathopen{\Big(} \frac{f \lVert u_d \rVert_{x_d}}{m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{f \lVert u_d \rVert_{x_d}}{m} \mathclose{\Big)} \right), ```` @@ -240,35 +238,33 @@ where ````math \begin{aligned} - g &= \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{Ξ»} + P \mathclose{\Big)} - \tan^{-1}(P),\\ - m &= \sqrt{\lVert u_1 \rVert_{x_1}^2 + … + \lVert u_d \rVert_{x_d}^2} > 0,\\ - P &= \frac{\nu}{Ξ» m},\\ - t &= \lVert v \rVert_{p}. + f &= \frac{\pi}{2} - \tan^{-1}\mathopen{\Big(} \frac{Ξ» + Ξ½}{Ξ» m} \mathclose{\Big)},\\ + m &= \sqrt{\lVert u_1 \rVert_{x_1}^2 + … + \lVert u_d \rVert_{x_d}^2}. \end{aligned} ```` -If ``m = 0`` and ``Ξ½ t < Ξ»``, then ``\operatorname{exp}_p(v) = p + v``. +If ``m = 0`` and ``-Ξ» < Ξ½``, then ``\operatorname{exp}_p(v) = p + X``. -For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). +The formula is derived in proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -exp(M::Segre{ℝ,V}, p, v) where {V} +exp(M::Segre{ℝ,V}, p, X) where {V} -function exp!(::Segre{ℝ,V}, q, p, v) where {V} +function exp!(::Segre{ℝ,V}, q, p, X) where {V} m = sqrt( sum([ - norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], X[2:end]) ]), ) - q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * m)^2) + q[1][1] = sqrt((p[1][1] + X[1][1])^2 + (p[1][1] * m)^2) - f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * m)) + f = pi / 2 - atan((p[1][1] + X[1][1]) / (p[1][1] * m)) if m == 0 for (x, y) in zip(p[2:end], q[2:end]) y .= x end else - for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) + for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], X[2:end]) a = norm(Sphere(n - 1), x, xdot) y .= x * cos(a * f / m) .+ xdot * (f / m) * sinc(a * f / (m * pi)) end @@ -278,26 +274,26 @@ function exp!(::Segre{ℝ,V}, q, p, v) where {V} end @doc raw""" - get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) + get_coordinates(M::Segre{𝔽, V}, p, X, ::DefaultOrthonormalBasis; kwargs...) -Get coordinates of `v` in the tangent space -``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} ×…× T_{x_d} S^{n_d - 1}`` +Get coordinates of `X` in the tangent space +``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} \mathbb{S}^{n_1 - 1} ×…× T_{x_d} \mathbb{S}^{n_d - 1}`` using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. """ -get_coordinates(M::Segre, p, v, ::DefaultOrthonormalBasis; kwargs...) +get_coordinates(M::Segre, p, X, ::DefaultOrthonormalBasis; kwargs...) function get_coordinates_orthonormal!( M::Segre{ℝ,V}, - X, + c, p, - v, + X, ::RealNumbers; kwargs..., ) where {V} - return X = vcat( - v[1], + return c = vcat( + X[1], p[1][1] * [ - get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], X[2:end]) ]..., ) end @@ -312,46 +308,46 @@ function get_embedding(::Segre{𝔽,V}) where {𝔽,V} end @doc raw""" - get_vector( M::Segre{𝔽, V}, p, X, DefaultOrthonormalBasis; kwargs...) + get_vector( M::Segre{𝔽, V}, p, c, DefaultOrthonormalBasis; kwargs...) -Get tangent vector `v` from coordinates in the tangent space -``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` +Get tangent vector `X` from coordinates in the tangent space +``T_{(Ξ», x_1, …, x_d)} \mathcal{S} = \mathbb{R} Γ— T_{x_1} \mathbb{S}^{n_1 - 1} Γ—β‹―Γ— T_{x_d} \mathbb{S}^{n_d - 1}`` using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. """ -get_vector(M::Segre, p, X, ::DefaultOrthonormalBasis; kwargs...) +get_vector(M::Segre, p, c, ::DefaultOrthonormalBasis; kwargs...) -function get_vector_orthonormal!(M::Segre{ℝ,V}, v, p, X, ::RealNumbers; kwargs...) where {V} - X_ = deepcopy(X) - v[1] = [X_[1]] - X_ = X_[2:end] +function get_vector_orthonormal!(M::Segre{ℝ,V}, X, p, c, ::RealNumbers; kwargs...) where {V} + c_ = deepcopy(c) + X[1] = [c_[1]] + c_ = c_[2:end] for (i, n) in enumerate(V) - v[i + 1] = + X[i + 1] = get_vector( Sphere(n - 1), p[i + 1], - X_[1:(n - 1)], + c_[1:(n - 1)], DefaultOrthonormalBasis(); kwargs..., ) / p[1][1] - X_ = X_[n:end] + c_ = c_[n:end] end - return v + return X end @doc raw""" - inner(M::Segre{ℝ, V}, p, u, v,) + inner(M::Segre{ℝ, V}, p, X, Y,) -Inner product between two tangent vectors ``u = (Ξ½, u_1, …, u_d)`` and ``v = (ΞΎ, v_1, …, v_d)`` at ``p ≐ (Ξ», x_1, \dots, x_d)``. +Inner product between two tangent vectors ``X = (Ξ½, u_1, …, u_d)`` and ``Y = (ΞΎ, v_1, …, v_d)`` at ``p ≐ (Ξ», x_1, \dots, x_d)``. This inner product is obtained by embedding the Segre manifold in the space of tensors equipped with the Euclidean metric: ````math - \langle u, v \rangle_{p} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle_{x_1} + \dots + \langle u_d, v_d \rangle_{x_d}), + \langle X, Y \rangle_{p} = \nu \xi + \lambda^2 (\langle u_1, v_1 \rangle_{x_1} + \dots + \langle u_d, v_d \rangle_{x_d}), ```` -where ``Ξ½, ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} S^{n_i - 1} βŠ‚ ℝ^{n_i}``. +where ``Ξ½, ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} \mathbb{S}^{n_i - 1} βŠ‚ ℝ^{n_i}``. """ -function inner(::Segre{ℝ}, p, u, v) - return u[1][1] * v[1][1] + p[1][1]^2 * dot(u[2:end], v[2:end]) +function inner(::Segre{ℝ}, p, X, Y) + return X[1][1] * Y[1][1] + p[1][1]^2 * dot(X[2:end], Y[2:end]) end @doc raw""" @@ -368,34 +364,33 @@ Let m = \sqrt{\sphericalangle(x_1, y_1)^2 + … + \sphericalangle(x_d, y_d)^2} ```` -and assume ``(ΞΌ, y_1, …, y_d)`` is the representation of ``q`` that minimizes ``m``. Then +and assume ``(ΞΌ, y_1, …, y_d)`` is the representative of ``q`` that minimizes ``m``. Then ````math \operatorname{log}_p(q) = - c \left( - \frac{Ξ» m \mathopen{\Big(} \operatorname{cos}(m) - \frac{Ξ»}{ΞΌ} \mathclose{\Big)}}{\operatorname{sin}(m)}, - \frac{\sphericalangle(x_1, y_1) (y_1 - ⟨x_1, y_1⟩ x_1)}{\sin(\sphericalangle(x_1, y_1))}, + \left( + \mu \cos{m} - \lambda, + (y_1 - ⟨x_1, y_1⟩ x_1) \frac{\mu \sphericalangle(x_1, y_1) \sin{m}}{\lambda m \sin{\sphericalangle(x_1, y_1)}}, \dots, - \frac{\sphericalangle(x_d, y_d) (y_d - ⟨x_d, y_d⟩ x_d)}{\sin(\sphericalangle(x_d, y_d))} - \right), + (y_d - ⟨x_d, y_d⟩ x_d) \frac{\mu \sphericalangle(x_d, y_d) \sin{m}}{\lambda m \sin{\sphericalangle(x_d, y_d)}} + \right). ```` -where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \operatorname{dist}(p, q)``. -For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). +The formula is derived in theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ log(M::Segre{ℝ,V}, p, q) where {V} -function log!(M::Segre{ℝ,V}, v, p, q) where {V} +function log!(M::Segre{ℝ,V}, X, p, q) where {V} closest_representative!(M, q, p) m = spherical_angle_sum(M, p, q) - v[1][1] = q[1][1] * cos(m) - p[1][1] - for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + X[1][1] = q[1][1] * cos(m) - p[1][1] + for (n, xdot, x, y) in zip(V, X[2:end], p[2:end], q[2:end]) a = distance(Sphere(n - 1), x, y) xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(m / pi) / sinc(a / pi) end - return v + return X end manifold_dimension(::Segre{𝔽,V}) where {𝔽,V} = (1 + sum(V .- 1)) @@ -410,7 +405,7 @@ Then this is \sqrt{\sphericalangle(x_1, y_1)^2 + … + \sphericalangle(x_d, y_d)^2}, ```` -where ``\sphericalangle(x_i, y_i)`` is the distance between ``x_i`` and ``y_i`` on the sphere ``S^{n_i - 1}``. +where ``\sphericalangle(x_i, y_i)`` is the distance between ``x_i`` and ``y_i`` on the sphere ``\mathbb{S}^{n_i - 1}``. """ function spherical_angle_sum(::Segre{ℝ,V}, p, q) where {V} @@ -425,10 +420,10 @@ end If `vector_at` is `nothing`, return a random point on ````math - ℝ^{+} Γ— S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1} + ℝ^{+} Γ— \mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1} ```` -from a log-normal distribution on ``ℝ^{+}`` and a uniform distribution on ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}``. +from a log-normal distribution on ``ℝ^{+}`` and a uniform distribution on ``\mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1}``. If `vector_at` is not `nothing`, return a random tangent vector from a normal distribution on the tangent space. """ @@ -450,30 +445,30 @@ function rand(M::Segre{ℝ,V}; vector_at=nothing, kwargs...) where {V} end @doc raw""" - riemann_tensor(M::Segre{ℝ, V}, p, u, v, w) + riemann_tensor(M::Segre{ℝ, V}, p, X, Y, Z) Riemann tensor of the Segre manifold at ``p``. -``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}``. -If ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}`` and ``u``, ``v``, ``w ∈ T_p (S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}) βŠ‚ T_p \mathcal{S}``, then +``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``\mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1}``. +If ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}`` and ``X``, ``Y``, ``Z ∈ T_p (\mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1}) βŠ‚ T_p \mathcal{S}``, then ````math - R_{\mathcal{S}}(u, v) w = R_{S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}}(u, v) w + Ξ»^{-2}(⟨u,w⟩_p v - ⟨v,w⟩_p u). + R_{\mathcal{S}}(X, Y) Z = R_{\mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1}}(X, Y) Z + Ξ»^{-2}(⟨X, Z⟩_p Y - ⟨Y, Z⟩_p X). ```` ``R_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ -function riemann_tensor(M::Segre{ℝ,V}, p, u, v, w) where {V} +function riemann_tensor(M::Segre{ℝ,V}, p, X, Y, Z) where {V} return [ [0.0], [ riemann_tensor(Sphere(n - 1), x, xdot1, xdot2, xdot3) for - (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], u[2:end], v[2:end], w[2:end]) + (n, x, xdot1, xdot2, xdot3) in zip(V, p[2:end], X[2:end], Y[2:end], Z[2:end]) ]..., ] + (1 / p[1][1]^2) * ( - inner(M, p, [[0.0], u[2:end]...], [[0.0], w[2:end]...]) * [[0.0], v[2:end]...] - - inner(M, p, [[0.0], v[2:end]...], [[0.0], w[2:end]...]) * [[0.0], u[2:end]...] + inner(M, p, [[0.0], X[2:end]...], [[0.0], Z[2:end]...]) * [[0.0], Y[2:end]...] - + inner(M, p, [[0.0], Y[2:end]...], [[0.0], Z[2:end]...]) * [[0.0], X[2:end]...] ) end @@ -482,8 +477,8 @@ end Sectional curvature of the Segre manifold at ``p``. -``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}`` -If ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}``, ``u_i ∈ T_{x_i} S^{n_i - 1}``, and ``v_j ∈ T_{x_j} S^{n_j - 1}``, then +``\mathcal{S}`` is locally a warped product of ``ℝ^{+}`` and ``\mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1}`` +If ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}``, ``u_i ∈ T_{x_i} \mathbb{S}^{n_i - 1}``, and ``v_j ∈ T_{x_j} \mathbb{S}^{n_j - 1}``, then ````math K_{\mathcal{S}}(u_i, v_j) = \frac{\delta_{i j} - 1}{\lambda^2}. @@ -491,9 +486,9 @@ If ``p ≐ (Ξ», x_1, …, x_d) ∈ \mathcal{S}``, ``u_i ∈ T_{x_i} S^{n_i - 1}` ``K_{\mathcal{S}}`` is zero in the remaining (orthogonal) directions. """ -function sectional_curvature(M::Segre{ℝ,V}, p, u, v) where {V} - return inner(M, p, riemann_tensor(M, p, u, v, v), u) / - (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) +function sectional_curvature(M::Segre{ℝ,V}, p, X, Y) where {V} + return inner(M, p, riemann_tensor(M, p, X, Y, Y), X) / + (inner(M, p, X, X) * inner(M, p, Y, Y) - inner(M, p, X, Y)^2) end function Base.show(io::IO, ::Segre{𝔽,V}) where {𝔽,V} diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index c61a069f7b..1bd12c7896 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -7,12 +7,12 @@ We denote this manifold by ``\mathcal{S}_A``. Similarly to ``\mathcal{S}``, when ``𝔽 = ℝ``, ``\mathcal{S}_A`` is a normal Riemannian covering of the product manifold ````math - ℝ^{+} Γ— S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1} + ℝ^{+} Γ— \mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1} ```` with a [warped product metric](https://en.wikipedia.org/wiki/Warped_product), but the warping function now depends on the _warping factor_ ``A``. ``A = 1`` corresponds to the usual Segre manifold. -The Segre manifold is a cone in the sense that if ``p \in \mathcal{S}``, then ``a p \in \mathcal{S}`` for all ``r \neq 0``. The tangent subspace at ``p`` defined ``\mathrm{d} (r p) / \mathrm{d} r`` is called the _radial_ direction. ``A < 1`` puts less weight on the directions orthogonal to the radial direction compared to ``\mathcal{S}``, while ``A > 1`` puts more weight on those directions. +The Segre manifold is a cone in the sense that if ``p \in \mathcal{S}``, then ``r p \in \mathcal{S}`` for all ``r \neq 0``. The tangent subspace at ``p`` defined ``\mathrm{d} (r p) / \mathrm{d} r`` is called the _radial_ direction. ``A < 1`` puts less weight on the directions orthogonal to the radial direction compared to ``\mathcal{S}``, while ``A > 1`` puts more weight on those directions. The geometry is summarized in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). @@ -68,20 +68,20 @@ function distance(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) whe end @doc raw""" - exp(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, v) + exp(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, X) Exponential map on the warped Segre manifold. -Let ``p ≐ (Ξ», x_1,…, x_d) ∈ \mathcal{S}_A`` and ``v = (Ξ½, u_1,…, u_d) ∈ T_p \mathcal{S}_A``. +Let ``p ≐ (Ξ», x_1,…, x_d) ∈ \mathcal{S}_A`` and ``X = (Ξ½, u_1,…, u_d) ∈ T_p \mathcal{S}_A``. Then the exponential map is given by ````math - \operatorname{exp}_p(v) ≐ + \operatorname{exp}_p(X) ≐ \left( - \sqrt{t^2 + 2 Ξ» Ξ½ t + Ξ»^2},\\ - x_1 \cos\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{g \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)},\\ - …,\\ - x_d \cos\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{g \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} + \sqrt{(Ξ» + Ξ½)^2 + (Ξ» A m)^2},\\ + x_1 \cos\mathopen{\Big(} \frac{f \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)} + \frac{u_1}{\lVert u_1 \rVert_{x_1}} \sin\mathopen{\Big(} \frac{f \lVert u_1 \rVert_{x_1}}{A m} \mathclose{\Big)},\\ + …,\\ + x_d \cos\mathopen{\Big(} \frac{f \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} + \frac{u_d}{\lVert u_d \rVert_{x_d}} \sin\mathopen{\Big(} \frac{f \lVert u_d \rVert_{x_d}}{A m} \mathclose{\Big)} \right), ```` @@ -89,35 +89,33 @@ where ````math \begin{aligned} - g &= \tan^{-1}\mathopen{\Big(} t \frac{\sqrt{P^2 + 1}}{Ξ»} + P \mathclose{\Big)} - \tan^{-1}(P),\\ - m &= \sqrt{\lVert u_1 \rVert_{x_1}^2 +… + \lVert u_d \rVert_{x_d}^2} > 0,\\ - P &= \frac{Ξ½}{Ξ» A m},\\ - t &= \lVert v \rVert_{p}. + f &= \frac{\pi}{2} - \tan^{-1}\mathopen{\Big(} \frac{Ξ» + Ξ½}{Ξ» A m} \mathclose{\Big)},\\ + m &= \sqrt{\lVert u_1 \rVert_{x_1}^2 + … + \lVert u_d \rVert_{x_d}^2}. \end{aligned} ```` -If ``m = 0`` and ``Ξ½ t < Ξ»``, then ``\operatorname{exp}_p(v) = p + v``. +If ``m = 0`` and ``-Ξ» < Ξ½``, then ``\operatorname{exp}_p(v) = p + X``. -For a proof, see proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). +The formula is derived in proposition 3.1 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ -exp(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, v) where {V,A} +exp(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, X) where {V,A} -function exp!(::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, v) where {V,A} +function exp!(::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, q, p, X) where {V,A} m = sqrt( sum([ - norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + norm(Sphere(n - 1), x, xdot)^2 for (n, x, xdot) in zip(V, p[2:end], X[2:end]) ]), ) - q[1][1] = sqrt((p[1][1] + v[1][1])^2 + (p[1][1] * A * m)^2) + q[1][1] = sqrt((p[1][1] + X[1][1])^2 + (p[1][1] * A * m)^2) - f = pi / 2 - atan((p[1][1] + v[1][1]) / (p[1][1] * A * m)) + f = pi / 2 - atan((p[1][1] + X[1][1]) / (p[1][1] * A * m)) if m == 0 for (x, y) in zip(p[2:end], q[2:end]) y .= x end else - for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], v[2:end]) + for (n, x, y, xdot) in zip(V, p[2:end], q[2:end], X[2:end]) a = norm(Sphere(n - 1), x, xdot) y .= x * cos(a * f / (A * m)) .+ @@ -131,84 +129,84 @@ end @doc raw""" get_coordinates(M::Segre{𝔽, V}, p, v, ::DefaultOrthonormalBasis; kwargs...) -Get coordinates of `v` in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. +Get coordinates of `X` in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} \mathbb{S}^{n_1 - 1} Γ—β‹―Γ— T_{x_d} \mathbb{S}^{n_d - 1}`` using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. """ get_coordinates( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, - v, + X, ::DefaultOrthonormalBasis; kwargs..., ) where {𝔽,V,A} function get_coordinates_orthonormal!( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, - X, + c, p, - v, + X, ::RealNumbers; kwargs..., ) where {𝔽,V,A} - return X = vcat( - v[1], + return c = vcat( + X[1], A * p[1][1] * [ - get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], v[2:end]) + get_coordinates(Sphere(n - 1), x, xdot, DefaultOrthonormalBasis(); kwargs...) for (n, x, xdot) in zip(V, p[2:end], X[2:end]) ]..., ) end @doc raw""" - get_vector( M::Segre{𝔽, V}, p, X, ::DefaultOrthonormalBasis; kwargs...) + get_vector(M::Segre{𝔽, V}, p, c, ::DefaultOrthonormalBasis; kwargs...) -Get tangent vector `v` from coordinates in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} S^{n_1 - 1} Γ—β‹―Γ— T_{x_d} S^{n_d - 1}`` using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. +Get tangent vector `X` from coordinates in the tangent space ``T_{(Ξ», x_1,…, x_d)} \mathcal{S}_A = \mathbb{R} Γ— T_{x_1} \mathbb{S}^{n_1 - 1} Γ—β‹―Γ— T_{x_d} \mathbb{S}^{n_d - 1}`` using a [`DefaultOrthonormalBasis`](@extref `ManifoldsBase.DefaultOrthonormalBasis`) on each factor. """ get_vector( M::MetricManifold{𝔽,Segre{𝔽,V},WarpedMetric{A}}, p, - X, + c, ::DefaultOrthonormalBasis; kwargs..., ) where {V,A,𝔽} function get_vector_orthonormal!( M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, - v, - p, X, + p, + c, ::RealNumbers; kwargs..., ) where {V,A} - X_ = deepcopy(X) - v[1] = [X_[1]] - X_ = X_[2:end] + c_ = deepcopy(c) + X[1] = [c_[1]] + c_ = c_[2:end] for (i, n) in enumerate(V) - v[i + 1] = + X[i + 1] = get_vector( Sphere(n - 1), p[i + 1], - X_[1:(n - 1)], + c_[1:(n - 1)], DefaultOrthonormalBasis(); kwargs..., ) / (A * p[1][1]) - X_ = X_[n:end] + c_ = c_[n:end] end - return v + return X end @doc raw""" - inner(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, u, v) + inner(M::MetricManifold{ℝ, Segre{ℝ, V}, WarpedMetric{A}}, p, X, Y) -Inner product between two tangent vectors ``u = (Ξ½, u_1,…, u_d)`` and ``v = (ΞΎ, v_1,…, v_d)`` at ``p = (Ξ», x_1,…, x_d``: +Inner product between two tangent vectors ``X = (Ξ½, u_1,…, u_d)`` and ``Y = (ΞΎ, v_1,…, v_d)`` at ``p \doteq (Ξ», x_1,…, x_d)``: ````math - ⟨u, v⟩_{p} = Ξ½ ΞΎ + (A Ξ»)^2 (⟨ u_1, v_1 ⟩_{x_1} +… + ⟨u_d, v_d⟩_{x_d}), + ⟨X, Y⟩_{p} = Ξ½ ΞΎ + (A Ξ»)^2 (⟨ u_1, v_1 ⟩_{x_1} +… + ⟨u_d, v_d⟩_{x_d}), ```` -where ``Ξ½``, ``ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} S^{n_i - 1} \subset ℝ^{n_i}``. +where ``Ξ½``, ``ΞΎ ∈ T_{Ξ»} ℝ^{+} = ℝ`` and ``u_i``, ``v_i ∈ T_{x_i} \mathbb{S}^{n_i - 1} \subset ℝ^{n_i}``. """ -function inner(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, u, v) where {V,A} - return u[1][1] * v[1][1] + (A * p[1][1])^2 * dot(u[2:end], v[2:end]) +function inner(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, X, Y) where {V,A} + return X[1][1] * Y[1][1] + (A * p[1][1])^2 * dot(X[2:end], Y[2:end]) end @doc raw""" @@ -224,45 +222,43 @@ Let m = \sqrt{\sphericalangle(x_1, y_1)^2 +… + \sphericalangle(x_d, y_d)^2} ```` -and assume ``(ΞΌ, y_1,…, y_d)`` is the representation of ``q`` that minimizes ``m``. Then +and assume ``(ΞΌ, y_1,…, y_d)`` is the representative of ``q`` that minimizes ``m``. Then ````math \operatorname{log}_p(q) = - c \left( - \frac{Ξ» A m \mathopen{\Big(} \cos(A m) - \frac{Ξ»}{ΞΌ} \mathclose{\Big)}}{\sin(A m)}, - \frac{\sphericalangle(x_1, y_1) (y_1 - ⟨ x_1, y_1 ⟩ x_1)}{\sin(\sphericalangle(x_1, y_1))}, - …, - \frac{\sphericalangle(x_d, y_d) (y_d - ⟨ x_d, y_d ⟩ x_d)}{\sin(\sphericalangle(x_d, y_d))} - \right), + \left( + \mu \cos{m} - \lambda, + (y_1 - ⟨x_1, y_1⟩ x_1) \frac{\mu \sphericalangle(x_1, y_1) \sin{A m}}{\lambda A m \sin{\sphericalangle(x_1, y_1)}}, + \dots, + (y_d - ⟨x_d, y_d⟩ x_d) \frac{\mu \sphericalangle(x_d, y_d) \sin{A m}}{\lambda A m \sin{\sphericalangle(x_d, y_d)}} + \right). ```` -where ``c`` is determined by ``\lVert \operatorname{log}_p(q) \rVert_{p} = \operatorname{dist}(p, q)``. - -For a proof, see theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). +The formula is derived in theorem 4.4 in [JacobssonSwijsenVandervekenVannieuwenhoven:2024](@cite). """ log(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, q) where {V,A} -function log!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, v, p, q) where {V,A} +function log!(M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, X, p, q) where {V,A} closest_representative!(M, q, p) m = spherical_angle_sum(M, p, q) - v[1][1] = q[1][1] * cos(A * m) - p[1][1] - for (n, xdot, x, y) in zip(V, v[2:end], p[2:end], q[2:end]) + X[1][1] = q[1][1] * cos(A * m) - p[1][1] + for (n, xdot, x, y) in zip(V, X[2:end], p[2:end], q[2:end]) a = distance(Sphere(n - 1), x, y) xdot .= (y - dot(x, y) * x) * (q[1][1] / p[1][1]) * sinc(A * m / pi) / sinc(a / pi) end - return v + return X end @doc raw""" - riemann_tensor(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, u, v) + riemann_tensor(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, X, Y) Riemann tensor of the warped Segre manifold at ``p``. -``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}``. If ``p ≐ (Ξ», x_1,…, x_d) ∈ \mathcal{S}_A`` and ``u``, ``v``, ``w ∈ T_{(x_1,…, x_d)} (S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}) \subset T_p \mathcal{S}_A`` then +``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``\mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1}``. If ``p ≐ (Ξ», x_1,…, x_d) ∈ \mathcal{S}_A`` and ``X``, ``Y``, ``Z ∈ T_{(x_1,…, x_d)} (\mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1}) \subset T_p \mathcal{S}_A`` then ````math - R_{\mathcal{S}_A}(u, v) w = R_{S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}}(u, v) w + Ξ»^{-2}(⟨ u, w ⟩_{p} v - ⟨ v, w ⟩_{p} u). + R_{\mathcal{S}_A}(X, Y) Z = R_{\mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1}}(X, Y) Z + Ξ»^{-2}(⟨ X, Z ⟩_{p} Y - ⟨ Y, Z ⟩_{p} X). ```` ``R_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ @@ -287,25 +283,25 @@ function riemann_tensor( end @doc raw""" - sectional_curvature(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, u, v) + sectional_curvature(M::MetricManifold{ℝ, Segre{ℝ,V}, WarpedMetric{A}}, p, X, Y) Sectional curvature of the warped Segre manifold at ``p``. -``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``S^{n_1 - 1} Γ—β‹―Γ— S^{n_d - 1}`` -If ``p = (Ξ», x_1,…, x_d) ∈ \mathcal{S}``, ``u_i ∈ T_{x_i} S^{n_i - 1}``, and ``v_j ∈ T_{x_j} S^{n_j - 1}``, then +``\mathcal{S}_A`` is locally a warped product of ``ℝ^{+}`` and ``\mathbb{S}^{n_1 - 1} Γ—β‹―Γ— \mathbb{S}^{n_d - 1}`` +If ``p = (Ξ», x_1,…, x_d) ∈ \mathcal{S}``, ``u_i ∈ T_{x_i} \mathbb{S}^{n_i - 1}``, and ``v_j ∈ T_{x_j} \mathbb{S}^{n_j - 1}``, then ````math - K_{\mathcal{S}_A}(u_i, v_j) = -(1 - \delta_{i j}) Ξ»^2. + K_{\mathcal{S}_A}(u_i, v_j) = \frac{A^{-2} \delta_{i j} - 1}{Ξ»^{2}}. ```` ``K_{\mathcal{S}_A}`` is zero in the remaining (orthogonal) directions. """ function sectional_curvature( M::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}, p, - u, - v, + X, + Y, ) where {V,A} - return inner(M, p, riemann_tensor(M, p, u, v, v), u) / - (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2) + return inner(M, p, riemann_tensor(M, p, X, Y, Y), X) / + (inner(M, p, X, X) * inner(M, p, Y, Y) - inner(M, p, X, Y)^2) end function show(io::IO, ::WarpedMetric{A}) where {A} diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index 3f23dfdcd2..738b85917d 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -19,6 +19,7 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences # n β‰₯ k, for same n,k X is in TpM and can be scaled by l unit_p(n, k) = 1 / sqrt(k) .* [ones(k)..., zeros(n - k)...] unit_X(n, k; l=1.0) = l / sqrt(n - k) .* [zeros(k)..., ones(n - k)...] + unit_c(n, k) = normalize([mod(k * i^i, 31) - 30 / 2 for i in 1:n]) # pseudo-rng # ps[i] is a point on Ms[i] ps = [ @@ -45,8 +46,8 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences [[0.8], unit_p(9, 2), unit_p(3, 2), unit_p(8, 3), unit_p(10, 3)], ] - # us[i] is a tangent vector to Ms[i] at ps[i] - us = [ + # Xs[i] is a tangent vector to Ms[i] at ps[i] + Xs = [ [[0.5], unit_X(10, 4)], [[0.6], unit_X(7, 3), unit_X(2, 1)], [[0.7], unit_X(7, 3), unit_X(9, 5), unit_X(9, 4)], @@ -57,8 +58,8 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences [[1.2], unit_X(9, 3), unit_X(3, 1), unit_X(8, 4), unit_X(10, 4)], ] - # vs[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representative to ps[i] for t in [-1, 1] - vs = [ + # Ys[i] is a tangent vector to Ms[i] at ps[i] such that exp(Ms[i], ps[i], t * vs[i]) is the closes representative to ps[i] for t in [-1, 1] + Ys = [ [[0.5], unit_X(10, 5)], [[0.6], unit_X(7, 4), unit_X(2, 1)], [[0.7], unit_X(7, 4), unit_X(9, 6), unit_X(9, 5)], @@ -69,568 +70,43 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences [[1.2], unit_X(9, 4), unit_X(3, 1), unit_X(8, 5), unit_X(10, 5)], ] - # When testing that exp(Ms[i], ps[i], t * vs[i]) is an extremum of the length functional, we parametrize curves in Ms[i] and take a derivative along dys[i] - dys = [ - [ - 0.24768051036976024, - 0.15340874919881428, - 0.10461792180729243, - 0.1621738878738882, - 0.13788895788409475, - 0.13920478959340893, - 0.1980520199776914, - 0.225220769065586, - 0.09192923424127934, - 0.15861132814448145, - 0.07788788182581427, - 0.2033127058413462, - 0.11406283238286104, - 0.020870012361419343, - 0.2719578430552649, - 0.15170700765742606, - 0.07022129511933332, - 0.04843952826362164, - 0.2555544578976192, - 0.06681340738035137, - 0.15586613310716685, - 0.018646851863471762, - 0.1979297092698637, - 0.23753411269988997, - 0.21343310337377225, - 0.08016910818336964, - 0.1464783972931314, - 0.025950651929534232, - 0.1449831966165307, - 0.23373068876892722, - 0.11880598168141776, - 0.19121899600576953, - 0.15179084381364852, - 0.04935589775227154, - 0.1560593153225572, - 0.04411343229804097, - 0.2392666728301238, - 0.1484349911958273, - 0.17060958026859915, - 0.01433037040599356, - ], - [ - 0.2703013619564934, - 0.1674196883015804, - 0.11417275710290055, - 0.17698535383607492, - 0.15048246250457872, - 0.15191847013635482, - 0.2161402633508973, - 0.2457903551976426, - 0.10032520193833194, - 0.1730974227854145, - 0.08500144200281991, - 0.22188141170224845, - 0.12448027862860386, - 0.022776086648557087, - 0.29679596211605436, - 0.16556252539583352, - 0.07663466003347703, - 0.05286354765112583, - 0.278894443170582, - 0.07291552728513738, - 0.17010150697308607, - 0.020349883191748984, - 0.21600678191201325, - 0.2592282859804155, - 0.23292611292832396, - 0.08749101451887183, - 0.15985638202387917, - 0.02832074493766232, - 0.1582246235190211, - 0.255077492415341, - 0.12965662340215453, - 0.20868317404203518, - ], - [ - 0.16353440643700792, - 0.10129020125571776, - 0.06907539765598648, - 0.10707750259980159, - 0.0910430491609086, - 0.09191184484141025, - 0.13076652451317197, - 0.14870505851042468, - 0.06069752009721213, - 0.1047252743607885, - 0.05142652727905344, - 0.13423996349664308, - 0.07531152759015192, - 0.013779707893699597, - 0.17956384365300332, - 0.10016660338980309, - 0.04636455972831437, - 0.03198285359980099, - 0.16873328677427074, - 0.0441144557626597, - 0.10291272221322205, - 0.012311836110395775, - 0.1306857672142806, - 0.1568351101623881, - 0.14092209282890691, - 0.05293273783140711, - 0.09671434268855209, - 0.017134268875714943, - 0.09572711622173373, - 0.1543238480770115, - 0.07844325605769907, - 0.12625492803046978, - 0.10022195734569302, - 0.03258789894704945, - 0.10304027338340047, - 0.029126490235301297, - 0.15797905641835802, - 0.09800621027247283, - 0.11264728258206483, - 0.009461820854890907, - 0.07619899497188476, - 0.06435512726649247, - 0.14418724370624061, - 0.020482591380646117, - 0.18622326856315144, - 0.17680302406232687, - 0.11411324587011096, - 0.04559115895133764, - 0.024318253167761508, - 0.0777066933426362, - 0.16696701026147626, - 0.06641466684484068, - 0.06421006278332052, - 0.1069248857665583, - 0.12159103864374035, - 0.05073753945931583, - 0.04924168633871106, - 0.12722583436268306, - 0.18563179386637813, - 0.0687128870870491, - 0.08905886988994213, - 0.009035432164352614, - 0.049561446318667116, - 0.1347085017272271, - 0.1200359392924501, - 0.027268283817115106, - 0.04224558795450571, - 0.04315262171954351, - 0.05403346926811662, - 0.0023262859537098515, - 0.010721414504714139, - 0.13403654903491943, - 0.10987330337776338, - 0.013298908898025385, - 0.14340914694684173, - 0.17825169707180502, - 0.10868078009526573, - 0.0016445884181541684, - 0.07063958523304881, - 0.1101738445443299, - 0.11758054831650003, - 0.060827727766064016, - 0.14865227744166581, - 0.11702503201869387, - 0.09342064187053477, - 0.15738531812684184, - 0.03201521439082036, - 0.06114448967602477, - 0.10382777552410098, - 0.1431354723068435, - 0.18877393058117947, - 0.04238816261102419, - ], - [ - 0.1715795373556408, - 0.1062732072642473, - 0.07247358541051933, - 0.11234521687243985, - 0.0955219430260548, - 0.09643347940647069, - 0.13719962830095694, - 0.15602065459839623, - 0.0636835553069129, - 0.10987726996268543, - 0.053956472834027505, - 0.14084394430027286, - 0.07901650388441198, - 0.014457605324831525, - 0.1883975482043314, - 0.10509433361797467, - 0.04864548006260954, - 0.03355626099441541, - 0.17703417838482685, - 0.046284681464683716, - 0.10797554869382073, - 0.0129175210883459, - 0.1371148981191942, - 0.164550666915154, - 0.14785480326481754, - 0.05553678192838664, - 0.1014722377736982, - 0.01797719507885178, - 0.10043644436402703, - 0.1619158624347057, - 0.08230229880238973, - 0.1324660822900412, - 0.10515241073061003, - 0.03419107175394852, - 0.10810937478733341, - 0.030559377859677404, - 0.16575088999747303, - 0.10282765922416374, - 0.11818900408120409, - 0.009927298359990544, - 0.07994763052677145, - 0.06752109970877263, - 0.15128058435355177, - 0.021490239451779292, - 0.19538458579496817, - 0.1855009091519671, - 0.1197270859333567, - 0.047834031570543896, - 0.02551459792914639, - 0.08152950063326206, - 0.17518100929637484, - 0.06968195903934253, - 0.06736889872885857, - 0.11218509200201603, - 0.1275727512737259, - 0.053233590023432004, - 0.05166414789821036, - 0.13348475269051732, - 0.19476401329869034, - 0.07209324101046329, - 0.09344015137889938, - 0.009479933332347762, - 0.051999638579474684, - 0.14133553242896432, - 0.12594114827928685, - 0.028609756342773685, - 0.04432387406709532, - 0.04527552966766203, - 0.056691664223667886, - 0.002440728384874828, - 0.011248858149159562, - 0.14063052279470464, - 0.11527855802353276, - 0.013953153258528188, - 0.15046420885860654, - 0.18702085012439856, - 0.11402736815129268, - 0.0017254945064788542, - 0.07411472372909801, - 0.11559388441532585, - 0.10893561836452229, - 0.15017707070132247, - 0.198060728501197, - 0.04447346273248423, - ], - [ - 0.24768051036976024, - 0.15340874919881428, - 0.10461792180729243, - 0.1621738878738882, - 0.13788895788409475, - 0.13920478959340893, - 0.1980520199776914, - 0.225220769065586, - 0.09192923424127934, - 0.15861132814448145, - 0.07788788182581427, - 0.2033127058413462, - 0.11406283238286104, - 0.020870012361419343, - 0.2719578430552649, - 0.15170700765742606, - 0.07022129511933332, - 0.04843952826362164, - 0.2555544578976192, - 0.06681340738035137, - 0.15586613310716685, - 0.018646851863471762, - 0.1979297092698637, - 0.23753411269988997, - 0.21343310337377225, - 0.08016910818336964, - 0.1464783972931314, - 0.025950651929534232, - 0.1449831966165307, - 0.23373068876892722, - 0.11880598168141776, - 0.19121899600576953, - 0.15179084381364852, - 0.04935589775227154, - 0.1560593153225572, - 0.04411343229804097, - 0.2392666728301238, - 0.1484349911958273, - 0.17060958026859915, - 0.01433037040599356, - ], - [ - 0.24768051036976024, - 0.15340874919881428, - 0.10461792180729243, - 0.1621738878738882, - 0.13788895788409475, - 0.13920478959340893, - 0.1980520199776914, - 0.225220769065586, - 0.09192923424127934, - 0.15861132814448145, - 0.07788788182581427, - 0.2033127058413462, - 0.11406283238286104, - 0.020870012361419343, - 0.2719578430552649, - 0.15170700765742606, - 0.07022129511933332, - 0.04843952826362164, - 0.2555544578976192, - 0.06681340738035137, - 0.15586613310716685, - 0.018646851863471762, - 0.1979297092698637, - 0.23753411269988997, - 0.21343310337377225, - 0.08016910818336964, - 0.1464783972931314, - 0.025950651929534232, - 0.1449831966165307, - 0.23373068876892722, - 0.11880598168141776, - 0.19121899600576953, - 0.15179084381364852, - 0.04935589775227154, - 0.1560593153225572, - 0.04411343229804097, - 0.2392666728301238, - 0.1484349911958273, - 0.17060958026859915, - 0.01433037040599356, - ], - [ - 0.16353440643700792, - 0.10129020125571776, - 0.06907539765598648, - 0.10707750259980159, - 0.0910430491609086, - 0.09191184484141025, - 0.13076652451317197, - 0.14870505851042468, - 0.06069752009721213, - 0.1047252743607885, - 0.05142652727905344, - 0.13423996349664308, - 0.07531152759015192, - 0.013779707893699597, - 0.17956384365300332, - 0.10016660338980309, - 0.04636455972831437, - 0.03198285359980099, - 0.16873328677427074, - 0.0441144557626597, - 0.10291272221322205, - 0.012311836110395775, - 0.1306857672142806, - 0.1568351101623881, - 0.14092209282890691, - 0.05293273783140711, - 0.09671434268855209, - 0.017134268875714943, - 0.09572711622173373, - 0.1543238480770115, - 0.07844325605769907, - 0.12625492803046978, - 0.10022195734569302, - 0.03258789894704945, - 0.10304027338340047, - 0.029126490235301297, - 0.15797905641835802, - 0.09800621027247283, - 0.11264728258206483, - 0.009461820854890907, - 0.07619899497188476, - 0.06435512726649247, - 0.14418724370624061, - 0.020482591380646117, - 0.18622326856315144, - 0.17680302406232687, - 0.11411324587011096, - 0.04559115895133764, - 0.024318253167761508, - 0.0777066933426362, - 0.16696701026147626, - 0.06641466684484068, - 0.06421006278332052, - 0.1069248857665583, - 0.12159103864374035, - 0.05073753945931583, - 0.04924168633871106, - 0.12722583436268306, - 0.18563179386637813, - 0.0687128870870491, - 0.08905886988994213, - 0.009035432164352614, - 0.049561446318667116, - 0.1347085017272271, - 0.1200359392924501, - 0.027268283817115106, - 0.04224558795450571, - 0.04315262171954351, - 0.05403346926811662, - 0.0023262859537098515, - 0.010721414504714139, - 0.13403654903491943, - 0.10987330337776338, - 0.013298908898025385, - 0.14340914694684173, - 0.17825169707180502, - 0.10868078009526573, - 0.0016445884181541684, - 0.07063958523304881, - 0.1101738445443299, - 0.11758054831650003, - 0.060827727766064016, - 0.14865227744166581, - 0.11702503201869387, - 0.09342064187053477, - 0.15738531812684184, - 0.03201521439082036, - 0.06114448967602477, - 0.10382777552410098, - 0.1431354723068435, - 0.18877393058117947, - 0.04238816261102419, - ], - [ - 0.1490765359911958, - 0.09233526241995971, - 0.06296852894216698, - 0.0976109157574458, - 0.08299404810701023, - 0.08378603465806785, - 0.11920562114578914, - 0.13555823199591513, - 0.0553313289630816, - 0.09546664504785775, - 0.04687997291732666, - 0.12237197777320692, - 0.06865333050063585, - 0.012561461312757724, - 0.16368883089666822, - 0.09131100042306806, - 0.042265527528094815, - 0.029155289884568912, - 0.153815789880318, - 0.040214352413767675, - 0.09381433834769744, - 0.011223362220940966, - 0.11913200349775391, - 0.1429695160437834, - 0.12846334848596738, - 0.04825302129601608, - 0.08816394973267236, - 0.015619449792770343, - 0.08726400271162271, - 0.1406802714694426, - 0.07150818680750592, - 0.11509288921319505, - 0.0913614606055903, - 0.029706843936407743, - 0.0939306128799265, - 0.026551453999575543, - 0.14401232745525105, - 0.08934160493420577, - 0.10268827852213556, - 0.008625313216639324, - 0.06946233801138785, - 0.05866557169947423, - 0.13143983149579208, - 0.018671751331583056, - 0.16975950445661273, - 0.161172091881058, - 0.1040246378463513, - 0.04156050213755719, - 0.022168307101803907, - 0.07083674267232855, - 0.15220566764447255, - 0.06054302998342982, - 0.058533332184146566, - 0.09747179158578337, - 0.11084132839998145, - 0.046251897641031985, - 0.044888291006624594, - 0.11597795894213936, - 0.1692203212911706, - 0.06263806747503713, - 0.08118528762078707, - 0.008236621012006807, - 0.04517978141038145, - 0.12279909313025451, - 0.10942371341935776, - 0.0248575292652322, - 0.038510708849485854, - 0.0393375529042932, - 0.049256438455844605, - 0.002120621948981863, - 0.00977354778184982, - 0.12218654692727692, - 0.10015954331772974, - 0.012123169149384955, - 0.13073052528871054, - 0.16249268953840867, - 0.09907244951333158, - 0.0014991924320470194, - 0.06439442866999417, - 0.10043351401912919, - 0.1071854004601844, - 0.055450025136289674, - 0.13551011723482043, - 0.10667899665704653, - 0.08516144084638168, - 0.14347108081661994, - 0.029184789698902848, - 0.0557387825256351, - 0.026753030352160315, - 0.057506912662784994, - 0.16716809419341475, - 0.11576080110723733, - 0.01392399094397694, - 0.0701719259281324, - 0.06969711242341488, - 0.1702065083755876, - 0.13916687524684004, - 0.05350498510320062, - 0.1415754204215561, - 0.06957602019036072, - 0.15092969351716987, - 0.028763669977259567, - 0.09378263985254962, - 0.07190282975849477, - 0.09464849295042106, - 0.13048104587817877, - 0.1720846656652933, - 0.03864067866059161, - ], + # cs[i] is coordinates for a tangent vector at ps[i] + cs = [ + unit_c(10, 1), + unit_c(8, 2), + unit_c(23, 3), + unit_c(21, 4), + unit_c(10, 5), + unit_c(10, 6), + unit_c(23, 7), + unit_c(27, 8), ] - # Xs[i] is coordinates for a tangent vector at ps[i] - Xs = [ - [-0.5, -0.4, 0.0, 0.2, -0.5, 0.5, -0.3, 0.9, -0.8, 0.6], - [0.2, -0.3, 0.2, 0.7, 0.5, 0.0, 0.1, 0.0], - [-0.3, -0.2, -0.5, 0.6, 0.1, 0.3, 0.0, zeros(16)...], - [-0.3, 0.9, 0.3, 0.9, 0.1, zeros(16)...], - [-0.3, 0.5, 0.9, 0.3, -0.3, -0.3, 0.4, -0.8, -0.3, 0.5], - [0.3, -0.4, 0.3, 0.8, -0.5, -0.5, -0.4, 0.2, -0.7, -0.8], - [0.5, 0.9, -0.8, 0.3, -0.7, 0.1, -0.1, zeros(16)...], - [-0.6, 0.0, -0.1, 0.1, -0.7, -0.1, 0.2, -0.0, 0.8, -0.5, 0.9, zeros(16)...], + # When testing that exp(Ms[i], ps[i], t * Xs[i]) is an extremum of the length functional, we take a directional derivative along dcs[i] + dcs = [ + unit_c(3 * 10, 9), + unit_c(3 * 8, 10), + unit_c(3 * 23, 11), + unit_c(3 * 21, 12), + unit_c(3 * 10, 13), + unit_c(3 * 10, 14), + unit_c(3 * 23, 15), + unit_c(3 * 27, 16), ] - for (M, V, p, q, v, u, dy, X) in zip(Ms, Vs, ps, qs, vs, us, dys, Xs) + for (M, V, p, q, X, Y, c, dc) in zip(Ms, Vs, ps, qs, Xs, Ys, cs, dcs) @testset "Manifold $M" begin + @testset "Segre" begin + get_manifold(::Segre{ℝ,V}) where {V} = Segre{ℝ,V}() + get_manifold(::MetricManifold{ℝ,Segre{ℝ,V},WarpedMetric{A}}) where {V,A} = + Segre{ℝ,V}() + @test Segre(V...) == get_manifold(M) + end + + @testset "manifold_dimension" begin + @test manifold_dimension(M) == 1 + sum(V .- 1) + end + @testset "is_point" begin @test is_point(M, p) @test is_point(M, q) @@ -644,19 +120,19 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences end @testset "is_vector" begin - @test is_vector(M, p, v; error=:error) - @test is_vector(M, p, u; error=:error) + @test is_vector(M, p, X; error=:error) + @test is_vector(M, p, Y; error=:error) @test_throws DomainError is_vector( M, [[1.0, 0.0], p[2:end]...], - v, + X, false, true, ) @test_throws DomainError is_vector( M, p, - [[1.0, 0.0], v[2:end]...], + [[1.0, 0.0], X[2:end]...], false, true, ) @@ -683,53 +159,55 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences @test isapprox(p_, (-1)^length(V) * p__) # vectors - v_ = zeros(prod(V)) - embed!(M, v_, p, v) - @test is_vector(get_embedding(M), p_, v_) + X_ = zeros(prod(V)) + embed!(M, X_, p, X) + @test is_vector(get_embedding(M), p_, X_) end @testset "get_coordinates" begin - @test isapprox(v, get_vector(M, p, get_coordinates(M, p, v))) - @test isapprox(X, get_coordinates(M, p, get_vector(M, p, X))) + @test isapprox(X, get_vector(M, p, get_coordinates(M, p, X))) + @test isapprox(c, get_coordinates(M, p, get_vector(M, p, c))) + + # Coordinates are ON @test isapprox( - dot(X, get_coordinates(M, p, v)), - inner(M, p, v, get_vector(M, p, X)), + dot(c, get_coordinates(M, p, X)), + inner(M, p, X, get_vector(M, p, c)), ) end @testset "exp" begin # Zero vector - p_ = exp(M, p, zeros.(size.(v))) + p_ = exp(M, p, zeros.(size.(X))) @test is_point(M, p_) @test isapprox(p, p_; atol=1e-5) # Tangent vector in the scaling direction - p_ = exp(M, p, [v[1], zeros.(size.(v[2:end]))...]) + p_ = exp(M, p, [X[1], zeros.(size.(X[2:end]))...]) @test is_point(M, p_) - @test isapprox([p[1] + v[1], p[2:end]...], p_; atol=1e-5) + @test isapprox([p[1] + X[1], p[2:end]...], p_; atol=1e-5) # Generic tangent vector - p_ = exp(M, p, v) + p_ = exp(M, p, X) @test is_point(M, p) geodesic_speed = - central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -1.0) - @test isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5) + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * X)), -1.0) + @test isapprox(geodesic_speed, -norm(M, p, X); atol=1e-5) geodesic_speed = - central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.811) - @test isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5) + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * X)), -0.811) + @test isapprox(geodesic_speed, -norm(M, p, X); atol=1e-5) geodesic_speed = - central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), -0.479) - @test isapprox(geodesic_speed, -norm(M, p, v); atol=1e-5) + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * X)), -0.479) + @test isapprox(geodesic_speed, -norm(M, p, X); atol=1e-5) geodesic_speed = - central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.181) - @test isapprox(geodesic_speed, norm(M, p, v); atol=1e-5) + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * X)), 0.181) + @test isapprox(geodesic_speed, norm(M, p, X); atol=1e-5) geodesic_speed = - central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 0.703) - @test isapprox(geodesic_speed, norm(M, p, v); atol=1e-5) + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * X)), 0.703) + @test isapprox(geodesic_speed, norm(M, p, X); atol=1e-5) geodesic_speed = - central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * v)), 1.0) - @test isapprox(geodesic_speed, norm(M, p, v); atol=1e-5) + central_fdm(3, 1)(t -> distance(M, p, exp(M, p, t * X)), 1.0) + @test isapprox(geodesic_speed, norm(M, p, X); atol=1e-5) # Geodesics are (locally) length-minizing. So let B_a be a one-parameter # family of curves such that B_0 is a geodesic. Then the derivative of @@ -737,32 +215,28 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences # nonnegative. n = manifold_dimension(M) - x = get_coordinates(M, p, v) - x0 = 0.0 * x - x1 = 0.2 * x - x2 = 0.4 * x - x3 = 0.6 * x - x4 = 0.8 * x - x5 = 1.0 * x + c0 = 0.0 * c + c1 = 0.25 * c + c2 = 0.5 * c + c3 = 0.75 * c + c4 = 1.0 * c - function curve_length(y::Vector{Float64}) - @assert(length(y) == 4 * n) + function curve_length(d::Vector{Float64}) + @assert(length(d) == 3 * n) # Control points - y1 = y[1:n] - y2 = y[(n + 1):(2 * n)] - y3 = y[(2 * n + 1):(3 * n)] - y4 = y[(3 * n + 1):(4 * n)] + d1 = d[1:n] + d2 = d[(n + 1):(2 * n)] + d3 = d[(2 * n + 1):(3 * n)] # Bezier curve from 0 to v with control points y1, ..., y4 function b(t) return ( - (1 - t)^5 * x0 + - 5 * t * (1 - t)^4 * (x1 + y1) + - 10 * t^2 * (1 - t)^3 * (x2 + y2) + - 10 * t^3 * (1 - t)^2 * (x3 + y3) + - 5 * t^4 * (1 - t) * (x4 + y4) + - t^5 * x5 + (1 - t)^4 * c0 + + 4 * t * (1 - t)^3 * (c1 + d1) + + 6 * t^2 * (1 - t)^2 * (c2 + d2) + + 4 * t^3 * (1 - t) * (c3 + d3) + + t^4 * c4 ) end @@ -775,26 +249,25 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences return sum(ds) end - # dy = rand(4 * n); dy = dy / norm(dy) - f = a -> curve_length(a * dy) + f = a -> curve_length(a * dc) @test isapprox(central_fdm(3, 1)(f, 0.0), 0.0; atol=1e-5) @test central_fdm(3, 2)(f, 0.0) >= 0.0 end @testset "log" begin # Same point - v_ = log(M, p, p) - @test is_vector(M, p, v_) - @test isapprox(zeros.(size.(v)), v_; atol=1e-5) + X_ = log(M, p, p) + @test is_vector(M, p, X_) + @test isapprox(zeros.(size.(X)), X_; atol=1e-5) # Scaled point - v_ = log(M, p, [q[1], p[2:end]...]) - @test is_vector(M, p, v_) - @test isapprox(v_, [q[1] - p[1], zeros.(size.(q[2:end]))...]; atol=1e-5) + X_ = log(M, p, [q[1], p[2:end]...]) + @test is_vector(M, p, X_) + @test isapprox(X_, [q[1] - p[1], zeros.(size.(q[2:end]))...]; atol=1e-5) # Generic tangent vector - v_ = log(M, p, q) - @test is_vector(M, p, v_) + X_ = log(M, p, q) + @test is_vector(M, p, X_) end @testset "norm" begin @@ -806,27 +279,27 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences # and 2 pi r for small circles. # Orthonormalize - u_ = u / norm(M, p, u) - v_ = v - inner(M, p, u_, v) * u_ - v_ = v_ / norm(M, p, v_) + X_ = X / norm(M, p, X) + Y_ = Y - inner(M, p, X_, Y) * X_ + Y_ = Y_ / norm(M, p, Y_) r = 1e-2 ps_ = [ - exp(M, p, r * (cos(theta) * u_ + sin(theta) * v_)) for + exp(M, p, r * (cos(theta) * X_ + sin(theta) * Y_)) for theta in 0.0:1e-3:(2 * pi) ] ds = [distance(M, p1, p2) for (p1, p2) in zip(ps_, [ps_[2:end]..., ps_[1]])] C = sum(ds) K = 3 * (2 * pi * r - C) / (pi * r^3) # https://en.wikipedia.org/wiki/Bertrand%E2%80%93Diguet%E2%80%93Puiseux_theorem - @test isapprox(K, sectional_curvature(M, p, u, v); rtol=1e-2, atol=1e-2) + @test isapprox(K, sectional_curvature(M, p, X, Y); rtol=1e-2, atol=1e-2) end @testset "riemann_tensor" begin @test isapprox( - sectional_curvature(M, p, u, v), - inner(M, p, riemann_tensor(M, p, u, v, v), u) / - (inner(M, p, u, u) * inner(M, p, v, v) - inner(M, p, u, v)^2), + sectional_curvature(M, p, X, Y), + inner(M, p, riemann_tensor(M, p, X, Y, Y), X) / + (inner(M, p, X, X) * inner(M, p, Y, Y) - inner(M, p, X, Y)^2), ) end end From 6d0db087698aeb01da38251a99511f1a23a82028 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Fri, 20 Dec 2024 15:47:23 +0100 Subject: [PATCH 33/35] formatting --- test/manifolds/segre.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index 738b85917d..368abb1dce 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -85,7 +85,7 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences # When testing that exp(Ms[i], ps[i], t * Xs[i]) is an extremum of the length functional, we take a directional derivative along dcs[i] dcs = [ unit_c(3 * 10, 9), - unit_c(3 * 8, 10), + unit_c(3 * 8, 10), unit_c(3 * 23, 11), unit_c(3 * 21, 12), unit_c(3 * 10, 13), From 36b6afa9b0a15d16043b92a65af75e036bfe29e9 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Fri, 20 Dec 2024 17:42:07 +0100 Subject: [PATCH 34/35] add news entry and date. --- NEWS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index d446bb20ee..eb55cd16fd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,12 +5,12 @@ 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.9] - unreleased +## [0.10.9] - 2024-12-20 ### Added -* the Segre manifold -* the warped metric +* the `Segre` manifold +* the `WarpedMetric` for the `Segre`manifold * The manifold `HeisenbergMatrices` as the underlying manifold of `HeisenbergGroup`. ### Changed From a2413c55e375e1f4fe388149a85b3d213b82f4b3 Mon Sep 17 00:00:00 2001 From: Simon Jacobsson Date: Fri, 20 Dec 2024 18:43:30 +0100 Subject: [PATCH 35/35] small commit --- src/manifolds/Segre.jl | 2 +- src/manifolds/SegreWarpedMetric.jl | 4 ++-- test/manifolds/segre.jl | 35 ++++++++++++++++++++++++++---- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/manifolds/Segre.jl b/src/manifolds/Segre.jl index e16439e6d3..0d6cfa1f7a 100644 --- a/src/manifolds/Segre.jl +++ b/src/manifolds/Segre.jl @@ -74,7 +74,7 @@ end ````math \mathcal{P} = ℝ^{+} \times \mathbb{S}^{n_1 - 1} \times \dots \times \mathbb{S}^{n_d - 1} ```` -with the metric [`inner`](@ref inner(::Segre, ::Any, ::Any, ::Any)). +with a warped product metric. Every equivalence class ``q \in \mathcal{S}`` has ``2^d`` representatives in ``\mathcal{P}``. `closest_representative!(M, q, p)` changes representative of `q` to the one that is closest to `p` in ``\mathcal{P}``. """ diff --git a/src/manifolds/SegreWarpedMetric.jl b/src/manifolds/SegreWarpedMetric.jl index 1bd12c7896..ce53b3ea1b 100644 --- a/src/manifolds/SegreWarpedMetric.jl +++ b/src/manifolds/SegreWarpedMetric.jl @@ -228,9 +228,9 @@ and assume ``(ΞΌ, y_1,…, y_d)`` is the representative of ``q`` that minimizes \operatorname{log}_p(q) = \left( \mu \cos{m} - \lambda, - (y_1 - ⟨x_1, y_1⟩ x_1) \frac{\mu \sphericalangle(x_1, y_1) \sin{A m}}{\lambda A m \sin{\sphericalangle(x_1, y_1)}}, + (y_1 - ⟨x_1, y_1⟩ x_1) \frac{\mu \sphericalangle(x_1, y_1) \sin(A m)}{\lambda A m \sin{\sphericalangle(x_1, y_1)}}, \dots, - (y_d - ⟨x_d, y_d⟩ x_d) \frac{\mu \sphericalangle(x_d, y_d) \sin{A m}}{\lambda A m \sin{\sphericalangle(x_d, y_d)}} + (y_d - ⟨x_d, y_d⟩ x_d) \frac{\mu \sphericalangle(x_d, y_d) \sin(A m)}{\lambda A m \sin{\sphericalangle(x_d, y_d)}} \right). ```` diff --git a/test/manifolds/segre.jl b/test/manifolds/segre.jl index 368abb1dce..df30e8bdab 100644 --- a/test/manifolds/segre.jl +++ b/test/manifolds/segre.jl @@ -7,10 +7,10 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences Segre(7, 2), Segre(7, 9, 9), Segre(9, 3, 6, 6), - MetricManifold(Segre(10), WarpedMetric(1.2025837056880606)), - MetricManifold(Segre(2, 9), WarpedMetric(1.1302422072971439)), - MetricManifold(Segre(9, 6, 10), WarpedMetric(1.4545138169484464)), - MetricManifold(Segre(9, 3, 8, 10), WarpedMetric(1.396673190458706)), + MetricManifold(Segre(10), WarpedMetric(1.20)), + MetricManifold(Segre(2, 9), WarpedMetric(1.13)), + MetricManifold(Segre(9, 6, 10), WarpedMetric(0.87)), + MetricManifold(Segre(9, 3, 8, 10), WarpedMetric(1.40)), ] # Vs[i] is the valence of Ms[i] @@ -115,6 +115,11 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences [[1.0, 0.0], p[2:end]...]; error=:error, ) + @test_throws DomainError is_point( + M, + [p[1], [1.0], p[3:end]...]; + error=:error, + ) @test_throws DomainError is_point(M, [[-1.0], p[2:end]...]; error=:error) @test_throws DomainError is_point(M, [p[1], 2 * p[2:end]...]; error=:error) end @@ -139,6 +144,10 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences @test_throws DomainError is_vector(M, p, p, false, true) end + @testset "connected_by_geodesic" begin + @test connected_by_geodesic(M, p, q) + end + Random.seed!(1) @testset "rand" begin @test is_point(M, rand(M)) @@ -319,4 +328,22 @@ using Manifolds, Test, Random, LinearAlgebra, FiniteDifferences q_ = [q[1], q[2], q[3], q[4], -q[5]] @test is_vector(M, p, log(M, p, q_)) end + + # Test the formulas for sectional curvature stated in the docs + @testset "sectional_curvature" begin + M = Segre(3, 3) + p = [[1.3], [1.0, 0.0, 0.0], [1.0, 0.0, 0.0]] + X = [[0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 0.0]] + Y = [[0.0], [0.0, 0.0, 1.0], [0.0, 0.0, 0.0]] + Z = [[0.0], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0]] + V = [[1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] + @test isapprox(0.0, sectional_curvature(M, p, X, Y)) + @test isapprox(-1 / p[1][1]^2, sectional_curvature(M, p, X, Z)) + @test isapprox(0.0, sectional_curvature(M, p, X, V)) + + M = MetricManifold(Segre(3, 3, 3), WarpedMetric(1.23)) + @test isapprox((1.23^(-2) - 1) / p[1][1]^2, sectional_curvature(M, p, X, Y)) + @test isapprox(-1 / p[1][1]^2, sectional_curvature(M, p, X, Z)) + @test isapprox(0.0, sectional_curvature(M, p, X, V)) + end end