Power manifold
A power manifold is based on a Manifold
$\mathcal M$ to build a $\mathcal M^{n_1 \times n_2 \times \cdots \times n_m}$. In the case where $m=1$ we can represent a manifold-valued vector of data of length $n_1$, for example a time series. The case where $m=2$ is useful for representing manifold-valued matrices of data of size $n_1 \times n_2$, for example certain types of images.
Example
There are two ways to store the data: in a multidimensional array or in a nested array.
Let's look at an example for both. Let $\mathcal M$ be Sphere(2)
the 2-sphere and we want to look at vectors of length 4.
For the default, the ArrayPowerRepresentation
, we store the data in a multidimensional array,
using Manifolds
M = PowerManifold(Sphere(2), 4)
p = cat([1.0, 0.0, 0.0],
[1/sqrt(2.0), 1/sqrt(2.0), 0.0],
[1/sqrt(2.0), 0.0, 1/sqrt(2.0)],
[0.0, 1.0, 0.0]
,dims=2)
3×4 Array{Float64,2}: 1.0 0.707107 0.707107 0.0 0.0 0.707107 0.0 1.0 0.0 0.0 0.707107 0.0
which is a valid point i.e.
is_manifold_point(M, p)
true
This can also be used in combination with HybridArrays.jl and StaticArrays.jl, by setting
using HybridArrays, StaticArrays
q = HybridArray{Tuple{3,StaticArrays.Dynamic()},Float64,2}(p)
3×4 HybridArrays.HybridArray{Tuple{3,StaticArrays.Dynamic()},Float64,2,2,Array{Float64,2}} with indices SOneTo(3)×Base.OneTo(4): 1.0 0.707107 0.707107 0.0 0.0 0.707107 0.0 1.0 0.0 0.0 0.707107 0.0
which is still a valid point on M
and PowerManifold
works with these, too.
An advantage of this representation is that it is quite efficient, especially when a HybridArray
(from the HybridArrays.jl package) is used to represent a point on the power manifold. A disadvantage is not being able to easily identify parts of the multidimensional array that correspond to a single point on the base manifold. Another problem is, that accessing a single point is p[:, 1]
which might be unintuitive.
For the NestedPowerRepresentation
we can now do
using Manifolds
M = PowerManifold(Sphere(2), NestedPowerRepresentation(), 4)
p = [ [1.0, 0.0, 0.0],
[1/sqrt(2.0), 1/sqrt(2.0), 0.0],
[1/sqrt(2.0), 0.0, 1/sqrt(2.0)],
[0.0, 1.0, 0.0],
]
4-element Array{Array{Float64,1},1}: [1.0, 0.0, 0.0] [0.7071067811865475, 0.7071067811865475, 0.0] [0.7071067811865475, 0.0, 0.7071067811865475] [0.0, 1.0, 0.0]
which is again a valid point so is_manifold_point
(M, p)
here also yields true. A disadvantage might be that with nested arrays one loses a little bit of performance. The data however is nicely encapsulated. Accessing the first data item is just p[1]
.
For accessing points on power manifolds in both representations you can use get_component
and set_component!
functions. They work work both point representations.
using Manifolds
M = PowerManifold(Sphere(2), NestedPowerRepresentation(), 4)
p = [ [1.0, 0.0, 0.0],
[1/sqrt(2.0), 1/sqrt(2.0), 0.0],
[1/sqrt(2.0), 0.0, 1/sqrt(2.0)],
[0.0, 1.0, 0.0],
]
set_component!(M, p, [0.0, 0.0, 1.0], 4)
get_component(M, p, 4)
3-element view(::Array{Float64,1}, :) with eltype Float64: 0.0 0.0 1.0
Types and Functions
Manifolds.AbstractPowerManifold
— TypeAbstractPowerManifold{𝔽,M,TPR} <: Manifold{𝔽}
An abstract Manifold
to represent manifolds that are build as powers of another Manifold
M
with representation type TPR
, a subtype of AbstractPowerRepresentation
.
Manifolds.AbstractPowerRepresentation
— TypeAbstractPowerRepresentation
An abstract representation type of points and tangent vectors on a power manifold.
Manifolds.ArrayPowerRepresentation
— TypeArrayPowerRepresentation
Representation of points and tangent vectors on a power manifold using multidimensional arrays where first dimensions are equal to representation_size
of the wrapped manifold and the following ones are equal to the number of elements in each direction.
Torus
uses this representation.
Manifolds.InversePowerRetraction
— TypeInversePowerRetraction(inverse_retractions::AbstractInverseRetractionMethod...)
Power inverse retraction of inverse_retractions
. Works on AbstractPowerManifold
s.
Manifolds.NestedPowerRepresentation
— TypeNestedPowerRepresentation
Representation of points and tangent vectors on a power manifold using arrays of size equal to TSize
of a PowerManifold
. Each element of such array stores a single point or tangent vector.
GraphManifold
uses this representation.
Manifolds.PowerBasisData
— TypePowerBasisData{TB<:AbstractArray}
Data storage for an array of basis data.
Manifolds.PowerFVectorDistribution
— TypePowerFVectorDistribution([type::VectorBundleFibers], [x], distr)
Generates a random vector at a point
from vector space (a fiber of a tangent bundle) of type type
using the power distribution of distr
.
Vector space type and point
can be automatically inferred from distribution distr
.
Manifolds.PowerManifold
— TypePowerManifold{𝔽,TM<:Manifold,TSize<:Tuple,TPR<:AbstractPowerRepresentation} <: AbstractPowerManifold{𝔽,TM}
The power manifold $\mathcal M^{n_1× n_2 × … × n_d}$ with power geometry TSize
statically defines the number of elements along each axis.
For example, a manifold-valued time series would be represented by a power manifold with $d$ equal to 1 and $n_1$ equal to the number of samples. A manifold-valued image (for example in diffusion tensor imaging) would be represented by a two-axis power manifold ($d=2$) with $n_1$ and $n_2$ equal to width and height of the image.
While the size of the manifold is static, points on the power manifold would not be represented by statically-sized arrays. Operations on small power manifolds might be faster if they are represented as ProductManifold
.
Constructor
PowerManifold(M, N_1, N_2, ..., N_d)
PowerManifold(M, NestedPowerRepresentation(), N_1, N_2, ..., N_d)
M^(N_1, N_2, ..., N_d)
Generate the power manifold $M^{N_1 × N_2 × … × N_d}$. By default, the ArrayPowerRepresentation
of points and tangent vectors is used, although a different one, for example NestedPowerRepresentation
, can be given as the second argument to the constructor. When M
is a PowerManifold
(not any AbstractPowerManifold
) itself, given dimensions will be appended to the dimensions already present, for example PowerManifold(PowerManifold(Sphere(2), 2), 3)
is equivalent to PowerManifold(Sphere(2), 2, 3)
. This feature preserves the representation of the inner power manifold (unless it's explicitly overridden).
Manifolds.PowerMetric
— TypePowerMetric <: Metric
Represent the Metric
on an AbstractPowerManifold
, i.e. the inner product on the tangent space is the sum of the inner product of each elements tangent space of the power manifold.
Manifolds.PowerPointDistribution
— TypePowerPointDistribution(M::AbstractPowerManifold, distribution)
Power distribution on manifold M
, based on distribution
.
Manifolds.PowerRetraction
— TypePowerRetraction(retraction::AbstractRetractionMethod)
Power retraction based on retraction
. Works on AbstractPowerManifold
s.
Manifolds.PowerVectorTransport
— TypePowerVectorTransport(method::AbstractVectorTransportMethod)
Power vector transport method based on method
. Works on AbstractPowerManifold
s.
Base.exp
— Methodexp(M::AbstractPowerManifold, p, X)
Compute the exponential map from p
in direction X
on the AbstractPowerManifold
M
, which can be computed using the base manifolds exponential map elementwise.
Base.getindex
— Methodgetindex(p, M::AbstractPowerManifold, i::Union{Integer,Colon,AbstractVector}...)
p[M::AbstractPowerManifold, i...]
Access the element(s) at index [i...]
of a point p
on an AbstractPowerManifold
M
by linear or multidimensional indexing. See also Array Indexing in Julia.
Base.log
— Methodlog(M::AbstractPowerManifold, p, q)
Compute the logarithmic map from p
to q
on the AbstractPowerManifold
M
, which can be computed using the base manifolds logarithmic map elementwise.
Base.setindex!
— Methodsetindex!(q, p, M::AbstractPowerManifold, i::Union{Integer,Colon,AbstractVector}...)
q[M::AbstractPowerManifold, i...] = p
Set the element(s) at index [i...]
of a point q
on an AbstractPowerManifold
M
by linear or multidimensional indexing to q
. See also Array Indexing in Julia.
Base.view
— Methodview(p, M::AbstractPowerManifold, i::Union{Integer,Colon,AbstractVector}...)
Get the view of the element(s) at index [i...]
of a point p
on an AbstractPowerManifold
M
by linear or multidimensional indexing.
LinearAlgebra.norm
— Methodnorm(M::AbstractPowerManifold, p, X)
Compute the norm of X
from the tangent space of p
on an AbstractPowerManifold
M
, i.e. from the element wise norms the Frobenius norm is computed.
Manifolds.flat
— Methodflat(M::AbstractPowerManifold, p, X::FVector{TangentSpaceType})
use the musical isomorphism to transform the tangent vector X
from the tangent space at p
on an AbstractPowerManifold
M
to a cotangent vector. This can be done elementwise for each entry of X
(and p
).
Manifolds.get_component
— Methodget_component(M::AbstractPowerManifold, p, idx...)
Get the component of a point p
on an AbstractPowerManifold
M
at index idx
.
Manifolds.power_dimensions
— Methodpower_dimensions(M::PowerManifold)
return the power of M
,
Manifolds.set_component!
— Methodset_component!(M::AbstractPowerManifold, q, p, idx...)
Set the component of a point q
on an AbstractPowerManifold
M
at index idx
to p
, which itself is a point on the Manifold
the power manifold is build on.
Manifolds.sharp
— Methodsharp(M::AbstractPowerManifold, p, ξ::FVector{CotangentSpaceType})
Use the musical isomorphism to transform the cotangent vector ξ
from the tangent space at p
on an AbstractPowerManifold
M
to a tangent vector. This can be done elementwise for every entry of ξ
(and p
).
ManifoldsBase.check_manifold_point
— Methodcheck_manifold_point(M::AbstractProductManifold, p; kwargs...)
Check whether p
is a valid point on an AbstractPowerManifold
M
, i.e. each element of p
has to be a valid point on the base manifold. If p
is not a point on M
a CompositeManifoldError
consisting of all error messages of the components, for which the tests fail is returned.
The tolerance for the last test can be set using the kwargs...
.
ManifoldsBase.check_tangent_vector
— Methodcheck_tangent_vector(M::AbstractPowerManifold, p, X; check_base_point = true, kwargs... )
Check whether X
is a tangent vector to p
an the AbstractPowerManifold
M
, i.e. atfer check_manifold_point
(M, p)
, and all projections to base manifolds must be respective tangent vectors. The optional parameter check_base_point
indicates, whether to call check_manifold_point
for p
. If X
is not a tangent vector to p
on M
a CompositeManifoldError
consisting of all error messages of the components, for which the tests fail is returned.
The tolerance for the last test can be set using the kwargs...
.
ManifoldsBase.distance
— Methoddistance(M::AbstractPowerManifold, p, q)
Compute the distance between q
and p
on an AbstractPowerManifold
, i.e. from the element wise distances the Forbenius norm is computed.
ManifoldsBase.injectivity_radius
— Methodinjectivity_radius(M::AbstractPowerManifold[, p])
the injectivity radius on an AbstractPowerManifold
is for the global case equal to the one of its base manifold. For a given point p
it's equal to the minimum of all radii in the array entries.
ManifoldsBase.inner
— Methodinner(M::AbstractPowerManifold, p, X, Y)
Compute the inner product of X
and Y
from the tangent space at p
on an AbstractPowerManifold
M
, i.e. for each arrays entry the tangent vector entries from X
and Y
are in the tangent space of the corresponding element from p
. The inner product is then the sum of the elementwise inner products.
ManifoldsBase.inverse_retract
— Methodinverse_retract(M::AbstractPowerManifold, p, q, m::InversePowerRetraction)
Compute the inverse retraction from p
with respect to q
on an AbstractPowerManifold
M
using an InversePowerRetraction
, which by default encapsulates a inverse retraction of the base manifold. Then this method is performed elementwise, so the encapsulated inverse retraction method has to be one that is available on the base Manifold
.
ManifoldsBase.manifold_dimension
— Methodmanifold_dimension(M::PowerManifold)
Returns the manifold-dimension of an PowerManifold
M
$=\mathcal N = (\mathcal M)^{n_1,…,n_d}$, i.e. with $n=(n_1,…,n_d)$ the array size of the power manifold and $d_{\mathcal M}$ the dimension of the base manifold $\mathcal M$, the manifold is of dimension
ManifoldsBase.project
— Methodproject(M::AbstractPowerManifold, p, X)
Project the point X
onto the tangent space at p
on the AbstractPowerManifold
M
by projecting all components.
ManifoldsBase.project
— Methodproject(M::AbstractPowerManifold, p)
Project the point p
from the embedding onto the AbstractPowerManifold
M
by projecting all components.
ManifoldsBase.retract
— Methodretract(M::AbstractPowerManifold, p, X, method::PowerRetraction)
Compute the retraction from p
with tangent vector X
on an AbstractPowerManifold
M
using a PowerRetraction
, which by default encapsulates a retraction of the base manifold. Then this method is performed elementwise, so the encapsulated retraction method has to be one that is available on the base Manifold
.
ManifoldsBase.vector_transport_to
— Methodvector_transport_to(M::AbstractPowerManifold, p, X, q, method::PowerVectorTransport)
Compute the vector transport the tangent vector X
at p
to q
on the PowerManifold
M
using an PowerVectorTransport
m
. This method is performed elementwise, i.e. the method m
has to be implemented on the base manifold.