Continuing the discussion from [ANN] Manopt.jl I would like to collect Ideas and approaches towards a common package that should be the base for “Things on manifolds”: Solving optimization problems (disclaimer, I am developing that in Manopt.jl), PDEs/ODEs on manifolds/integration and such. Basically any Julia package that might need tools from manifolds.
In my opinion a manifold should consist of 3, maybe four types: a manifold, a point on a manifold and a tangent vector. That way one could easily do exponential maps via multiple dispatch. Since for a manifold like the symmetric positive definite matrices, the Riemannian metric might be changed (leading to different geodesics and hence different exp/log…) one might also consider a type for the metric or include that into the manifold type.
Finally it should be lightweight and for example conversions from vectors/matrices to the (power) Euclidean manifold should be done with convert
What one could also provide in general are “meta” manifolds like TangentBundle or the just mentioned power manifold or a product manifold.
What are other ideas/approaches to manifolds a common framework/package should incorporate? Which functions should be implemented on a manifold (epx/log/distance…?)
I agree that these three types (manifold, point, tangent vectors) should in the basic framework. There are some potential use cases for cotangent vectors or elements of other vector bundles but probably it’s not that important.
I think it would be a good idea to include both modifying and non-modifying versions of basic functions, as well as versions for wrapped and non-wrapped points and tangent vectors. I’ve found that working with wrapped, immutable arrays is easier but good performance requires using non-wrapped and modifying functions. Here is my solution: https://github.com/mateuszbaran/FunManifolds.jl/blob/master/src/manifolds.jl . I’ve probably defined too many variants and probably some could be expressed in terms of other. Ideally, one should only have to define the modifying non-wrapped variants of operations but that’s hard without some assumptions about the array representation of points and tangent vectors.
There should be some basic manifolds which have basic operations defined in the package, although it could be hard to agree what these basic manifolds and operations are. Euclidean manifold and a sphere are definitely basic, while basic operations should include conversion to/from ambient array representation, projection, retraction, exp, log, zero tangent vector (probably expressed using log by default?), vector operations on tangent spaces, inner product, getting dimension of a manifold, norm of a tangent vector (calculated using inner product), geodesic distance (calculated using norm of log by default?).
All operations should be AD-friendly (automatic differentiation). ForwardDiff is very convenient for forward mode, and there are multiple packages for reverse mode. I’m not sure which one would be the best for manifold optimisation.
I think we could of course also implement types for cotangent vectors – just because we don’t see a use for them (yet), that might be useful to be taken into account already.
Yes, we should try to find a way to do both without defining too many variants.
Oh, I just noticed I might be guilty of function piracy (yarrr) – but yes you’re right we should take that into account.
I would also be ok with the point that such a package might collect manifolds, document their functions and provide a whole library of manifolds, too. Also, you’Re right, I would always do easy fallbacks as defaults (i.e. the norm falls back to log). That avoids too many implementations for a new manifold; if performance is an issue for your norm you can still implement it for the manifold you’re just adding.
I haven’t thought about that point yet, but it seems reasonable to take that into account.
Hello, thanks for your tremendous contribution, which was much awaited. We use Riemannian geometry mainly for classification purposes, but of course there too specific optimization problems arise now and then. For those using Riemannian geometry in applied settings the concept of metric is central, as the ensuing geodesic, distance, exp and log map, mean, etc., are the useful objects in practice. Thus i believe the metric deserves to be one of the fundamental types of a manifold.
We use a lot the positive-definite matrix manifold. In order to have a uniform library for a bunch of ‘metrics’ I am developing this package, if ever some code may be useful:
Your right, of course the metric is of huge importance. The question at hand is more like: Do we introduce two data types (manifold & metric) which again introduces a lot of pairs that just hace to raise an error or do we introduce one type (manifold) and have (for example for the two metric you use, actually exactely the two I had in mind ) two manifolds (AffineSPD and logEuclideanSPD for example) and the manifold itself encodes the metric at the same time.
Note that I favour Riemannian metrics – for a really huge number of metric two types might again be a good choice. For Manopt I aim to provide the other Riemannian metric as a second manifold, indeed.
The first option appears more appealing to me (two data types). On a different note, you may also want to check with the growing community working on optimal transport, to maybe add the Wasserstein metric as well, which has been recently shown by Rajendra Bhatia to be a Riemannian metric for the manifold of positive-definite matrices.
I know about Wasserstein metric (mainly from Bernhard Schmitzer); for me, the metric would maybe get a field within the manifold, instead of introducing more manifolds, but maybe not a fourth type (that might clutter interfaces too much, for example parallel transport already has 4 arguments and would then get 5).
But as so often, that is maybe also a matter of taste.
For the Wasserstein metric, I would also first have to learn how to compute it before I can add it.
If you are intersted, i found Bhatia’s papers on the subject excellent:
The following reference describes a very efficient gradient descent algorithm for finding the Wasserstein’s Fréchet mean (which I implemented in PosDefManifold):
id like to have a manifold type
a diffable manifold type
a riemannian manifold type
a pseudo-riemannian manifold type
a seperate metric type
a seperate connection type
Ideally i should be able to switch between charts for a point on manifold if the point present in both charts. but i am not sure if i have enough expertise on julia or manifolds