# Tangent/Cotangent bundles in Manifolds.jl

**URL:** <https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801>\
**Category:** General Usage\
**Tags:** manifolds\
**Created:** [June 25, 2026, 12:55pm UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801 "2026-06-25T12:55:48Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [June 25, 2026, 12:55pm UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/1 "2026-06-25T12:55:48Z")

</div>

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](https://juliamanifolds.github.io/Manifolds.jl/stable/features/atlases/#Cotangent-space-and-musical-isomorphisms).

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 🙂 )

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [June 25, 2026, 1:46pm UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/2 "2026-06-25T13:46:30Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [June 25, 2026, 1:58pm UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/3 "2026-06-25T13:58:33Z")

</div>

Well, we do have [the tangent bundle](https://juliamanifolds.github.io/Manifolds.jl/stable/manifolds/vector_bundle/#Manifolds.TangentBundle), 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](https://juliamanifolds.github.io/Manifolds.jl/stable/features/atlases/#Manifolds.RieszRepresenterCotangentVector) 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](https://manoptjl.org/stable/solvers/vectorbundle_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.

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [June 26, 2026, 12:03am UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/4 "2026-06-26T00:03:55Z")

</div>

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

```julia
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](https://github.com/JuliaManifolds/Manifolds.jl/issues/911); offline now but will try to see if I can do a PR next week…)

```julia

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.

---

<div class="post-metadata">

**Author:** ![mateuszbaran](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mateuszbaran/32/221842_2.png) [@mateuszbaran](https://discourse.julialang.org/u/mateuszbaran)\
**Post date:** [June 26, 2026, 7:41am UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/5 "2026-06-26T07:41:23Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [June 26, 2026, 9:20am UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/6 "2026-06-26T09:20:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [June 26, 2026, 12:35pm UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/7 "2026-06-26T12:35:20Z")

</div>

> [@kellertuer](#):
>
> be typed as [Atlases and charts · Manifolds.jl](https://juliamanifolds.github.io/Manifolds.jl/stable/features/atlases/#Manifolds.RieszRepresenterCotangentVector)

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.

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [June 26, 2026, 12:51pm UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/8 "2026-06-26T12:51:43Z")

</div>

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

> [@foobar\_lv2](#):
>
> \phi\_{ij}\phi\_{ji}(x) = x

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](https://juliamanifolds.github.io/Manifolds.jl/stable/manifolds/sphere/) or the manifold of [symmetric positive definite matrices](https://juliamanifolds.github.io/Manifolds.jl/stable/manifolds/symmetricpositivedefinite/) 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.

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [June 26, 2026, 1:14pm UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/9 "2026-06-26T13:14:20Z")

</div>

Wikipedia describes that in different words here [Differentiable manifold - Wikipedia](https://en.wikipedia.org/wiki/Differentiable_manifold#Patching_together_Euclidean_pieces_to_form_a_manifold)

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.

> [@kellertuer](#):
>
> Are the […] meant to be products?

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!

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [June 26, 2026, 1:28pm UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/10 "2026-06-26T13:28:07Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mateuszbaran](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mateuszbaran/32/221842_2.png) [@mateuszbaran](https://discourse.julialang.org/u/mateuszbaran)\
**Post date:** [July 1, 2026, 8:52am UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/11 "2026-07-01T08:52:51Z")

</div>

> [@foobar\_lv2](#):
>
> Sorry for the slightly offtopic question, but does [Manifolds.jl](https://juliaregistries.github.io/General/packages/redirect_to_repo/Manifolds) 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](https://juliaregistries.github.io/General/packages/redirect_to_repo/Manifolds) 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.

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 🙂 .

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.

> [@kellertuer](#):
>
> infinite-dimensional manifolds

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

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [July 1, 2026, 11:20am UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/12 "2026-07-01T11:20:10Z")

</div>

> [@mateuszbaran](#):
>
> I don’t have a good practical use case for partitions of unity yet.

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 🤷 .

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.

---

<div class="post-metadata">

**Author:** ![mateuszbaran](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mateuszbaran/32/221842_2.png) [@mateuszbaran](https://discourse.julialang.org/u/mateuszbaran)\
**Post date:** [July 1, 2026, 12:11pm UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/13 "2026-07-01T12:11:38Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mateuszbaran](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mateuszbaran/32/221842_2.png) [@mateuszbaran](https://discourse.julialang.org/u/mateuszbaran)\
**Post date:** [September 23, 2026, 10:45am UTC](https://discourse.julialang.org/t/tangent-cotangent-bundles-in-manifolds-jl/137801/14 "2026-09-23T10:45:23Z")

</div>

> [@foobar\_lv2](#):
>
> Sorry for the slightly offtopic question, but does [Manifolds.jl](https://juliaregistries.github.io/General/packages/redirect_to_repo/Manifolds) support the “transition maps first” construction of manifolds?

The newest version of Manifolds.jl now has a significantly expanded chart-based capabilities, see this tutorial: [work in charts · Manifolds.jl](https://juliamanifolds.github.io/Manifolds.jl/stable/tutorials/working-in-charts/#Jacobi-fields-and-differentials-in-charts). The implementation is actually centered around transition maps (and their differentials), though I don’t have a good example of a manifold that doesn’t have a reasonable Euclidean embedding representation (and embedding theorems suggest such example may not even exist). Right now the example uses the 3D torus but we now support any parametric manifolds in R^n generically.
