Tangent/Cotangent bundles in Manifolds.jl

What would be the canonical way to represent a cotangent vector with Manifolds.jl? As far as I can see, there is no space for T \mathcal{M} or T^* \mathcal{M}, hence the canonical representation would be a tuple (pt, vec)? Is there a way to give the vec the information if it is tangent or cotangent? I only found Atlases and charts · Manifolds.jl.

Part of my question is because I have functions \varphi: T^* \mathcal{M} \to T^* \mathcal{M} which I want to differentiate (but I mostly care about \mathbb{R}^n so the question is more curiosity driven).

(I’m totally fine with the answer: keep track of it yourself which is practical enough, just want to make sure I don’t overlook anything :slight_smile: )

Hm, not sure I know of any way of tracking that object, I guess you could always create a new manifold type for it specifically as the union of the two spaces.

For the actual differentiation part, have you checked out ManifoldDiff.jl?

Well, we do have the tangent bundle, and yes on there you would use tuples (p, X) to represent points, and in principle X could of course be typed as Atlases and charts · Manifolds.jl for cotangent vectors.

Beyond that I think we simply did not yet have the need nor any one formalising these aspects on manifolds much more. For my applications in optimization I for now always only needed tangent vectors; for the one case of the vector bundle newton we rephrased it (via sharp/flat) as a tangent bundle problem before implementing.

If you need more, it is probably best to either discuss that here or in a new issue in Manifolds.jl so we can help you implement / draft what you need.

I just noticed in the source code CotangentBundle is also defined already

M = Euclidean(2)
coTM = CotangentBundle(M)

In my case, I will use/experiment with different minimization algorithms which use coTM as the base manifold. There is however a follow-up case where M to start with would be non-flat, that’s why if possible having it directly clearly split might be useful.

One part I noticed (opened an issue; offline now but will try to see if I can do a PR next week…)


M = Euclidean(2)
TM = TangentBundle(M)
pt = SA[1.0,1];   nopt = SA[1.0, 1.0, 1.0];   v = SA[1.0,0.0]

is_point(TM, (pt, v)) # == true
is_point(TM, (nopt, v)) # == true
is_point(TM, nothing) # == true

It seems is_point is a tad optimistic for (co)tangent bundles and always returns true no matter what.

I’ve been thinking about cotangent vector representation for JuliaManifolds but so far nearly always the right solution was to take the corresponding (through musical isomorphisms) tangent vector instead. The natural way to represent cotangent vectors is as a Julia function but then the only cheap thing you can do with it is evaluation. It’s perfectly fine for reverse mode AD but it doesn’t lead to a well-motivated API.

The other reasonable way of handling cotangent vectors is by taking coordinates, but so far we have only a fairly basic support for charts and atlases, and even there the “just use tangent vectors” approach seems to work well so far. I guess things might be different when you don’t have a canonical way of transforming cotangent vectors to tangent vectors but that’s not a problem I’ve encountered so far.

is_point is indeed a bit optimistic, perhaps it wasn’t a great decision to make it that way.

That is_point is optimistic could be one thing we can change, it is one line to change.

For cotangent vectors I for example have the following problem: any \xi \in T^*_p\mathcal M is a linear function on the tangent space. So in code one could expect them to be functions \xi: T_p\mathcal M \to \mathbb R or that we at least have an API that does this operation.

Now take the sphere M = \mathbb S^2 and the North Pole p=(0,0,1)^T, Then we could maybe agree writing \xi(X) = \langle a, X \rangle that we can identify the cotangent vector with the vector a. However, as long as on the tangent space it agrees, it is the same cotangent vector, so for any b = a+\alpha p, \alpha \in \mathbb R we have the same cotangent vector. We loose uniqueness (in vector representation) and that is_point(coTpM, a) should return true for all real vectors of length 3

Sorry for the slightly offtopic question, but does Manifolds.jl support the “transition maps first” construction of manifolds?

I.e. I have a collection of U_i\subseteq \mathbb{R}^n and U_{ji}\subseteq U_i, and sufficiently smooth \phi_{ji}:U_{ji}\to U_{ij} with \phi_{ij}\phi_{ji}(x) = x and \phi_{ij}\phi_{jk}\phi_{k i}(x) = x whenever the lefthand side is defined. That gives you an atlas, in the sense of coordinate charts on an underlying space M, by defining points as (i, x): x \in U_i modulo (i,x)\sim (j,\phi_{ji}x) whenever the rhs is defined.

A good apriori representation of an underlying M may not be immediately available, and should be entirely superfluous anyways.

As an example for helpful things to expect from Manifolds.jl and companions: set up the wiring for solving ODEs (i.e. set up the stop conditions and switches to change to a different chart and equation; the same for transporting whatever tangent/cotangent stuff along, and for setting up the necesary AD for the transition maps; maybe providing inverse transition maps via Newton; maybe helper functions for setting up and using partitions of unity, etc).

Or is that in fact trivial (yay, parametrizations are trivial maps x -> (i, x))? If so, that would make for a nice tutorial-example in the docs.

To be honest I have zero knowledge about what you mean with “transition maps first” construction – and I am not able to follow your construction idea. Are the

meant to be products? Also as Mateusz already wrote, for now we do have a limited range of features for Atlases, but we did not yet have any contributor that needed them and took the time to introduce them thoroughly. I also do work not at all with ODEs nor much (actually also not at all) with AD.

So since I do not understand it, I can also not say whether it is trivial.

What we do have is a library of manifolds, for example the sphere or the manifold of symmetric positive definite matrices and such, we collect different metrics, retractions, vector transports and try to document and test them thoroughly.

We also do not cover symbolically defined manifolds nor infinite-dimensional manifolds nor do we do fancy algebra related topics.

Wikipedia describes that in different words here Differentiable manifold - Wikipedia

Most textbooks start with an “underlying” apriori topological space M because ensuring Hausdorffness of the quotient space is sometimes kinda annoying. But I’d view that as a technicality.

I meant \phi_{ij}\circ\phi_{ji} = \mathrm{id} on U_{ji} and \phi_{ij}\circ\phi_{jk}\circ\phi_{k i} = \mathrm{id} on U_{ki}\cap \phi_{jk}^{-1}(U_{jk})\cap (\phi_{jl}\circ\phi_{ki})^{-1}(U_{ij}).

PS. The “why would you do that” is: I have hand-crafted coordinate charts that are good for different regimes of some differential equation, and corresponding transition maps. I’d like to forget that this all comes from some underlying global thing. Look, as long as my solution doesn’t leave the collection of regions I cobbled together, it doesn’t need to fit together globally! Nobody prevents me from transplanting my dynamical system from an original compact(ish) manifold to some covering space of a forward invariant(ish) subset!

I see. As I wrote, we do have only a very limited support for atlases for now.

I now understand the definition you were referring to and mathematically it looks nice, but how that could (a) be realised in code and (b) be used numerically, I have no clue.
So no, we do not cover that nor it is planned to be covered. Even if someone would come by who would see how to make use of this numerically, it could probably be a new package (based on ManifoldsBase.jl) as a “sister package” to Manifolds.jl.

I haven’t tried it yet but I don’t see a reason why it wouldn’t work with fairly minimal changes. I’m going to work a bit this summer on atlases so I can add making such example to my todo list. At the very least, (i, x) is a perfectly valid representation of points as far as Manifolds.jl is concerned – we have extremely minimal assumptions about points. I know nearly every numerical piece of software assumes working with array-indexable objects but that’s not the case here :slight_smile: .

We already have vector transport, exp (including chart switching) and log in a chart (I don’t have a good reason to have multi-chart log). I’m planning to add Jacobi fields and maybe some volume-related stuff soon. I don’t have a good practical use case for partitions of unity yet.

I have an old sketch of infinite-dimensional manifolds so I could revive it if needed but they are quite technical to work with.

If you take the coord-only viewpoint, then the manifold is a quotient space. Hence, functions f: M -> R are only well-defined if they respect the relation ~, i.e. if f_i(x_i) = f_j(\phi_{ji}x_i). This means that it becomes hard to write down well-defined functions on the manifold! Especially if you want them to be continuous or even differentiable.

Partitions of unity allow you to do that, in a simple albeit inefficient way: Take any collection f_i of functions, define F(p) = \sum_j \rho_j(p) f_j(\phi_j p), i.e. F(i, x_i) = \sum_j\rho_{j}(\phi_{ji}x_i)f_j(\phi_{ji}x_i). In other words, they might not give you a basis for function spaces on the manifold (linear dependence in the overlaps), but they give you a simple set of generators.

Is that a good idea for actual numerics? Meh. For ODEs into the manifold you want hysteresis around chart-switching, i.e. you want get_chart_index(M::AbstractManifold, A::AbstractAtlas, i, a) instead of a well-defined modulo ~ version of get_chart_index(M::AbstractManifold, A::AbstractAtlas, p). For PDEs on the manifold, you want domain decomposition methods of some kind (setting that up is also something where users may want help with).

Are partitions of unity useful for quickly trying things out? Probably! And I vaguely remember that some domain decomposition methods with overlaps want a partition of unity anyways – but that’s not my field, so :person_shrugging: .

The general point was: For some problems, different regimes are best described in different coordinates. “Use good coordinates for each regime and switch between them as appropriate” is not a deep insight, but requires some “trivial but annoying” book-keeping to get right. This book-keeping can often be fruitfully described in the terminology of “manifold / atlas / chart”. So it would be cool if manifolds.jl provided functionality for that unplatonic viewpoint!

One could joke that “appropriate coordinates for each regime” is how students today first encounter (embedded sub-) manifolds: As the structure of that which follows from the standard proof of the implicit function theorem. I think that joke would be quite ahistorical, though.

I guess partitions of unity might be useful for some cases of numerical chart-based quadratures but I didn’t have any use for that so far. Regarding hysteresis for ODEs, we currently rely on the user for that. We just have a function for checking if too close to chart boundary and if so, we do a sharp transition in the solver. This is recorded in the returned object and can be used to reconstruct the entire trajectory.

Regarding PDEs on manifolds, I’ve looked briefly at how people work with them, mostly regarding the heat equation, and it looked like the most viable approach would be to solve multiple PDEs in charts with coupled boundary conditions and use Euclidean solvers but I think Manifolds.jl wouldn’t be of much help and it might be better to work with these solvers directly.

BTW, I also share the same point of view that coordinates should be properly chosen to fit the given regime but surprisingly many people seem to ignore it.