Skip to content
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

Nilpotent Lie groups #26344

Closed
ehaka mannequin opened this issue Sep 25, 2018 · 55 comments
Closed

Nilpotent Lie groups #26344

ehaka mannequin opened this issue Sep 25, 2018 · 55 comments

Comments

@ehaka
Copy link
Mannequin

ehaka mannequin commented Sep 25, 2018

Implementation of nilpotent Lie groups as manifolds with a distinguished global coordinate system (exponential coordinates).

Planned features:

  • representation of elements in exponential coordinates of the first or second kind
  • multiplication of symbolic points (using the manifold point framework)
  • the frames of left-invariant and right-invariant vector fields
  • the exponential map exp:\mathfrak{g}\to G and the logarithm
  • the adjoint map Ad:G\times \mathfrak{g}\to\mathfrak{g}

Depends on #26080

CC: @tscrim @egourgoulhon

Component: group theory

Keywords: Lie groups, Lie algebras, nilpotent

Author: Eero Hakavuori

Branch: b2ef2d9

Reviewer: Eric Gourgoulhon, Travis Scrimshaw

Issue created by migration from https://trac.sagemath.org/ticket/26344

@ehaka ehaka mannequin added this to the sage-8.4 milestone Sep 25, 2018
@ehaka ehaka mannequin added c: group theory labels Sep 25, 2018
@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 25, 2018

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 25, 2018

comment:1

A partial first version is now ready, containing the exponential map, exponential coordinates of the first and second kind and group multiplication. Vector fields and the adjoint map are still completely missing, but I thought it would be good to get a working copy up in case there are already some glaring flaws.

In particular, one thing that did not feel quite right was the current method of computing the symbolic group law. The only way I could think of was to extract the structural coefficients of the Lie algebra and to create a new Lie algebra over SR using the same structural coefficients. Two immediate issues of the current approach are

  1. the overhead of creating a new Lie algebra
  2. the original base ring of the Lie algebra needs to admit a coercion into SR

Another thing is how to handle the symbolic group law. Currently it is done by creating two dummy-variables, computing the group law as a vector expression in exponential coordinates (through the BCH formula) and then evaluating the group law by substitution of the dummy-variables.

This is still work-in-progress, but I would be happy to hear comments or suggestions.


New commits:

1276e0etrac #26080: initial implementation of the BCH formula
5972b6btrac #26080: converted bch iterator to a generator function and added interface for non-nilpotent Lie algebras
e12ea13trac #26080: efficiency improvements
369f7a6trac #26080: replaced old stopiteration
63006eatrac #26344: minimal working example of nilpotent Lie groups as manifolds

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 25, 2018

Commit: 63006ea

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 25, 2018

Dependencies: #26080

@tscrim
Copy link
Collaborator

tscrim commented Sep 25, 2018

comment:3

Eric, I am cc-ing you in case you have any comments.

The symbolic ring is usually a bit of a slow beast. it definitely feels wrong to have to have a second copy of the Lie algebra over SR. You probably could just use the structure coeffs info.

Anyways, I will think more about this.

@egourgoulhon
Copy link
Member

comment:4

Good to see that Lie groups are arriving in Sage!
I'll have a look tomorrow, focusing on the SR issue.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 26, 2018

Branch pushed to git repo; I updated commit sha1. New commits:

8e4dfb1trac #26344: invariant vector fields

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 26, 2018

Changed commit from 63006ea to 8e4dfb1

@tscrim
Copy link
Collaborator

tscrim commented Sep 26, 2018

comment:6

I am not sure I agree with caching the *_invariant_frame. I think this is already done by the atlas for the manifold and there is probably not much benefit to having this cached at the top level as not a lot of computation is done in the methods themselves.

Another comment is that structure_coefficients should exist anytime the Lie algebra has a basis because of the category. I believe the variable_names() and indices() should not fail either. So I don't see a meaningful exception being thrown.

Now that I have enough time, I see why you are using the symbolic ring to create the group law. You are considering things as generic parameters and seeing what the result is. In principle, creating the LieAlgebraWithStructureCoefficients should be relatively quick. It might be better to implement a change_ring() method for the class instead of the helper function (which could have more general use). Unfortunately I don't see a way out of creating that (at least, one that is efficient), but it should not take a lot (well, a disproportionate amount) of memory.

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 26, 2018

comment:7

Replying to @tscrim:

I am not sure I agree with caching the *_invariant_frame. I think this is already done by the atlas for the manifold and there is probably not much benefit to having this cached at the top level as not a lot of computation is done in the methods themselves.

Right, I did not realize there is manifold level caching. I will remove it from here.

Another comment is that structure_coefficients should exist anytime the Lie algebra has a basis because of the category.

This is a good point, and I should in fact change indices() to basis().keys() as in the category code of structure_coefficients, so it will work regardless within the category.

It might be better to implement a change_ring() method for the class instead of the helper function (which could have more general use).

Ideally construction of a Lie group would not rely on the Lie algebra having a change_ring() method, but instead only rely on things required/defined in the finite dimensional (nilpotent) Lie algebras with basis category.

However it would make sense to by default use change_ring if it exists, and to implement this at least for LieAlgebraWithStructureCoefficients. Then only in the case when change_ring is not defined, the code could fall back to creation of a new Lie algebra using structure_coefficients().

Thanks for the comments!

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 26, 2018

Branch pushed to git repo; I updated commit sha1. New commits:

61963e0trac #26344: added change_ring to LieAlgebraWithStructureCoefficients and modified symbolic Lie algebra creation

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 26, 2018

Changed commit from 8e4dfb1 to 61963e0

@egourgoulhon
Copy link
Member

comment:9

I gave a first glance: this looks very nice!

A very minor remark: in the example shown in line 151 of lie_group.py (as well as in other similar examples), a shortcut for

sage: list(X[0].components(exp1_frame))

is

sage: X[0][exp1_frame,:]

Maybe you chose the longer version as being more explicit?
Also you can display the components of the vector field X[0] by

sage: X[0].display(exp1_frame)
X_0 = d/dx_0 - 1/2*x_1 d/dx_2

Since exp1_frame is the default vector frame on G, this can be shorten to simply
X[0].display().

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 27, 2018

comment:10

Replying to @egourgoulhon:

I gave a first glance: this looks very nice!

A very minor remark: in the example shown in line 151 of lie_group.py (as well as in other similar examples), a shortcut for

sage: list(X[0].components(exp1_frame))

is

sage: X[0][exp1_frame,:]

Maybe you chose the longer version as being more explicit?
Also you can display the components of the vector field X[0] by

sage: X[0].display(exp1_frame)
X_0 = d/dx_0 - 1/2*x_1 d/dx_2

This choice was just a consequence of lack of knowledge on my part. Thanks for the advice, this will clean up the doc quite a bit!

Since exp1_frame is the default vector frame on G, this can be shorten to simply
X[0].display().

At this point I don't know what should be the default frame. The best sounding options are either the coordinate frame of the default system of coordinates, or the left-invariant frame.

@egourgoulhon
Copy link
Member

comment:11

Replying to @ehaka:

Since exp1_frame is the default vector frame on G, this can be shorten to simply
X[0].display().

At this point I don't know what should be the default frame. The best sounding options are either the coordinate frame of the default system of coordinates, or the left-invariant frame.

In this case, it is probably better to keep the explicit form, i.e. X[0].display(exp1_frame).

@egourgoulhon
Copy link
Member

comment:12

In the documentation, maybe you could use the method at() of vector fields to illustrate that the members of G.left_invariant_frame() do obey the definition of a left invariant vector field, for instance:

sage: L = lie_algebras.Heisenberg(QQ, 1)
sage: G = NilpotentLieGroup(L, 'G'); G
Lie group of Heisenberg algebra of rank 1 over Rational Field
sage: p,q,z = L.basis()

Let us first introduce a specific element k and generic element g in G:

sage: k = G.exp(p)*G.exp(q); k
exp(p1 + q1 + 1/2*z)
sage: g = G(G.chart_exp1()[:]); g  # a generic element of G
exp(x_0*p1 + x_1*q1 + x_2*z)

We introduce next the left translation by k:

sage: L_k = G.diff_map(G, coord_functions=(k*g).coordinates()); L_k
Differentiable map from the Lie group of Heisenberg algebra of rank 1 over Rational Field to itself
sage: L_k.display()
G --> G
   (x_0, x_1, x_2) |--> (x_0 + 1, x_1 + 1, -1/2*x_0 + 1/2*x_1 + x_2 + 1/2)

Then we check that X[0] obeys the definition of a left invariant vector field as follows:

sage: X = G.left_invariant_frame(); X
Vector frame (G, (X_0,X_1,X_2))
sage: L_k.differential(g)(X[0].at(g)) == X[0].at(L_k(g))
True

Of course, we have as well

sage: L_k.differential(g)(X[1].at(g)) == X[1].at(L_k(g))
True
sage: L_k.differential(g)(X[2].at(g)) == X[2].at(L_k(g))
True

Of course, a full check would require that k is a generic element of G; this is possible, by defining k from symbolic coordinates.

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 27, 2018

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 27, 2018

Changed commit from 61963e0 to 8a022e8

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 27, 2018

comment:13

I moved the code over to a public branch so you can feel free to add improvements in if you so wish. I'm also still happy to hear comments and corrections and do the implementation myself as well.

Replying to @egourgoulhon:

In the documentation, maybe you could use the method at() of vector fields to illustrate that the members of G.left_invariant_frame() do obey the definition of a left invariant vector field

Thanks for the suggestion, this is indeed a very good demonstration of basic Lie group functionality. I also ended up adding the creation of left/right translations as a prebuilt method as these maps should see heavy use in practice.

I have still to add in the methods for the logarithm and adjoint maps, after that I would for the moment be satisfied with the basic Lie group functionality. Or at least I can't think of what it is I am missing.


New commits:

8a022e8trac #26344: added methods to create left and right translations and improved docs

@tscrim
Copy link
Collaborator

tscrim commented Sep 27, 2018

comment:14

There is also no real penalty for having more tickets (at least, I will continue to be reviewing tickets for at least the next year :)). So it doesn't hurt to do things in smaller bites too.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 28, 2018

Changed commit from 8a022e8 to c16d1f1

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 28, 2018

Branch pushed to git repo; I updated commit sha1. New commits:

c16d1f1trac #26344: conjugation, adjoint and logarithm

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 28, 2018

comment:16

The missing parts of the initial set of features I had in mind are now in. It didn't seem right to add the adjoint without adding the conjugation map as well so that is now there as well.

At this point I'll move the ticket over to the bug-hunting/improvement phase.

@ehaka ehaka mannequin added the s: needs review label Sep 28, 2018
@egourgoulhon
Copy link
Member

comment:17

I took the liberty of adding a new section "Lie groups" at the manifold metaticket #18528 and put your ticket there. I hope you don't mind.

@egourgoulhon
Copy link
Member

comment:26

Replying to @ehaka:

Another question I have is where should the Lie group functionality go in the source and reference?
Currently the source is under sage.groups.lie_group.py and the doc is not linked anywhere since I didn't know where to put it.

For the reference manual, there are naturally two options:

since Lie groups lie at the intersection of both topics. Depending on which one you choose, I would rename the source file lie_group.py to nilpotent_lie_group.py and place it in the new subdirectory src/sage/groups/lie_groups or src/sage/manifolds/differentiable/lie_groups.

@tscrim
Copy link
Collaborator

tscrim commented Sep 29, 2018

comment:27

I would probably put it in with the groups as I think that is there more prominent feature. Moreover, our canonical Lie groups are usually thought of as (matrix) groups, GL, O, U, etc.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 30, 2018

Changed commit from d3c77ac to 383a19a

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Sep 30, 2018

Branch pushed to git repo; I updated commit sha1. New commits:

383a19atrac #26344: lie_gps subfolder and doc fixes

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Sep 30, 2018

comment:29

I moved the file to sage/groups/lie_gps/nilpotent_lie_group.py. All the other subfolders in groups were *_gps so I copied that folder convention.

I added the subsection of Lie groups to the group reference, but it is slightly disturbing to have a separate "Lie groups" subsection when there is the matrix groups heading containing GL and others. On the other hand, the abstract-manifold Lie group doesn't fit under the "Matrix and affine groups" heading, and extending it to something like "Matrix, affine, and Lie groups" seemed even worse. Hopefully this a problem that will solve itself once more Lie group functionality eventually gets added in so that the "Lie groups" heading feels more fleshed out.

@tscrim
Copy link
Collaborator

tscrim commented Sep 30, 2018

comment:30

I would argue that this is okay since the other matrix groups do not know they are Lie groups when working over topological fields and also work for a larger class of base fields (e.g., finite fields).

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 3, 2018

Changed commit from 383a19a to 790338e

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 3, 2018

Branch pushed to git repo; I updated commit sha1. New commits:

790338etrac #26344: doc tweaks

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Oct 3, 2018

comment:32

I changed the docs of NilpotentLieGroup to suggest using the L.lie_group('G') syntax over NilpotentLieGroup(L, 'G'). Having now played around with these for a bit, the former seemed to be the more convenient entry point.

Although now the NilpotentLieGroup entry point is not really even relevant as it does not provide any extra functionality. Possibly it could/should be removed from the global namespace? The only benefit I see to keeping it at this moment is being able to use NilpotentLieGroup? to see some usage examples.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 3, 2018

Branch pushed to git repo; I updated commit sha1. New commits:

e0d909fNew (sub)catalog of groups.lie, some small code improvements and doc tweaks.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 3, 2018

Changed commit from 790338e to e0d909f

@tscrim
Copy link
Collaborator

tscrim commented Oct 3, 2018

comment:34

It probably should be removed, but it should be a new subcatalog groups.lie. So I did this.

I removed the Group.__init__ as that was not doing anything useful.

I cached chart_exp2 and just called that instead of _Exp2.

Other misc doc tweaks.

If my changes are good, then I think we can set a positive review unless Eric has some more comments.

@tscrim
Copy link
Collaborator

tscrim commented Oct 3, 2018

Reviewer: Eric Gourgoulhon and Travis Scrimshaw

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 3, 2018

Changed commit from e0d909f to b2ef2d9

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 3, 2018

Branch pushed to git repo; I updated commit sha1. New commits:

b2ef2d9trac #26344: avoid creation of exp2 chart in `_repr_` + typo fix

@ehaka
Copy link
Mannequin Author

ehaka mannequin commented Oct 3, 2018

comment:36

Ah, I didn't know about the groups catalog, this is a very good solution, thanks! I fixed a typo in the catalog and removed the now empty file lie_gps/all.py

I modified the _repr_ method of Lie group elements to avoid unnecessarily calling chart_exp2 in case the default chart is _Exp1, since the computation is quite expensive. Although the current form is not ideal either, since now if the default coordinate chart is something other than chart_exp2 or _Exp1, then it will still unnecessarily compute the transitions to and from exp-2 coordinates. Not sure how to handle this without the _Exp2=None default.

Other than that, the changes look good to me.

@egourgoulhon
Copy link
Member

comment:37

Replying to @tscrim:

If my changes are good, then I think we can set a positive review unless Eric has some more comments.

Everything looks good to me, so I agree with the positive review.
Thanks for the nice work!

@vbraun
Copy link
Member

vbraun commented Oct 5, 2018

Changed branch from public/groups/nilpotent_lie_groups-26344 to b2ef2d9

@jdemeyer
Copy link

Changed reviewer from Eric Gourgoulhon and Travis Scrimshaw to Eric Gourgoulhon, Travis Scrimshaw

@jdemeyer
Copy link

Changed commit from b2ef2d9 to none

@embray
Copy link
Contributor

embray commented Oct 28, 2018

comment:41

This should be re-targeted for 8.5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants