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

Add symplectic structures #30362

Closed
tobiasdiez opened this issue Aug 14, 2020 · 225 comments
Closed

Add symplectic structures #30362

tobiasdiez opened this issue Aug 14, 2020 · 225 comments

Comments

@tobiasdiez
Copy link
Contributor

This ticket implements the basics of symplectic structures,
like Poisson brackets and Hamiltonian vector fields.

TODO (as follow-up tickets):

  • Extract general coordinate stuff from EuclideanSpace
    to new class VectorSpace, and let SymplecticVectorSpace
    derive from VectorSpace

CC: @tscrim @nthiery @mjungmath @egourgoulhon @mkoeppe

Component: manifolds

Author: Tobias Diez

Branch: b78d8a2

Reviewer: Eric Gourgoulhon, Michael Jung, Matthias Koeppe, Travis Scrimshaw

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

@tobiasdiez tobiasdiez added this to the sage-9.2 milestone Aug 14, 2020
@mjungmath
Copy link

comment:1

In my humble opinion, I think the very first step should be to establish a Poisson manifold. This is much more general, i.e. symplectic structures / manifolds are special cases of them. Since none of these are implemented yet, it is much easier to start with the more general setup.

I would like to get some initial feedback, before I cleanup the code and documentation.

I am still busy with other things, but as soon as I have some free time, I could go through your code. However, it would be good to at least remove unneccessary methods (like e.g. hodge_star or sqrt_abs_det) to make the code much more readable and seek your new features immediately.

I noticed that you already added typing. I think, this belongs to another ticket, namely #29775, and should be discussed there before we apply it to new things. There is still this issue with pyflakes and it seems there are still different opinions.

For me SymplecticFormParal is only a implementation detail, so I don't actually want to expose it to the user. Any ideas? (probably needs some modifications in the tensorfield.restrict method).

The use of ...Paral is of course necessary since structures on manifolds are "glued together" via parallelizable parts. I agree in so far that there is no explicit need to expose it to the user since this is all managed via methods in manifold.py, that's right. Howver, in my opinion, there's also nothing wrong about it. Since this is a general problem not only restricted to symplectic forms, I suggest you open another ticket if you want to discuss it.

@mjungmath
Copy link

comment:2

I swiftly overviewed your code. It's a nice addition! However, I have some comments:

  • I think, this is redundant:
         PseudoRiemannianMetric._del_derived(self)
+        self._del_inverse()
 
     def _del_inverse(self):
The method `_del_inverse` is already invoked in `PseudoRiemannianMetric._del_derived`.
  • I am not sure that sharp and flat are proper names for lowering/raising the index w.r.t. a symplectic structure, I presume they are reserved for metrics only. raise and lower sounds more appropriate to me.

  • In my opinion this change is not necessary either:

     """
-    def __init__(self, n, name, field, structure, base_manifold=None,
+    def __init__(self, n, name, field='real', structure=RealDifferentialStructure(), base_manifold=None,
                  diff_degree=infinity, latex_name=None, start_index=0,
                  category=None, unique_tag=None):
The default input is already managed by the factory method `Manifolds`. And in my opinion, it should stay there for maintenance reasons.
  • It would be good to add a new category for symplectic manifolds and also a new structure in manifolds/structure.py. Besides, I am not sure, is it possible to combine structures? Symplectic and pseudo-Riemannian structures certainly do not exclude each other. If not, I think this is something we should attack at some point. The more structures we allow, the more flexible the framework has to be.

  • I still think that starting with Poisson manifolds is a more reasonable approach. Anyway, someone always has to have the time to do it.

@mkoeppe mkoeppe modified the milestones: sage-9.2, sage-9.3 Sep 5, 2020
@egourgoulhon
Copy link
Member

comment:4

Symplectic structures are certainly a nice addition to Sage! Thank you for contributing to this.

I gave a look to the code, but I have to say that in the current state, it is hardly readable for me, because the docstrings are simply copied from other files, without any cleaning nor adaptation of the doctests to the new features introduced here. Can I suggest that you move forward and provide a first version with some minimal documentation and doctests, cleaning out what does not pertain to this ticket.

Replying to @mjungmath:

For me SymplecticFormParal is only a implementation detail, so I don't actually want to expose it to the user. Any ideas? (probably needs some modifications in the tensorfield.restrict method).

The use of ...Paral is of course necessary since structures on manifolds are "glued together" via parallelizable parts. I agree in so far that there is no explicit need to expose it to the user since this is all managed via methods in manifold.py, that's right. Howver, in my opinion, there's also nothing wrong about it. Since this is a general problem not only restricted to symplectic forms, I suggest you open another ticket if you want to discuss it.

SymplecticFormParal is not exposed to the user, since the interface should not be via the class names but rather via a method M.symplectic_form() of the manifold M, which returns a SymplecticFormParal if M is parallelizable and a SymplecticForm otherwise.

Besides, I agree with Michael's remarks in comment:2.

@mjungmath
Copy link

comment:5

Replying to @egourgoulhon:

Can I suggest that you move forward and provide a first version with some minimal documentation and doctests, cleaning out what does not pertain to this ticket.

+1

@tobiasdiez
Copy link
Contributor Author

comment:6

Thanks for the feedback. I'll cleanup and improve the code accordingly. I might need a couple of weeks for this however as I'm currently quite busy.

@tobiasdiez
Copy link
Contributor Author

comment:7

Thanks for the initial reviews!

Replying to @mjungmath:

I swiftly overviewed your code. It's a nice addition! However, I have some comments:

  • I think, this is redundant:
         PseudoRiemannianMetric._del_derived(self)
+        self._del_inverse()
 
     def _del_inverse(self):
The method `_del_inverse` is already invoked in `PseudoRiemannianMetric._del_derived`.

Agreed! Not sure why I added it in the first place, but I've now reverted this change.

  • I am not sure that sharp and flat are proper names for lowering/raising the index w.r.t. a symplectic structure, I presume they are reserved for metrics only. raise and lower sounds more appropriate to me.

The terminology sharp and flat (as well as musical isomorphisms) is standard in symplectic geometry, too. See for example Abraham Marsden Foundations of Mechanics.

  • In my opinion this change is not necessary either:
     """
-    def __init__(self, n, name, field, structure, base_manifold=None,
+    def __init__(self, n, name, field='real', structure=RealDifferentialStructure(), base_manifold=None,
                  diff_degree=infinity, latex_name=None, start_index=0,
                  category=None, unique_tag=None):
The default input is already managed by the factory method `Manifolds`. And in my opinion, it should stay there for maintenance reasons.

I think, it's strange if the constructor requires more data than actually is required. Although that might be a matter of taste, but I find M = TopologicalManifold(2, 'M') more readable than M = Manifold(2, 'M', structure='topological').

  • It would be good to add a new category for symplectic manifolds and also a new structure in manifolds/structure.py. Besides, I am not sure, is it possible to combine structures? Symplectic and pseudo-Riemannian structures certainly do not exclude each other. If not, I think this is something we should attack at some point. The more structures we allow, the more flexible the framework has to be.

Agreed! But I would like to leave the categorical questions to a follow-up ticket!

  • I still think that starting with Poisson manifolds is a more reasonable approach. Anyway, someone always has to have the time to do it.

I'm working on it.

@tobiasdiez

This comment has been minimized.

@tobiasdiez
Copy link
Contributor Author

Dependencies: #30901, #30748

@mjungmath
Copy link

comment:9
  • I am not sure that sharp and flat are proper names for lowering/raising the index w.r.t. a symplectic structure, I presume they are reserved for metrics only. raise and lower sounds more appropriate to me.

The terminology sharp and flat (as well as musical isomorphisms) is standard in symplectic geometry, too. See for example Abraham Marsden Foundations of Mechanics.

You have a page? I only find the terminology 'lowering' and 'raising'.

@tobiasdiez
Copy link
Contributor Author

comment:10

In the second edition, its definition 3.2.1 (p. 174, chapter about symplectic geometry). They don't write "sharp" or "flat" as words, but use the musical symbols.

@egourgoulhon
Copy link
Member

comment:11

Replying to @tobiasdiez:

Although that might be a matter of taste, but I find M = TopologicalManifold(2, 'M') more readable than M = Manifold(2, 'M', structure='topological').

I agree, but the reason for using the function Manifold instead of a direct call to a specific class, like TopologicalManifold, is to not clutter Sage's global namespace, which is already very large. Likewise, at the user level, one has to use Manifold(..., structure='symplectic') instead of SymplecticManifold(...).

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 25, 2020

Changed commit from 1dfcf8a to edc41c5

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 25, 2020

Branch pushed to git repo; I updated commit sha1. Last 10 new commits:

13216c1Fix multiarch for shared libraries
d9f36dcDon't use Python 3.8 syntax
94e20c7Revert some of the changes
6dd6e5cFix compilation
eceefb3Remove string wrap
d345bffFix test
c47c4bfCorrect indent
360b312Merge branch 'public/build/multiarchsimple' of git://trac.sagemath.org/sage into public/manifolds/symplectic
2f2997cRevert del_inverse change
edc41c5Rework symplectic form, and introduce Poisson structures

@tobiasdiez
Copy link
Contributor Author

comment:13

Ok, makes sense!

I've continued working on it, introduced Poisson structures, wrote most of the documentation and introduced a few tests. It's not yet finished, but if you have a spare minute I would like to get feedback.

A few questions:

  • I get the following error message. What's the origin, and what do I have to do to make it work?
src/sage/manifolds/differentiable/symplectic_form.py:973: in poisson
    if frame not in self._poisson._components:
sage/structure/element.pyx:493: in sage.structure.element.Element.__getattr__
    ???
sage/structure/element.pyx:506: in sage.structure.element.Element.getattr_from_category
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

>   ???
E   AttributeError: 'SymplecticVectorSpace_with_category' object has no attribute '__custom_name'
  • I'm still somewhat confused by the subclasses that handle the structure on a parallelizable manifold. For example, in the symplectic form class I create the Poisson tensor, give it a name etc.
poisson_name = f'poisson_{self._name}'
poisson_latex_name = f'{self._latex_name}^{{-1}}'
self._poisson = PoissonTensorField(self._vmodule, poisson_name, poisson_latex_name)

How do I make sure that it derives from TensorFieldParal if the manifold is parallelizable? I can of course put the same code in SymplecticFormParal and replace PoissonTensorField by PoissonTensorFieldParal but this appears to be somewhat subopmimal.

Moreover, do I have to copy-paste the documentation from the parent class, or what is the convention?

  • How do I obtain a general function on a manifold? On a vector space M, I can do something like
q, p = M.cartesian_coordinates()[:]
f = M.scalar_field(function('f')(q,p), name='f')

but what would be the version on a sphere (in such a way that the code works for M being a vector space and a sphere)?

  • Since the hodge star operator makes sense also with respect to a symplectic form, I would propose to move the current method from Metric to DifferentialForm: DifferentialForm.hodge_star(Metric|SymplecticForm) (with an alias in Metric and SymplecticForm). Opinions?

  • What is the best way to test if two differential forms are equal (including / except of their name)?

Thanks!

@egourgoulhon
Copy link
Member

comment:14

Replying to @tobiasdiez:

  • I'm still somewhat confused by the subclasses that handle the structure on a parallelizable manifold. For example, in the symplectic form class I create the Poisson tensor, give it a name etc.
poisson_name = f'poisson_{self._name}'
poisson_latex_name = f'{self._latex_name}^{{-1}}'
self._poisson = PoissonTensorField(self._vmodule, poisson_name, poisson_latex_name)

How do I make sure that it derives from TensorFieldParal if the manifold is parallelizable?

You should construct the Poisson tensor from the module of vector fields on the manifold, not by a direct call to PoissonTensorField, see the example of DifferentiableManifold.metric() in src/sage/manifods/differentiable/manifold.py.

Moreover, do I have to copy-paste the documentation from the parent class, or what is the convention?

I don't understand the question, sorry. Could you rephrase it?

  • How do I obtain a general function on a manifold? On a vector space M, I can do something like
q, p = M.cartesian_coordinates()[:]
f = M.scalar_field(function('f')(q,p), name='f')

but what would be the version on a sphere (in such a way that the code works for M being a vector space and a sphere)?

The symbolic functions created by function(...) are functions of coordinates on a given chart; so to construct a generic function on a manifold, you have to pass a dictionary with as many charts as necessary to cover the manifold:

   f = M.scalar_field({X1: function('f_1')(q1, p1), X2: function('f_2')(q2, p2),...})

where X1 is the chart with coordinates (q1, p1), etc.

  • Since the hodge star operator makes sense also with respect to a symplectic form, I would propose to move the current method from Metric to DifferentialForm: DifferentialForm.hodge_star(Metric|SymplecticForm) (with an alias in Metric and SymplecticForm). Opinions?

The Hodge star is already in DifferentialForm: it is called hodge_dual() there and its code
is simply return metric.hodge_star(self).

  • What is the best way to test if two differential forms are equal (including / except of their name)?

I would say simply a == b.
This is actually computing a - b (in an efficient way, using the full antisymmetry of a and b's components) and tests whether the result is zero.

A question from my side: why is this ticket depending on #30901 and #30748 ? In the ticket description you write Please ignore the dependencies, these are just there so that I can work locally on my PC. This looks somewhat odd...

Maybe this is related, but the ticket branch contains the following modified files:

-rw-r--r--	.gitignore	9	
-rw-r--r--	src/sage/all.py	6	
-rw-r--r--	src/sage/all_cmdline.py	1	
-rw-r--r--	src/sage/env.py	76	
-rw-r--r--	src/sage/libs/gap/util.pyx	1		
-rw-r--r--	src/sage/libs/singular/singular.pyx	11	
-rw-r--r--	src/sage/misc/lazy_import.pyx	69	
-rw-r--r--	src/sage/misc/startup_guard.py	25			
-rw-r--r--	src/test.py	64	

Do they really pertain to this ticket?

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 25, 2020

Changed commit from edc41c5 to c6fb9c6

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 25, 2020

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

c6fb9c6Fix tests

@tobiasdiez
Copy link
Contributor Author

comment:16

Replying to @egourgoulhon:

Replying to @tobiasdiez:

  • I'm still somewhat confused by the subclasses that handle the structure on a parallelizable manifold. For example, in the symplectic form class I create the Poisson tensor, give it a name etc.
poisson_name = f'poisson_{self._name}'
poisson_latex_name = f'{self._latex_name}^{{-1}}'
self._poisson = PoissonTensorField(self._vmodule, poisson_name, poisson_latex_name)

How do I make sure that it derives from TensorFieldParal if the manifold is parallelizable?

You should construct the Poisson tensor from the module of vector fields on the manifold, not by a direct call to PoissonTensorField, see the example of DifferentiableManifold.metric() in src/sage/manifods/differentiable/manifold.py.

Ok, thanks! That makes sense indeed and worked.

Moreover, do I have to copy-paste the documentation from the parent class, or what is the convention?

I don't understand the question, sorry. Could you rephrase it?

If I implement a method in say PoissonTensorFieldParal that overrides a method in PoissonTensorField, do I have to add documentation/tests/examples to the method in ``PoissonTensorFieldParal` (given that the signature of the method is exactly the same)?
I think sphinx normally copies the documentation given in the parent class.

  • How do I obtain a general function on a manifold? On a vector space M, I can do something like
q, p = M.cartesian_coordinates()[:]
f = M.scalar_field(function('f')(q,p), name='f')

but what would be the version on a sphere (in such a way that the code works for M being a vector space and a sphere)?

The symbolic functions created by function(...) are functions of coordinates on a given chart; so to construct a generic function on a manifold, you have to pass a dictionary with as many charts as necessary to cover the manifold:

   f = M.scalar_field({X1: function('f_1')(q1, p1), X2: function('f_2')(q2, p2),...})

where X1 is the chart with coordinates (q1, p1), etc.

That worked! Merci!

  • Since the hodge star operator makes sense also with respect to a symplectic form, I would propose to move the current method from Metric to DifferentialForm: DifferentialForm.hodge_star(Metric|SymplecticForm) (with an alias in Metric and SymplecticForm). Opinions?

The Hodge star is already in DifferentialForm: it is called hodge_dual() there and its code
is simply return metric.hodge_star(self).

  • What is the best way to test if two differential forms are equal (including / except of their name)?

I would say simply a == b.
This is actually computing a - b (in an efficient way, using the full antisymmetry of a and b's components) and tests whether the result is zero.

That worked as well!

A question from my side: why is this ticket depending on #30901 and #30748 ? In the ticket description you write Please ignore the dependencies, these are just there so that I can work locally on my PC. This looks somewhat odd...

Maybe this is related, but the ticket branch contains the following modified files:

-rw-r--r--	.gitignore	9	
-rw-r--r--	src/sage/all.py	6	
-rw-r--r--	src/sage/all_cmdline.py	1	
-rw-r--r--	src/sage/env.py	76	
-rw-r--r--	src/sage/libs/gap/util.pyx	1		
-rw-r--r--	src/sage/libs/singular/singular.pyx	11	
-rw-r--r--	src/sage/misc/lazy_import.pyx	69	
-rw-r--r--	src/sage/misc/startup_guard.py	25			
-rw-r--r--	src/test.py	64	

Do they really pertain to this ticket?

Sorry for these (unnessary) changes. The only way I currently have to work on sage is with the virtual environment created in #30371. The compiled cython however only works correctly if the changes of #30901 and #30748 are included. Thus, until these packages are merged, I have to sadly include them as dependencies on all packages I develop...maybe you or Matthias have a better idea for a workaround.

Now all tests are passing (not sure about the doctests), and the only thing left is to change the documentation a bit.


New commits:

c6fb9c6Fix tests

@mkoeppe
Copy link
Contributor

mkoeppe commented Nov 25, 2020

comment:17

Replying to @tobiasdiez:

A question from my side: why is this ticket depending on #30901 and #30748 ? In the ticket description you write Please ignore the dependencies, these are just there so that I can work locally on my PC. This looks somewhat odd...

Indeed, this is not the way to do this.

Sorry for these (unnessary) changes. The only way I currently have to work on sage is with the virtual environment created in #30371. [...]maybe you or Matthias have a better idea for a workaround.

I would suggest to create a clean branch starting from the latest beta and to push that to the ticket only. Use git cherry-pick to get the commits from your branch (with the dependencies that you say you need for running Sage) onto the clean branch. Push the clean branch to the ticket.

@tobiasdiez
Copy link
Contributor Author

Author: Tobias Diez

@tobiasdiez

This comment has been minimized.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 27, 2020

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

c507da7Add documentation to symplectic vector space

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 27, 2020

Changed commit from c6fb9c6 to c507da7

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 27, 2020

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

da7e6c3Revise docs for Poissen tensors

@tobiasdiez
Copy link
Contributor Author

comment:166

Thanks for the review and the fix!

@mkoeppe
Copy link
Contributor

mkoeppe commented Dec 21, 2021

comment:167

Looks good to me too.

@mjungmath
Copy link

comment:168

Last question: do we really need to import everything in the test files?

Otherwise, LGTM.

@tobiasdiez
Copy link
Contributor Author

comment:169

Replying to @mjungmath:

Last question: do we really need to import everything in the test files?

Otherwise, LGTM.

Sadly yes, at the moment, since there are a few cyclic imports that are only resolved using the sage.all import.

@mjungmath
Copy link

comment:170

Then we should probably add a TODO comment so that we don't forget to rectify this in due course, no?

@vbraun
Copy link
Member

vbraun commented Dec 23, 2021

comment:171

Merge conflict

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Dec 24, 2021

Changed commit from 8ca1724 to b78d8a2

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Dec 24, 2021

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

b78d8a2#30362: fix merge conflict

@egourgoulhon
Copy link
Member

comment:173

Merge conflict fixed.

@vbraun
Copy link
Member

vbraun commented Jan 31, 2022

Changed branch from public/manifolds/symplectic to b78d8a2

@egourgoulhon
Copy link
Member

comment:176

Now that the branch has been merged in Sage 9.6.beta0 (unfortunately it did not make its way to Sage 9.5...), there remains a last thing to do: preparing some examples of use for Sage 9.6 release tour, on the same footing as what has been done for Sage 9.5:
https://wiki.sagemath.org/ReleaseTours/sage-9.5#Manifolds. I've just added an entry for this in Sage 9.6 release tour. Tobias, could you provide some nice examples?

@egourgoulhon
Copy link
Member

Changed commit from b78d8a2 to none

@tobiasdiez
Copy link
Contributor Author

comment:177

Is a copy&paste from the doctests good enough?

Should I paste it here then, or how does one get access to the wiki?

@tscrim
Copy link
Collaborator

tscrim commented Feb 8, 2022

comment:178

Replying to @tobiasdiez:

Is a copy&paste from the doctests good enough?

It would be a bit better to give a very quick summary and some simple example usage (which can by c/p from the doctests).

Should I paste it here then, or how does one get access to the wiki?

You can edit the wiki by logging in with your trac account info. I don't know if it works for gh authentication.

@egourgoulhon
Copy link
Member

comment:179

Replying to @egourgoulhon:

Now that the branch has been merged in Sage 9.6.beta0 (unfortunately it did not make its way to Sage 9.5...), there remains a last thing to do: preparing some examples of use for Sage 9.6 release tour, on the same footing as what has been done for Sage 9.5:
https://wiki.sagemath.org/ReleaseTours/sage-9.5#Manifolds. I've just added an entry for this in Sage 9.6 release tour. Tobias, could you provide some nice examples?

Ping
(since the release of Sage 9.6 seems to be close).

@egourgoulhon
Copy link
Member

comment:180

Another ping, pointing to the new release tour page, which is editable via a github login:
https://trac.sagemath.org/wiki/ReleaseTours/sage-9.6?version=13#Symplecticmanifolds
Tobias, would you have time to provide a few examples there?

@tobiasdiez
Copy link
Contributor Author

comment:181

Sorry, I've been somewhat busy and forgot about this. Thanks for the reminder! I've now updated the release notes with a quick introduction.

@egourgoulhon
Copy link
Member

comment:182

Replying to @tobiasdiez:

I've now updated the release notes with a quick introduction.

Thanks!

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

7 participants