Shape spaces
Shape spaces are spaces of $k$ points in $\mathbb{R}^n$ up to simultaneous action of a group on all points. The most commonly encountered are Kendall's pre-shape and shape spaces. In the case of the Kendall's pre-shape spaces the action is translation and scaling. In the case of the Kendall's shape spaces the action is translation, scaling and rotation.
using Manifolds, Plots
M = KendallsShapeSpace(2, 3)
# two random point on the shape space
p = [
0.4385117672460505 -0.6877826444042382 0.24927087715818771
-0.3830259932279294 0.35347460720654283 0.029551386021386548
]
q = [
-0.42693314765896473 -0.3268567431952937 0.7537898908542584
0.3054740561061169 -0.18962848284149897 -0.11584557326461796
]
# let's plot them as triples of points on a plane
fig = scatter(p[1,:], p[2,:], label="p", aspect_ratio=:equal)
scatter!(fig, q[1,:], q[2,:], label="q")
# aligning q to p
A = get_orbit_action(M)
a = optimal_alignment(A, p, q)
rot_q = apply(A, a, q)
scatter!(fig, rot_q[1,:], rot_q[2,:], label="q aligned to p")
A more extensive usage example is available in the hand_gestures.jl
tutorial.
Manifolds.KendallsPreShapeSpace
โ TypeKendallsPreShapeSpace{n,k} <: AbstractSphere{โ}
Kendall's pre-shape space of $k$ landmarks in $โ^n$ represented by nรk matrices. In each row the sum of elements of a matrix is equal to 0. The Frobenius norm of the matrix is equal to 1 [Ken84][Ken89].
The space can be interpreted as tuples of $k$ points in $โ^n$ up to simultaneous translation and scaling of all points, so this can be thought of as a quotient manifold.
Constructor
KendallsPreShapeSpace(n::Int, k::Int)
See also
KendallsShapeSpace
, esp. for the references
Manifolds.KendallsShapeSpace
โ TypeKendallsShapeSpace{n,k} <: AbstractDecoratorManifold{โ}
Kendall's shape space, defined as quotient of a KendallsPreShapeSpace
(represented by nรk matrices) by the action ColumnwiseMultiplicationAction
.
The space can be interpreted as tuples of $k$ points in $โ^n$ up to simultaneous translation and scaling and rotation of all points [Ken84][Ken89].
This manifold possesses the IsQuotientManifold
trait.
Constructor
KendallsShapeSpace(n::Int, k::Int)
References
Provided functions
ManifoldsBase.check_point
โ Methodcheck_point(M::KendallsPreShapeSpace, p; atol=sqrt(max_eps(X, Y)), kwargs...)
Check whether p
is a valid point on KendallsPreShapeSpace
, i.e. whether each row has zero mean. Other conditions are checked via embedding in ArraySphere
.
ManifoldsBase.check_vector
โ Methodcheck_vector(M::KendallsPreShapeSpace, p, X; kwargs... )
Check whether X
is a valid tangent vector on KendallsPreShapeSpace
, i.e. whether each row has zero mean. Other conditions are checked via embedding in ArraySphere
.
ManifoldsBase.get_embedding
โ Methodget_embedding(M::KendallsPreShapeSpace)
Return the space KendallsPreShapeSpace
M
is embedded in, i.e. ArraySphere
of matrices of the same shape.
ManifoldsBase.manifold_dimension
โ Methodmanifold_dimension(M::KendallsPreShapeSpace)
Return the dimension of the KendallsPreShapeSpace
manifold M
. The dimension is given by $n(k - 1) - 1$.
ManifoldsBase.project
โ Methodproject(M::KendallsPreShapeSpace, p, X)
Project tangent vector X
at point p
from the embedding to KendallsPreShapeSpace
by selecting the right element from the tangent space to orthogonal section representing the quotient manifold M
. See Section 3.7 of [SK16] for details.
ManifoldsBase.project
โ Methodproject(M::KendallsPreShapeSpace, p)
Project point p
from the embedding to KendallsPreShapeSpace
by selecting the right element from the orthogonal section representing the quotient manifold M
. See Section 3.7 of [SK16] for details.
The method computes the mean of the landmarks and moves them to make their mean zero; afterwards the Frobenius norm of the landmarks (as a matrix) is normalised to fix the scaling.
Base.exp
โ Methodexp(M::KendallsShapeSpace, p, X)
Compute the exponential map on KendallsShapeSpace
M
. See [GMTP21] for discussion about its computation.
Base.log
โ Methodlog(M::KendallsShapeSpace, p, q)
Compute the logarithmic map on KendallsShapeSpace
M
. See the [exp
](@ref exp(::KendallsShapeSpace, ::Any, ::Any)onential map for more details
Base.rand
โ Methodrand(::KendallsShapeSpace; vector_at=nothing)
When vector_at
is nothing
, return a random point x
on the KendallsShapeSpace
manifold M
by generating a random point in the embedding.
When vector_at
is not nothing
, return a random vector from the tangent space with mean zero and standard deviation ฯ
.
Manifolds.get_total_space
โ Methodget_total_space(::Grassmann{n,k})
Return the total space of the KendallsShapeSpace
manifold, which is the KendallsPreShapeSpace
manifold.
Manifolds.horizontal_component
โ Methodhorizontal_component(::KendallsShapeSpace, p, X)
Compute the horizontal component of tangent vector X
at p
on KendallsShapeSpace
M
. See [GMTP21], Section 2.3 for details.
ManifoldsBase.get_embedding
โ Methodget_embedding(M::KendallsShapeSpace)
Get the manifold in which KendallsShapeSpace
M
is embedded, i.e. KendallsPreShapeSpace
of matrices of the same shape.
ManifoldsBase.is_flat
โ Methodis_flat(::KendallsShapeSpace)
Return false. KendallsShapeSpace
is not a flat manifold.
ManifoldsBase.manifold_dimension
โ Methodmanifold_dimension(M::KendallsShapeSpace)
Return the dimension of the KendallsShapeSpace
manifold M
. The dimension is given by $n(k - 1) - 1 - n(n - 1)/2$ in the typical case where $k \geq n+1$, and $(k + 1)(k - 2) / 2$ otherwise, unless $k$ is equal to 1, in which case the dimension is 0. See [Ken84] for a discussion of the over-dimensioned case.