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 Array{Float64,1}: 0.0 0.0 1.0
Types and Functions
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.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.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.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.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
).