-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Towards a common Manifold Framework / Package #6
Comments
Regarding types: I considered doing that (eg having a different type for points on the manifold and tangent vectors), but opted against it as over-engineering, so I have everything as just plain arrays. My motivation at the time was inserting manifolds into an existing package for optimization, and so the simplest things were, the happier I was. I still think this is a good idea: types are good, but complicate things (eg should they be AbstractArrays or not, what underlying array type should they use, etc.) So my prefered API would be an extension of the current one, with things like
etc, where the x, y, v would simply be arrays. Does this look good or is it too limitative for your use cases? |
(I moved the discussion here for convenience; doesn't mean that we should keep the name or the code) Another use case that would have to fit inside such a package: implicit manifolds defined by |
I do dispatch on all three types and can check dimensions and such based on types. I did an implementation in Matlab with matrices and felt much much much better with proper types, also to abstract from a matrix or vector representation, since I might want to do shape manifolds and such, where the inner representation can be a graph. For implicit manifolds (in my mind) the manifold type would hold the information ( I know that's quite an abstract way to look at manifolds, points and tangent vectors (I like to also include cotangents). To the moving of the discussion – I'm fine with that, I wanted to avoid exactly keeping the name of something, but with that cleared – I am fine and happy to lead the discussion (independent of where we do that). Edit: Of course one could do |
About types, I think a common interface wouldn't really impose that many restrictions on them. It's mostly about specifying a few abstract types and method stubs that formalize the interface (which can be implemented in any way). Manopt.jl and FunManifolds.jl already introduce them in a similar way. They could be implemented in any way. I also agree that having proper types makes working with points and tangent vectors much easier. There is also the matter of argument order. Julia style guide suggests that mutated input should go very early in the order, so @kellertuer Could you give an example of what do you mean by BTW, let's also link the other thread from discourse: https://discourse.julialang.org/t/towards-a-common-manifold-framework-package/24910 |
One more point: efficient implementation of product manifolds (and power manifold, functional manifolds and some other) is very tricky. ManifoldProjections.jl uses array reshapes, Manopt.jl uses simple This is mainly to show what things should fit in the general framework, my implementation is definitely too specialized for a general package. |
My concern with having points/vectors being types is that it forces you to do everything in that framework, adds a lot of complexity and is pretty inconvenient for playing around/debugging: you can't do Possibly a good solution would be to have a package with a low-level API, in the style
Really? Reshapes and views used to suck a lot pre-1.0 but seem fine now. At least I've had good experiences on pretty large optimization problems. I was never satisfied with the design for power/product manifold, but I needed something quick and dirty for a project.
That's true; I kinda like the convention of putting dispatch operations first (so that every manifold-related function starts with a manifold), but don't have strong feelings about it. |
Well the norm yould be just a real number, so printing that is easy. For Matrix manifold points I have overloaded the operators, for tangent vectors as well (on the most abstract layer). From my side the decision was also in favor of (what's called in Manopt.jl) In the end, converts or low level APIs are a solution to the same annoance you feel, just from two different side. And yes I can understand that annoyance. Concerning the performance – for now Manopt.jl has also goals to educate and illustrate. Sure, performance is an issue still, but is not yet my main focus. I am also in favour of using views. For my sizes (512^2 point array of symmetric positive definite 3x3 matrices for example) the speed is enough (and at least 2x faster than Matlab/mex where I started out with). Finally, I also focused on documenting all formulae (instead of performance boosting) but of course being faster is always nice :) I am also in favour of putting dispatch operations first (manifold always first, on tangent operators the base point second etc) – not because there's a style guide, but because I am used to think that way on manifolds. Despite being used to that order (and that it might take some time to get used to something different) I would be ok with changing that if a majority is for that. Last but not least, I was wondering (and no offense meant) what we are aiming for with a comnmon framework. For best of cases that we can easily use one anothers manifolds. Then, the interfaces should be really fixed by conventions, but I think
should for best of cases not matter. IF we find such a common interface, that would be really nice, each implementation of a manifold focusing on a different goal, but still being interchangable. Do you think we can find such an interface? Which functions should it cover? Otherwise I would also favoru to have a collection of manifolds in such a Package, whether that's a good idea, i don't know, maybe I just like to collect things. |
Yes, that's what I was thinking: the possibility to mix manifolds and solvers from different packages. There are many good suggestions here so let me make a first draft: https://gist.github.com/mateuszbaran/6ac0115866562d09ea5e856216568a73 Notice that there are no restrictions on types of points and tangent vectors, as @kellertuer suggests, the interface should be transparent to such details. I'm eagerly awaiting comments. I'm not particularly attached to names I've used there. Defining non-mutating operations using mutating operations is very tempting but doing it in a way that is AD-friendly is challenging. For example, in I think that it would be totally OK if not all manifolds implemented all these functions but it'd be useful to explicitly state which functions particular solvers rely upon.
The API I've sketched is pretty much level-independent actually, so maybe that's enough? Whether
The problem with this is that such a collection would in some way endorse these implementations and I don't think we could agree what is the right way to implement, for example, the product manifold. Even myself, I see that both my approach and the Manopt.jl's have different goals and should just coexist. Maybe such basic package shouldn't have any implementations of manifolds? As I see it, some reference (not even exported) for testing solvers would have some usefulness but maybe that's all.
That depends on the application and what is considered fine. Using heavily optimised linear algebra from StaticArrays can easily make an order of magnitude of difference. For example here: https://gist.github.com/mateuszbaran/9fa1c7ffcd3f9445c80503e80bd0dad8 is a benchmark that compares simple dot product using both reshapes and a vector of |
Cool! I commented on https://gist.github.com/mateuszbaran/9fa1c7ffcd3f9445c80503e80bd0dad8
Me too :-) we could call this package ManifoldMuseum.jl and have it contain a number of manifolds with implementations of the basic operations on them. |
Thanks Mateusz for the ideas. Actually Manopt.jl has retractions (but not yet fallbacks providing errors see here, but for example Stiefel has retractions (that I will rename to retract – I like that!). My problem with transparency (well or let's say something that is not yet clear to me) – if we introduce a type for points and vectors but still allow just arrays instead of these types – does that lead to unwanted side effects? I love the idea of a |
So I played around with these ideas a bit, and there are a few things that bother me:
|
For the third point I first have to understand the differences more – I think I am working on mutable ones but my manifold points are immutable? I think we should either decide for one or have a proper type hierarchy to dispatch to one or the other case. |
That's not sufficient: eg points could be 2D arrays, or CuArrays, and then it'd be nice to keep everything of the same type.
That's typically the sort of things I'd do with dispatch (or not do at all)
No, immutables is for things like static arrays (https://github.com/JuliaArrays/StaticArrays.jl) where you can't do things like x .= 0 for instance. |
Ah, then I am also for leaving out immutable arrays for now. Concerning the type – hm, we could (ah you will not like that) introduce a Parametric Type? |
On top of what @antoine-levitt said, in my opinion most code should be agnostic of array type (that is, using lots of |
I use Yes, I am in favour of |
OK, here's a bare-bones version with Sphere, based on https://gist.github.com/mateuszbaran/6ac0115866562d09ea5e856216568a73 : https://github.com/JuliaNLSolvers/ManifoldMuseum. I'll add you two (and anyone interested) as committers, feel free to break everything |
I don't understand your exp/log
and for log I am also not sure what! should do – replace the value in x? That would be type instable for the approach with types I'd like to stick to. And – what if I really want to have y=exp(M,x,v)`? We could also continue over there further. Also, what to do with different types of noise (I am also doing image processing, there different types of noise are very important). |
That's using the convention that mutated arguments go first (which are now second because we put manifold types first).
Where does that come in? In |
Thanks for the explanation, on exp I am not that much a fan of putting that into |
Thanks, I'll soon start working on some tests and examples.
OK, |
I'm excited that this is happening. I'm pretty new to both Julia and topology/geometry, but I've been thinking about a general interface for manifolds and would be happy to contribute. My interest is statistics on Riemannian manifolds (and their products), such as matrix Lie groups. A few additional desiderata:
|
Thanks for your input. I think to summarise the current state
|
And I think we should start to track these things in separate threads, since we already have a repository, see https://github.com/JuliaNLSolvers/ManifoldMuseum |
Awesome! Will do! |
This is truly exciting progress here. I would like to bring a couple of aspects to your attention, just to see if there are chances that this can be handled within the targeted framework. I'm interested in ODE integration, say on the sphere (ocean surface). As you can imagine, ocean surface velocity fields are provided only on the ocean surface. Viewing the sphere as embedded in R^3 and equipping it with manifold projections or whatever is really not helpful here. So one would want to work in (geographic) coordinates, that have the manifold constraint already built in. As long as you only want to integrate the ODE in coordinates there is no need to even start with a manifold framework code, you simply treat everything as if working in R^2 and that's it. However, in my field, we are often interested in stretching by the induced flow, which is essentially measured by pullbacks of metric tensors (or their inverses, interpreted as diffusion tensor fields). Funnily, diffusion tensor fields are, of course, not given in longitude-latitude coordinates, but in meters. Long story short, I wonder if handling coordinates/units and changes thereof, tensors and pullbacks is within the scope of this effort, or if that should be put on top of this framework elsewhere. See also Ferrite-FEM/Tensors.jl#107. |
I don't have much experience with this but I think metric tensors can be handled in the current framework: just do a flat manifold with a varying inner product. We might want to add a function to get the metric tensor (which would fallback to I). That's one design objectives on my end: make the interface easy with lots of fallbacks, so that it's only a couple of lines to define a custom manifold that does what's of interest to your particular application. Units are always a pain, I don't think we want to bother with Unitful in this package (support should be automatic as long as we don't specialize on Float64s). Also, there are tons of things one could do with manifolds, but I think it'd be more productive to focus on functionality that is helpful to build non-trivial algorithms (ie optimisation, ODE solving) on top. But admittedly that might be too narrow-minded of me. |
I didn't necessarily mean to handle units explicitly. It's just that
Yes, if there was a way to get these objects "automatically" knowing the coordinates of the current point and the corresponding coordinate system, that would be great. I guess my "feature wish" is to have some generic structure for coordinate systems, so that one would define different charts and transitions between them, and get transformation rules/pullbacks for free. This would somehow mean that any coordinate representation (vector/matrix/tensor) is associated to a chart. Not sure if that's adding too much overhead... |
I've been trying to think of a way to do this in my own work that doesn't add lots of overhead. Supposing we have an atlas for a manifold. To get a point from a set of coordinates, we need to define which chart should be applied to those coordinates to take them to a point. But if we perturb the coordinates by some amount, they may now be outside of the region covered by that chart. So before using the coordinates, we need to choose a chart, and then we need to check if the coordinates fit in that chart. It's a mess for efficiency. |
For the atlas I would try to model the charts as |
That's really clever. I'm still concerned about its efficiency though. I guess if we are stuck using an atlas with multiple charts, it might be the best we can do. There's also the problem that we can't computationally represent a specific point on a manifold without selecting a set of coordinates and a chart with which to describe it. This isn't a problem for manifolds that have a canonical set of coordinates (e.g. matrices in matrix Lie groups). Maybe the discussion of points, coordinates, and charts should move to its own issue. |
CC @kellertuer, @mateuszbaran, @pkofod
This is to continue the discussion from https://discourse.julialang.org/t/ann-manopt-jl/24906/17
The text was updated successfully, but these errors were encountered: